Info
Get involved
Documentation
00001 /* 00002 SAL - Simple Application Library 00003 Copyright (C) 2006-2006 Kronon 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 Kronon 00020 kronon88@users.sourceforge.net 00021 */ 00022 00023 //SAL network functionality 00024 //Created by Kronon 00025 00026 //Doxy gen information 00027 00032 #include "SAL_network.h" 00033 00041 int SAL_start_network() 00042 { 00043 //Start SDLNet library 00044 if(SDLNet_Init()==-1) 00045 { 00046 salError("Couldn't start network.", SDLNet_GetError()); 00047 exit(2); 00048 } 00049 return 0; 00050 } 00051 00059 int SAL_stop_network() 00060 { 00061 //Stop threads 00062 for(SAL_struct.internal.event.network_listeners.setLoopBegin(); SAL_struct.internal.event.network_listeners.inLoop(); ) 00063 { 00064 //Free thread 00065 SDL_WaitThread(SAL_struct.internal.event.network_listeners.getLoopEntry()->thread, NULL); 00066 //Free socket set 00067 SDLNet_FreeSocketSet(SAL_struct.internal.event.network_listeners.getLoopEntry()->socketSet); 00068 //Free all sockets in network listener 00069 for(SAL_struct.internal.event.network_listeners.getLoopEntry()->sockets.setLoopBegin(); SAL_struct.internal.event.network_listeners.getLoopEntry()->sockets.inLoop(); ) 00070 { 00071 SDLNet_UDP_Close(SAL_struct.internal.event.network_listeners.getLoopEntry()->sockets.getLoopEntry()); 00072 } 00073 } 00074 00075 SDLNet_Quit(); 00076 return 0; 00077 } 00078 00085 int addUdpInputSocket(Uint16 portNr) 00086 { 00087 if(SAL_struct.internal.event.network_listeners.getSize() == 0) 00088 { 00089 //Add first network listener thread 00090 SAL_struct.internal.event.last_network_listener = new SAL_network_listener; 00091 SAL_struct.internal.event.last_network_listener->socketSet = SDLNet_AllocSocketSet(SAL_struct.setting.common.max_con_network_listener); 00092 SAL_struct.internal.event.network_listeners.append(SAL_struct.internal.event.last_network_listener); 00093 SAL_struct.internal.event.last_network_listener->thread = SDL_CreateThread(SAL_network_listener_thread, NULL); 00094 printf("0 listeners adding 1\n"); 00095 } 00096 else if(SAL_struct.internal.event.last_network_listener->sockets.getSize() < SAL_struct.setting.common.max_con_network_listener) 00097 { 00098 //Add another network listener thread 00099 SAL_struct.internal.event.last_network_listener = new SAL_network_listener; 00100 SAL_struct.internal.event.last_network_listener->socketSet = SDLNet_AllocSocketSet(SAL_struct.setting.common.max_con_network_listener); 00101 SAL_struct.internal.event.network_listeners.append(SAL_struct.internal.event.last_network_listener); 00102 SAL_struct.internal.event.last_network_listener->thread = SDL_CreateThread(SAL_network_listener_thread, NULL); 00103 printf("Multi listeners adding 1\n"); 00104 } 00105 //Create and safe socket 00106 UDPsocket socket = SDLNet_UDP_Open(portNr); 00107 SAL_struct.internal.event.last_network_listener->sockets.append(socket); 00108 00109 //Add socket to listening socket set 00110 if(SDLNet_UDP_AddSocket(SAL_struct.internal.event.last_network_listener->socketSet, socket) == -1) 00111 { 00112 salError("Failed to sign socket to socket set"); 00113 } 00114 00115 return 0; 00116 } 00117 00124 int addUdpOutputSocket(Uint16 portNr) 00125 { 00126 UDPsocket socket = NULL; 00127 socket = SDLNet_UDP_Open(portNr); 00128 if(!socket) //Couldn't open specified socket 00129 { 00130 socket = SDLNet_UDP_Open(0); //Check if it helps to open an random socket instead 00131 if(!socket) 00132 { 00133 salError("Couldn open any socket"); 00134 return -1; 00135 } 00136 else 00137 salError("Couldn't open socket, opend random socket instead"); 00138 } 00139 SAL_struct.internal.event.socketsOut.append(socket); 00140 return 0; 00141 } 00142 00153 int sendUdpMessage(const char* message, Uint16 mesLen, IPaddress *addresses, Uint8 numIp, UDPsocket socket) 00154 { 00155 UDPpacket *packet = SDLNet_AllocPacket(mesLen); //Create new packet thats used over and over again 00156 int numSent; 00157 packet->len = mesLen; 00158 packet->data = (Uint8 *)message; 00159 00160 if(numIp == 0) //Send message to one ip address 00161 { 00162 packet->address = *addresses; //Set recipient NOTE:does this work? 00163 numSent = SDLNet_UDP_Send(socket, -1, packet); //Send message 00164 if(!numSent) 00165 { 00166 salError("Packet couldn't be send"); 00167 return -1; 00168 } 00169 } 00170 else //Send message to enlisted ip addresses 00171 { 00172 for(int i = 0; i< numIp; i++) //Loop truh enlisted addresses 00173 { 00174 packet->address = *addresses; //NOTE:Does this work? 00175 numSent = SDLNet_UDP_Send(socket, -1, packet); 00176 if(!numSent) 00177 { 00178 salError("Packet couldn't be send"); 00179 return -1; 00180 } 00181 addresses++; //Select next address 00182 } 00183 } 00184 return 0; 00185 } 00186 00194 int SAL_network_listener_thread(void * unused) 00195 { 00196 UDPpacket *packet; 00197 SAL_network_listener *listener; //This network listener 00198 int numRecv = 0, numWaiting = 0; //Number of connections receved 00199 listener = SAL_struct.internal.event.last_network_listener; 00200 00201 packet = SDLNet_AllocPacket(SAL_MAX_PACKET_SIZE); //Create new packet thats used over and over again 00202 if(!packet) 00203 { 00204 salError("Failed to create packet",SDLNet_GetError()); 00205 } 00206 00207 while(SAL_struct.internal.checks.alive) 00208 { 00209 //Wait for network activity or network time out 00210 numWaiting = SDLNet_CheckSockets(listener->socketSet, SAL_struct.setting.common.network_time_out_time); 00211 if(numWaiting==-1) 00212 { 00213 salError("Network error while waiting for package"); 00214 } 00215 else if(numWaiting == 0) //Time out 00216 { 00217 if(SAL_struct.setting.common.network_time_out_function) 00218 { 00219 SAL_struct.setting.common.network_time_out_function(); 00220 } 00221 continue; 00222 } 00223 00224 for(listener->sockets.setLoopBegin(); listener->sockets.inLoop(); ) 00225 { 00226 numRecv=SDLNet_UDP_Recv(listener->sockets.getLoopEntry(), packet); //Fetch new packet 00227 00228 //Message whas receved on other port 00229 if(numRecv == 0) 00230 { 00231 // printf("message goes to other\n"); 00232 continue; 00233 } 00234 //Port whas caught in an error 00235 if(numRecv == -1) 00236 { 00237 salError("Network error while retreaving packet"); 00238 } 00239 else 00240 { 00241 //TODO:Fetch data using network byte order 00242 00243 //Get space for incoming data 00244 Uint32 *data = (Uint32 *)malloc(sizeof(char) * packet->len); 00245 //Translate incomming message to correct Endian and store into memory 00246 Uint32 *tData = (Uint32 *)packet->data; //32 bits is faster then 8 bits:) 00247 for(Uint16 i = 0; i < packet->len/4; i++) 00248 { 00249 data[i] = tData[i]; //Copy data 00250 } 00251 00252 #ifdef SAL_DEBUG 00253 char * cData = (char *) data; //To be able to read the data as chars 00254 for(Uint16 i = 0; i < packet->len; i++) 00255 { 00256 printf("%c",(char) cData[i]); 00257 } 00258 00259 printf("\n"); 00260 #endif 00261 //TODO: run event handler 00262 } 00263 } 00264 } 00265 SDLNet_FreePacket(packet); 00266 return 0; 00267 } 00268 00275 int salSetNetworkHandler(int (*network_handler)(char *message, IPaddress *address)) 00276 { 00277 SAL_struct.internal.event.network_handler.handler = network_handler; 00278 return 0; 00279 }