/* Timer callback to terminate a transaction. */ static void terminate_tsx_callback( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry) { struct my_timer *m = (struct my_timer *)entry; pjsip_transaction *tsx = pjsip_tsx_layer_find_tsx(&m->tsx_key, PJ_FALSE); int status_code = entry->id; if (tsx) { pjsip_tsx_terminate(tsx, status_code); } }
/* Find and terminate tsx with the specified key. */ static void terminate_our_tsx(int status_code) { pjsip_transaction *tsx; tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); if (!tsx) { PJ_LOG(3,(THIS_FILE," error: timer unable to find transaction")); return; } pjsip_tsx_terminate(tsx, status_code); pj_mutex_unlock(tsx->mutex); }
/* Test transaction layer. */ static int tsx_layer_test(void) { pj_str_t target, from, tsx_key; pjsip_tx_data *tdata; pjsip_transaction *tsx, *found; pj_status_t status; PJ_LOG(3,(THIS_FILE, " transaction layer test")); target = pj_str(TARGET_URI); from = pj_str(FROM_URI); status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &target, &from, &target, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { app_perror(" error: unable to create request", status); return -110; } status = pjsip_tsx_create_uac(NULL, tdata, &tsx); if (status != PJ_SUCCESS) { app_perror(" error: unable to create transaction", status); return -120; } pj_strdup(tdata->pool, &tsx_key, &tsx->transaction_key); found = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE); if (found != tsx) { return -130; } pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); flush_events(500); if (pjsip_tx_data_dec_ref(tdata) != PJSIP_EBUFDESTROYED) { return -140; } return 0; }
/* Callback to be called to handle transaction state changed. */ static void tu_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event) { struct uac_data *uac_data; pj_status_t status; if (tsx->role == PJSIP_ROLE_UAS) { if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { struct uas_data *uas_data; uas_data = (struct uas_data*) tsx->mod_data[mod_tu.id]; if (uas_data->uac_tsx) { uac_data = (struct uac_data*) uas_data->uac_tsx->mod_data[mod_tu.id]; uac_data->uas_tsx = NULL; } } return; } /* Get the data that we attached to the UAC transaction previously */ uac_data = (struct uac_data*) tsx->mod_data[mod_tu.id]; /* Handle incoming response */ if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { pjsip_rx_data *rdata; pjsip_response_addr res_addr; pjsip_via_hdr *hvia; pjsip_tx_data *tdata; rdata = event->body.tsx_state.src.rdata; /* Do not forward 100 response for INVITE (we already responded * INVITE with 100) */ if (tsx->method.id == PJSIP_INVITE_METHOD && rdata->msg_info.msg->line.status.code == 100) { return; } /* Create response to be forwarded upstream * (Via will be stripped here) */ status = pjsip_endpt_create_response_fwd(global.endpt, rdata, 0, &tdata); if (status != PJ_SUCCESS) { app_perror("Error creating response", status); return; } /* Get topmost Via header of the new response */ hvia = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); if (hvia == NULL) { /* Invalid response! Just drop it */ pjsip_tx_data_dec_ref(tdata); return; } /* Calculate the address to forward the response */ pj_bzero(&res_addr, sizeof(res_addr)); res_addr.dst_host.type = PJSIP_TRANSPORT_UDP; res_addr.dst_host.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP); /* Destination address is Via's received param */ res_addr.dst_host.addr.host = hvia->recvd_param; if (res_addr.dst_host.addr.host.slen == 0) { /* Someone has messed up our Via header! */ res_addr.dst_host.addr.host = hvia->sent_by.host; } /* Destination port is the rport */ if (hvia->rport_param != 0 && hvia->rport_param != -1) res_addr.dst_host.addr.port = hvia->rport_param; if (res_addr.dst_host.addr.port == 0) { /* Ugh, original sender didn't put rport! * At best, can only send the response to the port in Via. */ res_addr.dst_host.addr.port = hvia->sent_by.port; } /* Forward response with the UAS transaction */ pjsip_tsx_send_msg(uac_data->uas_tsx, tdata); } /* If UAC transaction is terminated, terminate the UAS as well. * This could happen because of: * - timeout on the UAC side * - receipt of 2xx response to INVITE */ if (tsx->state == PJSIP_TSX_STATE_TERMINATED && uac_data && uac_data->uas_tsx) { pjsip_transaction *uas_tsx; struct uas_data *uas_data; uas_tsx = uac_data->uas_tsx; uas_data = (struct uas_data*) uas_tsx->mod_data[mod_tu.id]; uas_data->uac_tsx = NULL; if (event->body.tsx_state.type == PJSIP_EVENT_TIMER) { /* Send 408/Timeout if this is an INVITE transaction, since * we must have sent provisional response before. For non * INVITE transaction, just destroy it. */ if (tsx->method.id == PJSIP_INVITE_METHOD) { pjsip_tx_data *tdata = uas_tsx->last_tx; tdata->msg->line.status.code = PJSIP_SC_REQUEST_TIMEOUT; tdata->msg->line.status.reason = pj_str("Request timed out"); tdata->msg->body = NULL; pjsip_tx_data_add_ref(tdata); pjsip_tx_data_invalidate_msg(tdata); pjsip_tsx_send_msg(uas_tsx, tdata); } else { /* For non-INVITE, just destroy the UAS transaction */ pjsip_tsx_terminate(uas_tsx, PJSIP_SC_REQUEST_TIMEOUT); } } else if (event->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { if (uas_tsx->state < PJSIP_TSX_STATE_TERMINATED) { pjsip_msg *msg; int code; msg = event->body.tsx_state.src.rdata->msg_info.msg; code = msg->line.status.code; uac_data->uas_tsx = NULL; pjsip_tsx_terminate(uas_tsx, code); } } } }
/* Callback to be called to handle new incoming requests. */ static pj_bool_t proxy_on_rx_request( pjsip_rx_data *rdata ) { pjsip_transaction *uas_tsx, *uac_tsx; struct uac_data *uac_data; struct uas_data *uas_data; pjsip_tx_data *tdata; pj_status_t status; if (rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD) { /* Verify incoming request */ status = proxy_verify_request(rdata); if (status != PJ_SUCCESS) { app_perror("RX invalid request", status); return PJ_TRUE; } /* * Request looks sane, next clone the request to create transmit data. */ status = pjsip_endpt_create_request_fwd(global.endpt, rdata, NULL, NULL, 0, &tdata); if (status != PJ_SUCCESS) { pjsip_endpt_respond_stateless(global.endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL); return PJ_TRUE; } /* Process routing */ status = proxy_process_routing(tdata); if (status != PJ_SUCCESS) { app_perror("Error processing route", status); return PJ_TRUE; } /* Calculate target */ status = proxy_calculate_target(rdata, tdata); if (status != PJ_SUCCESS) { app_perror("Error calculating target", status); return PJ_TRUE; } /* Everything is set to forward the request. */ /* If this is an ACK request, forward statelessly. * This happens if the proxy records route and this ACK * is sent for 2xx response. An ACK that is sent for non-2xx * final response will be absorbed by transaction layer, and * it will not be received by on_rx_request() callback. */ if (tdata->msg->line.req.method.id == PJSIP_ACK_METHOD) { status = pjsip_endpt_send_request_stateless(global.endpt, tdata, NULL, NULL); if (status != PJ_SUCCESS) { app_perror("Error forwarding request", status); return PJ_TRUE; } return PJ_TRUE; } /* Create UAC transaction for forwarding the request. * Set our module as the transaction user to receive further * events from this transaction. */ status = pjsip_tsx_create_uac(&mod_tu, tdata, &uac_tsx); if (status != PJ_SUCCESS) { pjsip_tx_data_dec_ref(tdata); pjsip_endpt_respond_stateless(global.endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL); return PJ_TRUE; } /* Create UAS transaction to handle incoming request */ status = pjsip_tsx_create_uas(&mod_tu, rdata, &uas_tsx); if (status != PJ_SUCCESS) { pjsip_tx_data_dec_ref(tdata); pjsip_endpt_respond_stateless(global.endpt, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL); pjsip_tsx_terminate(uac_tsx, PJSIP_SC_INTERNAL_SERVER_ERROR); return PJ_TRUE; } /* Feed the request to the UAS transaction to drive it's state * out of NULL state. */ pjsip_tsx_recv_msg(uas_tsx, rdata); /* Attach a data to the UAC transaction, to be used to find the * UAS transaction when we receive response in the UAC side. */ uac_data = (struct uac_data*) pj_pool_alloc(uac_tsx->pool, sizeof(struct uac_data)); uac_data->uas_tsx = uas_tsx; uac_tsx->mod_data[mod_tu.id] = (void*)uac_data; /* Attach data to the UAS transaction, to find the UAC transaction * when cancelling INVITE request. */ uas_data = (struct uas_data*) pj_pool_alloc(uas_tsx->pool, sizeof(struct uas_data)); uas_data->uac_tsx = uac_tsx; uas_tsx->mod_data[mod_tu.id] = (void*)uas_data; /* Everything is setup, forward the request */ status = pjsip_tsx_send_msg(uac_tsx, tdata); if (status != PJ_SUCCESS) { pjsip_tx_data *err_res; /* Fail to send request, for some reason */ /* Destroy transmit data */ pjsip_tx_data_dec_ref(tdata); /* I think UAC transaction should have been destroyed when * it fails to send request, so no need to destroy it. pjsip_tsx_terminate(uac_tsx, PJSIP_SC_INTERNAL_SERVER_ERROR); */ /* Send 500/Internal Server Error to UAS transaction */ pjsip_endpt_create_response(global.endpt, rdata, 500, NULL, &err_res); pjsip_tsx_send_msg(uas_tsx, err_res); return PJ_TRUE; } /* Send 100/Trying if this is an INVITE */ if (rdata->msg_info.msg->line.req.method.id == PJSIP_INVITE_METHOD) { pjsip_tx_data *res100; pjsip_endpt_create_response(global.endpt, rdata, 100, NULL, &res100); pjsip_tsx_send_msg(uas_tsx, res100); } } else { /* This is CANCEL request */ pjsip_transaction *invite_uas; struct uas_data *uas_data; pj_str_t key; /* Find the UAS INVITE transaction */ pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_UAS_ROLE, pjsip_get_invite_method(), rdata); invite_uas = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); if (!invite_uas) { /* Invite transaction not found, respond CANCEL with 481 */ pjsip_endpt_respond_stateless(global.endpt, rdata, 481, NULL, NULL, NULL); return PJ_TRUE; } /* Respond 200 OK to CANCEL */ pjsip_endpt_respond(global.endpt, NULL, rdata, 200, NULL, NULL, NULL, NULL); /* Send CANCEL to cancel the UAC transaction. * The UAS INVITE transaction will get final response when * we receive final response from the UAC INVITE transaction. */ uas_data = (struct uas_data*) invite_uas->mod_data[mod_tu.id]; if (uas_data->uac_tsx && uas_data->uac_tsx->status_code < 200) { pjsip_tx_data *cancel; pj_mutex_lock(uas_data->uac_tsx->mutex); pjsip_endpt_create_cancel(global.endpt, uas_data->uac_tsx->last_tx, &cancel); pjsip_endpt_send_request(global.endpt, cancel, -1, NULL, NULL); pj_mutex_unlock(uas_data->uac_tsx->mutex); } /* Unlock UAS tsx because it is locked in find_tsx() */ pj_mutex_unlock(invite_uas->mutex); } return PJ_TRUE; }
/* Double terminate test. */ static int double_terminate(void) { pj_str_t target, from, tsx_key; pjsip_tx_data *tdata; pjsip_transaction *tsx; pj_status_t status; PJ_LOG(3,(THIS_FILE, " double terminate test")); target = pj_str(TARGET_URI); from = pj_str(FROM_URI); /* Create request. */ status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &target, &from, &target, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { app_perror(" error: unable to create request", status); return -10; } /* Create transaction. */ status = pjsip_tsx_create_uac(NULL, tdata, &tsx); if (status != PJ_SUCCESS) { app_perror(" error: unable to create transaction", status); return -20; } /* Save transaction key for later. */ pj_strdup_with_null(tdata->pool, &tsx_key, &tsx->transaction_key); /* Add reference to transmit buffer (tsx_send_msg() will dec txdata). */ pjsip_tx_data_add_ref(tdata); /* Send message to start timeout timer. */ status = pjsip_tsx_send_msg(tsx, NULL); /* Terminate transaction. */ status = pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); if (status != PJ_SUCCESS) { app_perror(" error: unable to terminate transaction", status); return -30; } tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); if (tsx) { /* Terminate transaction again. */ pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); if (status != PJ_SUCCESS) { app_perror(" error: unable to terminate transaction", status); return -40; } pj_mutex_unlock(tsx->mutex); } flush_events(500); if (pjsip_tx_data_dec_ref(tdata) != PJSIP_EBUFDESTROYED) { return -50; } return PJ_SUCCESS; }
static int uac_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed) { unsigned i; pjsip_tx_data *request; pjsip_transaction **tsx; pj_timestamp t1, t2, elapsed; pjsip_via_hdr *via; pj_status_t status; /* Create the request first. */ pj_str_t str_target = pj_str("sip:[email protected]"); pj_str_t str_from = pj_str("\"Local User\" <sip:[email protected]>"); pj_str_t str_to = pj_str("\"Remote User\" <sip:[email protected]>"); pj_str_t str_contact = str_from; status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &str_target, &str_from, &str_to, &str_contact, NULL, -1, NULL, &request); if (status != PJ_SUCCESS) { app_perror(" error: unable to create request", status); return status; } via = (pjsip_via_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_VIA, NULL); /* Create transaction array */ tsx = (pjsip_transaction**) pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*)); pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user)); mod_tsx_user.id = -1; /* Benchmark */ elapsed.u64 = 0; pj_get_timestamp(&t1); for (i=0; i<working_set; ++i) { status = pjsip_tsx_create_uac(&mod_tsx_user, request, &tsx[i]); if (status != PJ_SUCCESS) goto on_error; /* Reset branch param */ via->branch_param.slen = 0; } pj_get_timestamp(&t2); pj_sub_timestamp(&t2, &t1); pj_add_timestamp(&elapsed, &t2); p_elapsed->u64 = elapsed.u64; status = PJ_SUCCESS; on_error: for (i=0; i<working_set; ++i) { if (tsx[i]) { pjsip_tsx_terminate(tsx[i], 601); tsx[i] = NULL; } } pjsip_tx_data_dec_ref(request); flush_events(2000); return status; }
static int uas_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed) { unsigned i; pjsip_tx_data *request; pjsip_via_hdr *via; pjsip_rx_data rdata; pj_sockaddr_in remote; pjsip_transaction **tsx; pj_timestamp t1, t2, elapsed; char branch_buf[80] = PJSIP_RFC3261_BRANCH_ID "0000000000"; pj_status_t status; /* Create the request first. */ pj_str_t str_target = pj_str("sip:[email protected]"); pj_str_t str_from = pj_str("\"Local User\" <sip:[email protected]>"); pj_str_t str_to = pj_str("\"Remote User\" <sip:[email protected]>"); pj_str_t str_contact = str_from; status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &str_target, &str_from, &str_to, &str_contact, NULL, -1, NULL, &request); if (status != PJ_SUCCESS) { app_perror(" error: unable to create request", status); return status; } /* Create Via */ via = pjsip_via_hdr_create(request->pool); via->sent_by.host = pj_str("192.168.0.7"); via->sent_by.port = 5061; via->transport = pj_str("udp"); via->rport_param = 1; via->recvd_param = pj_str("192.168.0.7"); pjsip_msg_insert_first_hdr(request->msg, (pjsip_hdr*)via); /* Create "dummy" rdata from the tdata */ pj_bzero(&rdata, sizeof(pjsip_rx_data)); rdata.tp_info.pool = request->pool; rdata.msg_info.msg = request->msg; rdata.msg_info.from = (pjsip_from_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL); rdata.msg_info.to = (pjsip_to_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL); rdata.msg_info.cseq = (pjsip_cseq_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL); rdata.msg_info.cid = (pjsip_cid_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL); rdata.msg_info.via = via; pj_sockaddr_in_init(&remote, 0, 0); status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM, &remote, sizeof(pj_sockaddr_in), NULL, &rdata.tp_info.transport); if (status != PJ_SUCCESS) { app_perror(" error: unable to get loop transport", status); return status; } /* Create transaction array */ tsx = (pjsip_transaction**) pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*)); pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user)); mod_tsx_user.id = -1; /* Benchmark */ elapsed.u64 = 0; pj_get_timestamp(&t1); for (i=0; i<working_set; ++i) { via->branch_param.ptr = branch_buf; via->branch_param.slen = PJSIP_RFC3261_BRANCH_LEN + pj_ansi_sprintf(branch_buf+PJSIP_RFC3261_BRANCH_LEN, "-%d", i); status = pjsip_tsx_create_uas(&mod_tsx_user, &rdata, &tsx[i]); if (status != PJ_SUCCESS) goto on_error; } pj_get_timestamp(&t2); pj_sub_timestamp(&t2, &t1); pj_add_timestamp(&elapsed, &t2); p_elapsed->u64 = elapsed.u64; status = PJ_SUCCESS; on_error: for (i=0; i<working_set; ++i) { if (tsx[i]) { pjsip_tsx_terminate(tsx[i], 601); tsx[i] = NULL; } } pjsip_tx_data_dec_ref(request); flush_events(2000); return status; }
/* * The generic test framework, used by most of the tests. */ static int perform_tsx_test(int dummy, char *target_uri, char *from_uri, char *branch_param, int test_time, const pjsip_method *method) { pjsip_tx_data *tdata; pjsip_transaction *tsx; pj_str_t target, from, tsx_key; pjsip_via_hdr *via; pj_time_val timeout; pj_status_t status; PJ_LOG(3,(THIS_FILE, " please standby, this will take at most %d seconds..", test_time)); /* Reset test. */ recv_count = 0; test_complete = 0; /* Init headers. */ target = pj_str(target_uri); from = pj_str(from_uri); /* Create request. */ status = pjsip_endpt_create_request( endpt, method, &target, &from, &target, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { app_perror(" Error: unable to create request", status); return -100; } /* Set the branch param for test 1. */ via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); via->branch_param = pj_str(branch_param); /* Add additional reference to tdata to prevent transaction from * deleting it. */ pjsip_tx_data_add_ref(tdata); /* Create transaction. */ status = pjsip_tsx_create_uac( &tsx_user, tdata, &tsx); if (status != PJ_SUCCESS) { app_perror(" Error: unable to create UAC transaction", status); pjsip_tx_data_dec_ref(tdata); return -110; } /* Get transaction key. */ pj_strdup(tdata->pool, &tsx_key, &tsx->transaction_key); /* Send the message. */ status = pjsip_tsx_send_msg(tsx, NULL); // Ignore send result. Some tests do deliberately triggers error // when sending message. if (status != PJ_SUCCESS) { // app_perror(" Error: unable to send request", status); pjsip_tx_data_dec_ref(tdata); // return -120; } /* Set test completion time. */ pj_gettimeofday(&timeout); timeout.sec += test_time; /* Wait until test complete. */ while (!test_complete) { pj_time_val now, poll_delay = {0, 10}; pjsip_endpt_handle_events(endpt, &poll_delay); pj_gettimeofday(&now); if (now.sec > timeout.sec) { PJ_LOG(3,(THIS_FILE, " Error: test has timed out")); pjsip_tx_data_dec_ref(tdata); return -130; } } if (test_complete < 0) { tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); if (tsx) { pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); pj_mutex_unlock(tsx->mutex); flush_events(1000); } pjsip_tx_data_dec_ref(tdata); return test_complete; } else { pj_time_val now; /* Allow transaction to destroy itself */ flush_events(500); /* Wait until test completes */ pj_gettimeofday(&now); if (PJ_TIME_VAL_LT(now, timeout)) { pj_time_val interval; interval = timeout; PJ_TIME_VAL_SUB(interval, now); flush_events(PJ_TIME_VAL_MSEC(interval)); } } /* Make sure transaction has been destroyed. */ if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) { PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed")); pjsip_tx_data_dec_ref(tdata); return -140; } /* Check tdata reference counter. */ if (pj_atomic_get(tdata->ref_cnt) != 1) { PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d", pj_atomic_get(tdata->ref_cnt))); pjsip_tx_data_dec_ref(tdata); return -150; } /* Destroy txdata */ pjsip_tx_data_dec_ref(tdata); return PJ_SUCCESS; }
/* * 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; }
/* * This is the handler to receive state changed notification from the * transaction. It is used to verify that the transaction behaves according * to the test scenario. */ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) { if (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) { /* * Transaction with TEST1_BRANCH_ID should terminate with transaction * timeout status. */ if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { if (test_complete == 0) test_complete = 1; /* Test the status code. */ if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, PJSIP_SC_TSX_TIMEOUT)); test_complete = -710; } /* If transport is reliable, then there must not be any * retransmissions. */ if (tp_flag & PJSIP_TRANSPORT_RELIABLE) { if (recv_count != 1) { PJ_LOG(3,(THIS_FILE, " error: there were %d (re)transmissions", recv_count)); test_complete = -715; } } else { /* Check the number of transmissions, which must be * 6 for INVITE and 10 for non-INVITE */ if (tsx->method.id==PJSIP_INVITE_METHOD && recv_count != 7) { PJ_LOG(3,(THIS_FILE, " error: there were %d (re)transmissions", recv_count)); test_complete = -716; } else if (tsx->method.id==PJSIP_OPTIONS_METHOD && recv_count != 11) { PJ_LOG(3,(THIS_FILE, " error: there were %d (re)transmissions", recv_count)); test_complete = -717; } else if (tsx->method.id!=PJSIP_INVITE_METHOD && tsx->method.id!=PJSIP_OPTIONS_METHOD) { PJ_LOG(3,(THIS_FILE, " error: unexpected method")); test_complete = -718; } } } } else if (pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0) { /* * Transaction with TEST2_BRANCH_ID should terminate with transport error. */ if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Test the status code. */ if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); test_complete = -720; } if (test_complete == 0) test_complete = 1; } } else if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) { /* * This test terminates the transaction while resolver is still * running. */ if (tsx->state == PJSIP_TSX_STATE_CALLING) { /* Terminate the transaction. */ pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Check if status code is correct. */ if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); test_complete = -730; } if (test_complete == 0) test_complete = 1; } } else if (pj_strcmp2(&tsx->branch, TEST4_BRANCH_ID)==0) { /* * This test simulates transport failure after several * retransmissions. */ if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Status code must be transport error. */ if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); test_complete = -730; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != TEST4_RETRANSMIT_CNT) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, TEST4_RETRANSMIT_CNT)); test_complete = -731; } if (test_complete == 0) test_complete = 1; } } else if (pj_strcmp2(&tsx->branch, TEST5_BRANCH_ID)==0) { /* * This test simulates transport failure after several * retransmissions. */ if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Status code must be PJSIP_SC_REQUEST_TERMINATED. */ if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); test_complete = -733; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != TEST5_RETRANSMIT_CNT) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, TEST5_RETRANSMIT_CNT)); test_complete = -734; } if (test_complete == 0) test_complete = 1; } } else if (pj_strcmp2(&tsx->branch, TEST6_BRANCH_ID)==0) { /* * Successfull non-INVITE transaction. */ if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { /* Status code must be 202. */ if (tsx->status_code != 202) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 202)); test_complete = -736; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != 0) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, 0)); test_complete = -737; } /* Must still keep last_tx */ if (tsx->last_tx == NULL) { PJ_LOG(3,(THIS_FILE, " error: transaction lost last_tx")); test_complete = -738; } if (test_complete == 0) { test_complete = 1; pjsip_tsx_terminate(tsx, 202); } } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Previous state must be COMPLETED. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) { test_complete = -7381; } } } else if (pj_strcmp2(&tsx->branch, TEST7_BRANCH_ID)==0) { /* * Successfull non-INVITE transaction. */ if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { /* Check prev state. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) { PJ_LOG(3,(THIS_FILE, " error: prev state is %s instead of %s", pjsip_tsx_state_str(e->body.tsx_state.prev_state), pjsip_tsx_state_str(PJSIP_TSX_STATE_PROCEEDING))); test_complete = -739; } /* Status code must be 202. */ if (tsx->status_code != 202) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 202)); test_complete = -740; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != 0) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, 0)); test_complete = -741; } /* Must still keep last_tx */ if (tsx->last_tx == NULL) { PJ_LOG(3,(THIS_FILE, " error: transaction lost last_tx")); test_complete = -741; } if (test_complete == 0) { test_complete = 1; pjsip_tsx_terminate(tsx, 202); } } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { /* Previous state must be COMPLETED. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) { test_complete = -742; } } } else if (pj_strcmp2(&tsx->branch, TEST8_BRANCH_ID)==0) { /* * Failed INVITE transaction. */ if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { /* Status code must be 301. */ if (tsx->status_code != 301) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 301)); test_complete = -745; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != 0) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, 0)); test_complete = -746; } /* Must still keep last_tx */ if (tsx->last_tx == NULL) { PJ_LOG(3,(THIS_FILE, " error: transaction lost last_tx")); test_complete = -747; } /* last_tx MUST be the INVITE request * (authorization depends on this behavior) */ if (tsx->last_tx && tsx->last_tx->msg->line.req.method.id != PJSIP_INVITE_METHOD) { PJ_LOG(3,(THIS_FILE, " error: last_tx is not INVITE")); test_complete = -748; } } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { test_complete = 1; /* Previous state must be COMPLETED. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) { test_complete = -750; } /* Status code must be 301. */ if (tsx->status_code != 301) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 301)); test_complete = -751; } } } else if (pj_strcmp2(&tsx->branch, TEST9_BRANCH_ID)==0) { /* * Failed INVITE transaction with provisional response. */ if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { /* Previous state must be PJSIP_TSX_STATE_PROCEEDING. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) { test_complete = -760; } /* Status code must be 302. */ if (tsx->status_code != 302) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 302)); test_complete = -761; } /* Must have correct retransmission count. */ if (tsx->retransmit_count != 0) { PJ_LOG(3,(THIS_FILE, " error: retransmit cnt is %d instead of %d", tsx->retransmit_count, 0)); test_complete = -762; } /* Must still keep last_tx */ if (tsx->last_tx == NULL) { PJ_LOG(3,(THIS_FILE, " error: transaction lost last_tx")); test_complete = -763; } /* last_tx MUST be INVITE. * (authorization depends on this behavior) */ if (tsx->last_tx && tsx->last_tx->msg->line.req.method.id != PJSIP_INVITE_METHOD) { PJ_LOG(3,(THIS_FILE, " error: last_tx is not INVITE")); test_complete = -764; } } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { test_complete = 1; /* Previous state must be COMPLETED. */ if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) { test_complete = -767; } /* Status code must be 302. */ if (tsx->status_code != 302) { PJ_LOG(3,(THIS_FILE, " error: status code is %d instead of %d", tsx->status_code, 302)); test_complete = -768; } } } }
/* * The generic test framework, used by most of the tests. */ static int perform_test( char *target_uri, char *from_uri, char *branch_param, int test_time, const pjsip_method *method, int request_cnt, int request_interval_msec, int expecting_timeout) { pjsip_tx_data *tdata; pj_str_t target, from; pjsip_via_hdr *via; pj_time_val timeout, next_send; int sent_cnt; pj_status_t status; PJ_LOG(3,(THIS_FILE, " please standby, this will take at most %d seconds..", test_time)); /* Reset test. */ recv_count = 0; test_complete = 0; tsx_key.slen = 0; /* Init headers. */ target = pj_str(target_uri); from = pj_str(from_uri); /* Create request. */ status = pjsip_endpt_create_request( endpt, method, &target, &from, &target, NULL, NULL, -1, NULL, &tdata); if (status != PJ_SUCCESS) { app_perror(" Error: unable to create request", status); return -10; } /* Set the branch param for test 1. */ via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); via->branch_param = pj_str(branch_param); /* Schedule first send. */ sent_cnt = 0; pj_gettimeofday(&next_send); pj_time_val_normalize(&next_send); /* Set test completion time. */ pj_gettimeofday(&timeout); timeout.sec += test_time; /* Wait until test complete. */ while (!test_complete) { pj_time_val now, poll_delay = {0, 10}; pjsip_endpt_handle_events(endpt, &poll_delay); pj_gettimeofday(&now); if (sent_cnt < request_cnt && PJ_TIME_VAL_GTE(now, next_send)) { /* Add additional reference to tdata to prevent transaction from * deleting it. */ pjsip_tx_data_add_ref(tdata); /* (Re)Send the request. */ PJ_LOG(4,(THIS_FILE, " (re)sending request %d", sent_cnt)); status = pjsip_endpt_send_request_stateless(endpt, tdata, 0, 0); if (status != PJ_SUCCESS) { app_perror(" Error: unable to send request", status); pjsip_tx_data_dec_ref(tdata); return -20; } /* Schedule next send, if any. */ sent_cnt++; if (sent_cnt < request_cnt) { pj_gettimeofday(&next_send); next_send.msec += request_interval_msec; pj_time_val_normalize(&next_send); } } if (now.sec > timeout.sec) { if (!expecting_timeout) PJ_LOG(3,(THIS_FILE, " Error: test has timed out")); pjsip_tx_data_dec_ref(tdata); return TEST_TIMEOUT_ERROR; } } if (test_complete < 0) { pjsip_transaction *tsx; tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); if (tsx) { pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); pj_mutex_unlock(tsx->mutex); flush_events(1000); } pjsip_tx_data_dec_ref(tdata); return test_complete; } /* Allow transaction to destroy itself */ flush_events(500); /* Make sure transaction has been destroyed. */ if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) { PJ_LOG(3,(THIS_FILE, " Error: transaction has not been destroyed")); pjsip_tx_data_dec_ref(tdata); return -40; } /* Check tdata reference counter. */ if (pj_atomic_get(tdata->ref_cnt) != 1) { PJ_LOG(3,(THIS_FILE, " Error: tdata reference counter is %d", pj_atomic_get(tdata->ref_cnt))); pjsip_tx_data_dec_ref(tdata); return -50; } /* Destroy txdata */ pjsip_tx_data_dec_ref(tdata); return PJ_SUCCESS; }
int dummy_function() { pj_caching_pool cp; sprintf(NULL, "%d", 0); rand(); #ifdef HAS_PJLIB pj_init(); pj_caching_pool_init(&cp, NULL, 0); pj_array_erase(NULL, 0, 0, 0); pj_create_unique_string(NULL, NULL); pj_hash_create(NULL, 0); pj_hash_get(NULL, NULL, 0, NULL); pj_hash_set(NULL, NULL, NULL, 0, 0, NULL); pj_ioqueue_create(NULL, 0, NULL); pj_ioqueue_register_sock(NULL, NULL, 0, NULL, NULL, NULL); pj_pool_alloc(NULL, 0); pj_timer_heap_create(NULL, 0, NULL); #endif #ifdef HAS_PJLIB_STUN pjstun_get_mapped_addr(&cp.factory, 0, NULL, NULL, 80, NULL, 80, NULL); #endif #ifdef HAS_PJLIB_GETOPT pj_getopt_long(0, NULL, NULL, NULL, NULL); #endif #ifdef HAS_PJLIB_XML pj_xml_parse(NULL, NULL, 100); pj_xml_print(NULL, NULL, 10, PJ_FALSE); pj_xml_clone(NULL, NULL); pj_xml_node_new(NULL, NULL); pj_xml_attr_new(NULL, NULL, NULL); pj_xml_add_node(NULL, NULL); pj_xml_add_attr(NULL, NULL); pj_xml_find_node(NULL, NULL); pj_xml_find_next_node(NULL, NULL, NULL); pj_xml_find_attr(NULL, NULL, NULL); pj_xml_find(NULL, NULL, NULL, NULL); #endif #ifdef HAS_PJLIB_SCANNER pj_cis_buf_init(NULL); pj_cis_init(NULL, NULL); pj_cis_dup(NULL, NULL); pj_cis_add_alpha(NULL); pj_cis_add_str(NULL, NULL); pj_scan_init(NULL, NULL, 0, 0, NULL); pj_scan_fini(NULL); pj_scan_peek(NULL, NULL, NULL); pj_scan_peek_n(NULL, 0, NULL); pj_scan_peek_until(NULL, NULL, NULL); pj_scan_get(NULL, NULL, NULL); pj_scan_get_unescape(NULL, NULL, NULL); pj_scan_get_quote(NULL, 0, 0, NULL); pj_scan_get_n(NULL, 0, NULL); pj_scan_get_char(NULL); pj_scan_get_until(NULL, NULL, NULL); pj_scan_strcmp(NULL, NULL, 0); pj_scan_stricmp(NULL, NULL, 0); pj_scan_stricmp_alnum(NULL, NULL, 0); pj_scan_get_newline(NULL); pj_scan_restore_state(NULL, NULL); #endif #ifdef HAS_PJLIB_DNS pj_dns_make_query(NULL, NULL, 0, 0, NULL); pj_dns_parse_packet(NULL, NULL, 0, NULL); pj_dns_packet_dup(NULL, NULL, 0, NULL); #endif #ifdef HAS_PJLIB_RESOLVER pj_dns_resolver_create(NULL, NULL, 0, NULL, NULL, NULL); pj_dns_resolver_set_ns(NULL, 0, NULL, NULL); pj_dns_resolver_handle_events(NULL, NULL); pj_dns_resolver_destroy(NULL, 0); pj_dns_resolver_start_query(NULL, NULL, 0, 0, NULL, NULL, NULL); pj_dns_resolver_cancel_query(NULL, 0); pj_dns_resolver_add_entry(NULL, NULL, 0); #endif #ifdef HAS_PJLIB_SRV_RESOLVER pj_dns_srv_resolve(NULL, NULL, 0, NULL, NULL, PJ_FALSE, NULL, NULL); #endif #ifdef HAS_PJLIB_CRC32 pj_crc32_init(NULL); pj_crc32_update(NULL, NULL, 0); pj_crc32_final(NULL); #endif #ifdef HAS_PJLIB_HMAC_MD5 pj_hmac_md5(NULL, 0, NULL, 0, NULL); #endif #ifdef HAS_PJLIB_HMAC_SHA1 pj_hmac_sha1(NULL, 0, NULL, 0, NULL); #endif #ifdef HAS_PJNATH_STUN pj_stun_session_create(NULL, NULL, NULL, PJ_FALSE, NULL); pj_stun_session_destroy(NULL); pj_stun_session_set_credential(NULL, NULL); pj_stun_session_create_req(NULL, 0, NULL, NULL); pj_stun_session_create_ind(NULL, 0, NULL); pj_stun_session_create_res(NULL, NULL, 0, NULL, NULL); pj_stun_session_send_msg(NULL, PJ_FALSE, NULL, 0, NULL); #endif #ifdef HAS_PJNATH_ICE pj_ice_strans_create(NULL, NULL, 0, NULL, NULL, NULL); pj_ice_strans_set_stun_domain(NULL, NULL, NULL); pj_ice_strans_create_comp(NULL, 0, 0, NULL); pj_ice_strans_add_cand(NULL, 0, PJ_ICE_CAND_TYPE_HOST, 0, NULL, PJ_FALSE); pj_ice_strans_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL); pj_ice_strans_start_ice(NULL, NULL, NULL, 0, NULL); pj_ice_strans_stop_ice(NULL); pj_ice_strans_sendto(NULL, 0, NULL, 0, NULL, 0); #endif #ifdef HAS_PJSIP_CORE_MSG_ELEM /* Parameter container */ pjsip_param_find(NULL, NULL); pjsip_param_print_on(NULL, NULL, 0, NULL, NULL, 0); /* SIP URI */ pjsip_sip_uri_create(NULL, 0); pjsip_name_addr_create(NULL); /* TEL URI */ pjsip_tel_uri_create(NULL); /* Message and headers */ pjsip_msg_create(NULL, PJSIP_REQUEST_MSG); pjsip_msg_print(NULL, NULL, 0); pjsip_accept_hdr_create(NULL); pjsip_allow_hdr_create(NULL); pjsip_cid_hdr_create(NULL); pjsip_clen_hdr_create(NULL); pjsip_cseq_hdr_create(NULL); pjsip_contact_hdr_create(NULL); pjsip_ctype_hdr_create(NULL); pjsip_expires_hdr_create(NULL, 0); pjsip_from_hdr_create(NULL); pjsip_max_fwd_hdr_create(NULL, 0); pjsip_min_expires_hdr_create(NULL, 0); pjsip_rr_hdr_create(NULL); pjsip_require_hdr_create(NULL); pjsip_retry_after_hdr_create(NULL, 0); pjsip_supported_hdr_create(NULL); pjsip_unsupported_hdr_create(NULL); pjsip_via_hdr_create(NULL); pjsip_warning_hdr_create(NULL, 0, NULL, NULL); pjsip_parse_uri(NULL, NULL, 0, 0); pjsip_parse_msg(NULL, NULL, 0, NULL); pjsip_parse_rdata(NULL, 0, NULL); pjsip_find_msg(NULL, 0, 0, NULL); #endif #ifdef HAS_PJSIP_CORE pjsip_endpt_create(NULL, NULL, NULL); pjsip_tpmgr_create(NULL, NULL, NULL, NULL, NULL); pjsip_tpmgr_destroy(NULL); pjsip_transport_send(NULL, NULL, NULL, 0, NULL, NULL); #endif #ifdef HAS_PJSIP_CORE_MSG_UTIL pjsip_endpt_create_request(NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, NULL, NULL); pjsip_endpt_create_request_from_hdr(NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, NULL, NULL); pjsip_endpt_create_response(NULL, NULL, -1, NULL, NULL); pjsip_endpt_create_ack(NULL, NULL, NULL, NULL); pjsip_endpt_create_cancel(NULL, NULL, NULL); pjsip_get_request_dest(NULL, NULL); pjsip_endpt_send_request_stateless(NULL, NULL, NULL, NULL); pjsip_get_response_addr(NULL, NULL, NULL); pjsip_endpt_send_response(NULL, NULL, NULL, NULL, NULL); pjsip_endpt_respond_stateless(NULL, NULL, -1, NULL, NULL, NULL); #endif #ifdef HAS_PJSIP_UDP_TRANSPORT pjsip_udp_transport_start(NULL, NULL, NULL, 1, NULL); #endif #ifdef HAS_PJSIP_TCP_TRANSPORT pjsip_tcp_transport_start(NULL, NULL, 1, NULL); #endif #ifdef HAS_PJSIP_TLS_TRANSPORT pjsip_tls_transport_start(NULL, NULL, NULL, NULL, 0, NULL); #endif #ifdef HAS_PJSIP_TRANSACTION pjsip_tsx_layer_init_module(NULL); pjsip_tsx_layer_destroy(); pjsip_tsx_create_uac(NULL, NULL, NULL); pjsip_tsx_create_uas(NULL, NULL, NULL); pjsip_tsx_recv_msg(NULL, NULL); pjsip_tsx_send_msg(NULL, NULL); pjsip_tsx_terminate(NULL, 200); pjsip_endpt_send_request(NULL, NULL, -1, NULL, NULL); pjsip_endpt_respond(NULL, NULL, NULL, -1, NULL, NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_SDP pjmedia_sdp_parse(NULL, NULL, 1024, NULL); pjmedia_sdp_print(NULL, NULL, 1024); pjmedia_sdp_validate(NULL); pjmedia_sdp_session_clone(NULL, NULL); pjmedia_sdp_session_cmp(NULL, NULL, 0); pjmedia_sdp_attr_to_rtpmap(NULL, NULL, NULL); pjmedia_sdp_attr_get_fmtp(NULL, NULL); pjmedia_sdp_attr_get_rtcp(NULL, NULL); pjmedia_sdp_conn_clone(NULL, NULL); pjmedia_sdp_media_clone(NULL, NULL); pjmedia_sdp_media_find_attr(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_SDP_NEGOTIATOR pjmedia_sdp_neg_create_w_local_offer(NULL, NULL, NULL); pjmedia_sdp_neg_create_w_remote_offer(NULL, NULL, NULL, NULL); pjmedia_sdp_neg_get_state(NULL); pjmedia_sdp_neg_negotiate(NULL, NULL, PJ_FALSE); #endif #ifdef HAS_PJSIP_UA_LAYER pjsip_ua_init_module(NULL, NULL); pjsip_ua_destroy(); pjsip_dlg_create_uac(NULL, NULL, NULL, NULL, NULL, NULL); pjsip_dlg_create_uas_and_inc_lock(NULL, NULL, NULL, NULL); pjsip_dlg_terminate(NULL); pjsip_dlg_set_route_set(NULL, NULL); pjsip_dlg_create_request(NULL, NULL, -1, NULL); pjsip_dlg_send_request(NULL, NULL, -1, NULL); pjsip_dlg_create_response(NULL, NULL, -1, NULL, NULL); pjsip_dlg_modify_response(NULL, NULL, -1, NULL); pjsip_dlg_send_response(NULL, NULL, NULL); pjsip_dlg_respond(NULL, NULL, -1, NULL, NULL, NULL); #endif #ifdef HAS_PJSIP_AUTH_CLIENT pjsip_auth_clt_init(NULL, NULL, NULL, 0); pjsip_auth_clt_clone(NULL, NULL, NULL); pjsip_auth_clt_set_credentials(NULL, 0, NULL); pjsip_auth_clt_init_req(NULL, NULL); pjsip_auth_clt_reinit_req(NULL, NULL, NULL, NULL); #endif #ifdef HAS_PJSIP_INV_SESSION pjsip_inv_usage_init(NULL, NULL); pjsip_inv_create_uac(NULL, NULL, 0, NULL); pjsip_inv_verify_request(NULL, NULL, NULL, NULL, NULL, NULL); pjsip_inv_create_uas(NULL, NULL, NULL, 0, NULL); pjsip_inv_terminate(NULL, 200, PJ_FALSE); pjsip_inv_invite(NULL, NULL); pjsip_inv_initial_answer(NULL, NULL, 200, NULL, NULL, NULL); pjsip_inv_answer(NULL, 200, NULL, NULL, NULL); pjsip_inv_end_session(NULL, 200, NULL, NULL); pjsip_inv_reinvite(NULL, NULL, NULL, NULL); pjsip_inv_update(NULL, NULL, NULL, NULL); pjsip_inv_send_msg(NULL, NULL); pjsip_dlg_get_inv_session(NULL); //pjsip_tsx_get_inv_session(NULL); pjsip_inv_state_name(PJSIP_INV_STATE_NULL); #endif #ifdef HAS_PJSIP_REGC //pjsip_regc_get_module(); pjsip_regc_create(NULL, NULL, NULL, NULL); pjsip_regc_destroy(NULL); pjsip_regc_get_info(NULL, NULL); pjsip_regc_get_pool(NULL); pjsip_regc_init(NULL, NULL, NULL, NULL, 0, NULL, 600); pjsip_regc_set_credentials(NULL, 1, NULL); pjsip_regc_set_route_set(NULL, NULL); pjsip_regc_register(NULL, PJ_TRUE, NULL); pjsip_regc_unregister(NULL, NULL); pjsip_regc_update_contact(NULL, 10, NULL); pjsip_regc_update_expires(NULL, 600); pjsip_regc_send(NULL, NULL); #endif #ifdef HAS_PJSIP_EVENT_FRAMEWORK pjsip_evsub_init_module(NULL); pjsip_evsub_instance(); pjsip_evsub_register_pkg(NULL, NULL, 30, 10, NULL); pjsip_evsub_create_uac(NULL, NULL, NULL, 10, NULL); pjsip_evsub_create_uas(NULL, NULL, NULL, 10, NULL); pjsip_evsub_terminate(NULL, PJ_FALSE); pjsip_evsub_get_state(NULL); pjsip_evsub_get_state_name(NULL); pjsip_evsub_initiate(NULL, NULL, -1, NULL); pjsip_evsub_accept(NULL, NULL, 200, NULL); pjsip_evsub_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL); pjsip_evsub_current_notify(NULL, NULL); pjsip_evsub_send_request(NULL, NULL); pjsip_tsx_get_evsub(NULL); pjsip_evsub_set_mod_data(NULL, 1, NULL); pjsip_evsub_get_mod_data(NULL, 1); #endif #ifdef HAS_PJSIP_CALL_TRANSFER pjsip_xfer_init_module(NULL); pjsip_xfer_create_uac(NULL, NULL, NULL); pjsip_xfer_create_uas(NULL, NULL, NULL, NULL); pjsip_xfer_initiate(NULL, NULL, NULL); pjsip_xfer_accept(NULL, NULL, 200, NULL); pjsip_xfer_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, 200, NULL, NULL); pjsip_xfer_current_notify(NULL, NULL); pjsip_xfer_send_request(NULL, NULL); #endif #ifdef HAS_PJSIP_PRESENCE pjsip_pres_init_module(NULL, NULL); pjsip_pres_instance(); pjsip_pres_create_uac(NULL, NULL, 0, NULL); pjsip_pres_create_uas(NULL, NULL, NULL, NULL); pjsip_pres_terminate(NULL, PJ_FALSE); pjsip_pres_initiate(NULL, 100, NULL); pjsip_pres_accept(NULL, NULL, 200, NULL); pjsip_pres_notify(NULL, PJSIP_EVSUB_STATE_ACTIVE, NULL, NULL, NULL); pjsip_pres_current_notify(NULL, NULL); pjsip_pres_send_request(NULL, NULL); pjsip_pres_get_status(NULL, NULL); pjsip_pres_set_status(NULL, NULL); #endif #ifdef HAS_PJSIP_IS_COMPOSING pjsip_iscomposing_create_xml(NULL, PJ_TRUE, NULL, NULL, 0); pjsip_iscomposing_create_body(NULL, PJ_TRUE, NULL, NULL, 0); pjsip_iscomposing_parse(NULL, NULL, 0, NULL, NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA pjmedia_endpt_create(NULL, NULL, 1, NULL); pjmedia_endpt_destroy(NULL); pjmedia_endpt_create_sdp(NULL, NULL, 1, NULL, NULL); #endif #ifdef HAS_PJMEDIA_EC pjmedia_echo_create(NULL, 0, 0, 0, 0, 0, NULL); pjmedia_echo_destroy(NULL); pjmedia_echo_playback(NULL, NULL); pjmedia_echo_capture(NULL, NULL, 0); pjmedia_echo_cancel(NULL, NULL, NULL, 0, NULL); #endif #ifdef HAS_PJMEDIA_SND_DEV pjmedia_snd_init(NULL); pjmedia_snd_get_dev_count(); pjmedia_snd_get_dev_info(0); pjmedia_snd_open(-1, -1, 8000, 1, 80, 16, NULL, NULL, NULL, NULL); pjmedia_snd_open_rec(-1, 8000, 1, 160, 16, NULL, NULL, NULL); pjmedia_snd_open_player(-1, 8000, 1, 160, 16, NULL, NULL, NULL); pjmedia_snd_stream_start(NULL); pjmedia_snd_stream_stop(NULL); pjmedia_snd_stream_close(NULL); pjmedia_snd_deinit(); #endif #ifdef HAS_PJMEDIA_SND_PORT pjmedia_snd_port_create(NULL, -1, -1, 8000, 1, 180, 16, 0, NULL); pjmedia_snd_port_create_rec(NULL, -1, 8000, 1, 160, 16, 0, NULL); pjmedia_snd_port_create_player(NULL, -1, 8000, 1, 160, 16, 0, NULL); pjmedia_snd_port_destroy(NULL); pjmedia_snd_port_get_snd_stream(NULL); pjmedia_snd_port_connect(NULL, NULL); pjmedia_snd_port_get_port(NULL); pjmedia_snd_port_disconnect(NULL); #endif #ifdef HAS_PJMEDIA_RESAMPLE pjmedia_resample_create(NULL, PJ_TRUE, PJ_TRUE, 0, 0, 0, 0, NULL); pjmedia_resample_run(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_SILENCE_DET pjmedia_silence_det_create(NULL, 8000, 80, NULL); pjmedia_silence_det_detect(NULL, NULL, 0, NULL); pjmedia_silence_det_apply(NULL, 0); #endif #ifdef HAS_PJMEDIA_PLC pjmedia_plc_create(NULL, 8000, 80, 0, NULL); pjmedia_plc_save(NULL, NULL); pjmedia_plc_generate(NULL, NULL); #endif #ifdef HAS_PJMEDIA_CONFERENCE pjmedia_conf_create(NULL, 10, 8000, 1, 160, 16, 0, NULL); pjmedia_conf_destroy(NULL); pjmedia_conf_get_master_port(NULL); pjmedia_conf_add_port(NULL, NULL, NULL, NULL, NULL); pjmedia_conf_configure_port(NULL, 1, 0, 0); pjmedia_conf_connect_port(NULL, 0, 0, 0); pjmedia_conf_disconnect_port(NULL, 0, 0); pjmedia_conf_remove_port(NULL, 0); pjmedia_conf_enum_ports(NULL, NULL, NULL); pjmedia_conf_get_port_info(NULL, 0, NULL); pjmedia_conf_get_ports_info(NULL, NULL, NULL); pjmedia_conf_get_signal_level(NULL, 0, NULL, NULL); pjmedia_conf_adjust_rx_level(NULL, 0, 0); pjmedia_conf_adjust_tx_level(NULL, 0, 0); #endif #ifdef HAS_PJMEDIA_MASTER_PORT pjmedia_master_port_create(NULL, NULL, NULL, 0, NULL); pjmedia_master_port_start(NULL); pjmedia_master_port_stop(NULL); pjmedia_master_port_set_uport(NULL, NULL); pjmedia_master_port_get_uport(NULL); pjmedia_master_port_set_dport(NULL, NULL); pjmedia_master_port_get_dport(NULL); pjmedia_master_port_destroy(NULL, PJ_FALSE); #endif #ifdef HAS_PJMEDIA_RTP pjmedia_rtp_session_init(NULL, 0, 0); pjmedia_rtp_encode_rtp(NULL, 0, 0, 0, 0, NULL, NULL); pjmedia_rtp_decode_rtp(NULL, NULL, 0, NULL, NULL, NULL); pjmedia_rtp_session_update(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_RTCP pjmedia_rtcp_init(NULL, NULL, 0, 0, 0); pjmedia_rtcp_get_ntp_time(NULL, NULL); pjmedia_rtcp_fini(NULL); pjmedia_rtcp_rx_rtp(NULL, 0, 0, 0); pjmedia_rtcp_tx_rtp(NULL, 0); pjmedia_rtcp_rx_rtcp(NULL, NULL, 0); pjmedia_rtcp_build_rtcp(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_JBUF pjmedia_jbuf_create(NULL, NULL, 0, 0, 0, NULL); pjmedia_jbuf_set_fixed(NULL, 0); pjmedia_jbuf_set_adaptive(NULL, 0, 0, 0); pjmedia_jbuf_destroy(NULL); pjmedia_jbuf_put_frame(NULL, NULL, 0, 0); pjmedia_jbuf_get_frame(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_STREAM pjmedia_stream_create(NULL, NULL, NULL, NULL, NULL, NULL); pjmedia_stream_destroy(NULL); pjmedia_stream_get_port(NULL, NULL); pjmedia_stream_get_transport(NULL); pjmedia_stream_start(NULL); pjmedia_stream_get_stat(NULL, NULL); pjmedia_stream_pause(NULL, PJMEDIA_DIR_ENCODING); pjmedia_stream_resume(NULL, PJMEDIA_DIR_ENCODING); pjmedia_stream_dial_dtmf(NULL, NULL); pjmedia_stream_check_dtmf(NULL); pjmedia_stream_get_dtmf(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_TONEGEN pjmedia_tonegen_create(NULL, 0, 0, 0, 0, 0, NULL); pjmedia_tonegen_is_busy(NULL); pjmedia_tonegen_stop(NULL); pjmedia_tonegen_play(NULL, 0, NULL, 0); pjmedia_tonegen_play_digits(NULL, 0, NULL, 0); pjmedia_tonegen_get_digit_map(NULL, NULL); pjmedia_tonegen_set_digit_map(NULL, NULL); #endif #ifdef HAS_PJMEDIA_UDP_TRANSPORT pjmedia_transport_udp_create(NULL, NULL, 0, 0, NULL); pjmedia_transport_udp_close(NULL); #endif #ifdef HAS_PJMEDIA_FILE_PLAYER pjmedia_wav_player_port_create(NULL, NULL, 0, 0, 0, NULL); pjmedia_wav_player_port_set_pos(NULL, 0); pjmedia_wav_player_port_get_pos(NULL); pjmedia_wav_player_set_eof_cb(NULL, NULL, NULL); #endif #ifdef HAS_PJMEDIA_FILE_CAPTURE pjmedia_wav_writer_port_create(NULL, NULL, 8000, 1, 80, 16, 0, 0, NULL); pjmedia_wav_writer_port_get_pos(NULL); pjmedia_wav_writer_port_set_cb(NULL, 0, NULL, NULL); #endif #ifdef HAS_PJMEDIA_MEM_PLAYER pjmedia_mem_player_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL); #endif #ifdef HAS_PJMEDIA_MEM_CAPTURE pjmedia_mem_capture_create(NULL, NULL, 1000, 8000, 1, 80, 16, 0, NULL); #endif #ifdef HAS_PJMEDIA_ICE pjmedia_ice_create(NULL, NULL, 0, NULL, NULL); pjmedia_ice_destroy(NULL); pjmedia_ice_start_init(NULL, 0, NULL, NULL, NULL); pjmedia_ice_init_ice(NULL, PJ_ICE_SESS_ROLE_CONTROLLED, NULL, NULL); pjmedia_ice_modify_sdp(NULL, NULL, NULL); pjmedia_ice_start_ice(NULL, NULL, NULL, 0); pjmedia_ice_stop_ice(NULL); #endif #ifdef HAS_PJMEDIA_G711_CODEC pjmedia_codec_g711_init(NULL); pjmedia_codec_g711_deinit(); #endif #ifdef HAS_PJMEDIA_GSM_CODEC pjmedia_codec_gsm_init(NULL); pjmedia_codec_gsm_deinit(); #endif #ifdef HAS_PJMEDIA_SPEEX_CODEC pjmedia_codec_speex_init(NULL, 0, 0, 0); pjmedia_codec_speex_deinit(); #endif #ifdef HAS_PJMEDIA_ILBC_CODEC pjmedia_codec_ilbc_init(NULL, 0); pjmedia_codec_ilbc_deinit(); #endif return 0; }