예제 #1
1
/*!
 * \brief Store the transport a message came in on, so it can be used for outbound messages to that contact.
 */
static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata)
{
	static const pj_str_t STR_WS = { "ws", 2 };
	static const pj_str_t STR_WSS = { "wss", 3 };
	pjsip_contact_hdr *contact;

	long type = rdata->tp_info.transport->key.type;

	if (type != (long)transport_type_ws && type != (long)transport_type_wss) {
		return PJ_FALSE;
	}

	if ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && !contact->star &&
		(PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
		pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);

		pj_cstr(&uri->host, rdata->pkt_info.src_name);
		uri->port = rdata->pkt_info.src_port;
		ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n",
			(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port);
		pj_strdup(rdata->tp_info.pool, &uri->transport_param, (type == (long)transport_type_ws) ? &STR_WS : &STR_WSS);
	}

	rdata->msg_info.via->rport_param = 0;

	return PJ_FALSE;
}
예제 #2
0
void SipAccount::onCallState(pjsua_call_id call_id, pjsip_event* e) {
  Logger::debug("SipAccount::onCallState(call_id=%d)...", call_id);
  PJ_UNUSED_ARG(e);

  pjsua_call_info ci;
  pjsua_call_get_info(call_id, &ci);

  std::string display, number;
  if (!getNumber(&ci.remote_info, &display, &number)) {
    Logger::warn("invalid URI received '%s'", pj_strbuf(&ci.remote_info));
    return;
  }

  std::string state = std::string(pj_strbuf(&ci.state_text), ci.state_text.slen);
  Logger::debug("[%s] call state changed to %s", number.c_str(), state.c_str());

#if 1
  if (ci.state == PJSIP_INV_STATE_CONFIRMED) {
    Logger::debug("hangup...");
    // code 0: pj takes care of hangup SIP status code
    pj_status_t status = pjsua_call_hangup(call_id, 0, NULL, NULL);
    if (status != PJ_SUCCESS) {
      Logger::warn("pjsua_call_hangup() failed (%s)", Helper::getPjStatusAsString(status).c_str());
    }
  }
#endif
}
예제 #3
0
bool SipAccount::getNumber(pj_str_t* uri, std::string* pDisplay, std::string* pNumber) {
  pj_pool_t* pool = pjsua_pool_create("", 128, 10);
  pjsip_name_addr* n = (pjsip_name_addr*)pjsip_parse_uri(pool, uri->ptr, uri->slen, PJSIP_PARSE_URI_AS_NAMEADDR);
  if (n == NULL) {
    Logger::warn("pjsip_parse_uri() failed for %s", pj_strbuf(uri));
    pj_pool_release(pool);
    return false;
  }
  if (!PJSIP_URI_SCHEME_IS_SIP(n)) {
    Logger::warn("pjsip_parse_uri() returned unknown schema for %s", pj_strbuf(uri));
    pj_pool_release(pool);
    return false;
  }

  *pDisplay = std::string(n->display.ptr, n->display.slen);

  pjsip_sip_uri *sip = (pjsip_sip_uri*)pjsip_uri_get_uri(n);
  std::string number = std::string(sip->user.ptr, sip->user.slen);
  
  // make number international
  *pNumber = Helper::makeNumberInternational(&m_settings.base, number);

  pj_pool_release(pool);
  return true;
}
예제 #4
0
static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
{
	char local_buf[256];
	char remote_buf[256];
	char *uuid;
	struct hepv3_capture_info *capture_info;
	pjsip_tpmgr_fla2_param prm;

	capture_info = hepv3_create_capture_info(&rdata->pkt_info.packet, rdata->pkt_info.len);
	if (!capture_info) {
		return PJ_SUCCESS;
	}

	if (!rdata->pkt_info.src_addr_len) {
		return PJ_SUCCESS;
	}
	pj_sockaddr_print(&rdata->pkt_info.src_addr, remote_buf, sizeof(remote_buf), 3);

	/* Attempt to determine what IP address we probably received this packet on */
	pjsip_tpmgr_fla2_param_default(&prm);
	prm.tp_type = rdata->tp_info.transport->key.type;
	pj_strset2(&prm.dst_host, rdata->pkt_info.src_name);
	prm.local_if = PJ_TRUE;

	/* If we can't get the local address use what we have already */
	if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), rdata->tp_info.pool, &prm) != PJ_SUCCESS) {
		pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
	} else {
		if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
			snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
				(int)pj_strlen(&prm.ret_addr),
				pj_strbuf(&prm.ret_addr),
				prm.ret_port);
		} else {
			snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
				(int)pj_strlen(&prm.ret_addr),
				pj_strbuf(&prm.ret_addr),
				prm.ret_port);
		}
	}

	uuid = assign_uuid(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag);
	if (!uuid) {
		ao2_ref(capture_info, -1);
		return PJ_SUCCESS;
	}

	ast_sockaddr_parse(&capture_info->src_addr, remote_buf, PARSE_PORT_REQUIRE);
	ast_sockaddr_parse(&capture_info->dst_addr, local_buf, PARSE_PORT_REQUIRE);
	capture_info->capture_time.tv_sec = rdata->pkt_info.timestamp.sec;
	capture_info->capture_time.tv_usec = rdata->pkt_info.timestamp.msec * 1000;
	capture_info->capture_type = HEPV3_CAPTURE_TYPE_SIP;
	capture_info->uuid = uuid;
	capture_info->zipped = 0;

	hepv3_send_packet(capture_info);

	return PJ_FALSE;
}
예제 #5
0
/*!
 * \internal
 * \brief Find the request tdata to get the serializer it used.
 * \since 14.0.0
 *
 * \param rdata The incoming message.
 *
 * \retval serializer on success.
 * \retval NULL on error or could not find the serializer.
 */
