Changeset 4498:1396b66d445d in roaraudio


Ignore:
Timestamp:
10/13/10 02:23:02 (14 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

implemented basic CAPS api for standards

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • include/libroar/caps.h

    r4497 r4498  
    3939#include "libroar.h" 
    4040 
     41struct roar_caps { 
     42 int version; 
     43 int type; 
     44 int flags; 
     45 void * data; 
     46 size_t len; 
     47}; 
     48 
     49struct roar_stds { 
     50 size_t stds_len; 
     51 uint32_t * stds; 
     52}; 
     53 
     54int roar_caps_to_msg(struct roar_message * mes,  struct roar_caps    * caps, void ** data); 
     55int roar_caps_from_msg(struct roar_caps  * caps, struct roar_message * mes,  void  * data); 
     56 
     57int roar_caps_stds(struct roar_connection * con, struct roar_stds ** out, struct roar_stds * in, int flags); 
     58 
     59struct roar_stds * roar_stds_new(size_t len); 
     60int roar_stds_free(struct roar_stds * stds); 
     61 
    4162#endif 
    4263 
  • libroar/caps.c

    r4497 r4498  
    3636#include "libroar.h" 
    3737 
     38int roar_caps_to_msg(struct roar_message * mes,  struct roar_caps    * caps, void ** data) { 
     39 char * datap; 
     40 size_t needlen = 4; 
     41 
     42 if ( mes == NULL || caps == NULL ) 
     43  return -1; 
     44 
     45 needlen += caps->len; 
     46 
     47 if ( needlen > sizeof(mes->data) ) { 
     48  if ( data == NULL ) 
     49   return -1; 
     50 
     51  if ( (*data = malloc(needlen)) == NULL ) 
     52   return -1; 
     53 
     54  datap = *data; 
     55 } else { 
     56  datap = mes->data; 
     57 } 
     58 
     59 datap[0] = caps->version; 
     60 datap[1] = caps->type; 
     61 datap[2] = (caps->flags & 0xFF00) >> 8; 
     62 datap[3] = caps->flags & 0xFF; 
     63 
     64 if ( caps->len != 0 ) { 
     65  memcpy(&(datap[4]), caps->data, caps->len); 
     66 } 
     67 
     68 mes->datalen = needlen; 
     69 
     70 return 0; 
     71} 
     72 
     73int roar_caps_from_msg(struct roar_caps  * caps, struct roar_message * mes,  void  * data) { 
     74 char * datap; 
     75 
     76 if ( mes == NULL || caps == NULL ) 
     77  return -1; 
     78 
     79 if ( data != NULL ) { 
     80  datap = data; 
     81 } else { 
     82  datap = mes->data; 
     83 } 
     84 
     85 // versin check. 
     86 if ( datap[0] != 0 || mes->datalen < 4 ) 
     87  return -1; 
     88 
     89 memset(caps, 0, sizeof(struct roar_caps)); 
     90 
     91 caps->version = datap[0]; 
     92 caps->type    = datap[1]; 
     93 caps->flags   = (datap[2] << 8) | datap[3]; 
     94 
     95 if ( mes->datalen == 4 ) { 
     96  caps->data    = NULL; 
     97  caps->len     = 0; 
     98 } else { 
     99  caps->data    = &(datap[4]); 
     100  caps->len     = mes->datalen - 4; 
     101 } 
     102 
     103 return 0; 
     104} 
     105 
     106int roar_caps_stds(struct roar_connection * con, struct roar_stds ** out, struct roar_stds * in, int flags) { 
     107 struct roar_message mes; 
     108 struct roar_caps caps; 
     109 char * data = NULL; 
     110 size_t i; 
     111 
     112 if ( flags == -1 ) 
     113  flags = 0; 
     114 
     115 if ( con == NULL ) 
     116  return -1; 
     117 
     118 if ( out != NULL ) 
     119  flags |= ROAR_CF_REQUEST; 
     120 
     121 if ( (flags & ROAR_CF_REQUEST) && out == NULL ) 
     122  return -1; 
     123 
     124 if ( in != NULL ) 
     125  if ( in->stds_len == 0 ) 
     126   in = NULL; 
     127 
     128 memset(&caps, 0, sizeof(caps)); 
     129 
     130 caps.version = 0; 
     131 caps.type    = ROAR_CT_STANDARDS; 
     132 caps.flags   = flags; 
     133 
     134 memset(&mes, 0, sizeof(mes)); 
     135 
     136 if ( in != NULL ) { 
     137  // we use a hack here to avoid double alloc: 
     138  // first pass the data in native byte order. 
     139  // after we got a buffer swap in-buffer. 
     140  caps.data = in->stds; 
     141  caps.len  = in->stds_len * 4; 
     142 } 
     143 
     144 if ( roar_caps_to_msg(&mes, &caps, &data) == -1 ) 
     145  return -1; 
     146 
     147 if ( in != NULL ) { 
     148  if ( data == NULL ) { 
     149   for (i = 0; i < in->stds_len; i++) { 
     150    ((uint32_t*)mes.data)[i+1] = ROAR_HOST2NET32(((uint32_t*)mes.data)[i+1]); 
     151   } 
     152  } else { 
     153   for (i = 0; i < in->stds_len; i++) { 
     154    ((uint32_t*)data)[i+1] = ROAR_HOST2NET32(((uint32_t*)data)[i+1]); 
     155   } 
     156  } 
     157 } 
     158 
     159 mes.cmd = ROAR_CMD_CAPS; 
     160 
     161 if ( roar_req(con, &mes, &data) == -1 ) 
     162  return -1; 
     163 
     164 if ( mes.cmd != ROAR_CMD_OK ) { 
     165  if ( data != NULL ) 
     166   free(data); 
     167  return -1; 
     168 } 
     169 
     170 if ( roar_caps_from_msg(&caps, &mes, data) == -1 ) { 
     171  if ( data != NULL ) 
     172   free(data); 
     173  return -1; 
     174 } 
     175 
     176 // check if response matches the request: 
     177 if ( caps.version != 0 || caps.type != ROAR_CT_STANDARDS || (caps.len & 0x3) != 0 ) { 
     178  if ( data != NULL ) 
     179   free(data); 
     180  return -1; 
     181 } 
     182 
     183 if ( out != NULL ) { 
     184  *out = roar_stds_new(caps.len/4); 
     185  if ( *out == NULL ) { 
     186   if ( data != NULL ) 
     187    free(data); 
     188   return -1; 
     189  } 
     190 
     191  for (i = 0; i < (*out)->stds_len; i++) { 
     192   (*out)->stds[i] = ROAR_NET2HOST32(((uint32_t*)caps.data)[i+1]); 
     193  } 
     194 } 
     195 
     196 if ( data != NULL ) 
     197  free(data); 
     198 
     199 return 0; 
     200} 
     201 
     202struct roar_stds * roar_stds_new(size_t len) { 
     203 struct roar_stds * ret; 
     204 
     205 if ( len == 0 ) 
     206  return NULL; 
     207 
     208 ret = roar_mm_malloc(sizeof(struct roar_stds)); 
     209 
     210 if ( ret == NULL ) 
     211  return NULL; 
     212 
     213 memset(ret, 0, sizeof(struct roar_stds)); 
     214 
     215 ret->stds_len = len; 
     216 ret->stds     = roar_mm_malloc(len*sizeof(uint32_t)); 
     217 
     218 if ( ret->stds == NULL ) { 
     219  roar_mm_free(ret); 
     220  return NULL; 
     221 } 
     222 
     223 memset(ret->stds, 0, len*sizeof(uint32_t)); 
     224 
     225 return ret; 
     226} 
     227 
     228int roar_stds_free(struct roar_stds * stds) { 
     229 if ( stds == NULL ) 
     230  return -1; 
     231 
     232 if ( stds->stds != NULL ) 
     233  roar_mm_free(stds->stds); 
     234 
     235 roar_mm_free(stds); 
     236 
     237 return 0; 
     238} 
     239 
    38240//ll 
Note: See TracChangeset for help on using the changeset viewer.