Changeset 5576:a98545bcc3f1 in roaraudio


Ignore:
Timestamp:
07/21/12 16:05:33 (12 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Support a common protocol interface (Closes: #257)

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5573 r5576  
    88        * Disable building of roard plugins on windows as PE doesn't 
    99          support them (Closes: #274) 
     10        * Support a common protocol interface (Closes: #257) 
    1011 
    1112v. 1.0beta3 - Sun Jul 15 2012 26:08 CEST 
  • include/libroar/roardl.h

    r5512 r5576  
    339339 
    340340 
     341// Common protocol interface: 
     342struct roar_dl_proto { 
     343 const int proto; 
     344 const char * description; 
     345 const int flags; 
     346 int (*set_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     347 int (*unset_proto)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     348 int (*handle)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     349 int (*flush)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     350 int (*flushed)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     351 int (*status)(int client, struct roar_vio_calls * vio, struct roar_buffer ** obuffer, void ** userdata, const struct roar_keyval * para, ssize_t paralen); 
     352}; 
     353 
     354#define ROAR_DL_PROTO_FLAGS_NONE         0 
     355 
     356#define ROAR_DL_PROTO_STATUS_RX_READY    0x0001 
     357#define ROAR_DL_PROTO_STATUS_TX_READY    0x0002 
     358#define ROAR_DL_PROTO_STATUS_WAIT_NOTIFY 0x0004 
     359 
     360// Parameters for FNREG registration: 
     361#define ROAR_DL_PROTO_SUBTYPE  1 /* 0 = roard */ 
     362#define ROAR_DL_PROTO_VERSION  0 
     363#define ROAR_DL_PROTO_SIZE     sizeof(struct roar_dl_proto) 
     364 
    341365// Reg FN: 
    342366 
  • include/libroar/roarfeatures.h

    r5381 r5576  
    5959#define ROAR_FT_FEATURE_HASH_API 
    6060#define ROAR_FT_FEATURE_RANDOM_NONCE 
     61#define ROAR_FT_FEATURE_UUID         /* see #230 */ 
     62#define ROAR_FT_FEATURE_COMMON_PROTO /* see #257 */ 
    6163 
    6264// libroar2 features: 
  • roard/clients.c

    r5574 r5576  
    144144 const struct roard_proto_handle * protohandle; 
    145145 struct roar_vio_calls    vio; 
    146  struct roar_client * c; 
     146 struct roar_client_server * cs; 
    147147 int supported = 0; 
    148148 int client; 
     
    174174   case -2: return  0; break; 
    175175   default: // TODO: write error handling 
    176      clients_get(client, &c); 
    177      fh = c->fh; 
     176     fh = ROAR_CLIENT(cs)->fh; 
    178177    break; 
    179178  } 
     
    200199 } 
    201200 
     201 if ( clients_get_server(client, &cs) == -1 ) { 
     202  clients_delete(client); 
     203  return -1; 
     204 } 
     205 
    202206 if ( update_nnode ) { 
    203   if ( clients_get(client, &c) != -1 ) { 
    204    if ( roar_nnode_free(&(c->nnode)) != -1 ) { 
    205     if ( sockaddr != NULL && addrlen != 0 ) { 
    206      roar_nnode_new_from_sockaddr(&(c->nnode), sockaddr, addrlen); 
    207     } else { 
    208      roar_nnode_new_from_fh(&(c->nnode), fh, 1); 
    209     } 
     207  if ( roar_nnode_free(&(ROAR_CLIENT(cs)->nnode)) != -1 ) { 
     208   if ( sockaddr != NULL && addrlen != 0 ) { 
     209    roar_nnode_new_from_sockaddr(&(ROAR_CLIENT(cs)->nnode), sockaddr, addrlen); 
     210   } else { 
     211    roar_nnode_new_from_fh(&(ROAR_CLIENT(cs)->nnode), fh, 1); 
    210212   } 
    211213  } 
     
    266268    supported = 0; 
    267269    if ( protohandle != NULL ) { 
     270     if ( protohandle->lhandle != NULL ) 
     271      roar_dl_context_restore(protohandle->lhandle); 
    268272     switch (protohandle->type) { 
    269273      case ROARD_PROTO_TYPE_BUILDIN: 
     
    280284        } 
    281285       break; 
     286      case ROARD_PROTO_TYPE_COMMON: 
     287        supported = 1; 
     288        if ( protohandle->impl.common->set_proto != NULL ) { 
     289         if ( protohandle->impl.common->set_proto(client, &vio, &(cs->outbuf), &(cs->protoinst), protohandle->para, protohandle->paralen) == -1 ) { 
     290          supported = 0; 
     291         } 
     292        } 
     293       break; 
    282294     } 
     295     if ( protohandle->lhandle != NULL ) 
     296      roar_dl_context_store(protohandle->lhandle); 
    283297    } 
    284298 
     
    298312 struct roar_client_server * cs; 
    299313 const struct roard_proto_handle * proto; 
     314 struct roar_vio_calls vio; 
    300315 int i; 
    301316 int close_client_fh = 1; 
     
    309324 proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto); 
    310325 if ( proto != NULL ) { 
     326  if ( proto->lhandle != NULL ) 
     327   roar_dl_context_restore(proto->lhandle); 
    311328  switch (proto->type) { 
    312329   case ROARD_PROTO_TYPE_BUILDIN: 
     
    317334      proto->impl.roardproto.delete_client(id); 
    318335    break; 
    319   } 
     336   case ROARD_PROTO_TYPE_COMMON: 
     337     if ( proto->impl.common->unset_proto != NULL ) { 
     338      roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
     339      proto->impl.common->unset_proto(id, &vio, &(cs->outbuf), &(cs->protoinst), proto->para, proto->paralen); 
     340     } 
     341    break; 
     342  } 
     343  if ( proto->lhandle != NULL ) 
     344   roar_dl_context_store(proto->lhandle); 
    320345 } 
    321346 
     
    692717 
    693718int clients_check     (int id) { 
    694  struct roar_client   * c; 
     719 struct roar_client_server * cs; 
    695720 struct roar_message    m; 
    696721 struct roar_connection con; 
     
    710735 _CHECK_CID(id); 
    711736 
    712  c = ROAR_CLIENT(g_clients[id]); 
    713  
    714  if ( c->fh == -1 ) 
    715   return -1; 
    716  
    717  roar_connect_fh(&con, c->fh); 
    718  
    719  ROAR_DBG("clients_check(id=%i): c->proto=%i", id, c->proto); 
    720  
    721  switch (c->proto) { 
     737 cs = g_clients[id]; 
     738 
     739 if ( ROAR_CLIENT(cs)->fh == -1 ) 
     740  return -1; 
     741 
     742 roar_connect_fh(&con, ROAR_CLIENT(cs)->fh); 
     743 
     744 ROAR_DBG("clients_check(id=%i): c->proto=%i", id, ROAR_CLIENT(cs)->proto); 
     745 
     746 switch (ROAR_CLIENT(cs)->proto) { 
    722747  case ROAR_PROTO_ROARAUDIO: 
    723748    r = roar_recv_message(&con, &m, &data); 
     
    794819  default: 
    795820    rv = -1; 
    796     proto = clients_get_protohandle(c->proto); 
     821    proto = clients_get_protohandle(ROAR_CLIENT(cs)->proto); 
    797822    if ( proto != NULL ) { 
    798823     roar_vio_open_fh_socket(&vio, clients_get_fh(id)); 
     
    807832        if ( proto->impl.roardproto.check_client != NULL ) 
    808833         rv = proto->impl.roardproto.check_client(id, &vio); 
     834       break; 
     835      case ROARD_PROTO_TYPE_COMMON: 
     836        if ( proto->impl.common->handle != NULL ) 
     837         rv = proto->impl.common->handle(id, &vio, &(cs->outbuf), &(cs->protoinst), proto->para, proto->paralen); 
     838        if ( rv == -1 ) 
     839         rv = clients_delete(id); 
    809840       break; 
    810841     } 
     
    852883      roar_dl_context_restore(p->lhandle); 
    853884     rv = p->impl.roardproto.flush_client(id, &vio); 
     885     if ( p->lhandle != NULL ) 
     886      roar_dl_context_store(p->lhandle); 
     887     return rv; 
     888    } 
     889   break; 
     890  case ROARD_PROTO_TYPE_COMMON: 
     891    if ( p->impl.common->flush != NULL ) { 
     892     if ( p->lhandle != NULL ) 
     893      roar_dl_context_restore(p->lhandle); 
     894     rv = p->impl.common->flush(id, &vio, &(cs->outbuf), &(cs->protoinst), p->para, p->paralen); 
    854895     if ( p->lhandle != NULL ) 
    855896      roar_dl_context_store(p->lhandle); 
     
    899940     } 
    900941    break; 
     942   case ROARD_PROTO_TYPE_COMMON: 
     943     if ( p->impl.common->flushed != NULL ) { 
     944      if ( p->lhandle != NULL ) 
     945       roar_dl_context_restore(p->lhandle); 
     946      rv = p->impl.common->flushed(id, &vio, &(cs->outbuf), &(cs->protoinst), p->para, p->paralen); 
     947      if ( p->lhandle != NULL ) 
     948       roar_dl_context_store(p->lhandle); 
     949      return rv; 
     950     } 
     951    break; 
    901952  } 
    902953 } 
     
    10371088} 
    10381089 
     1090int clients_register_proto_common(const struct roar_dl_proto * proto, struct roar_dl_lhandle * lhandle) { 
     1091 const size_t len = sizeof(__protos)/sizeof(*__protos); 
     1092 size_t i; 
     1093 
     1094 ROAR_DBG("clients_register_proto_common(proto=%p, lhandle=%p) = ?", proto, lhandle); 
     1095 
     1096 if ( proto == NULL ) 
     1097  return -1; 
     1098 
     1099 for (i = 0; __protos[i].proto != -1; i++); 
     1100 
     1101 // i is now at pos of current EOS entry. 
     1102 
     1103 // test if we have space for one more entry: 
     1104 if ( (i+1) >= len ) 
     1105  return -1; 
     1106 
     1107 __protos[i].impl.common = proto; 
     1108 
     1109 __protos[i].proto   = proto->proto; 
     1110 __protos[i].type    = ROARD_PROTO_TYPE_COMMON; 
     1111 __protos[i].lhandle = lhandle; 
     1112 
     1113 return 0; 
     1114} 
     1115 
    10391116int clients_unregister_proto(int proto) { 
    10401117 size_t i; 
     
    11051182   continue; 
    11061183 
    1107   // protocols of type BUILDIN are handled above. 
    1108   if ( p->type == ROARD_PROTO_TYPE_BUILDIN ) 
    1109    continue; 
    1110  
    11111184  strncpy(subsys, "      ", 6); 
    11121185  description = "(none)"; 
    11131186 
    1114   if ( p->type == ROARD_PROTO_TYPE_ROARDPROTO ) { 
    1115    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_WAVEFORM ) 
    1116     subsys[0] = 'W'; 
    1117    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_MIDI ) 
    1118     subsys[1] = 'M'; 
    1119    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_CB ) 
    1120     subsys[2] = 'C'; 
    1121    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_LIGHT ) 
    1122     subsys[3] = 'L'; 
    1123    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_RAW ) 
    1124     subsys[4] = 'R'; 
    1125    if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_COMPLEX ) 
    1126     subsys[5] = 'X'; 
    1127  
    1128    description = p->impl.roardproto.description; 
     1187  switch (p->type) { 
     1188   case ROARD_PROTO_TYPE_BUILDIN: 
     1189     continue; 
     1190    break; 
     1191   case ROARD_PROTO_TYPE_ROARDPROTO: 
     1192     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_WAVEFORM ) 
     1193      subsys[0] = 'W'; 
     1194     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_MIDI ) 
     1195      subsys[1] = 'M'; 
     1196     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_CB ) 
     1197      subsys[2] = 'C'; 
     1198     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_LIGHT ) 
     1199      subsys[3] = 'L'; 
     1200     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_RAW ) 
     1201      subsys[4] = 'R'; 
     1202     if ( p->impl.roardproto.subsystems & ROAR_SUBSYS_COMPLEX ) 
     1203      subsys[5] = 'X'; 
     1204 
     1205     description = p->impl.roardproto.description; 
     1206    break; 
     1207   case ROARD_PROTO_TYPE_COMMON: 
     1208     description = p->impl.common->description; 
     1209    break; 
    11291210  } 
    11301211 
  • roard/include/client.h

    r5571 r5576  
    9797 struct roar_dl_lhandle * lhandle; 
    9898 enum roard_proto_type type; 
     99 const struct roar_keyval * para; 
     100 ssize_t paralen; 
    99101 union { 
    100102  int buildin; // dummy 
    101103  struct roard_proto roardproto; 
    102104  // add common here when ready. 
     105  const struct roar_dl_proto * common; 
    103106 } impl; 
    104107}; 
     
    139142// proto support 
    140143const struct roard_proto_handle * clients_get_protohandle(const int proto); 
     144int clients_register_proto_common(const struct roar_dl_proto * proto, struct roar_dl_lhandle * lhandle); 
    141145int clients_register_proto  (struct roard_proto * proto, struct roar_dl_lhandle * lhandle); 
    142146int clients_unregister_proto(int proto); 
  • roard/plugins.c

    r5567 r5576  
    3737static int _plugins_inited = 0; 
    3838 
     39static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle); 
     40static const struct roar_dl_fnreg _plugin_callbacks = { 
     41 .fn = -1, 
     42 .subtype = -1, 
     43 .version = -1, 
     44 .callback = plugin_callback, 
     45 .userdata = NULL 
     46}; 
     47 
    3948static struct _roard_plugin * _find_free(void) { 
    4049 int i; 
     
    115124  return -1; 
    116125 } 
     126 
     127 roar_dl_register_fn(ROAR_DL_HANDLE_APPLICATION, ROAR_DL_FN_REGFN, ROAR_DL_FNREG_SUBTYPE, &_plugin_callbacks, ROAR_DL_FNREG_SIZE, ROAR_DL_FNREG_VERSION, ROAR_DL_FNREG_OPT_NONE); 
    117128 
    118129 for (i = 0; i < MAX_PLUGINS; i++) { 
     
    222233} 
    223234 
     235static int plugin_callback(enum roar_dl_fnreg_action action, int fn, int subtype, const void * object, size_t objectlen, int version, int options, void * userdata, struct roar_dl_lhandle * lhandle) { 
     236 
     237 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = ?", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); 
     238 
     239 switch (fn) { 
     240  case ROAR_DL_FN_PROTO: 
     241    if ( subtype != ROAR_DL_PROTO_SUBTYPE ) { 
     242     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=TYPEMM", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); 
     243 
     244     roar_err_set(ROAR_ERROR_TYPEMM); 
     245     return -1; 
     246    } 
     247    if ( objectlen != ROAR_DL_PROTO_SIZE ) { 
     248     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADLIB", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); 
     249     roar_err_set(ROAR_ERROR_BADLIB); 
     250     return -1; 
     251    } 
     252    if ( version != ROAR_DL_PROTO_VERSION ) { 
     253     ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=BADVERSION", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); 
     254     roar_err_set(ROAR_ERROR_BADVERSION); 
     255     return -1; 
     256    } 
     257    switch (action) { 
     258     case ROAR_DL_FNREG: 
     259       return clients_register_proto_common(object, lhandle); 
     260      break; 
     261     case ROAR_DL_FNUNREG: 
     262       return clients_unregister_proto(((const struct roard_proto *)object)->proto); 
     263      break; 
     264    } 
     265   break; 
     266 } 
     267 
     268 ROAR_DBG("plugin_callback(action=%i, fn=%i, subtype=%i, object=%p, objectlen=%llu, version=%i, options=0x%x, userdata=%p, lhandle=%p) = -1 // error=NOTSUP", (int)action, fn, subtype, object, (long long unsigned int)objectlen, version, options, userdata, lhandle); 
     269 roar_err_set(ROAR_ERROR_NOTSUP); 
     270 return -1; 
     271} 
     272 
    224273//ll 
Note: See TracChangeset for help on using the changeset viewer.