static struct ast_taskprocessor *find_request_serializer(pjsip_rx_data *rdata)
{
	struct ast_taskprocessor *serializer = NULL;
	pj_str_t tsx_key;
	pjsip_transaction *tsx;

	pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
		&rdata->msg_info.cseq->method, rdata);

	tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
	if (!tsx) {
		ast_debug(1, "Could not find %.*s transaction for %d response.\n",
			(int) pj_strlen(&rdata->msg_info.cseq->method.name),
			pj_strbuf(&rdata->msg_info.cseq->method.name),
			rdata->msg_info.msg->line.status.code);
		return NULL;
	}

	if (tsx->last_tx) {
		const char *serializer_name;

		serializer_name = tsx->last_tx->mod_data[distributor_mod.id];
		if (!ast_strlen_zero(serializer_name)) {
			serializer = ast_taskprocessor_get(serializer_name, TPS_REF_IF_EXISTS);
		}
	}

#ifdef HAVE_PJ_TRANSACTION_GRP_LOCK
	pj_grp_lock_release(tsx->grp_lock);
#else
	pj_mutex_unlock(tsx->mutex);
#endif

	return serializer;
}
예제 #6
0
static pj_bool_t on_rx_request_tcp_hack(pjsip_rx_data *rdata) {
	 PJ_LOG(3,(THIS_FILE, "CB TCP HACK"));
	if (strstr(pj_strbuf(&rdata->msg_info.msg->line.req.method.name), "INVITE")) {
		 PJ_LOG(3,(THIS_FILE, "We have an invite here"));

	}

	return PJ_FALSE;

}
예제 #7
0
static void set_redirecting_id(pjsip_name_addr *name_addr, struct ast_party_id *data,
			       struct ast_set_party_id *update)
{
	pjsip_sip_uri *uri = pjsip_uri_get_uri(name_addr->uri);
	char *semi;
	pj_str_t uri_user;

	uri_user = uri->user;

