void nfosc_stop() { int i; if (!running) return; running = false; if( main_thread ) pthread_detach(main_thread); main_thread = NULL; lo_bundle osc_bundle = lo_bundle_new(LO_TT_IMMEDIATE); for (i=0;i<buffer_size;i++) { lo_message del_message = lo_message_new(); lo_message_add_int32(del_message, tag_buffer[i].device_id); lo_message_add_int32(del_message, tag_buffer[i].symbol_id); lo_message_add_int32(del_message, tag_buffer[i].type_id); lo_message_add_string(del_message, tag_buffer[i].uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/del", del_message); if (verbose) printf("del %d %d %d %s\n",tag_buffer[i].session_id,tag_buffer[i].symbol_id,tag_buffer[i].type_id,tag_buffer[i].uid_str); } lo_timetag frame_time; lo_timetag_now (&frame_time); for (int dev=0;dev<no_devices;dev++) { if (pnd[dev]==NULL) continue; lo_message frm_message = lo_message_new(); lo_message_add_int32(frm_message, -1); lo_message_add_timetag(frm_message, frame_time); lo_message_add_int32(frm_message, 0); // sensor dim if (device_count>1) sprintf(source_string, "NFOSC:%d",dev); lo_message_add_string(frm_message, source_string); // source name lo_bundle_add_message(osc_bundle, "/tuio2/frm", frm_message); lo_message sid_message = lo_message_new(); lo_bundle_add_message(osc_bundle, "/tuio2/alv", sid_message); } int ret = lo_send_bundle(target, osc_bundle); if(ret == -1) { fprintf(stderr, "an OSC error occured: %s\n", lo_address_errstr(target)); exit(1); } for (int dev=0;dev<no_devices;dev++) { if (pnd[dev]!=NULL) { printf("closing NFC reader #%d: %s\n",dev,nfc_device_get_name(pnd[dev])); nfc_close(pnd[dev]); } } nfc_exit(context); write_database(); }
int Pure_lo_message_add_timetag(void* arg0, lo_timetag* arg1) { return lo_message_add_timetag(arg0, *arg1); }
void main_loop(void *data) { int i,j,n; int32_t fseq = 0; //verbose = 2; // get the local IP adress for the TUIO2 source attribute char hostname[64]; struct hostent *hp = NULL; struct in_addr *addr = NULL; gethostname(hostname, 64); hp = gethostbyname(hostname); if (hp==NULL) { sprintf(hostname, "%s.local", hostname); hp = gethostbyname(hostname); } if (hp!=NULL) { for (i = 0; hp->h_addr_list[i] != 0; ++i) { addr = (struct in_addr *)(hp->h_addr_list[i]); } } else { //generate a random internet address srand ( (unsigned int)time(NULL) ); int32_t r = rand(); addr = (struct in_addr*)&r; } while (running) { uint8_t tag_count = 0; bool updated = false; lo_bundle osc_bundle = lo_bundle_new(LO_TT_IMMEDIATE); nfc_target ant[MAX_TARGET_COUNT]; // List ISO14443A targets if (verbose>1) printf("polling for a ISO14443A (MIFARE) tag:\n"); nfc_modulation nm = { .nmt = NMT_ISO14443A, .nbr = NBR_106, }; lo_timetag frame_time; lo_timetag_now (&frame_time); for (int dev=0;dev<no_devices;dev++) { if (pnd[dev] == NULL) continue; if (!running) return; lo_message frm_message = lo_message_new(); lo_message_add_int32(frm_message, fseq); lo_message_add_timetag(frm_message, frame_time); lo_message_add_int32(frm_message, 0); // sensor dim if (device_count>1) sprintf(source_string, "NFOSC:%d",dev); lo_message_add_string(frm_message, source_string); // source name lo_bundle_add_message(osc_bundle, "/tuio2/frm", frm_message); fseq++; int szTargetFound = nfc_initiator_list_passive_targets (pnd[dev], nm, ant, MAX_TARGET_COUNT); if (szTargetFound<0) { if (no_devices==1) printf("NFC reader disconnected ...\n"); else printf("NFC reader #%d disconnected ...\n",dev); pnd[dev] = NULL; device_count--; if (device_count==0) { running=false; return; } continue; } else if (szTargetFound>0) { for (n = 0; n < szTargetFound; n++) { if (!running) return; bool added = false; nfosc_t found_tag; found_tag.type_id = MIFARE_OTHER; found_tag.device_id = dev; decode_hex(ant[n].nti.nai.abtUid,ant[n].nti.nai.szUidLen); strcpy(found_tag.uid_str,uid_str); if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x09)) { if (verbose>1) printf("NXP MIFARE Mini - UID: %s\n",uid_str); found_tag.type_id = MIFARE_MINI; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x08)) { if (verbose>1) printf("NXP MIFARE Classic 1K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_1K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x18)) { if (verbose>1) printf("NXP MIFARE Classic 4K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_4K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x38)) { if (verbose>1) printf("Nokia MIFARE Classic 4K - emulated - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_4K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x44) && (ant[n].nti.nai.btSak == 0x00)) { if (verbose>1) printf("NXP MIFARE Ultralight - UID: %s\n",uid_str); found_tag.type_id = MIFARE_ULTRALIGHT; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x03) && (ant[n].nti.nai.abtAtqa[1] == 0x44) && (ant[n].nti.nai.btSak == 0x20)) { if (verbose>1) printf("NXP MIFARE DESFire - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x03) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x28)) { if (verbose>1) printf("NXP JCOP31 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x48) && (ant[n].nti.nai.btSak == 0x20)) { /* @todo handle ATS to be able to know which one it is */ if (verbose>1) printf("NXP JCOP31 or JCOP41 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x28)) { if (verbose>1) printf("NXP JCOP41 - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x04) && (ant[n].nti.nai.btSak == 0x88)) { if (verbose>1) printf("Infineon MIFARE Classic 1K - UID: %s\n",uid_str); found_tag.type_id = MIFARE_CLASSIC_1K; } else if ((ant[n].nti.nai.abtAtqa[0] == 0x00) && (ant[n].nti.nai.abtAtqa[1] == 0x02) && (ant[n].nti.nai.btSak == 0x98)) { if (verbose>1) printf("Gemplus MPCOS - UID: %s\n",uid_str); } else if ((ant[n].nti.nai.abtAtqa[0] == 0x0C) && (ant[n].nti.nai.abtAtqa[1] == 0x00)) { /* @note not sure if Jewel can be detected using this modulation */ if (verbose>1) printf("Innovision R&T Jewel - UID: %s\n",uid_str); } else { if (verbose>1) { printf("ATQA (SENS_RES): %s\n", decode_hex(ant[n].nti.nai.abtAtqa,2)); printf(" UID (NFCID%c): ",(ant[n].nti.nai.abtUid[0]==0x08?'3':'1')); printf("%s\n",decode_hex(ant[n].nti.nai.abtUid,ant[n].nti.nai.szUidLen)); printf(" SAK (SEL_RES): %s\n", decode_hex(&ant[n].nti.nai.btSak,1)); if (ant[n].nti.nai.szAtsLen) { printf(" ATS (ATR): %s\n",decode_hex(ant[n].nti.nai.abtAts,ant[n].nti.nai.szAtsLen)); } printf("\n"); } } int32_t symbol_id = max_symbol_id; int32_t i; for (i=0;i<max_symbol_id;i++) { if (strcmp(tag_database[i].uid_str,found_tag.uid_str)==0) { symbol_id = i; found_tag.symbol_id = symbol_id; break; } } if (symbol_id==max_symbol_id) { symbol_id = max_symbol_id; max_symbol_id++; found_tag.symbol_id = symbol_id; session_id++; found_tag.session_id = session_id; tag_database[symbol_id] = found_tag; tag_buffer[buffer_size] = found_tag; buffer_size++; if (verbose) printf("assigning ID %d to UID %s\n",found_tag.symbol_id,found_tag.uid_str); added = true; } else { int32_t b_pos = buffer_size; for (i=0;i<buffer_size;i++) { if ((strcmp(tag_buffer[i].uid_str,found_tag.uid_str)==0) && (tag_buffer[i].device_id==found_tag.device_id)) { found_tag.session_id = tag_buffer[i].session_id; b_pos=i; break; } } if (b_pos==buffer_size) { session_id++; found_tag.session_id = session_id; tag_buffer[buffer_size] = found_tag; buffer_size++; added=true; } } lo_message sym_message = lo_message_new(); lo_message_add_int32(sym_message, found_tag.session_id); lo_message_add_int32(sym_message, found_tag.type_id); lo_message_add_int32(sym_message, found_tag.symbol_id); switch (found_tag.type_id) { case MIFARE_ULTRALIGHT: lo_message_add_string(sym_message, "mifare/ul"); break; case MIFARE_CLASSIC_1K: lo_message_add_string(sym_message, "mifare/1k"); break; case MIFARE_CLASSIC_4K: lo_message_add_string(sym_message, "mifare/4k"); break; case MIFARE_MINI: lo_message_add_string(sym_message, "mifare/mini"); break; default: lo_message_add_string(sym_message, "mifare/other"); } lo_message_add_string(sym_message, found_tag.uid_str); lo_bundle_add_message(osc_bundle, "/tuio2/sym", sym_message); if (added) { lo_message add_message = lo_message_new(); lo_message_add_int32(add_message, found_tag.device_id); lo_message_add_int32(add_message, found_tag.symbol_id); lo_message_add_int32(add_message, found_tag.type_id); lo_message_add_string(add_message, found_tag.uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/add", add_message); updated = true; if (verbose) printf("add %d %d %d %s\n",found_tag.device_id,found_tag.symbol_id,found_tag.type_id,found_tag.uid_str); } frame_buffer[tag_count] = found_tag; tag_count++; } } lo_message sid_message = lo_message_new(); for (i=0;i<tag_count;i++) if (frame_buffer[i].device_id==dev) lo_message_add_int32(sid_message, frame_buffer[i].session_id); lo_bundle_add_message(osc_bundle, "/tuio2/alv", sid_message); } for (i=0;i<buffer_size;i++) { bool removed = true; for (j=0;j<=tag_count;j++) { if ((strcmp(tag_buffer[i].uid_str,frame_buffer[j].uid_str)==0) && (tag_buffer[i].device_id == frame_buffer[j].device_id)) { removed=false; break; } } if (removed) { lo_message del_message = lo_message_new(); lo_message_add_int32(del_message, tag_buffer[i].device_id); lo_message_add_int32(del_message, tag_buffer[i].symbol_id); lo_message_add_int32(del_message, tag_buffer[i].type_id); lo_message_add_string(del_message, tag_buffer[i].uid_str); lo_bundle_add_message(osc_bundle, "/nfosc/del", del_message); updated = true; if (verbose) printf("del %d %d %d %s\n",tag_buffer[i].device_id,tag_buffer[i].symbol_id,tag_buffer[i].type_id,tag_buffer[i].uid_str); } } if (updated) { if(lo_send_bundle(target, osc_bundle) == -1) { fprintf(stderr, "an OSC error occured: %s\n", lo_address_errstr(target)); } } if (verbose>1) { if (tag_count==0) printf("no tag was found ...\n\n"); else if (tag_count==1) printf("1 tag was found ...\n\n"); else printf("%d tags were found ...\n\n",tag_count); } buffer_size = tag_count; for (i=0; i<tag_count; i++) { tag_buffer[i] = frame_buffer[i]; frame_buffer[i] = empty_tag; } for (int dev=0;dev<no_devices;dev++) { if (pnd[dev] == NULL) continue; if (nfc_device_set_property_bool(pnd[dev],NP_ACTIVATE_FIELD,false)<0) { if (running) { if (no_devices==1) printf("NFC reader disconnected ...\n"); else printf("NFC reader #%d disconnected ...\n",dev); } pnd[dev] = NULL; device_count--; if (device_count==0) { running=false; return; } } else { nfc_device_set_property_bool(pnd[dev],NP_ACTIVATE_FIELD,true); } } usleep(1000/no_devices); } }
//this is not a JACK process cylce int process() { if(shutdown_in_progress==1) { return 0; } if(process_enabled==1) { //as long as there is data ready to be sent, read and try to send //need: handle case where receiver can not read data fast enough // while(rb_can_read(rb) // >=input_port_count*bytes_per_sample*period_size) // { while(rb_can_read(rb) >=port_count*bytes_per_sample*period_size) { //fake consume // rb_advance_read_pointer(rb,port_count*bytes_per_sample*period_size); lo_message mm=lo_message_new(); //add message counter lo_message_add_int64(mm,message_number_out); //indicate how many xruns (in sender's JACK) lo_message_add_int64(mm,remote_xrun_counter); gettimeofday(&tv, NULL); lo_timetag tt; tt.sec=(long)tv.tv_sec; tt.frac=(long)tv.tv_usec; lo_message_add_timetag(mm,tt); lo_message_add_int32(mm,sample_rate); //blob array, holding one period per channel // lo_blob blob[input_port_count]; lo_blob blob[port_count]; void* membuf = malloc(period_size*bytes_per_sample); int i; for( i=0; i<port_count; i++ ) { //void* membuf = malloc(period_size*bytes_per_sample); rb_read (rb, (char*)membuf, period_size*bytes_per_sample); blob[i]=lo_blob_new(period_size*bytes_per_sample,membuf); lo_message_add_blob(mm,blob[i]); } int ret=lo_send_message(loa_tcp,"/audio",mm); last_lo_send_message_tcp_return=ret; if(ret<0) { // fprintf(stderr," TCP WARN: msg no: %" PRId64 " size: %" PRId64 " ret: %d ",message_number_out,lo_message_length(mm,"/audio"),ret); } else { total_bytes_successfully_sent+=ret; // fprintf(stderr," msg no: %" PRId64 " size: %" PRId64 " ret: %d ",message_number_out,lo_message_length(mm,"/audio"),ret); message_number_out++; } //free //lo_free(membuf); lo_message_free(mm); free(membuf); //free blobls ... for( i=0; i<port_count; i++ ) { free(blob[i]); } if(ret<0) { return ret; } }//end while has data return 0; }//end if process enabled //process not yet enabled, buffering else { if(relaxed_display_counter>=update_display_every_nth_cycle || last_test_cycle==1 ) { if((int)message_number<=0 && starting_transmission==0) { fprintf(stderr,"\rwaiting for audio input data..."); } fflush(stderr); relaxed_display_counter=0; } relaxed_display_counter++; return 0; }//end if process not enabled //return 0; } //end process
static int osc_send(CSOUND *csound, OSCSEND *p) { /* Types I allow at present: 0) int 1) float 2) string 3) double 4) char 5) table as blob */ char port[8]; char *pp = port; char *hh; if (*p->port<0) pp = NULL; else snprintf(port, 8, "%d", (int) MYFLT2LRND(*p->port)); hh = (char*) p->host->data; if (*hh=='\0') hh = NULL; if(p->addr != NULL) lo_address_free(p->addr); p->addr = lo_address_new(hh, pp); if (p->cnt++ ==0 || *p->kwhen!=p->last) { int i=0; int msk = 0x20; /* First argument */ lo_message msg = lo_message_new(); char *type = (char*)p->type->data; MYFLT **arg = p->arg; p->last = *p->kwhen; for (i=0; type[i]!='\0'; i++, msk <<=1) { /* Need to add type checks */ switch (type[i]) { case 'i': lo_message_add_int32(msg, (int32_t) MYFLT2LRND(*arg[i])); break; case 'l': case 'h': lo_message_add_int64(msg, (int64_t) MYFLT2LRND(*arg[i])); break; case 'c': lo_message_add_char(msg, (char) (*arg[i] + FL(0.5))); break; case 'm': { union a { int32_t x; uint8_t m[4]; } mm; mm.x = *arg[i]+FL(0.5); lo_message_add_midi(msg, mm.m); break; } case 'f': lo_message_add_float(msg, (float)(*arg[i])); break; case 'd': lo_message_add_double(msg, (double)(*arg[i])); break; case 's': lo_message_add_string(msg, ((STRINGDAT *)arg[i])->data); break; case 'b': /* Boolean */ if (*arg[i]==FL(0.0)) lo_message_add_true(msg); else lo_message_add_false(msg); break; case 't': /* timestamp */ { lo_timetag tt; tt.sec = (uint32_t)(*arg[i]+FL(0.5)); msk <<= 1; i++; if (UNLIKELY(type[i]!='t')) return csound->PerfError(csound, p->h.insdshead, Str("Time stamp is two values")); tt.frac = (uint32_t)(*arg[i]+FL(0.5)); lo_message_add_timetag(msg, tt); break; } //#ifdef SOMEFINEDAY case 'G': /* fGen Table/blob */ { lo_blob myblob; int len, olen; FUNC *ftp; void *data; /* make sure fn exists */ if (LIKELY((ftp=csound->FTnp2Find(csound,arg[i]))!=NULL)) { len = ftp->flen; /* and set it up */ data = csound->Malloc(csound, olen=sizeof(FUNC)-sizeof(MYFLT*)+ sizeof(MYFLT)*len); memcpy(data, ftp, sizeof(FUNC)-sizeof(MYFLT*)); memcpy(data+sizeof(FUNC)-sizeof(MYFLT*), ftp->ftable, sizeof(MYFLT)*len); } else { return csound->PerfError(csound, p->h.insdshead, Str("ftable %.2f does not exist"), *arg[i]); } myblob = lo_blob_new(olen, data); lo_message_add_blob(msg, myblob); csound->Free(csound, data); lo_blob_free(myblob); break; } //#endif case 'a': /* Audio as blob */ { lo_blob myblob; MYFLT *data = csound->Malloc(csound, sizeof(MYFLT)*(CS_KSMPS+1)); data[0] = CS_KSMPS; memcpy(&data[1], arg[i], data[0]); myblob = lo_blob_new(sizeof(MYFLT)*(CS_KSMPS+1), data); lo_message_add_blob(msg, myblob); csound->Free(csound, data); lo_blob_free(myblob); break; } case 'A': /* Array/blob */ { lo_blob myblob; int len = 1; ARRAYDAT *ss; /* make sure fn exists */ if (LIKELY((ss = (ARRAYDAT*)arg[i]) !=NULL && ss->data != NULL)) { int j, d; for (j=0,d=ss->dimensions; d>0; j++, d--) len *= ss->sizes[j]; len *= sizeof(MYFLT); } else { return csound->PerfError(csound, p->h.insdshead, Str("argument %d is not an array"), i); } // two parts needed { void *dd = malloc(len+sizeof(int)*(1+ss->dimensions)); memcpy(dd, &ss->dimensions, sizeof(int)); memcpy(dd+sizeof(int), ss->sizes, sizeof(int)*ss->dimensions); memcpy(dd+sizeof(int)*(1+ss->dimensions), ss->data, len); /* printf("dd length = %d dimensions = %d, %d %d %.8x %.8x %.8x %.8x\n", */ /* len+sizeof(int)*(1+ss->dimensions), ss->dimensions, */ /* ((int*)dd)[0], ((int*)dd)[1], ((int*)dd)[2], ((int*)dd)[3], */ /* ((int*)dd)[4], ((int*)dd)[5]); */ myblob = lo_blob_new(len, dd); free(dd); } lo_message_add_blob(msg, myblob); lo_blob_free(myblob); break; } case 'S': csound->Warning(csound, "S unimplemented"); break; //#endif default: csound->Warning(csound, Str("Unknown OSC type %c\n"), type[1]); } } lo_send_message(p->addr, (char*)p->dest->data, msg); lo_message_free(msg); } return OK; }
static int osc_send(CSOUND *csound, OSCSEND *p) { /* Types I allow at present: 0) int 1) float 2) string 3) double 4) char 5) table as blob */ if (p->cnt++ ==0 || *p->kwhen!=p->last) { int i=0; int msk = 0x20; /* First argument */ lo_message msg = lo_message_new(); char *type = (char*)p->type->data; MYFLT **arg = p->arg; p->last = *p->kwhen; for (i=0; type[i]!='\0'; i++, msk <<=1) { /* Need to add type checks */ switch (type[i]) { case 'i': lo_message_add_int32(msg, (int32_t) MYFLT2LRND(*arg[i])); break; case 'l': lo_message_add_int64(msg, (int64_t) MYFLT2LRND(*arg[i])); break; case 'c': lo_message_add_char(msg, (char) (*arg[i] + FL(0.5))); break; case 'm': { union a { int32_t x; uint8_t m[4]; } mm; mm.x = *arg[i]+FL(0.5); lo_message_add_midi(msg, mm.m); break; } case 'f': lo_message_add_float(msg, (float)(*arg[i])); break; case 'd': lo_message_add_double(msg, (double)(*arg[i])); break; case 's': lo_message_add_string(msg, ((STRINGDAT *)arg[i])->data); break; case 'b': /* Boolean */ if (*arg[i]==FL(0.0)) lo_message_add_true(msg); else lo_message_add_false(msg); break; case 't': /* timestamp */ { lo_timetag tt; tt.sec = (uint32_t)(*arg[i]+FL(0.5)); msk <<= 1; i++; if (UNLIKELY(type[i]!='t')) return csound->PerfError(csound, p->h.insdshead, Str("Time stamp is two values")); tt.frac = (uint32_t)(*arg[i]+FL(0.5)); lo_message_add_timetag(msg, tt); break; } //#ifdef SOMEFINEDAY case 'T': /* Table/blob */ { lo_blob myblob; int len; FUNC *ftp; void *data; /* make sure fn exists */ if (LIKELY((ftp=csound->FTnp2Find(csound,arg[i]))!=NULL)) { data = ftp->ftable; len = ftp->flen-1; /* and set it up */ } else { return csound->PerfError(csound, p->h.insdshead, Str("ftable %.2f does not exist"), *arg[i]); } myblob = lo_blob_new(sizeof(MYFLT)*len, data); lo_message_add_blob(msg, myblob); lo_blob_free(myblob); break; } //#endif default: csound->Warning(csound, Str("Unknown OSC type %c\n"), type[1]); } } lo_send_message(p->addr, (char*)p->dest->data, msg); lo_message_free(msg); } return OK; }
int lo_message_add_varargs_internal(lo_message msg, const char *types, va_list ap, const char *file, int line) { int count = 0; int ret = 0; while (types && *types) { count++; switch (*types++) { case LO_INT32:{ int32_t i = va_arg(ap, int32_t); lo_message_add_int32(msg, i); break; } case LO_FLOAT:{ float f = (float) va_arg(ap, double); lo_message_add_float(msg, f); break; } case LO_STRING:{ char *s = va_arg(ap, char *); #ifndef USE_ANSI_C if (s == (char *) LO_MARKER_A) { fprintf(stderr, "liblo error: lo_send or lo_message_add called with " "invalid string pointer for arg %d, probably arg mismatch\n" "at %s:%d, exiting.\n", count, file, line); } #endif lo_message_add_string(msg, s); break; } case LO_BLOB:{ lo_blob b = va_arg(ap, lo_blob); lo_message_add_blob(msg, b); break; } case LO_INT64:{ int64_t i64 = va_arg(ap, int64_t); lo_message_add_int64(msg, i64); break; } case LO_TIMETAG:{ lo_timetag tt = va_arg(ap, lo_timetag); lo_message_add_timetag(msg, tt); break; } case LO_DOUBLE:{ double d = va_arg(ap, double); lo_message_add_double(msg, d); break; } case LO_SYMBOL:{ char *s = va_arg(ap, char *); #ifndef USE_ANSI_C if (s == (char *) LO_MARKER_A) { fprintf(stderr, "liblo error: lo_send or lo_message_add called with " "invalid symbol pointer for arg %d, probably arg mismatch\n" "at %s:%d, exiting.\n", count, file, line); va_end(ap); return -2; } #endif lo_message_add_symbol(msg, s); break; } case LO_CHAR:{ char c = va_arg(ap, int); lo_message_add_char(msg, c); break; } case LO_MIDI:{ uint8_t *m = va_arg(ap, uint8_t *); lo_message_add_midi(msg, m); break; } case LO_TRUE: lo_message_add_true(msg); break; case LO_FALSE: lo_message_add_false(msg); break; case LO_NIL: lo_message_add_nil(msg); break; case LO_INFINITUM: lo_message_add_infinitum(msg); break; case '$': if (*types == '$') { // type strings ending in '$$' indicate not to perform // LO_MARKER checking va_end(ap); return 0; } // fall through to unknown type default:{ ret = -1; // unknown type fprintf(stderr, "liblo warning: unknown type '%c' at %s:%d\n", *(types - 1), file, line); break; } } } #ifndef USE_ANSI_C void *i = va_arg(ap, void *); if (((unsigned long)i & 0xFFFFFFFFUL) != ((unsigned long)LO_MARKER_A & 0xFFFFFFFFUL)) { ret = -2; // bad format/args fprintf(stderr, "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with " "mismatching types and data at\n%s:%d, exiting.\n", file, line); va_end(ap); return ret; } i = va_arg(ap, void *); if (((unsigned long)i & 0xFFFFFFFFUL) != ((unsigned long)LO_MARKER_B & 0xFFFFFFFFUL)) { ret = -2; // bad format/args fprintf(stderr, "liblo error: lo_send, lo_message_add, or lo_message_add_varargs called with " "mismatching types and data at\n%s:%d, exiting.\n", file, line); } #endif va_end(ap); return ret; }
void test_deserialise() { char *buf, *buf2, *tmp; const char *types = NULL, *path; lo_arg **argv = NULL; size_t len, size; char data[256]; int result = 0; lo_blob btest = lo_blob_new(sizeof(testdata), testdata); uint8_t midi_data[4] = {0xff, 0xf7, 0xAA, 0x00}; lo_timetag tt = {0x1, 0x80000000}; lo_blob b = NULL; // build a message lo_message msg = lo_message_new(); TEST(0 == lo_message_get_argc(msg)); lo_message_add_float(msg, 0.12345678f); // 0 f lo_message_add_int32(msg, 123); // 1 i lo_message_add_string(msg, "123"); // 2 s lo_message_add_blob(msg, btest); // 3 b lo_message_add_midi(msg, midi_data); // 4 m lo_message_add_int64(msg, 0x0123456789abcdefULL); // 5 h lo_message_add_timetag(msg, tt); // 6 t lo_message_add_double(msg, 0.9999); // 7 d lo_message_add_symbol(msg, "sym"); // 8 S lo_message_add_char(msg, 'X'); // 9 c lo_message_add_char(msg, 'Y'); // 10 c lo_message_add_true(msg); // 11 T lo_message_add_false(msg); // 12 F lo_message_add_nil(msg); // 13 N lo_message_add_infinitum(msg); // 14 I // test types, args TEST(15 == lo_message_get_argc(msg)); types = lo_message_get_types(msg); TEST(NULL != types); argv = lo_message_get_argv(msg); TEST(NULL != argv); TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON); TEST('i' == types[1] && 123 == argv[1]->i); TEST('s' == types[2] && !strcmp(&argv[2]->s, "123")); TEST('b' == types[3]); b = (lo_blob)argv[3]; TEST(lo_blob_datasize(b) == sizeof(testdata)); TEST(12 == lo_blobsize(b)); TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata))); TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4)); TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h); TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac); TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON); TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym")); TEST('c' == types[9] && 'X' == argv[9]->c); TEST('c' == types[10] && 'Y' == argv[10]->c); TEST('T' == types[11] && NULL == argv[11]); TEST('F' == types[12] && NULL == argv[12]); TEST('N' == types[13] && NULL == argv[13]); TEST('I' == types[14] && NULL == argv[14]); // serialise it len = lo_message_length(msg, "/foo"); printf("serialise message_length=%d\n", (int)len); buf = calloc(len, sizeof(char)); size = 0; tmp = lo_message_serialise(msg, "/foo", buf, &size); TEST(tmp == buf && size == len && 92 == len); lo_message_free(msg); // deserialise it printf("deserialise\n"); path = lo_get_path(buf, len); TEST(NULL != path && !strcmp(path, "/foo")); msg = lo_message_deserialise(buf, size, NULL); TEST(NULL != msg); // repeat same test as above TEST(15 == lo_message_get_argc(msg)); types = lo_message_get_types(msg); TEST(NULL != types); argv = lo_message_get_argv(msg); TEST(NULL != argv); TEST('f' == types[0] && fabs(argv[0]->f - 0.12345678f) < FLT_EPSILON); TEST('i' == types[1] && 123 == argv[1]->i); TEST('s' == types[2] && !strcmp(&argv[2]->s, "123")); TEST('b' == types[3]); b = (lo_blob)argv[3]; TEST(lo_blob_datasize(b) == sizeof(testdata)); TEST(12 == lo_blobsize(b)); TEST(!memcmp(lo_blob_dataptr(b), &testdata, sizeof(testdata))); TEST('m' == types[4] && !memcmp(&argv[4]->m, midi_data, 4)); TEST('h' == types[5] && 0x0123456789abcdefULL == argv[5]->h); TEST('t' == types[6] && 1 == argv[6]->t.sec && 0x80000000 == argv[6]->t.frac); TEST('d' == types[7] && fabs(argv[7]->d - 0.9999) < FLT_EPSILON); TEST('S' == types[8] && !strcmp(&argv[8]->s, "sym")); TEST('c' == types[9] && 'X' == argv[9]->c); TEST('c' == types[10] && 'Y' == argv[10]->c); TEST('T' == types[11] && NULL == argv[11]); TEST('F' == types[12] && NULL == argv[12]); TEST('N' == types[13] && NULL == argv[13]); TEST('I' == types[14] && NULL == argv[14]); // serialise it again, compare len = lo_message_length(msg, "/foo"); printf("serialise message_length=%d\n", (int)len); buf2 = calloc(len, sizeof(char)); size = 0; tmp = lo_message_serialise(msg, "/foo", buf2, &size); TEST(tmp == buf2 && size == len && 92 == len); TEST(!memcmp(buf, buf2, len)); lo_message_free(msg); lo_blob_free(btest); free(buf); free(buf2); // deserialise failure tests with invalid message data msg = lo_message_deserialise(data, 0, &result); // 0 size TEST(NULL == msg && LO_ESIZE == result); snprintf(data, 256, "%s", "/foo"); // unterminated path string msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_EINVALIDPATH == result); snprintf(data, 256, "%s", "/f_o"); // non-0 in pad area msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_EINVALIDPATH == result); snprintf(data, 256, "%s", "/t__"); // types missing replace_char(data, 4, '_', '\0'); msg = lo_message_deserialise(data, 4, &result); TEST(NULL == msg && LO_ENOTYPE == result); snprintf(data, 256, "%s%s", "/t__", "____"); // types empty replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EBADTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",f_"); // short message replace_char(data, 7, '_', '\0'); msg = lo_message_deserialise(data, 7, &result); TEST(NULL == msg && LO_EINVALIDTYPE == result); snprintf(data, 256, "%s%s", "/t__", "ifi_"); // types missing comma replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EBADTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",ifi"); // types unterminated replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 8, &result); TEST(NULL == msg && LO_EINVALIDTYPE == result); snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 12, &result); TEST(NULL == msg && LO_EINVALIDARG == result); snprintf(data, 256, "%s%s", "/t__", ",ii_"); // not enough arg data again replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 15, &result); TEST(NULL == msg && LO_EINVALIDARG == result); snprintf(data, 256, "%s%s", "/t__", ",f__"); // too much arg data replace_char(data, 8, '_', '\0'); msg = lo_message_deserialise(data, 16, &result); TEST(NULL == msg && LO_ESIZE == result); snprintf(data, 256, "%s%s", "/t__", ",bs_"); // blob longer than msg length replace_char(data, 8, '_', '\0'); *(uint32_t *)(data + 8) = lo_htoo32((uint32_t)99999); msg = lo_message_deserialise(data, 256, &result); TEST(NULL == msg && LO_EINVALIDARG == result); }