/** * Registers a new AUID. If the AUID already exist (case-insensitive comparison on the id), * then it will be updated with the new supplied values. * @param auids The destination list. * @param id The id of the new AUID to add (e.g. xcap-caps). * @param mime_type The MIME-Type of the new AUID to add (e.g. application/xcap-caps+xml). * @param ns The Namespace of the new AUID to add (e.g. urn:ietf:params:xml:ns:xcap-caps). * @param document_name The name of the new AUID to add (e.g. index). * @param is_global Indicates whether the AUID scope is global or not (user). * @retval Zero if succeed and non-zero error code otherwise. */ int txcap_auid_register(txcap_auids_L_t* auids, const char* id, const char* mime_type, const char* ns, const char* document_name, tsk_bool_t is_global) { const tsk_list_item_t* item; int ret = -1; if(!auids || !id){ return -1; } if((item = tsk_list_find_item_by_pred(auids, pred_find_auid_by_id, id))){ tsk_strupdate(&((txcap_auid_t*)item->data)->mime_type, mime_type); tsk_strupdate(&((txcap_auid_t*)item->data)->ns, ns); tsk_strupdate(&((txcap_auid_t*)item->data)->document_name, document_name); ((txcap_auid_t*)item->data)->global = is_global; ret = 0; } else{ txcap_auid_t* auid; if((auid = txcap_auid_create(tauid_dummy, id, mime_type, ns, document_name, is_global))){ tsk_list_push_back_data(auids, (void**)&auid); ret = 0; }else{ ret = -2; } } return ret; }
/**@ingroup thttp_message_group */ int thttp_message_add_header(thttp_message_t *self, const thttp_header_t *hdr) { #define ADD_HEADER(type, field) \ case thttp_htype_##type: \ { \ if(!self->field) \ { \ self->field = (thttp_header_##type##_t*)header; \ return 0; \ } \ break; \ } if(self && hdr) { thttp_header_t *header = tsk_object_ref((void*)hdr); switch(header->type) { ADD_HEADER(Content_Type, Content_Type); ADD_HEADER(Content_Length, Content_Length); default: break; } tsk_list_push_back_data(self->headers, (void**)&header); return 0; } return -1; }
static const tsdp_header_M_t* tmedia_session_ghost_get_lo(tmedia_session_t* self) { tmedia_session_ghost_t* ghost; ghost = (tmedia_session_ghost_t*)self; if(self->M.lo){ return self->M.lo; } else if(!(self->M.lo = tsdp_header_M_create(ghost->media, 0, ghost->proto ? ghost->proto: "RTP/AVP"))){ TSK_DEBUG_ERROR("Failed to create lo"); return tsk_null; } // add format if(!tsk_strnullORempty(ghost->first_format)){ tsk_string_t* fmt = tsk_string_create(ghost->first_format); if(!self->M.lo->FMTs){ self->M.lo->FMTs = tsk_list_create(); } tsk_list_push_back_data(self->M.lo->FMTs, (void**)&fmt); TSK_OBJECT_SAFE_FREE(fmt); } return self->M.lo; }
/** Initialze the list of auids with default values from __txcap_auids * auids must be null; */ int txcap_auids_init(txcap_auids_L_t** auids) { size_t i; size_t count; if(!auids){ TSK_DEBUG_ERROR("invalid parameter."); return -1; } else if(*auids){ TSK_DEBUG_WARN("auids already initialized."); } else{ *auids = tsk_list_create(); } count = sizeof(__txcap_auids)/sizeof(auid_t); for(i = 0; i<count; i++){ txcap_auid_t* auid = txcap_auid_create(__txcap_auids[i].type, __txcap_auids[i].id, __txcap_auids[i].mime_type, __txcap_auids[i].ns, __txcap_auids[i].document_name, __txcap_auids[i].global); tsk_list_push_back_data(*auids, (void**)&auid); } return 0; }
// // [[DHCP OPTION - RFC 2132 3.8. Domain Name Server Option]] object definition // static tsk_object_t* tnet_dhcp_option_dns_ctor(tsk_object_t * self, va_list * app) { tnet_dhcp_option_dns_t *option = self; if(option){ const void* payload = va_arg(*app, const void*); tsk_size_t payload_size = va_arg(*app, tsk_size_t); const uint8_t* payloadPtr = (const uint8_t*)payload; const uint8_t* payloadEnd = (payloadPtr + payload_size); /* init base */ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Domain_Server); option->servers = tsk_list_create(); if(payload_size<4 || payload_size%4){ TSK_DEBUG_ERROR("DHCP - The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4."); } else{ tsk_size_t i; char* ip4 = 0; uint32_t address; tsk_string_t* addrstring; for(i=0; i<payload_size && (payloadPtr< payloadEnd); i+=4){ /* Code Len Address 1 Address 2 +-----+-----+-----+-----+-----+-----+-----+-----+-- | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ... +-----+-----+-----+-----+-----+-----+-----+-----+-- */ address = (uint32_t)tnet_htonl_2(payloadPtr); tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF); addrstring = tsk_string_create(ip4); tsk_list_push_back_data(option->servers, (void*)&addrstring); TSK_FREE(ip4); payloadPtr+= 4; } } } return self; }
/**@ingroup tnet_nat_group * * Creates and sends a STUN2 binding request to the STUN/TURN server in order to get the server reflexive * address associated to this file descriptor (or socket). The caller should call @ref tnet_nat_stun_unbind to destroy the binding. * * @param [in,out] p_self The NAT context. * @param localFD The local file descriptor (or socket) for which to get the reflexive server address. * * @return A valid binding id if succeed and @ref kStunBindingInvalidId otherwise. If the returned id is valid then * the newly created binding will contain the server-reflexive address associated to the local file descriptor. * * @sa @ref tnet_nat_stun_unbind. **/ tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD) { tnet_stun_binding_id_t id = kStunBindingInvalidId; tnet_stun_binding_t *p_binding = tsk_null; int ret; if (!p_self || localFD == TNET_INVALID_FD) { TSK_DEBUG_ERROR("Invalid parameter"); goto bail; } if ((ret = tnet_stun_binding_create(localFD, p_self->socket_type, p_self->server_address, p_self->server_port, p_self->username, p_self->password, &p_binding))) { goto bail; } if ((ret = tnet_nat_stun_send_bind(p_self, p_binding))) { goto bail; } id = p_binding->id; tsk_list_push_back_data(p_self->stun_bindings, (void**)&p_binding); bail: TSK_OBJECT_SAFE_FREE(p_binding); return id; }
/**@ingroup tsk_params_group * Adds a parameter to the list of parameters. If the parameter already exist(case-insensitive), then it's value will be updated. * @param self The destination list. * @param name The name of the parameter to add. * @param value The value of the parameter to add. * @retval Zero if succeed and -1 otherwise. */ int tsk_params_add_param(tsk_params_L_t **self, const char* name, const char* value) { tsk_param_t *param; if(!self || !name) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(!*self){ *self = tsk_list_create(); } if((param = (tsk_param_t*)tsk_params_get_param_by_name(*self, name))){ tsk_strupdate(¶m->value, value); /* Already exist ==> update the value. */ } else{ param = tsk_param_create(name, value); tsk_list_push_back_data(*self, (void**)¶m); } return 0; }
int tmedia_params_add_param(tmedia_params_L_t **self, tmedia_param_access_type_t access_type, tmedia_type_t media_type, tmedia_param_plugin_type_t plugin_type, tmedia_param_value_type_t value_type, const char* key, void* value) { tmedia_param_t *param; if(!self) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(!*self){ *self = tmedia_params_create(); } if((param = tmedia_param_create(access_type, media_type, plugin_type, value_type, key, value))){ tsk_list_push_back_data(*self, (void**)¶m); } return 0; }
// @param str e.g. "1 1 udp 1 192.168.196.1 57806 typ host name video_rtcp network_name {0C0137CC-DB78-46B6-9B6C-7E097FFA79FE} username StFEVThMK2DHThkv password qkhKUDr4WqKRwZTo generation 0" tnet_ice_candidate_t* tnet_ice_candidate_parse(const char* str) { char *v, *copy; int32_t k; tnet_ice_candidate_t* candidate; if(tsk_strnullORempty(str)){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } if(!(candidate = tsk_object_new(&tnet_ice_candidate_def_s))){ TSK_DEBUG_ERROR("Failed to create candidate"); return tsk_null; } k = 0; copy = tsk_strdup(str); v = strtok(copy, " "); while(v){ switch(k){ case 0: { memcpy(candidate->foundation, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->foundation))); break; } case 1: { candidate->comp_id = atoi(v); break; } case 2: { candidate->transport_str = tsk_strdup(v); break; } case 3: { candidate->priority = atoi(v); break; } case 4: { memcpy(candidate->connection_addr, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->connection_addr))); break; } case 5: { tnet_family_t family; candidate->port = atoi(v); family = tnet_get_family(candidate->connection_addr, candidate->port); candidate->transport_e = _tnet_ice_candidate_get_transport_type((family == AF_INET6), candidate->transport_str); break; } case 6: { v = strtok(tsk_null, " "); tsk_strupdate(&candidate->cand_type_str, v); candidate->type_e = _tnet_ice_candtype_get_transport_type(v); break; } default: { const char* name = v; const char* value = (v = strtok(tsk_null, " ")); tsk_param_t* param = tsk_param_create(name, value); if(param){ tsk_list_push_back_data(candidate->extension_att_list, (void**)¶m); } break; } } ++k; v = strtok(tsk_null, " "); } if(k < 6){ TSK_DEBUG_ERROR("Failed to parse: %s", str); TSK_OBJECT_SAFE_FREE(candidate); } TSK_FREE(copy); return candidate; }
// // [[DHCP SIP4]] object definition // static tsk_object_t* tnet_dhcp_option_sip_ctor(tsk_object_t * self, va_list * app) { tnet_dhcp_option_sip_t *option = self; if(option){ const void* payload = va_arg(*app, const void*); tsk_size_t payload_size = va_arg(*app, tsk_size_t); const uint8_t* payloadPtr = (const uint8_t*)payload; const uint8_t* payloadEnd = (payloadPtr + payload_size); /* init base */ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_SIP_Servers_DHCP_Option); option->servers = tsk_list_create(); /* Set values as per RFC 3361. */ if(*payloadPtr == 0){ /* enc=0 */ /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |120|27 | 0 | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'c'|'o'|'m'| 0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+---+---+ | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'n'|'e'|'t'| 0 | +---+---+--- +---+---+---+---+---+---+---+---+---+---+ */ tsk_size_t offset = 1; char* server = 0; payloadPtr++; while((payloadPtr < payloadEnd) && !tnet_dns_rr_qname_deserialize(payload, &server, &offset)){ tsk_string_t* string = tsk_string_create(server); tsk_list_push_back_data(option->servers, (void*)&string); TSK_FREE(server); payloadPtr += offset; } } else{ /* Code Len enc Address 1 Address 2 +-----+-----+-----+-----+-----+-----+-----+-----+-- | 120 | n | 1 | a1 | a2 | a3 | a4 | a1 | ... +-----+-----+-----+-----+-----+-----+-----+-----+-- */ uint32_t address; tsk_string_t* addrstring; char* ip4 = 0; while(payloadPtr < payloadEnd){ ++payloadPtr; address = tnet_htonl_2(payloadPtr); tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF); addrstring = tsk_string_create(ip4); tsk_list_push_back_data(option->servers, (void*)&addrstring); TSK_FREE(ip4); payloadPtr+= 4; } } } return self; }
tdav_audiounit_handle_t* tdav_audiounit_handle_create(uint64_t session_id) { tdav_audiounit_instance_t* inst = tsk_null; // create audio unit component if(!__audioSystem){ AudioComponentDescription audioDescription; audioDescription.componentType = kAudioUnitType_Output; audioDescription.componentSubType = kDoubangoAudioUnitSubType; audioDescription.componentManufacturer = kAudioUnitManufacturer_Apple; audioDescription.componentFlags = 0; audioDescription.componentFlagsMask = 0; if((__audioSystem = AudioComponentFindNext(NULL, &audioDescription))){ // leave blank } else { TSK_DEBUG_ERROR("Failed to find new audio component"); goto done; } } // create list used to hold instances if(!__audioUnitInstances && !(__audioUnitInstances = tsk_list_create())){ TSK_DEBUG_ERROR("Failed to create new list"); goto done; } //= lock the list tsk_list_lock(__audioUnitInstances); // For iOS we are using full-duplex AudioUnit and to keep it unique for both // the consumer and producer we use the session id. #if TARGET_OS_IPHONE // find the instance from the list const tsk_list_item_t* item; tsk_list_foreach(item,__audioUnitInstances){ if(((tdav_audiounit_instance_t*)item->data)->session_id == session_id){ inst = tsk_object_ref(item->data); goto done; } } #endif // create instance object and put it into the list if((inst = tsk_object_new(tdav_audiounit_instance_def_t))){ OSStatus status = noErr; tdav_audiounit_instance_t* _inst; // create new instance if((status= AudioComponentInstanceNew(__audioSystem, &inst->audioUnit)) != noErr){ TSK_DEBUG_ERROR("AudioComponentInstanceNew() failed with status=%ld", (signed long)status); TSK_OBJECT_SAFE_FREE(inst); goto done; } _inst = inst, _inst->session_id = session_id; tsk_list_push_back_data(__audioUnitInstances, (void**)&_inst); } done: //= unlock the list tsk_list_unlock(__audioUnitInstances); return (tdav_audiounit_handle_t*)inst; }