Main Page   Compound List   File List   Compound Members   File Members  

net.c

00001 /* DICElib (DIstributed CAVE Engine library) 
00002  * Copyright (c) 2001 Bruno Barberi Gnecco <brunobg@lsi.usp.br>
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to
00006  * deal in the Software without restriction, including without limitation the
00007  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00008  * sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies of the Software, its documentation and marketing & publicity
00013  * materials, and acknowledgment shall be given in the documentation, materials
00014  * and software packages that this Software was used.
00015  *
00016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00019  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00020  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022  */
00023 
00024 #include "_dicelib.h"
00025 #include <string.h>
00026 #include <errno.h>
00027 #include <fcntl.h>
00028 #ifndef WINDOWS
00029 #include <netdb.h>
00030 #include <sys/socket.h>
00031 #include <sys/types.h>
00032 #include <unistd.h>
00033 #include <arpa/inet.h>
00034 #include <netinet/in.h>
00035 #else
00036 #include <winsock.h>
00037 #endif
00038 
00039 #define PACK_MAX_LENGTH         16384
00040 
00041 #define FUNCTION        "DICE_packet_send"
00042 
00053 int dice_packet_send ( dice_packet *p, int socket ) {
00054         static char                     packet[PACK_MAX_LENGTH];
00055         char                            *buffer;
00056         int                             size = 256, sent = 0, i;
00057         unsigned short                  length = 4;
00058 
00059         _dice_debug(3, dice_printf(FUNCTION, "(%p,%d)\n", p, socket);)
00060 
00061         memset(packet, 0, size);
00062         packet[0] = (char)p->packtype;
00063         packet[1] = '\0';
00064 
00065         switch ( p->packtype ) {
00066           case INVALID:
00067                 return -1;
00068           case SYNC:
00069                 length = 4;
00070                 break;
00071           case VARIABLE_ASYNC:
00072           case VARIABLE_SYNC:
00073                 buffer = DICE_type_pack("string", (void *)p->variable.name, &i);
00074                 memcpy(&packet[length], buffer, i);
00075                 length += i;
00076                 free(buffer);
00077                 buffer = DICE_type_pack("string", (void *)p->variable.type, &i);
00078                 memcpy(&packet[length], buffer, i);
00079                 length += i;
00080                 free(buffer);
00081                 buffer = DICE_type_pack(p->variable.type, (void *)p->variable.value, &i);
00082                 if (length + i >= PACK_MAX_LENGTH) {
00083                         _dice_debug(1, dice_printf(FUNCTION, "Packet %s is too big: %d bytes\n", 
00084                                         p->variable.name, length+i);)
00085                         return -1;
00086                 }
00087                 memcpy(&packet[length], buffer, i);
00088                 length += i;
00089                 free(buffer);
00090                 break;
00091           case VARIABLE_FREE_ASYNC:
00092           case VARIABLE_FREE_SYNC:
00093                 buffer = DICE_type_pack("string", (void *)p->variable.name, &i);
00094                 memcpy(&packet[length], buffer, i);
00095                 length += i;
00096                 free(buffer);
00097                 break;
00098           case READY:
00099                 length = 4;
00100                 break;
00101           case CONTINUE:
00102                 length = 4;
00103                 break;
00104           case HELLO:
00105                 buffer = DICE_type_pack("unsigned_long", (void *)&p->hello.id, &i);
00106                 memcpy(&packet[length], buffer, i);
00107                 length += i;
00108                 free(buffer);   
00109                 buffer = DICE_type_pack("string", (void *)p->hello.function, &i);
00110                 memcpy(&packet[length], buffer, i);
00111                 length += i;
00112                 free(buffer);
00113                 break;
00114           case GOODBYE:
00115                 length = 4;
00116                 break;
00117           default:
00118                 return -1;
00119                 break;
00120         }
00121 
00122         packet[2] = (length>>8) & 0xFF;
00123         packet[3] = length & 0xFF;
00124 
00125         _dice_debug(3, dice_printf(FUNCTION, "type %s, length %d, sending.\n", 
00126                         dice_packet_name(p->packtype), length);)
00127         while ( sent < length ) {
00128                 i = send(socket, packet+sent, length-sent, 0);
00129                 if ( i == -1 ) {
00130                         /* etc */
00131                         _dice_debug(1, dice_printf(FUNCTION, "%s\n",
00132                                         strerror(errno));)
00133                         return -1;
00134                 }
00135                 sent += i;
00136         }
00137         return 0;
00138 }
00139 
00140 #undef FUNCTION
00141 #define FUNCTION        "DICE_packet_get"
00142 
00151 dice_packet dice_packet_get ( int socket ) {
00152         static unsigned char            queue[16384];
00153         dice_packet                     pack;
00154         int                             i;
00155         unsigned short                  length;
00156         char                            *p;
00157         
00158         _dice_debug(3, dice_printf(FUNCTION, "(%d)\n", socket);)
00159 
00160         pack.packtype = INVALID;
00161 
00162         i = read(socket, queue, 4);
00163         if ( i < 0 ) {
00164                 _dice_debug(1, dice_printf(FUNCTION, "%s\n",
00165                                 strerror(errno));)
00166                 return pack;
00167         }
00168         if ( i == 0 ) {
00169                 /*todo: closed connection... gotta do something here. */
00170                 return pack;
00171         }
00172         while ( i != 4 ) { 
00173                 i += read(socket, queue+i, 4-i);
00174         };
00175 
00176         pack.packtype = (dice_packet_type)queue[0];
00177         if ( queue[1] != '\0' ) {
00178                 _dice_debug(1, dice_printf(FUNCTION, "Packet has problems.\n");)
00179                 return pack;
00180         }
00181         length = (((unsigned int)queue[2])<<8) + (unsigned int)queue[3];
00182 
00183         _dice_debug(3, dice_printf(FUNCTION, "type %s, length %d.\n", 
00184                         dice_packet_name(pack.packtype), length);)
00185         /* read the rest of it */
00186         i = 4;
00187         while ( i < length )
00188                 i += read(socket, queue+i, length-i);
00189         p = queue+4;
00190 
00191         /* fill the structure */
00192         switch ( pack.packtype ) {
00193           case SYNC:
00194                 return pack;
00195           case VARIABLE_SYNC:
00196           case VARIABLE_ASYNC:
00197                 pack.variable.name = (char *)DICE_type_unpack("string", p, &i);
00198                 p += i;
00199                 pack.variable.type = (char *)DICE_type_unpack("string", p, &i);
00200                 p += i;
00201                 if ( !dice_type_is_valid(pack.variable.type) && !dice_is_server() ) {
00202                         _dice_debug(1, dice_printf(FUNCTION, 
00203                                         "register %s!", pack.variable.type);)
00204                         return pack;
00205 #if 0
00206                         if ( DICE_type_register(pack.variable.type) == -1 ) {
00207                                 /* todo something! */
00208                         }
00209 #endif
00210                 }
00211                 pack.variable.value = DICE_type_unpack(pack.variable.type, p, &i);
00212                 p += i;
00213                 if ( p - (char *)queue != length )
00214                         _dice_debug(2, dice_printf(FUNCTION, 
00215                                         "Packet has problems: size[%d] nominal:[%d].\n",
00216                                         p - (char *)queue, length);)
00217                 return pack;
00218           case VARIABLE_FREE_SYNC:
00219           case VARIABLE_FREE_ASYNC:
00220                 pack.variable.name = (char *)DICE_type_unpack("string", p, &i);
00221                 p += i;
00222                 if ( p - (char *)queue != length )
00223                         _dice_debug(2, dice_printf(FUNCTION, "Packet has problems.\n");)
00224                 return pack;
00225           case READY:
00226                 return pack;
00227           case CONTINUE:
00228                 return pack;
00229           case HELLO:
00230                 pack.hello.id = *(unsigned long *)DICE_type_unpack("unsigned_long", p, &i);
00231                 p += i;
00232                 pack.hello.function = (char *)DICE_type_unpack("string", p, &i);
00233                 p += i;
00234                 if ( p - (char *)queue != length )
00235                         _dice_debug(2, dice_printf(FUNCTION, 
00236                                         "Packet has problems: size[%d] nominal:[%d]; (%ld %s)\n",
00237                                         p - (char *)queue, length, pack.hello.id, pack.hello.function);)
00238                 return pack;
00239           case GOODBYE:
00240                 return pack;
00241           default:
00242                 pack.packtype = INVALID;
00243                 return pack;
00244         }
00245 }
00246 
00247 char *dice_packet_name ( dice_packet_type t ) {
00248         switch ( t ) {
00249                 case    INVALID:
00250                         return "INVALID";
00251                 case    SYNC:           
00252                         return "SYNC";
00253                 case    VARIABLE_ASYNC: 
00254                         return "VARIABLE_ASYNC";
00255                 case    VARIABLE_SYNC:  
00256                         return "VARIABLE_SYNC";
00257                 case    VARIABLE_FREE_ASYNC:
00258                         return "VARIABLE_FREE_ASYNC";
00259                 case    VARIABLE_FREE_SYNC:
00260                         return "VARIABLE_FREE_SYNC";
00261                 case    READY:          
00262                         return "READY";
00263                 case    CONTINUE:       
00264                         return "CONTINUE";
00265                 case    HELLO:
00266                         return "HELLO";
00267                 case    GOODBYE:
00268                         return "GOODBYE";
00269         }
00270         return NULL;
00271 };

Generated at Sun Dec 9 16:13:18 2001 for dicelib by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001