Changeset 4430:773d77b04aed in roaraudio


Ignore:
Timestamp:
10/09/10 14:29:36 (13 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

implement SERVER_INFO with IT_SERVER

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/serverinfo.c

    r4428 r4430  
    4242}; 
    4343 
    44 struct roar_server_info * roar_server_info(struct roar_connection * con); 
     44struct roar_server_info * roar_server_info(struct roar_connection * con) { 
     45 struct roar_message mes; 
     46 uint16_t * d16; 
     47 
     48 memset(&mes, 0, sizeof(mes)); 
     49 
     50 mes.cmd = ROAR_CMD_SERVER_INFO; 
     51 mes.datalen = 2*2; 
     52 d16 = (uint16_t*)mes.data; 
     53 
     54 d16[0] = ROAR_HOST2NET16(0); // version 
     55 d16[1] = ROAR_HOST2NET16(ROAR_IT_SERVER); 
     56 
     57 if ( roar_req(con, &mes, NULL) != 0 ) 
     58  return NULL; 
     59 
     60 if ( mes.cmd != ROAR_CMD_OK ) 
     61  return NULL; 
     62 
     63 return roar_server_info_from_mes(&mes); 
     64} 
    4565 
    4666int roar_server_info_free(struct roar_server_info * info) { 
     
    6080 int idx = 0; 
    6181 struct ie iebuf[sizeof(struct roar_server_info)/sizeof(char*)]; 
    62  uint16_t * d16; 
     82 uint16_t * d16, * dptr; 
     83 char * textpart; 
     84 int i; 
    6385 
    6486 if ( mes == NULL || info == NULL ) 
     
    87109 d16 = (uint16_t*)mes->data; 
    88110 
    89  return -1; 
    90 } 
    91  
    92 struct roar_server_info * roar_server_info_from_mes(struct roar_message * mes); 
     111 mes->data[0] = 0; // version 
     112 mes->data[1] = 0; // reserved 
     113 
     114 d16[1] = ROAR_HOST2NET16(idx); 
     115 
     116 dptr = &(d16[2]); 
     117 
     118 for (i = 0; i < idx; i++) { 
     119  dptr[0] = ROAR_HOST2NET16(iebuf[i].type & 0xFF); 
     120  dptr[1] = ROAR_HOST2NET16(iebuf[i].len); 
     121  dptr += 2; 
     122 } 
     123 
     124 textpart = mes->data + (4 + 4*idx); 
     125 
     126 for (i = 0; i < idx; i++) { 
     127  memcpy(textpart, iebuf[i].buf, iebuf[i].len); 
     128  textpart += iebuf[i].len; 
     129 } 
     130 
     131 return 0; 
     132} 
     133 
     134struct roar_server_info * roar_server_info_from_mes(struct roar_message * mes) { 
     135 struct ie iebuf[sizeof(struct roar_server_info)/sizeof(char*)]; 
     136 struct ie * ieptr; 
     137 struct roar_server_info * ret = NULL; 
     138 uint16_t * d16, * dptr; 
     139 int idx; 
     140 int i; 
     141 size_t needlen = 4; 
     142 char * textpart; 
     143 char * textbuf; 
     144 char ** tptr; 
     145 
     146 if ( mes == NULL ) 
     147  return NULL; 
     148 
     149 memset(iebuf, 0, sizeof(iebuf)); 
     150 
     151 // some basic texts like version: 
     152 if ( mes->datalen < needlen ) 
     153  return NULL; 
     154 
     155 if ( mes->data[0] != 0 ) /* version */ 
     156  return NULL; 
     157 
     158 if ( mes->data[1] != 0 ) /* reserved */ 
     159  return NULL; 
     160 
     161 d16 = (uint16_t*)mes->data; 
     162 
     163 idx = ROAR_NET2HOST16(d16[1]); 
     164 
     165 // return error if our index buffer is too short. 
     166 if ( idx > (sizeof(iebuf)/sizeof(*iebuf)) ) 
     167  return NULL; 
     168 
     169 needlen += 4*idx; 
     170 
     171 // recheck if we have a complet index. 
     172 if ( mes->datalen < needlen ) 
     173  return NULL; 
     174 
     175 d16 = (uint16_t*)mes->data; 
     176 dptr = &(d16[2]); 
     177 
     178 textpart = mes->data + (4 + 4*idx); 
     179 
     180 for (i = 0; i < idx; i++) { 
     181  iebuf[i].type = ROAR_NET2HOST16(dptr[0]) & 0xFF; 
     182  iebuf[i].len  = ROAR_NET2HOST16(dptr[1]); 
     183  iebuf[i].buf  = textpart; 
     184  needlen  += iebuf[i].len; 
     185  textpart += iebuf[i].len; 
     186 } 
     187 
     188 // recheck if we have all the data... 
     189 if ( mes->datalen < needlen ) 
     190  return NULL; 
     191 
     192 // alloc the needed space. this can be reduced in future to the actual needed value. 
     193 ret = roar_mm_malloc(2*sizeof(struct roar_server_info) + mes->datalen); 
     194 
     195 if ( ret == NULL ) 
     196  return NULL; 
     197 
     198 // for the size see the alloc call above. 
     199 memset(ret, 0, 2*sizeof(struct roar_server_info) + mes->datalen); 
     200 
     201 textbuf = (char*)ret + sizeof(struct roar_server_info); 
     202 
     203 for (i = 0; i < idx; i++) { 
     204  ieptr = &(iebuf[i]); 
     205 
     206   // ignore empty fields 
     207  if ( ieptr->len == 0 ) 
     208   continue; 
     209  if ( ieptr->len == 1 && ieptr->buf[0] == 0 ) 
     210   continue; 
     211 
     212#define _ck(TYPE,member) case TYPE: tptr = &(ret->member); break; 
     213  switch (ieptr->type) { 
     214   _ck(ROAR_ITST_VERSION, version); 
     215   _ck(ROAR_ITST_LOCATION, location); 
     216   _ck(ROAR_ITST_DESCRIPTION, description); 
     217   _ck(ROAR_ITST_CONTACT, contact); 
     218   _ck(ROAR_ITST_SERIAL, serial); 
     219   _ck(ROAR_ITST_ADDRESS, address); 
     220   _ck(ROAR_ITST_UIURL, uiurl); 
     221   _ck(ROAR_ITST_UN_SYSNAME, un.sysname); 
     222   _ck(ROAR_ITST_UN_RELEASE, un.release); 
     223   _ck(ROAR_ITST_UN_NODENAME, un.nodename); 
     224   _ck(ROAR_ITST_UN_MACHINE, un.machine); 
     225   default: 
     226     continue; 
     227    break; 
     228  } 
     229#undef _ck 
     230 
     231  *tptr = textbuf; 
     232   memcpy(textbuf, ieptr->buf, ieptr->len); 
     233   textbuf += ieptr->len; 
     234   *textbuf = 0; // set \0 
     235   textbuf++; 
     236 } 
     237 
     238 return ret; 
     239} 
    93240 
    94241 
Note: See TracChangeset for help on using the changeset viewer.