/** UI Command **/ static void ui_make_new_call() { char buf[128]; pjsua_msg_data msg_data; input_result result; pj_str_t tmp; printf("(You currently have %d calls)\n", pjsua_call_get_count()); ui_input_url("Make call", buf, sizeof(buf), &result); if (result.nb_result != PJSUA_APP_NO_NB) { if (result.nb_result == -1 || result.nb_result == 0) { puts("You can't do that with make call!"); return; } else { pjsua_buddy_info binfo; pjsua_buddy_get_info(result.nb_result-1, &binfo); tmp.ptr = buf; pj_strncpy(&tmp, &binfo.uri, sizeof(buf)); } } else if (result.uri_result) { tmp = pj_str(result.uri_result); } else { tmp.slen = 0; } pjsua_msg_data_init(&msg_data); TEST_MULTIPART(&msg_data); pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL, &msg_data, ¤t_call); }
static pj_str_t pjnath_strerror2(pj_status_t statcode, char *buf, pj_size_t bufsize ) { int stun_code = statcode - PJ_STATUS_FROM_STUN_CODE(0); const pj_str_t cmsg = pj_stun_get_err_reason(stun_code); pj_str_t errstr; buf[bufsize-1] = '\0'; if (cmsg.slen == 0) { /* Not found */ errstr.ptr = buf; errstr.slen = pj_ansi_snprintf(buf, bufsize, "Unknown STUN err-code %d", stun_code); } else { errstr.ptr = buf; pj_strncpy(&errstr, &cmsg, bufsize); if (errstr.slen < (int)bufsize) buf[errstr.slen] = '\0'; else buf[bufsize-1] = '\0'; } if (errstr.slen < 0) errstr.slen = 0; else if (errstr.slen > (int)bufsize) errstr.slen = bufsize; return errstr; }
/* Callback called when *client* subscription state has changed. */ static void pjsua_evsub_on_state( pjsip_evsub *sub, pjsip_event *event) { pjsua_buddy *buddy; PJ_UNUSED_ARG(event); PJSUA_LOCK(); buddy = (pjsua_buddy*) pjsip_evsub_get_mod_data(sub, pjsua_var.mod.id); if (buddy) { PJ_LOG(4,(THIS_FILE, "Presence subscription to %.*s is %s", (int)pjsua_var.buddy[buddy->index].uri.slen, pjsua_var.buddy[buddy->index].uri.ptr, pjsip_evsub_get_state_name(sub))); if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { if (buddy->term_reason.ptr == NULL) { buddy->term_reason.ptr = (char*) pj_pool_alloc(buddy->pool, PJSUA_BUDDY_SUB_TERM_REASON_LEN); } pj_strncpy(&buddy->term_reason, pjsip_evsub_get_termination_reason(sub), PJSUA_BUDDY_SUB_TERM_REASON_LEN); } else { buddy->term_reason.slen = 0; } /* Call callback */ if (pjsua_var.ua_cfg.cb.on_buddy_state) (*pjsua_var.ua_cfg.cb.on_buddy_state)(buddy->index); /* Clear subscription */ if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) { buddy->sub = NULL; buddy->status.info_cnt = 0; pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL); } } PJSUA_UNLOCK(); }
static void ui_make_multi_call() { char menuin[32]; int count; char buf[128]; input_result result; pj_str_t tmp; int i; printf("(You currently have %d calls)\n", pjsua_call_get_count()); if (!simple_input("Number of calls", menuin, sizeof(menuin))) return; count = my_atoi(menuin); if (count < 1) return; ui_input_url("Make call", buf, sizeof(buf), &result); if (result.nb_result != PJSUA_APP_NO_NB) { pjsua_buddy_info binfo; if (result.nb_result == -1 || result.nb_result == 0) { puts("You can't do that with make call!"); return; } pjsua_buddy_get_info(result.nb_result-1, &binfo); tmp.ptr = buf; pj_strncpy(&tmp, &binfo.uri, sizeof(buf)); } else { tmp = pj_str(result.uri_result); } for (i=0; i<my_atoi(menuin); ++i) { pj_status_t status; status = pjsua_call_make_call(current_acc, &tmp, &call_opt, NULL, NULL, NULL); if (status != PJ_SUCCESS) break; } }
/* Build server entries in the query_job based on received SRV response */ static void build_server_entries(pj_dns_srv_async_query *query_job, pj_dns_parsed_packet *response) { unsigned i; /* Save the Resource Records in DNS answer into SRV targets. */ query_job->srv_cnt = 0; for (i=0; i<response->hdr.anscount && query_job->srv_cnt < PJ_DNS_SRV_MAX_ADDR; ++i) { pj_dns_parsed_rr *rr = &response->ans[i]; struct srv_target *srv = &query_job->srv[query_job->srv_cnt]; if (rr->type != PJ_DNS_TYPE_SRV) { PJ_LOG(4,(query_job->objname, "Received non SRV answer for SRV query_job!")); continue; } if (rr->rdata.srv.target.slen > PJ_MAX_HOSTNAME) { PJ_LOG(4,(query_job->objname, "Hostname is too long!")); continue; } /* Build the SRV entry for RR */ pj_bzero(srv, sizeof(*srv)); srv->target_name.ptr = srv->target_buf; pj_strncpy(&srv->target_name, &rr->rdata.srv.target, sizeof(srv->target_buf)); srv->port = rr->rdata.srv.port; srv->priority = rr->rdata.srv.prio; srv->weight = rr->rdata.srv.weight; ++query_job->srv_cnt; } if (query_job->srv_cnt == 0) { PJ_LOG(4,(query_job->objname, "Could not find SRV record in DNS answer!")); return; } /* First pass: * order the entries based on priority. */ for (i=0; i<query_job->srv_cnt-1; ++i) { unsigned min = i, j; for (j=i+1; j<query_job->srv_cnt; ++j) { if (query_job->srv[j].priority < query_job->srv[min].priority) min = j; } SWAP(struct srv_target, &query_job->srv[i], &query_job->srv[min]); } /* Second pass: * Order the entry in a list. * * The algorithm for selecting server among servers with the same * priority is described in RFC 2782. */ for (i=0; i<query_job->srv_cnt; ++i) { unsigned j, count=1, sum; /* Calculate running sum for servers with the same priority */ sum = query_job->srv[i].sum = query_job->srv[i].weight; for (j=i+1; j<query_job->srv_cnt && query_job->srv[j].priority == query_job->srv[i].priority; ++j) { sum += query_job->srv[j].weight; query_job->srv[j].sum = sum; ++count; } if (count > 1) { unsigned r; /* Elect one random number between zero and the total sum of * weight (inclusive). */ r = pj_rand() % (sum + 1); /* Select the first server which running sum is greater than or * equal to the random number. */ for (j=i; j<i+count; ++j) { if (query_job->srv[j].sum >= r) break; } /* Must have selected one! */ pj_assert(j != i+count); /* Put this entry in front (of entries with same priority) */ SWAP(struct srv_target, &query_job->srv[i], &query_job->srv[j]); /* Remove all other entries (of the same priority) */ /* Don't need to do this. * See https://trac.pjsip.org/repos/ticket/1719 while (count > 1) { pj_array_erase(query_job->srv, sizeof(struct srv_target), query_job->srv_cnt, i+1); --count; --query_job->srv_cnt; } */ } }
/* * Get detailed buddy info. */ PJ_DEF(pj_status_t) pjsua_buddy_get_info( pjsua_buddy_id buddy_id, pjsua_buddy_info *info) { unsigned total=0; pjsua_buddy *buddy; PJ_ASSERT_RETURN(buddy_id>=0 && buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy), PJ_EINVAL); PJSUA_LOCK(); pj_bzero(info, sizeof(pjsua_buddy_info)); buddy = &pjsua_var.buddy[buddy_id]; info->id = buddy->index; if (pjsua_var.buddy[buddy_id].uri.slen == 0) { PJSUA_UNLOCK(); return PJ_SUCCESS; } /* uri */ info->uri.ptr = info->buf_ + total; pj_strncpy(&info->uri, &buddy->uri, sizeof(info->buf_)-total); total += info->uri.slen; /* contact */ info->contact.ptr = info->buf_ + total; pj_strncpy(&info->contact, &buddy->contact, sizeof(info->buf_)-total); total += info->contact.slen; /* status and status text */ if (buddy->sub == NULL || buddy->status.info_cnt==0) { info->status = PJSUA_BUDDY_STATUS_UNKNOWN; info->status_text = pj_str("?"); } else if (pjsua_var.buddy[buddy_id].status.info[0].basic_open) { info->status = PJSUA_BUDDY_STATUS_ONLINE; /* copy RPID information */ info->rpid = buddy->status.info[0].rpid; if (info->rpid.note.slen) info->status_text = info->rpid.note; else info->status_text = pj_str("Online"); } else { info->status = PJSUA_BUDDY_STATUS_OFFLINE; info->status_text = pj_str("Offline"); } /* monitor pres */ info->monitor_pres = buddy->monitor; /* subscription state and termination reason */ if (buddy->sub) { info->sub_state = pjsip_evsub_get_state(buddy->sub); if (info->sub_state == PJSIP_EVSUB_STATE_TERMINATED && total < sizeof(info->buf_)) { info->sub_term_reason.ptr = info->buf_ + total; pj_strncpy(&info->sub_term_reason, pjsip_evsub_get_termination_reason(buddy->sub), sizeof(info->buf_) - total); total += info->sub_term_reason.slen; } else { info->sub_term_reason = pj_str(""); } } else if (total < sizeof(info->buf_)) { info->sub_term_reason.ptr = info->buf_ + total; pj_strncpy(&info->sub_term_reason, &buddy->term_reason, sizeof(info->buf_) - total); total += info->sub_term_reason.slen; } else { info->sub_term_reason = pj_str(""); } PJSUA_UNLOCK(); return PJ_SUCCESS; }