/* * file com_browse.c - base communication to browse for network games * * $Id: com_browse.c,v 1.3 2004/05/14 10:00:33 alfie Exp $ * * Program XBLAST * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2; or (at your option) * any later version * * This program is distributed in the hope that it will be entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "com_browse.h" #include "net_dgram.h" #include "str_util.h" /* * local types */ struct _xb_browse_data { XBBrowseData *next; char *hostname; unsigned short port; XBBool broadcast; XBDatagram *dgram; }; /* * */ static XBBrowseData * CreateBrowseData (const char *hostname, unsigned port, XBBool broadcast, const XBBrowseTeleAny *tele) { XBBrowseData *ptr; size_t len; unsigned char data[MAX_DGRAM_SIZE]; /* write telegram */ assert (NULL != tele); len = BrowseTele_Write (tele, data); /* alloc data */ ptr = calloc (1, sizeof (*ptr)); assert (NULL != ptr); /* set values */ ptr->hostname = (hostname != NULL) ? DupString (hostname) : NULL; ptr->port = port; ptr->broadcast = broadcast; ptr->dgram = Net_CreateDatagram (data, len); /* that's all */ return ptr; } /* CreateBrowseData */ /* * */ static void DeleteBrowseData (XBBrowseData *ptr) { assert (NULL != ptr); if (NULL != ptr->hostname) { free (ptr->hostname); } Net_DeleteDatagram (ptr->dgram); /* --- */ free (ptr); } /* DeleteBrowseData */ /* * */ static XBCommResult WriteBrowse (XBComm *comm) { XBBrowseData *next; /* get communication */ XBCommBrowse *bComm = (XBCommBrowse *) comm; assert (NULL != bComm); /* send data if any */ if (NULL != bComm->sndFirst) { if (! Net_SendDatagramTo (bComm->sndFirst->dgram, comm->socket, bComm->sndFirst->hostname, bComm->sndFirst->port, bComm->sndFirst->broadcast) ) { return XCR_Error; } next = bComm->sndFirst->next; DeleteBrowseData (bComm->sndFirst); bComm->sndFirst = next; if (NULL == bComm->sndFirst) { bComm->sndLast = NULL; } } /* any data left */ if (NULL == bComm->sndFirst) { Socket_UnregisterWrite (CommSocket (comm)); } return XCR_OK; } /* WriteBrowse */ /* * read datagram from host and port */ static XBCommResult ReadBrowse (XBComm *comm) { XBDatagram *rcv; const char *host; unsigned short port; const void *data; size_t len; XBBrowseTele tele; /* get communication */ XBCommBrowse *bComm = (XBCommBrowse *) comm; assert (NULL != bComm); /* get datagram */ if (NULL == (rcv = Net_ReceiveDatagramFrom (bComm->comm.socket, &host, &port) ) || NULL == (data = Net_DgramData (rcv, &len) ) ) { return XCR_OK; } /* parse it */ if (XBBT_None != BrowseTele_Parse (&tele, data, len) ) { assert (NULL != bComm->receiveFunc); (*bComm->receiveFunc) (bComm, &tele, host, port); } return XCR_OK; } /* ReadBrowse */ /* * intialize data structure */ XBComm * Browse_CommInit (XBCommBrowse *bComm, XBCommType commType, XBSocket *pSocket, BrowseReceiveFunc receiveFunc, XBCommFunc deleteFunc) { assert (NULL != bComm); assert (NULL != receiveFunc); /* set values */ CommInit (&bComm->comm, commType, pSocket, ReadBrowse, WriteBrowse, deleteFunc); bComm->sndFirst = NULL; bComm->receiveFunc = receiveFunc; /* that's all */ return &bComm->comm; } /* Browse_CommInit */ /* * */ void Browse_Send (XBCommBrowse *bComm, const char *hostname, unsigned port, XBBool broadcast, const XBBrowseTeleAny *tele) { XBBrowseData *ptr; assert (NULL != bComm); /* append data to queue */ ptr = CreateBrowseData (hostname, port, broadcast, tele); if (NULL != bComm->sndLast) { bComm->sndLast->next = ptr; } else { bComm->sndFirst = ptr; } bComm->sndLast = ptr; /* --- */ Socket_RegisterWrite (CommSocket (&bComm->comm)); } /* Browse_Send */ void Browse_Finish (XBCommBrowse *bComm) { XBBrowseData *next; /* clean up send queue */ while (NULL != bComm->sndFirst) { next = bComm->sndFirst->next; DeleteBrowseData (bComm->sndFirst); bComm->sndFirst = next; } CommFinish (&bComm->comm); } /* Browse_Finish */ /* * end of file com_browse.c */