	/* Always truncate redirecting number at a semicolon. */
	semi = pj_strchr(&uri_user, ';');
	if (semi) {
		/*
		 * We need to be able to handle URI's looking like
		 * "sip:1235557890;[email protected];user=phone"
		 *
		 * Where the uri->user field will result in:
		 * "1235557890;phone-context=national"
		 *
		 * People don't care about anything after the semicolon
		 * showing up on their displays even though the RFC
		 * allows the semicolon.
		 */
		pj_strset(&uri_user, (char *) pj_strbuf(&uri_user), semi - pj_strbuf(&uri_user));
	}

	if (pj_strlen(&uri_user)) {
		update->number = 1;
		data->number.valid = 1;
		set_redirecting_value(&data->number.str, &uri_user);
	}

	if (pj_strlen(&name_addr->display)) {
		update->name = 1;
		data->name.valid = 1;
		set_redirecting_value(&data->name.str, &name_addr->display);
	}
}
예제 #8
0
static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs)
{
	pjmedia_sdp_attr *attr;
	pjmedia_sdp_rtpmap *rtpmap;
	pjmedia_sdp_fmtp fmtp;
	struct ast_format *format;
	int i, num = 0;
	char name[256];
	char media[20];
	char fmt_param[256];

	ast_rtp_codecs_payloads_initialize(codecs);

	/* Iterate through provided formats */
	for (i = 0; i < stream->desc.fmt_count; ++i) {
		/* The payload is kept as a string for things like t38 but for video it is always numerical */
		ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
		/* Look for the optional rtpmap attribute */
		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
			continue;
		}

		/* Interpret the attribute as an rtpmap */
		if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_prov, attr, &rtpmap)) != PJ_SUCCESS) {
			continue;
		}

		ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
		ast_copy_pj_str(media, (pj_str_t*)&stream->desc.media, sizeof(media));
		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
							     media, name, 0, rtpmap->clock_rate);
		/* Look for an optional associated fmtp attribute */
		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
			continue;
		}

		if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
			sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
			if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
				ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
				ast_format_sdp_parse(format, fmt_param);
			}
		}
	}
}
예제 #9
0
static pj_bool_t handle_rx_message(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
{
	pjsip_contact_hdr *contact;

	if (!endpoint) {
		return PJ_FALSE;
	}

	if (endpoint->nat.rewrite_contact && (contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) &&
		!contact->star && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
		pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
		pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);

		pj_cstr(&uri->host, rdata->pkt_info.src_name);
		if (strcasecmp("udp", rdata->tp_info.transport->type_name)) {
			uri->transport_param = pj_str(rdata->tp_info.transport->type_name);
		} else {
			uri->transport_param.slen = 0;
		}
		uri->port = rdata->pkt_info.src_port;
		ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n",
			(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port);

		/* rewrite the session target since it may have already been pulled from the contact header */
		if (dlg && (!dlg->remote.contact
			|| pjsip_uri_cmp(PJSIP_URI_IN_REQ_URI, dlg->remote.contact->uri, contact->uri))) {
			dlg->remote.contact = (pjsip_contact_hdr*)pjsip_hdr_clone(dlg->pool, contact);
			dlg->target = dlg->remote.contact->uri;
		}
	}

	if (endpoint->nat.force_rport) {
		rdata->msg_info.via->rport_param = rdata->pkt_info.src_port;
	}

	return PJ_FALSE;
}
예제 #10
0
//////////////////////////////////////////////////////////////////////////
// Request handler to receive out-of-dialog NOTIFY (from Asterisk)
static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
{
	if (strstr(pj_strbuf(&rdata->msg_info.msg->line.req.method.name),
		"NOTIFY"))
	{
		pjsip_generic_string_hdr * hdr;
		pj_str_t did_str = pj_str("Event");
		hdr = (pjsip_generic_string_hdr*) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &did_str, NULL);
		if (!hdr) return false;

		// We have an event header, now determine if it's contents are "message-summary"
		if (pj_strcmp2(&hdr->hvalue, "message-summary")) return false;

		pjsip_msg_body * body_p = rdata->msg_info.msg->body;

		wchar_t* buf = (wchar_t*)pj_pool_alloc(app_config.pool, body_p->len);
		buf = PJ_STRING_TO_NATIVE((char*)body_p->data, buf, body_p->len);

		// Process body message as desired...
		if (strncmp((char*)body_p->data, "Messages-Waiting: yes", body_p->len) != 0)
		{
			if (cb_mwi != 0) cb_mwi(1, buf);
		}
		else
		{
			if (cb_mwi != 0) cb_mwi(0, buf);
		}
		PJ_LOG(3,(THIS_FILE,"MWI message: %s", buf));
	}

	pjsip_endpt_respond_stateless(pjsip_ua_get_endpt(pjsip_ua_instance()),
		rdata, 200, NULL,
		NULL, NULL);

	return PJ_TRUE;
}
예제 #11
0
std::string PJUtils::pj_str_to_string(const pj_str_t* pjstr)
{
  return (pjstr != NULL) ? std::string(pj_strbuf(pjstr), pj_strlen(pjstr)) : std::string("");
}
예제 #12
0
static pj_status_t multihomed_on_tx_message(pjsip_tx_data *tdata)
{
	pjsip_tpmgr_fla2_param prm;
	pjsip_cseq_hdr *cseq;
	pjsip_via_hdr *via;

	/* Use the destination information to determine what local interface this message will go out on */
	pjsip_tpmgr_fla2_param_default(&prm);
	prm.tp_type = tdata->tp_info.transport->key.type;
	pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
	prm.local_if = PJ_TRUE;

	/* If we can't get the local address use best effort and let it pass */
	if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
		return PJ_SUCCESS;
	}

	/* The port in the message should always be that of the original transport */
	prm.ret_port = tdata->tp_info.transport->local_name.port;

	/* If the IP source differs from the existing transport see if we need to update it */
	if (pj_strcmp(&prm.ret_addr, &tdata->tp_info.transport->local_name.host)) {

		/* If the transport it is going out on is different reflect it in the message */
		if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP ||
			tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP6) {
			pjsip_transport *transport;

			transport = multihomed_get_udp_transport(&prm.ret_addr, prm.ret_port);

			if (transport) {
				tdata->tp_info.transport = transport;
			}
		}

		/* If the chosen transport is not bound to any we can't use the source address as it won't get back to us */
		if (!multihomed_bound_any(tdata->tp_info.transport)) {
			pj_strassign(&prm.ret_addr, &tdata->tp_info.transport->local_name.host);
		}
	} else {
		/* The transport chosen will deliver this but ensure it is updated with the right information */
		pj_strassign(&prm.ret_addr, &tdata->tp_info.transport->local_name.host);
	}

	/* If the message needs to be updated with new address do so */
	if (tdata->msg->type == PJSIP_REQUEST_MSG || !(cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL)) ||
		pj_strcmp2(&cseq->method.name, "REGISTER")) {
		pjsip_contact_hdr *contact = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
		if (contact && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))
			&& !(tdata->msg->type == PJSIP_RESPONSE_MSG && tdata->msg->line.status.code / 100 == 3)) {
			pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);

			/* prm.ret_addr is allocated from the tdata pool OR the transport so it is perfectly fine to just do an assignment like this */
			pj_strassign(&uri->host, &prm.ret_addr);
			uri->port = prm.ret_port;
			ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n",
				(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port);

			pjsip_tx_data_invalidate_msg(tdata);
		}
	}

	if (tdata->msg->type == PJSIP_REQUEST_MSG && (via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL))) {
		pj_strassign(&via->sent_by.host, &prm.ret_addr);
		via->sent_by.port = prm.ret_port;

		pjsip_tx_data_invalidate_msg(tdata);
	}

	/* Update the SDP if it is present */
	if (tdata->msg->body && ast_sip_is_content_type(&tdata->msg->body->content_type, "application", "sdp") &&
		multihomed_rewrite_sdp(tdata->msg->body->data)) {
		struct pjmedia_sdp_session *sdp = tdata->msg->body->data;
		int stream;

		pj_strassign(&sdp->conn->addr, &prm.ret_addr);

		for (stream = 0; stream < sdp->media_count; ++stream) {
			if (sdp->media[stream]->conn) {
				pj_strassign(&sdp->media[stream]->conn->addr, &prm.ret_addr);
			}
		}

		pjsip_tx_data_invalidate_msg(tdata);
	}

	return PJ_SUCCESS;
}
예제 #13
0
/*!
 * \internal
 * \brief Compute a hash value on a pjlib string
 * \since 13.10.0
 *
 * \param[in] str The pjlib string to add to the hash
 * \param[in] hash The hash value to add to
 *
 * \details
 * This version of the function is for when you need to compute a
 * string hash of more than one string.
 *
 * This famous hash algorithm was written by Dan Bernstein and is
 * commonly used.
 *
 * \sa http://www.cse.yorku.ca/~oz/hash.html
 */
