Changeset 3887:faf4ff8e547c in roaraudio


Ignore:
Timestamp:
05/22/10 08:51:47 (14 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

added basic V2 message support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroar/proto.c

    r3882 r3887  
    3636#include "libroar.h" 
    3737 
    38 #define _ROAR_MESS_BUF_LEN (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */) 
     38#define _ROAR_MESS_BUF_LEN_V0  (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */) 
     39#define _ROAR_MESS_BUF_LEN_V1  (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 4 /* pos */ + 2 /* datalen */ + \ 
     40                                1 /* flags */) 
     41#define _ROAR_MESS_BUF_LEN_V2  (1 /* version */ + 1 /* cmd */ + 2 /* stream */ + 8 /* pos */ + 2 /* datalen */ + \ 
     42                                4 /* flags */   + 2 /* seq */) 
     43#define _ROAR_MESS_BUF_LEN     _ROAR_MESS_BUF_LEN_V0 
     44#define _ROAR_MESS_BUF_LEN_MAX ROAR_MAX3(_ROAR_MESS_BUF_LEN_V0, _ROAR_MESS_BUF_LEN_V1, _ROAR_MESS_BUF_LEN_V2) 
     45 
     46#define _ROAR_MESS_CRC_LEN_V0  0 /* No CRC */ 
     47#define _ROAR_MESS_CRC_LEN_V1  1 
     48#define _ROAR_MESS_CRC_LEN_V2  4 
     49#define _ROAR_MESS_CRC_LEN_MAX ROAR_MAX3(_ROAR_MESS_CRC_LEN_V0, _ROAR_MESS_CRC_LEN_V1, _ROAR_MESS_CRC_LEN_V2) 
     50 
    3951int roar_send_message (struct roar_connection * con, struct roar_message * mes, char * data) { 
    4052 struct roar_vio_calls * vio; 
     
    4759 
    4860int roar_vsend_message(struct roar_vio_calls * vio, struct roar_message * mes, char *  data) { 
    49  char buf[_ROAR_MESS_BUF_LEN]; 
     61 char buf[_ROAR_MESS_BUF_LEN_MAX]; 
     62 char crc[_ROAR_MESS_CRC_LEN_MAX]; 
     63 size_t headerlen = 0; 
     64 size_t crclen    = 0; 
     65 char * bufptr; 
    5066 
    5167 roar_errno = ROAR_ERROR_UNKNOWN; 
     
    5369 ROAR_DBG("roar_send_message(*): try to send an request..."); 
    5470 
    55  buf[0] = _ROAR_MESSAGE_VERSION; 
    56  buf[1] = (unsigned char) mes->cmd; 
    57  *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream); 
    58  *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->pos); 
    59  *(uint16_t*)(buf+8) = ROAR_HOST2NET16(mes->datalen); 
    60  
    61  if ( roar_vio_write(vio, buf, _ROAR_MESS_BUF_LEN) != _ROAR_MESS_BUF_LEN ) { 
     71 headerlen = _ROAR_MESS_BUF_LEN; 
     72 
     73 mes->version = _ROAR_MESSAGE_VERSION; 
     74 
     75 buf[0] = mes->version; // first byte is always the version. 
     76 
     77 switch (mes->version) { 
     78  case 0: 
     79    buf[1]              = (unsigned char) mes->cmd; 
     80    *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream); 
     81    *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->pos); 
     82    *(uint16_t*)(buf+8) = ROAR_HOST2NET16(mes->datalen); 
     83    headerlen           = _ROAR_MESS_BUF_LEN_V0; 
     84   break; 
     85  case 1: 
     86    buf[1]              = (unsigned char) (mes->flags & 0xFF); 
     87    buf[2]              = (unsigned char)  mes->cmd; 
     88    // ... 
     89    roar_errno = ROAR_ERROR_NOTSUP; 
     90    return -1; 
     91   break; 
     92  case 2: 
     93    headerlen           = 16; 
     94    buf[1]              = (unsigned char) mes->cmd; 
     95    *(uint16_t*)(buf+2) = ROAR_HOST2NET16(mes->stream); 
     96    *(uint32_t*)(buf+4) = ROAR_HOST2NET32(mes->flags); 
     97    if ( mes->flags & ROAR_MF_LSPOS ) { 
     98     *(uint64_t*)(buf+8) = ROAR_HOST2NET16(mes->pos64); 
     99     bufptr = buf+16; 
     100     headerlen          += 4; 
     101    } else { 
     102     *(uint32_t*)(buf+8) = ROAR_HOST2NET16(mes->pos); 
     103     bufptr = buf+12; 
     104    } 
     105    *(uint16_t*)(bufptr+0) = ROAR_HOST2NET16(mes->datalen); 
     106    *(uint16_t*)(bufptr+2) = ROAR_HOST2NET16(mes->seq); 
     107   break; 
     108  default: 
     109    roar_errno = ROAR_ERROR_NOTSUP; 
     110    return -1; 
     111 } 
     112 
     113 if ( roar_vio_write(vio, buf, headerlen) != headerlen ) { 
    62114  roar_errno = ROAR_ERROR_PIPE; 
    63115  return -1; 
     
    71123 } 
    72124 
     125 if ( crclen != 0 ) { 
     126  if ( roar_vio_write(vio, crc, crclen) != crclen ) { 
     127   roar_errno = ROAR_ERROR_PIPE; 
     128   return -1; 
     129  } 
     130 } 
     131 
    73132 roar_errno = ROAR_ERROR_NONE; 
    74133 
     
    87146 
    88147int roar_vrecv_message(struct roar_vio_calls * vio, struct roar_message * mes, char ** data) { 
    89  char buf[_ROAR_MESS_BUF_LEN]; 
     148 // TODO: add CRC support. 
     149 char buf[_ROAR_MESS_BUF_LEN_MAX]; 
     150// char crc[_ROAR_MESS_CRC_LEN_MAX]; 
     151 size_t headerlen = 0; 
     152// size_t crclen    = 0; 
     153 size_t needlen; 
     154 char * bufptr; 
    90155 
    91156 roar_errno = ROAR_ERROR_UNKNOWN; 
     
    101166 memset(mes, 0, sizeof(struct roar_message)); 
    102167 
    103  if ( roar_vio_read(vio, buf, _ROAR_MESS_BUF_LEN) != _ROAR_MESS_BUF_LEN ) { 
     168 if ( roar_vio_read(vio, buf, _ROAR_MESS_BUF_LEN_V0) != _ROAR_MESS_BUF_LEN_V0 ) { 
    104169  roar_errno = ROAR_ERROR_PROTO; 
    105170  return -1; 
     
    108173 ROAR_DBG("roar_recv_message(*): Got a header"); 
    109174 
    110  if ( buf[0] != _ROAR_MESSAGE_VERSION ) { 
    111   roar_errno = ROAR_ERROR_PROTO; 
    112   return -1; 
    113  } 
    114  
    115  mes->cmd     = (unsigned char)buf[1]; 
    116  mes->stream  = ROAR_NET2HOST16(*(uint16_t*)(buf+2)); 
    117  mes->pos     = ROAR_NET2HOST32(*(uint32_t*)(buf+4)); 
    118  mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(buf+8)); 
     175 mes->version = buf[0]; 
     176 headerlen    = _ROAR_MESS_BUF_LEN_V0; 
     177 
     178 switch (mes->version) { 
     179  case 0: 
     180    // we already have all data, so create the struct 
     181    mes->cmd     = (unsigned char)buf[1]; 
     182    mes->stream  = ROAR_NET2HOST16(*(uint16_t*)(buf+2)); 
     183    mes->pos     = ROAR_NET2HOST32(*(uint32_t*)(buf+4)); 
     184    mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(buf+8)); 
     185   break; 
     186  case 2: 
     187    mes->cmd     = (unsigned char)buf[1]; 
     188    mes->stream  = ROAR_NET2HOST16(*(uint16_t*)(buf+2)); 
     189    mes->flags   = ROAR_NET2HOST32(*(uint32_t*)(buf+4)); 
     190    if ( mes->flags & ROAR_MF_LSPOS ) { 
     191     headerlen = 20; 
     192    } else { 
     193     headerlen = 16; 
     194    } 
     195   break; 
     196  default: 
     197    roar_errno = ROAR_ERROR_PROTO; 
     198    return -1; 
     199   break; 
     200 } 
     201 
     202 // check specal case where headerlen < _ROAR_MESS_BUF_LEN_V0, this means that we need to put 
     203 // some data we read as header into the data part of the message. 
     204 if ( headerlen > _ROAR_MESS_BUF_LEN_V0 ) { 
     205  needlen = headerlen - _ROAR_MESS_BUF_LEN_V0; 
     206  if ( roar_vio_read(vio, buf+_ROAR_MESS_BUF_LEN_V0, needlen) != (ssize_t)needlen ) { 
     207   roar_errno = ROAR_ERROR_PROTO; 
     208   return -1; 
     209  } 
     210 } 
     211 
     212 switch (mes->version) { 
     213  case 2: 
     214    if ( mes->flags & ROAR_MF_LSPOS ) { 
     215     mes->pos64   = ROAR_NET2HOST32(*(uint64_t*)(buf+8)); 
     216     bufptr       = buf+16; 
     217    } else { 
     218     mes->pos     = ROAR_NET2HOST32(*(uint32_t*)(buf+8)); 
     219     bufptr       = buf+12; 
     220    } 
     221    mes->datalen = ROAR_NET2HOST16(*(uint16_t*)(bufptr+0)); 
     222    mes->seq     = ROAR_NET2HOST16(*(uint16_t*)(bufptr+1)); 
     223   break; 
     224 } 
    119225 
    120226 if ( (int16_t)mes->stream == -1 ) 
     
    123229 ROAR_DBG("roar_recv_message(*): command=%i(%s)", mes->cmd, 
    124230           mes->cmd == ROAR_CMD_OK ? "OK" : (mes->cmd == ROAR_CMD_ERROR ? "ERROR" : "UNKNOWN")); 
     231 
     232// Below we only have data handling, handling of header is finished: 
    125233 
    126234 if ( mes->datalen == 0 ) { 
Note: See TracChangeset for help on using the changeset viewer.