/* Save transaction key to global variables. */ static void save_key(pjsip_transaction *tsx) { pj_str_t key; pj_strdup(tsx->pool, &key, &tsx->transaction_key); pj_strcpy(&tsx_key, &key); }
PJ_DEF(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri_cstr) { pjxpidf_pres *pres; pj_xml_node *presentity; pj_xml_node *atom; pj_xml_node *addr; pj_xml_node *status; pj_xml_attr *attr; pj_str_t uri; pj_str_t tmp; /* <presence> */ pres = xml_create_node(pool, &STR_PRESENCE, NULL); /* <presentity> */ presentity = xml_create_node(pool, &STR_PRESENTITY, NULL); pj_xml_add_node(pres, presentity); /* uri attribute */ uri.ptr = (char*) pj_pool_alloc(pool, uri_cstr->slen + STR_SUBSCRIBE_PARAM.slen); pj_strcpy( &uri, uri_cstr); pj_strcat( &uri, &STR_SUBSCRIBE_PARAM); attr = xml_create_attr(pool, &STR_URI, &uri); pj_xml_add_attr(presentity, attr); /* <atom> */ atom = xml_create_node(pool, &STR_ATOM, NULL); pj_xml_add_node(pres, atom); /* atom id */ pj_create_unique_string(pool, &tmp); attr = xml_create_attr(pool, &STR_ATOMID, &tmp); pj_xml_add_attr(atom, attr); /* address */ addr = xml_create_node(pool, &STR_ADDRESS, NULL); pj_xml_add_node(atom, addr); /* address'es uri */ attr = xml_create_attr(pool, &STR_URI, uri_cstr); pj_xml_add_attr(addr, attr); /* status */ status = xml_create_node(pool, &STR_STATUS, NULL); pj_xml_add_node(addr, status); /* status attr */ attr = xml_create_attr(pool, &STR_STATUS, &STR_OPEN); pj_xml_add_attr(status, attr); return pres; }
int transport_rt_test( pjsip_transport_type_e tp_type, pjsip_transport *ref_tp, char *target_url, int *lost) { enum { THREADS = 4, INTERVAL = 10 }; int i; pj_status_t status; pj_pool_t *pool; pj_bool_t logger_enabled; pj_timestamp zero_time, total_time; unsigned usec_rt; unsigned total_sent; unsigned total_recv; PJ_UNUSED_ARG(tp_type); PJ_UNUSED_ARG(ref_tp); PJ_LOG(3,(THIS_FILE, " multithreaded round-trip test (%d threads)...", THREADS)); PJ_LOG(3,(THIS_FILE, " this will take approx %d seconds, please wait..", INTERVAL)); /* Make sure msg logger is disabled. */ logger_enabled = msg_logger_set_enabled(0); /* Register module (if not yet registered) */ if (rt_module.id == -1) { status = pjsip_endpt_register_module( endpt, &rt_module ); if (status != PJ_SUCCESS) { app_perror(" error: unable to register module", status); return -600; } } /* Create pool for this test. */ pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000); if (!pool) return -610; /* Initialize static test data. */ pj_ansi_strcpy(rt_target_uri, target_url); rt_call_id = pj_str("RT-Call-Id/"); rt_stop = PJ_FALSE; /* Initialize thread data. */ for (i=0; i<THREADS; ++i) { char buf[1]; pj_str_t str_id; pj_strset(&str_id, buf, 1); pj_bzero(&rt_test_data[i], sizeof(rt_test_data[i])); /* Init timer entry */ rt_test_data[i].tx_timer.id = i; rt_test_data[i].tx_timer.cb = &rt_tx_timer; rt_test_data[i].timeout_timer.id = i; rt_test_data[i].timeout_timer.cb = &rt_timeout_timer; /* Generate Call-ID for each thread. */ rt_test_data[i].call_id.ptr = (char*) pj_pool_alloc(pool, rt_call_id.slen+1); pj_strcpy(&rt_test_data[i].call_id, &rt_call_id); buf[0] = '0' + (char)i; pj_strcat(&rt_test_data[i].call_id, &str_id); /* Init mutex. */ status = pj_mutex_create_recursive(pool, "rt", &rt_test_data[i].mutex); if (status != PJ_SUCCESS) { app_perror(" error: unable to create mutex", status); return -615; } /* Create thread, suspended. */ status = pj_thread_create(pool, "rttest%p", &rt_worker_thread, (void*)(long)i, 0, PJ_THREAD_SUSPENDED, &rt_test_data[i].thread); if (status != PJ_SUCCESS) { app_perror(" error: unable to create thread", status); return -620; } } /* Start threads! */ for (i=0; i<THREADS; ++i) { pj_time_val delay = {0,0}; pj_thread_resume(rt_test_data[i].thread); /* Schedule first message transmissions. */ rt_test_data[i].tx_timer.user_data = (void*)1; pjsip_endpt_schedule_timer(endpt, &rt_test_data[i].tx_timer, &delay); } /* Sleep for some time. */ pj_thread_sleep(INTERVAL * 1000); /* Signal thread to stop. */ rt_stop = PJ_TRUE; /* Wait threads to complete. */ for (i=0; i<THREADS; ++i) { pj_thread_join(rt_test_data[i].thread); pj_thread_destroy(rt_test_data[i].thread); } /* Destroy rt_test_data */ for (i=0; i<THREADS; ++i) { pj_mutex_destroy(rt_test_data[i].mutex); pjsip_endpt_cancel_timer(endpt, &rt_test_data[i].timeout_timer); } /* Gather statistics. */ pj_bzero(&total_time, sizeof(total_time)); pj_bzero(&zero_time, sizeof(zero_time)); usec_rt = total_sent = total_recv = 0; for (i=0; i<THREADS; ++i) { total_sent += rt_test_data[i].sent_request_count; total_recv += rt_test_data[i].recv_response_count; pj_add_timestamp(&total_time, &rt_test_data[i].total_rt_time); } /* Display statistics. */ if (total_recv) total_time.u64 = total_time.u64/total_recv; else total_time.u64 = 0; usec_rt = pj_elapsed_usec(&zero_time, &total_time); PJ_LOG(3,(THIS_FILE, " done.")); PJ_LOG(3,(THIS_FILE, " total %d messages sent", total_sent)); PJ_LOG(3,(THIS_FILE, " average round-trip=%d usec", usec_rt)); pjsip_endpt_release_pool(endpt, pool); *lost = total_sent-total_recv; /* Flush events. */ flush_events(500); /* Restore msg logger. */ msg_logger_set_enabled(logger_enabled); return 0; }
/* * The public API to invoke DNS SRV resolution. */ PJ_DEF(pj_status_t) pj_dns_srv_resolve( const pj_str_t *domain_name, const pj_str_t *res_name, unsigned def_port, pj_pool_t *pool, pj_dns_resolver *resolver, unsigned option, void *token, pj_dns_srv_resolver_cb *cb, pj_dns_srv_async_query **p_query) { pj_size_t len; pj_str_t target_name; pj_dns_srv_async_query *query_job; pj_status_t status; PJ_ASSERT_RETURN(domain_name && domain_name->slen && res_name && res_name->slen && pool && resolver && cb, PJ_EINVAL); /* Build full name */ len = domain_name->slen + res_name->slen + 2; target_name.ptr = (char*) pj_pool_alloc(pool, len); pj_strcpy(&target_name, res_name); if (res_name->ptr[res_name->slen-1] != '.') pj_strcat2(&target_name, "."); len = target_name.slen; pj_strcat(&target_name, domain_name); target_name.ptr[target_name.slen] = '\0'; /* Build the query_job state */ query_job = PJ_POOL_ZALLOC_T(pool, pj_dns_srv_async_query); query_job->common.type = PJ_DNS_TYPE_SRV; query_job->objname = target_name.ptr; query_job->resolver = resolver; query_job->token = token; query_job->cb = cb; query_job->option = option; query_job->full_name = target_name; query_job->domain_part.ptr = target_name.ptr + len; query_job->domain_part.slen = target_name.slen - len; query_job->def_port = (pj_uint16_t)def_port; /* Start the asynchronous query_job */ query_job->dns_state = PJ_DNS_TYPE_SRV; PJ_LOG(5, (query_job->objname, "Starting async DNS %s query_job: target=%.*s:%d", pj_dns_get_type_name(query_job->dns_state), (int)target_name.slen, target_name.ptr, def_port)); status = pj_dns_resolver_start_query(resolver, &target_name, query_job->dns_state, 0, &dns_callback, query_job, &query_job->q_srv); if (status==PJ_SUCCESS && p_query) *p_query = query_job; return status; }
void SIPCall::setContactHeader(pj_str_t *contact) { pj_strcpy(&contactHeader_, contact); }
// // Copy the contents of other string. // void strcpy(const Pj_String &rhs) { pj_strcpy(this, &rhs); }
// // Copy the contents of other string. // void strcpy(const pj_str_t *s) { pj_strcpy(this, s); }
/* * This is the handler to receive message for this test. It is used to * control and verify the behavior of the message transmitted by the * transaction. */ static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata) { if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST1_BRANCH_ID) == 0) { /* * The TEST1_BRANCH_ID test performs the verifications for transaction * retransmission mechanism. It will not answer the incoming request * with any response. */ pjsip_msg *msg = rdata->msg_info.msg; PJ_LOG(4,(THIS_FILE, " received request")); /* Only wants to take INVITE or OPTIONS method. */ if (msg->line.req.method.id != PJSIP_INVITE_METHOD && msg->line.req.method.id != PJSIP_OPTIONS_METHOD) { PJ_LOG(3,(THIS_FILE, " error: received unexpected method %.*s", msg->line.req.method.name.slen, msg->line.req.method.name.ptr)); test_complete = -600; return PJ_TRUE; } if (recv_count == 0) { recv_count++; //pj_gettimeofday(&recv_last); recv_last = rdata->pkt_info.timestamp; } else { pj_time_val now; unsigned msec_expected, msec_elapsed; int max_received; //pj_gettimeofday(&now); now = rdata->pkt_info.timestamp; PJ_TIME_VAL_SUB(now, recv_last); msec_elapsed = now.sec*1000 + now.msec; ++recv_count; msec_expected = (1<<(recv_count-2))*PJSIP_T1_TIMEOUT; if (msg->line.req.method.id != PJSIP_INVITE_METHOD) { if (msec_expected > PJSIP_T2_TIMEOUT) msec_expected = PJSIP_T2_TIMEOUT; max_received = 11; } else { max_received = 7; } if (DIFF(msec_expected, msec_elapsed) > TEST1_ALLOWED_DIFF) { PJ_LOG(3,(THIS_FILE, " error: expecting retransmission no. %d in %d " "ms, received in %d ms", recv_count-1, msec_expected, msec_elapsed)); test_complete = -610; } if (recv_count > max_received) { PJ_LOG(3,(THIS_FILE, " error: too many messages (%d) received", recv_count)); test_complete = -620; } //pj_gettimeofday(&recv_last); recv_last = rdata->pkt_info.timestamp; } return PJ_TRUE; } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST4_BRANCH_ID) == 0) { /* * The TEST4_BRANCH_ID test simulates transport failure after several * retransmissions. */ recv_count++; if (recv_count == TEST4_RETRANSMIT_CNT) { /* Simulate transport failure. */ pjsip_loop_set_failure(loop, 2, NULL); } else if (recv_count > TEST4_RETRANSMIT_CNT) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -631; } return PJ_TRUE; } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST5_BRANCH_ID) == 0) { /* * The TEST5_BRANCH_ID test simulates user terminating the transaction * after several retransmissions. */ recv_count++; if (recv_count == TEST5_RETRANSMIT_CNT+1) { pj_str_t key; pjsip_transaction *tsx; pjsip_tsx_create_key( rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, &rdata->msg_info.msg->line.req.method, rdata); tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); if (tsx) { pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); pj_mutex_unlock(tsx->mutex); } else { PJ_LOG(3,(THIS_FILE, " error: uac transaction not found!")); test_complete = -633; } } else if (recv_count > TEST5_RETRANSMIT_CNT+1) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -634; } return PJ_TRUE; } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST6_BRANCH_ID) == 0) { /* * The TEST6_BRANCH_ID test successfull non-INVITE transaction. */ pj_status_t status; recv_count++; if (recv_count > 1) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -635; } status = pjsip_endpt_respond_stateless(endpt, rdata, 202, NULL, NULL, NULL); if (status != PJ_SUCCESS) { app_perror(" error: unable to send response", status); test_complete = -636; } return PJ_TRUE; } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST7_BRANCH_ID) == 0) { /* * The TEST7_BRANCH_ID test successfull non-INVITE transaction * with provisional response. */ pj_status_t status; pjsip_response_addr res_addr; struct response *r; pjsip_tx_data *tdata; pj_time_val delay = { 2, 0 }; recv_count++; if (recv_count > 1) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -640; return PJ_TRUE; } /* Respond with provisional response */ status = pjsip_endpt_create_response(endpt, rdata, 100, NULL, &tdata); pj_assert(status == PJ_SUCCESS); status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr); pj_assert(status == PJ_SUCCESS); status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL, NULL); pj_assert(status == PJ_SUCCESS); /* Create the final response. */ status = pjsip_endpt_create_response(endpt, rdata, 202, NULL, &tdata); pj_assert(status == PJ_SUCCESS); /* Schedule sending final response in couple of of secs. */ r = pj_pool_alloc(tdata->pool, sizeof(*r)); r->res_addr = res_addr; r->tdata = tdata; if (r->res_addr.transport) pjsip_transport_add_ref(r->res_addr.transport); timer.entry.cb = &send_response_callback; timer.entry.user_data = r; pjsip_endpt_schedule_timer(endpt, &timer.entry, &delay); return PJ_TRUE; } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST8_BRANCH_ID) == 0) { /* * The TEST8_BRANCH_ID test failed INVITE transaction. */ pjsip_method *method; pj_status_t status; method = &rdata->msg_info.msg->line.req.method; recv_count++; if (method->id == PJSIP_INVITE_METHOD) { if (recv_count > 1) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -635; } status = pjsip_endpt_respond_stateless(endpt, rdata, 301, NULL, NULL, NULL); if (status != PJ_SUCCESS) { app_perror(" error: unable to send response", status); test_complete = -636; } } else if (method->id == PJSIP_ACK_METHOD) { if (recv_count == 2) { pj_str_t key; pj_time_val delay = { 5, 0 }; /* Schedule timer to destroy transaction after 5 seconds. * This is to make sure that transaction does not * retransmit ACK. */ pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, &pjsip_invite_method, rdata); pj_strcpy(&timer.tsx_key, &key); timer.entry.id = 301; timer.entry.cb = &terminate_tsx_callback; pjsip_endpt_schedule_timer(endpt, &timer.entry, &delay); } if (recv_count > 2) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -638; } } else { PJ_LOG(3,(THIS_FILE," error: not expecting %s", pjsip_rx_data_get_info(rdata))); test_complete = -639; } } else if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST9_BRANCH_ID) == 0) { /* * The TEST9_BRANCH_ID test failed INVITE transaction with * provisional response. */ pjsip_method *method; pj_status_t status; method = &rdata->msg_info.msg->line.req.method; recv_count++; if (method->id == PJSIP_INVITE_METHOD) { pjsip_response_addr res_addr; struct response *r; pjsip_tx_data *tdata; pj_time_val delay = { 2, 0 }; if (recv_count > 1) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -650; return PJ_TRUE; } /* Respond with provisional response */ status = pjsip_endpt_create_response(endpt, rdata, 100, NULL, &tdata); pj_assert(status == PJ_SUCCESS); status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr); pj_assert(status == PJ_SUCCESS); status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL, NULL); pj_assert(status == PJ_SUCCESS); /* Create the final response. */ status = pjsip_endpt_create_response(endpt, rdata, 302, NULL, &tdata); pj_assert(status == PJ_SUCCESS); /* Schedule sending final response in couple of of secs. */ r = pj_pool_alloc(tdata->pool, sizeof(*r)); r->res_addr = res_addr; r->tdata = tdata; if (r->res_addr.transport) pjsip_transport_add_ref(r->res_addr.transport); timer.entry.cb = &send_response_callback; timer.entry.user_data = r; pjsip_endpt_schedule_timer(endpt, &timer.entry, &delay); } else if (method->id == PJSIP_ACK_METHOD) { if (recv_count == 2) { pj_str_t key; pj_time_val delay = { 5, 0 }; /* Schedule timer to destroy transaction after 5 seconds. * This is to make sure that transaction does not * retransmit ACK. */ pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, &pjsip_invite_method, rdata); pj_strcpy(&timer.tsx_key, &key); timer.entry.id = 302; timer.entry.cb = &terminate_tsx_callback; pjsip_endpt_schedule_timer(endpt, &timer.entry, &delay); } if (recv_count > 2) { PJ_LOG(3,(THIS_FILE," error: not expecting %d-th packet!", recv_count)); test_complete = -638; } } else { PJ_LOG(3,(THIS_FILE," error: not expecting %s", pjsip_rx_data_get_info(rdata))); test_complete = -639; } return PJ_TRUE; } return PJ_FALSE; }
int string_test(void) { const pj_str_t hello_world = { HELLO_WORLD, HELLO_WORLD_LEN }; const pj_str_t just_hello = { JUST_HELLO, JUST_HELLO_LEN }; pj_str_t s1, s2, s3, s4, s5; enum { RCOUNT = 10, RLEN = 16 }; pj_str_t random[RCOUNT]; pj_pool_t *pool; int i; pool = pj_pool_create(mem, SNULL, 4096, 0, SNULL); if (!pool) return -5; /* * pj_str(), pj_strcmp(), pj_stricmp(), pj_strlen(), * pj_strncmp(), pj_strchr() */ s1 = pj_str(HELLO_WORLD); if (pj_strcmp(&s1, &hello_world) != 0) return -10; if (pj_stricmp(&s1, &hello_world) != 0) return -20; if (pj_strcmp(&s1, &just_hello) <= 0) return -30; if (pj_stricmp(&s1, &just_hello) <= 0) return -40; if (pj_strlen(&s1) != strlen(HELLO_WORLD)) return -50; if (pj_strncmp(&s1, &hello_world, 5) != 0) return -60; if (pj_strnicmp(&s1, &hello_world, 5) != 0) return -70; if (pj_strchr(&s1, HELLO_WORLD[1]) != s1.ptr+1) return -80; /* * pj_strdup() */ if (!pj_strdup(pool, &s2, &s1)) return -100; if (pj_strcmp(&s1, &s2) != 0) return -110; /* * pj_strcpy(), pj_strcat() */ s3.ptr = (char*) pj_pool_alloc(pool, 256); if (!s3.ptr) return -200; pj_strcpy(&s3, &s2); pj_strcat(&s3, &just_hello); if (pj_strcmp2(&s3, HELLO_WORLD JUST_HELLO) != 0) return -210; /* * pj_strdup2(), pj_strtrim(). */ pj_strdup2(pool, &s4, " " HELLO_WORLD "\t "); pj_strtrim(&s4); if (pj_strcmp2(&s4, HELLO_WORLD) != 0) return -250; /* * pj_utoa() */ s5.ptr = (char*) pj_pool_alloc(pool, 16); if (!s5.ptr) return -270; s5.slen = pj_utoa(UL_VALUE, s5.ptr); /* * pj_strtoul() */ if (pj_strtoul(&s5) != UL_VALUE) return -280; /* * pj_strtoul2() */ s5 = pj_str("123456"); pj_strtoul2(&s5, SNULL, 10); /* Crash test */ if (pj_strtoul2(&s5, &s4, 10) != 123456UL) return -290; if (s4.slen != 0) return -291; if (pj_strtoul2(&s5, &s4, 16) != 0x123456UL) return -292; s5 = pj_str("0123ABCD"); if (pj_strtoul2(&s5, &s4, 10) != 123) return -293; if (s4.slen != 4) return -294; if (s4.ptr == SNULL || *s4.ptr != 'A') return -295; if (pj_strtoul2(&s5, &s4, 16) != 0x123ABCDUL) return -296; if (s4.slen != 0) return -297; /* * pj_create_random_string() * Check that no duplicate strings are returned. */ for (i=0; i<RCOUNT; ++i) { int j; random[i].ptr = (char*) pj_pool_alloc(pool, RLEN); if (!random[i].ptr) return -320; random[i].slen = RLEN; pj_create_random_string(random[i].ptr, RLEN); for (j=0; j<i; ++j) { if (pj_strcmp(&random[i], &random[j])==0) return -330; } } /* Done. */ pj_pool_release(pool); /* Case sensitive comparison test. */ i = strcmp_test(); if (i != 0) return i; /* Caseless comparison test. */ i = stricmp_test(); if (i != 0) return i; return 0; }