static int pjstr_hash_add(pj_str_t *str, int hash)
{
	return buf_hash_add(pj_strbuf(str), pj_strlen(str), hash);
}
예제 #14
0
std::string pj_str_to_string(const pj_str_t* pjstr)
{
  return ((pjstr != NULL) && (pj_strlen(pjstr) > 0)) ?
              std::string(pj_strbuf(pjstr), pj_strlen(pjstr)) : std::string("");
}
예제 #15
0
/*
 * Open codec.
 */
static pj_status_t amr_codec_open( pjmedia_codec *codec, 
				   pjmedia_codec_param *attr )
{
    struct amr_data *amr_data = (struct amr_data*) codec->codec_data;
    pjmedia_codec_amr_pack_setting *setting;
    unsigned i;
    pj_uint8_t octet_align = 0;
    pj_int8_t enc_mode;
    const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11};
    unsigned idx;

    PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
    PJ_ASSERT_RETURN(amr_data != NULL, PJ_EINVALIDOP);

    idx = (attr->info.clock_rate <= 8000? IDX_AMR_NB: IDX_AMR_WB);
    enc_mode = pjmedia_codec_amr_get_mode(attr->info.avg_bps);
    pj_assert(enc_mode >= 0 && enc_mode < amr_bitrates_size[idx]);

    /* Check octet-align */
    for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
	if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, 
		       &STR_FMTP_OCTET_ALIGN) == 0)
	{
	    octet_align = (pj_uint8_t)
			  (pj_strtoul(&attr->setting.dec_fmtp.param[i].val));
	    break;
	}
    }

    /* Check mode-set */
    for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
	const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8};
        
	if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, 
		       &STR_FMTP_MODE_SET) == 0)
	{
	    const char *p;
	    pj_size_t l;
	    pj_int8_t diff = 99;

	    /* Encoding mode is chosen based on local default mode setting:
	     * - if local default mode is included in the mode-set, use it
	     * - otherwise, find the closest mode to local default mode;
	     *   if there are two closest modes, prefer to use the higher
	     *   one, e.g: local default mode is 4, the mode-set param
	     *   contains '2,3,5,6', then 5 will be chosen.
	     */
	    p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val);
	    l = pj_strlen(&attr->setting.enc_fmtp.param[i].val);
	    while (l--) {
		if (*p>='0' && *p<=('0'+amr_bitrates_size[idx]-1)) {
		    pj_int8_t tmp = *p - '0' - enc_mode;

		    if (PJ_ABS(diff) > PJ_ABS(tmp) || 
			(PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff))
		    {
			diff = tmp;
			if (diff == 0) break;
		    }
		}
		++p;
	    }
	    PJ_ASSERT_RETURN(diff != 99, PJMEDIA_CODEC_EFAILED);

	    enc_mode = enc_mode + diff;

	    break;
	}
    }

    amr_data->clock_rate = attr->info.clock_rate;
    amr_data->vad_enabled = (attr->setting.vad != 0);
    amr_data->plc_enabled = (attr->setting.plc != 0);
    amr_data->enc_mode = enc_mode;

    if (idx == IDX_AMR_NB) {
#ifdef USE_AMRNB
        amr_data->encoder = Encoder_Interface_init(amr_data->vad_enabled);
#endif
    } else {
#ifdef USE_AMRWB
        amr_data->encoder = E_IF_init();
#endif
    }
    if (amr_data->encoder == NULL) {
	TRACE_((THIS_FILE, "Encoder initialization failed"));
	amr_codec_close(codec);
	return PJMEDIA_CODEC_EFAILED;
    }
    setting = &amr_data->enc_setting;
    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
    setting->reorder = 0;
    setting->octet_aligned = octet_align;
    setting->cmr = 15;

    if (idx == IDX_AMR_NB) {
#ifdef USE_AMRNB
        amr_data->decoder = Decoder_Interface_init();
#endif
    } else {
#ifdef USE_AMRWB
        amr_data->decoder = D_IF_init();
#endif
    }
    if (amr_data->decoder == NULL) {
	TRACE_((THIS_FILE, "Decoder initialization failed"));
	amr_codec_close(codec);
	return PJMEDIA_CODEC_EFAILED;
    }
    setting = &amr_data->dec_setting;
    pj_bzero(setting, sizeof(pjmedia_codec_amr_pack_setting));
    setting->amr_nb = (idx == IDX_AMR_NB? 1: 0);
    setting->reorder = 0;
    setting->octet_aligned = octet_align;

    TRACE_((THIS_FILE, "AMR codec allocated: clockrate=%d vad=%d, plc=%d,"
                       " bitrate=%d", amr_data->clock_rate,
			amr_data->vad_enabled, amr_data->plc_enabled, 
			amr_bitrates[idx][amr_data->enc_mode]));
    return PJ_SUCCESS;
}
예제 #16
0
파일: accountinfo.cpp 프로젝트: Bjoe/qpjsip
QString AccountInfo::getStatusText() const
{
    return pj_strbuf(&accountInfo.status_text);
}
예제 #17
0
static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
{
	char local_buf[256];
	char remote_buf[256];
	char *uuid;
	struct hepv3_capture_info *capture_info;
	pjsip_cid_hdr *cid_hdr;
	pjsip_from_hdr *from_hdr;
	pjsip_to_hdr *to_hdr;

	capture_info = hepv3_create_capture_info(tdata->buf.start, (size_t)(tdata->buf.cur - tdata->buf.start));
	if (!capture_info) {
		return PJ_SUCCESS;
	}

	if (!(tdata->tp_info.transport->flag & PJSIP_TRANSPORT_RELIABLE)) {
		pjsip_tpmgr_fla2_param prm;

		/* Attempt to determine what IP address will we send this packet out of */
		pjsip_tpmgr_fla2_param_default(&prm);
		prm.tp_type = tdata->tp_info.transport->key.type;
		pj_strset2(&prm.dst_host, tdata->tp_info.dst_name);
		prm.local_if = PJ_TRUE;

		/* If we can't get the local address use what we have already */
		if (pjsip_tpmgr_find_local_addr2(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), tdata->pool, &prm) != PJ_SUCCESS) {
			pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
		} else {
			if (prm.tp_type & PJSIP_TRANSPORT_IPV6) {
				snprintf(local_buf, sizeof(local_buf), "[%.*s]:%hu",
					(int)pj_strlen(&prm.ret_addr),
					pj_strbuf(&prm.ret_addr),
					prm.ret_port);
			} else {
				snprintf(local_buf, sizeof(local_buf), "%.*s:%hu",
					(int)pj_strlen(&prm.ret_addr),
					pj_strbuf(&prm.ret_addr),
					prm.ret_port);
			}
		}
	} else {
		/* For reliable transports they can only ever come from the transport
		 * local address.
		 */
		pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
	}

	pj_sockaddr_print(&tdata->tp_info.dst_addr, remote_buf, sizeof(remote_buf), 3);

	cid_hdr = PJSIP_MSG_CID_HDR(tdata->msg);
	from_hdr = PJSIP_MSG_FROM_HDR(tdata->msg);
	to_hdr = PJSIP_MSG_TO_HDR(tdata->msg);

	uuid = assign_uuid(&cid_hdr->id, &to_hdr->tag, &from_hdr->tag);
	if (!uuid) {
		ao2_ref(capture_info, -1);
		return PJ_SUCCESS;
	}

	ast_sockaddr_parse(&capture_info->src_addr, local_buf, PARSE_PORT_REQUIRE);
	ast_sockaddr_parse(&capture_info->dst_addr, remote_buf, PARSE_PORT_REQUIRE);

	capture_info->protocol_id = transport_to_protocol_id(tdata->tp_info.transport);
	capture_info->capture_time = ast_tvnow();
	capture_info->capture_type = HEPV3_CAPTURE_TYPE_SIP;
	capture_info->uuid = uuid;
	capture_info->zipped = 0;

	hepv3_send_packet(capture_info);

	return PJ_SUCCESS;
}
예제 #18
0
void SipAccount::onIncomingCall(pjsua_call_id call_id, pjsip_rx_data *rdata) {
  Logger::debug("SipAccount::onIncomingCall(call_id=%d)...", call_id);
  PJ_UNUSED_ARG(rdata);

  pj_status_t status = pjsua_call_set_user_data(call_id, this);
  if (status != PJ_SUCCESS) {
    Logger::error("pjsua_acc_set_user_data() failed (%s)", Helper::getPjStatusAsString(status).c_str());
  }

  pjsua_call_info ci;
  pjsua_call_get_info(call_id, &ci);

#if 0
  Logger::debug("local_info %s", pj_strbuf(&ci.local_info));
  Logger::debug("local_contact %s", pj_strbuf(&ci.local_contact));
  Logger::debug("remote_info %s", pj_strbuf(&ci.remote_info));
  Logger::debug("remote_contact %s", pj_strbuf(&ci.remote_contact));
  Logger::debug("call_id %s", pj_strbuf(&ci.call_id));
#endif

  std::string display, number;
  if (!getNumber(&ci.remote_info, &display, &number)) {
    Logger::warn("invalid URI received '%s'", pj_strbuf(&ci.remote_info));
    return;
  }

  std::string msg;
  bool block = false;
  if (number == "anonymous" or number == "") {
    block = m_pPhone->isAnonymousNumberBlocked(&m_settings.base, &msg);
  } else {
    block = m_pPhone->isNumberBlocked(&m_settings.base, number, &msg);
  }
  Logger::notice(msg.c_str());

#if 0
  // 302 redirect
  Use pjsua_call_hangup() and put the destination URL in the Contact
  header of the pjsua_msg_data.

  pj_pool_t* pool = pjsua_pool_create("", 512, 512);
  pjsua_msg_data msgData;
  pjsua_msg_data_init(&msgData);

  pj_str_t tmp;
  pjsip_generic_string_hdr* hdr =
    pjsip_generic_string_hdr_create(pool, pj_cstr(&tmp, "Contact"), pj_cstr(&tmp, "URI ...TODO"));
  pj_list_push_back(&msgData.hdr_list, hdr);
  // codes: http://de.wikipedia.org/wiki/SIP-Status-Codes
   // enum pjsip_status_code...
  pjsua_call_hangup(call_id, PJSIP_SC_MOVED_TEMPORARILY, NULL, &msgData);
  pj_pool_release(pool);
#endif

  if (block) {
    // answer incoming calls with 200/OK, then we hangup in onCallState...
    pj_status_t status = pjsua_call_answer(call_id, 200, NULL, NULL);
    if (status != PJ_SUCCESS) {
      Logger::warn("pjsua_call_answer() failed (%s)", Helper::getPjStatusAsString(status).c_str());
    }
  }
}