Example #1
0
/** 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, &current_call);
}
Example #2
0
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;
}
Example #3
0
/* 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();
}
Example #4
0
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;
    }
}
Example #5
0
/* 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;
	    }
	    */
	}
    }
Example #6
0
/*
 * 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;
}