示例#1
0
/*!
 * \internal
 * \brief Set an ast_party_id structure based on data in a Remote-Party-ID header
 *
 * This makes use of \ref set_id_from_hdr for setting name and number. It uses
 * the privacy and screen parameters in order to set presentation information.
 *
 * \param rdata The incoming message
 * \param[out] id The ID to set
 * \retval 0 Succesfully set the party ID
 * \retval non-zero Could not set the party ID
 */
static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
{
	static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
	static const pj_str_t privacy_str = { "privacy", 7 };
	static const pj_str_t screen_str = { "screen", 6 };
	pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str);
	pjsip_param *screen;
	pjsip_param *privacy;

	if (!rpid_hdr) {
		return -1;
	}

	set_id_from_hdr(rpid_hdr, id);

	if (!id->number.valid) {
		return -1;
	}

	privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str);
	screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str);
	if (privacy && !pj_stricmp2(&privacy->value, "full")) {
		id->number.presentation |= AST_PRES_RESTRICTED;
		id->name.presentation |= AST_PRES_RESTRICTED;
	}
	if (screen && !pj_stricmp2(&screen->value, "yes")) {
		id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
		id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
	}

	return 0;
}
static pjsip_authorization_hdr* pjsip_authorization_hdr_clone(  pj_pool_t *pool,
								const pjsip_authorization_hdr *rhs)
{
    /* This function also serves Proxy-Authorization header. */
    pjsip_authorization_hdr *hdr;
    if (rhs->type == PJSIP_H_AUTHORIZATION)
	hdr = pjsip_authorization_hdr_create(pool);
    else
	hdr = pjsip_proxy_authorization_hdr_create(pool);

    pj_strdup(pool, &hdr->scheme, &rhs->scheme);

    if (pj_stricmp2(&hdr->scheme, "digest") == 0) {
	pj_strdup(pool, &hdr->credential.digest.username, &rhs->credential.digest.username);
	pj_strdup(pool, &hdr->credential.digest.realm, &rhs->credential.digest.realm);
	pj_strdup(pool, &hdr->credential.digest.nonce, &rhs->credential.digest.nonce);
	pj_strdup(pool, &hdr->credential.digest.uri, &rhs->credential.digest.uri);
	pj_strdup(pool, &hdr->credential.digest.response, &rhs->credential.digest.response);
	pj_strdup(pool, &hdr->credential.digest.algorithm, &rhs->credential.digest.algorithm);
	pj_strdup(pool, &hdr->credential.digest.cnonce, &rhs->credential.digest.cnonce);
	pj_strdup(pool, &hdr->credential.digest.opaque, &rhs->credential.digest.opaque);
	pj_strdup(pool, &hdr->credential.digest.qop, &rhs->credential.digest.qop);
	pj_strdup(pool, &hdr->credential.digest.nc, &rhs->credential.digest.nc);
	pjsip_param_clone(pool, &hdr->credential.digest.other_param, &rhs->credential.digest.other_param);
    } else if (pj_stricmp2(&hdr->scheme, "pgp") == 0) {
	pj_assert(0);
	return NULL;
    } else {
	pj_assert(0);
	return NULL;
    }

    return hdr;
}
static pjsip_www_authenticate_hdr* pjsip_www_authenticate_hdr_clone( pj_pool_t *pool,
								     const pjsip_www_authenticate_hdr *rhs)
{
    /* This function also serves Proxy-Authenticate header. */
    pjsip_www_authenticate_hdr *hdr;
    if (rhs->type == PJSIP_H_WWW_AUTHENTICATE)
	hdr = pjsip_www_authenticate_hdr_create(pool);
    else
	hdr = pjsip_proxy_authenticate_hdr_create(pool);

    pj_strdup(pool, &hdr->scheme, &rhs->scheme);

    if (pj_stricmp2(&hdr->scheme, "digest") == 0) {
	pj_strdup(pool, &hdr->challenge.digest.realm, &rhs->challenge.digest.realm);
	pj_strdup(pool, &hdr->challenge.digest.domain, &rhs->challenge.digest.domain);
	pj_strdup(pool, &hdr->challenge.digest.nonce, &rhs->challenge.digest.nonce);
	pj_strdup(pool, &hdr->challenge.digest.opaque, &rhs->challenge.digest.opaque);
	hdr->challenge.digest.stale = rhs->challenge.digest.stale;
	pj_strdup(pool, &hdr->challenge.digest.algorithm, &rhs->challenge.digest.algorithm);
	pj_strdup(pool, &hdr->challenge.digest.qop, &rhs->challenge.digest.qop);
	pjsip_param_clone(pool, &hdr->challenge.digest.other_param, 
			  &rhs->challenge.digest.other_param);
    } else if (pj_stricmp2(&hdr->scheme, "pgp") == 0) {
	pj_assert(0);
	return NULL;
    } else {
	pj_assert(0);
	return NULL;
    }

    return hdr;

}
static int pjsip_www_authenticate_hdr_print( pjsip_www_authenticate_hdr *hdr,
					     char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf + size;

    copy_advance(buf, hdr->name);
    *buf++ = ':';
    *buf++ = ' ';

    copy_advance(buf, hdr->scheme);
    *buf++ = ' ';

    if (pj_stricmp2(&hdr->scheme, "digest") == 0)
	printed = print_digest_challenge(&hdr->challenge.digest, buf, endbuf - buf);
    else if (pj_stricmp2(&hdr->scheme, "pgp") == 0)
	printed = print_pgp_challenge(&hdr->challenge.pgp, buf, endbuf - buf);
    else {
	pj_assert(0);
	return -1;
    }

    if (printed == -1)
	return -1;

    buf += printed;
    *buf = '\0';
    return (int)(buf-startbuf);
}
示例#5
0
文件: auth.c 项目: zndxlx/pjsip_r
/*
 * This function is called to get the password for the specified username.
 * This function is also used to check whether the username is valid.
 */
pj_status_t pj_turn_get_password(const pj_stun_msg *msg,
					 void *user_data, 
					 const pj_str_t *realm,
					 const pj_str_t *username,
					 pj_pool_t *pool,
					 pj_stun_passwd_type *data_type,
					 pj_str_t *data)
{
    unsigned i;

    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(pool);

    if (pj_stricmp2(realm, g_realm)) {
	LOG((THIS_FILE, "auth error: invalid realm '%.*s'", 
			(int)realm->slen, realm->ptr));
	return PJ_EINVAL;
    }

    for (i=0; i<PJ_ARRAY_SIZE(g_cred); ++i) {
	if (pj_stricmp2(username, g_cred[i].username) == 0) {
	    *data_type = PJ_STUN_PASSWD_PLAIN;
	    *data = pj_str(g_cred[i].passwd);
	    return PJ_SUCCESS;
	}
    }

    LOG((THIS_FILE, "auth error: user '%.*s' not found", 
		    (int)username->slen, username->ptr));
    return PJ_ENOTFOUND;
}
示例#6
0
pjsip_hdr* parse_hdr_p_charging_function_addresses(pjsip_parse_ctx* ctx)
{
  // The P-Charging-Function-Addresses header has the following ABNF:
  //
  // P-Charging-Addr        = "P-Charging-Function-Addresses" HCOLON
  //                          charge-addr-params
  //                          *(SEMI charge-addr-params)
  // charge-addr-params     = ccf / ecf / generic-param
  // ccf                    = "ccf" EQUAL gen-value
  // ecf                    = "ecf" EQUAL gen-value
  //
  // Where the ccf and ecf elements may be repeated to specify backup CDFs
  // for redundancy.

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_p_c_f_a_hdr* hdr = pjsip_p_c_f_a_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;
  pjsip_param *param;

  for (;;) {
    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);
    param = PJ_POOL_ALLOC_T(pool, pjsip_param);
    param->name = name;
    param->value = value;
    if (!pj_stricmp2(&name, "ccf")) {
      pj_list_insert_before(&hdr->ccf, param);
    } else if (!pj_stricmp2(&name, "ecf")) {
      pj_list_insert_before(&hdr->ecf, param);
    } else {
      pj_list_insert_before(&hdr->other_param, param);
    }

    // We might need to swallow the ';'.
    if (!pj_scan_is_eof(scanner) && *scanner->curptr == ';') {
      pj_scan_get_char(scanner);
    }

    // If we're EOF or looking at a newline, we're done.
    pj_scan_skip_whitespace(scanner);
    if (pj_scan_is_eof(scanner) ||
        (*scanner->curptr == '\r') ||
        (*scanner->curptr == '\n')) {
      break;
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
示例#7
0
pjsip_hdr* parse_hdr_session_expires(pjsip_parse_ctx* ctx)
{
  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_session_expires_hdr* hdr = pjsip_session_expires_hdr_create(pool);
  const pjsip_parser_const_t* pc = pjsip_parser_const();

  // Parse the expiry number
  pj_str_t int_str;
  pj_scan_get(scanner, &pc->pjsip_DIGIT_SPEC, &int_str);
  hdr->expires = pj_strtoul(&int_str);
  pj_scan_skip_whitespace(scanner);

  // Parse the rest of the params, looking for the refresher param
  while (*scanner->curptr == ';')
  {
    // Consume the ';'.
    pj_scan_get_char(scanner);
    pj_scan_skip_whitespace(scanner);

    // Parse the param.
    pj_str_t name;
    pj_str_t value;
    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);
    if (!pj_stricmp2(&name, "refresher"))
    {
      if (!pj_stricmp2(&value, "uac"))
      {
        hdr->refresher = SESSION_REFRESHER_UAC;
      }
      else if (!pj_stricmp2(&value, "uas"))
      {
        hdr->refresher = SESSION_REFRESHER_UAS;
      }
      else
      {
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
      }
    }
    else
    {
      pjsip_param* param = PJ_POOL_ALLOC_T(pool, pjsip_param);
      param->name = name;
      param->value = value;
      pj_list_insert_before(&hdr->other_param, param);
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
示例#8
0
static int has_diversion_reason(pjsip_rx_data *rdata)
{
	pjsip_param *reason;
	pjsip_fromto_hdr *hdr = get_diversion_header(rdata);

	if (!hdr) {
		return 0;
	}
	reason = get_diversion_reason(hdr);
	return reason
		&& (!pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_QUOTED_VALUE)
			|| !pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_VALUE));
}
示例#9
0
/**
 * This method is to parse and add the choice type 
 * argument values to command structure.
 **/
static pj_status_t add_choice_node(pj_cli_t *cli,
				   pj_xml_node *xml_node,
				   pj_cli_arg_spec *arg,
				   pj_cli_get_dyn_choice get_choice)
{
    pj_xml_node *choice_node;
    pj_xml_node *sub_node;
    pj_cli_arg_choice_val choice_values[PJ_CLI_MAX_CHOICE_VAL];
    pj_status_t status = PJ_SUCCESS;

    sub_node = xml_node;
    arg->type = PJ_CLI_ARG_CHOICE;
    arg->get_dyn_choice = get_choice;						

    choice_node = sub_node->node_head.next;
    while (choice_node != (pj_xml_node*)&sub_node->node_head) {
	pj_xml_attr *choice_attr;
	unsigned *stat_cnt = &arg->stat_choice_cnt;
	pj_cli_arg_choice_val *choice_val = &choice_values[*stat_cnt];		     
	pj_bzero(choice_val, sizeof(*choice_val));

	choice_attr = choice_node->attr_head.next;
	while (choice_attr != &choice_node->attr_head) {
	    if (!pj_stricmp2(&choice_attr->name, "value")) {
		pj_strassign(&choice_val->value, &choice_attr->value);
	    } else if (!pj_stricmp2(&choice_attr->name, "desc")) {
		pj_strassign(&choice_val->desc, &choice_attr->value);
	    }
	    choice_attr = choice_attr->next;
	}		
	if (++(*stat_cnt) >= PJ_CLI_MAX_CHOICE_VAL)
	    break;
	choice_node = choice_node->next;
    }    
    if (arg->stat_choice_cnt > 0) {
        unsigned i;

	arg->stat_choice_val = (pj_cli_arg_choice_val *)
				pj_pool_zalloc(cli->pool, 
					       arg->stat_choice_cnt *
					       sizeof(pj_cli_arg_choice_val));

        for (i = 0; i < arg->stat_choice_cnt; i++) {
	    pj_strdup(cli->pool, &arg->stat_choice_val[i].value, 
		      &choice_values[i].value);
            pj_strdup(cli->pool, &arg->stat_choice_val[i].desc, 
		      &choice_values[i].desc);            
        }
    }
    return status;
}
示例#10
0
文件: main.c 项目: Jopie64/pjsip
int main(int argc, char *argv[])
{
    int rc;
    int interractive = 0;

    boost();
    init_signals();

    while (argc > 1) {
        char *arg = argv[--argc];

        if (*arg=='-' && *(arg+1)=='i') {
            interractive = 1;

        } else if (*arg=='-' && *(arg+1)=='p') {
            pj_str_t port = pj_str(argv[--argc]);

            param_echo_port = pj_strtoul(&port);

        } else if (*arg=='-' && *(arg+1)=='s') {
            param_echo_server = argv[--argc];

        } else if (*arg=='-' && *(arg+1)=='t') {
            pj_str_t type = pj_str(argv[--argc]);

            if (pj_stricmp2(&type, "tcp")==0)
                param_echo_sock_type = pj_SOCK_STREAM();
            else if (pj_stricmp2(&type, "udp")==0)
                param_echo_sock_type = pj_SOCK_DGRAM();
            else {
                PJ_LOG(3,("", "error: unknown socket type %s", type.ptr));
                return 1;
            }
        }
    }

    rc = test_main();

    if (interractive) {
        char s[10];
        puts("");
        puts("Press <ENTER> to exit");
        if (!fgets(s, sizeof(s), stdin))
            return rc;
    }

    return rc;
}
示例#11
0
文件: registrar.cpp 项目: jmmL/sprout
/// Get private ID from a received message by checking the Authorization
/// header. If that uses the Digest scheme and contains a non-empty
/// username, it puts that username into id and returns true;
/// otherwise returns false.
bool get_private_id(pjsip_rx_data* rdata, std::string& id)
{
  bool success = false;

  pjsip_authorization_hdr* auth_hdr = (pjsip_authorization_hdr*)
    pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, NULL);
  if (auth_hdr != NULL)
  {
    if (pj_stricmp2(&auth_hdr->scheme, "digest") == 0)
    {
      id = PJUtils::pj_str_to_string(&auth_hdr->credential.digest.username);
      if (!id.empty())
      {
        success = true;
      }
    }
    else
    {
      // LCOV_EXCL_START
      LOG_WARNING("Unsupported scheme \"%.*s\" in Authorization header when determining private ID - ignoring",
                  auth_hdr->scheme.slen, auth_hdr->scheme.ptr);
      // LCOV_EXCL_STOP
    }
  }
  return success;
}
示例#12
0
文件: sdp.cpp 项目: dyfet/sflphone
void Sdp::setActiveRemoteSdpSession(const pjmedia_sdp_session *sdp)
{
    activeRemoteSession_ = (pjmedia_sdp_session*) sdp;

    if (!sdp) {
        ERROR("Remote sdp is NULL while parsing telephone event attribute");
        return;
    }

    for (unsigned i = 0; i < sdp->media_count; i++)
        if (pj_stricmp2(&sdp->media[i]->desc.media, "audio") == 0) {
            pjmedia_sdp_media *r_media = sdp->media[i];
            static const pj_str_t STR_TELEPHONE_EVENT = { (char*) "telephone-event", 15};
            pjmedia_sdp_attr *attribute = pjmedia_sdp_attr_find(r_media->attr_count, r_media->attr, &STR_TELEPHONE_EVENT, NULL);

            if (attribute != NULL) {
                pjmedia_sdp_rtpmap *rtpmap;
                pjmedia_sdp_attr_to_rtpmap(memPool_, attribute, &rtpmap);
                telephoneEventPayload_ = pj_strtoul(&rtpmap->pt);
            }

            return;
        }

    ERROR("Could not found dtmf event from remote sdp");
}
/*!
 * \internal
 * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header
 *
 * This makes use of \ref set_id_from_hdr for setting name and number. It uses
 * the contents of a Privacy header in order to set presentation information.
 *
 * \param rdata The incoming message
 * \param[out] id The ID to set
 * \retval 0 Successfully set the party ID
 * \retval non-zero Could not set the party ID
 */
static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
{
	static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
	static const pj_str_t privacy_str = { "Privacy", 7 };
	pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str);
	pjsip_generic_string_hdr *privacy;

	if (!pai_hdr) {
		return -1;
	}

	set_id_from_hdr(pai_hdr, id);

	if (!id->number.valid) {
		return -1;
	}

	privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL);
	if (privacy && !pj_stricmp2(&privacy->hvalue, "id")) {
		id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
		id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
	} else {
		id->number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
		id->name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
	}

	return 0;
}
示例#14
0
/*
 * Generate default attribute.
 */
static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, 
				      const pjmedia_codec_info *id, 
				      pjmedia_codec_param *attr )
{
    PJ_UNUSED_ARG(factory);
    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);

    PJ_UNUSED_ARG(id);
    PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, "iLBC")==0, PJ_EINVAL);

    pj_bzero(attr, sizeof(pjmedia_codec_param));

    attr->info.clock_rate = CLOCK_RATE;
    attr->info.channel_cnt = 1;
    attr->info.avg_bps = ilbc_factory.bps;
    attr->info.max_bps = 15200;
    attr->info.pcm_bits_per_sample = 16;
    attr->info.frm_ptime = (short)ilbc_factory.mode;
    attr->info.pt = PJMEDIA_RTP_PT_ILBC;

    attr->setting.frm_per_pkt = 1;
    attr->setting.vad = 1;
    attr->setting.plc = 1;
    attr->setting.penh = 1;
    attr->setting.dec_fmtp.cnt = 1;
    attr->setting.dec_fmtp.param[0].name = STR_MODE;
    if (ilbc_factory.mode == 30)
	attr->setting.dec_fmtp.param[0].val = pj_str("30");
    else
	attr->setting.dec_fmtp.param[0].val = pj_str("20");

    return PJ_SUCCESS;
}
static int has_diversion_reason(pjsip_rx_data *rdata)
{
	pjsip_param *reason;
	pjsip_fromto_hdr *hdr = get_diversion_header(rdata);

	return hdr &&
		(reason = get_diversion_reason(hdr)) &&
		!pj_stricmp2(&reason->value, SEND_TO_VM_REDIRECT_VALUE);
}
static int has_call_feature(pjsip_rx_data *rdata)
{
	static const pj_str_t call_feature_str = { "X-Digium-Call-Feature", 21 };

	pjsip_generic_string_hdr *hdr = pjsip_msg_find_hdr_by_name(
		rdata->msg_info.msg, &call_feature_str, NULL);

	return hdr && !pj_stricmp2(&hdr->hvalue, SEND_TO_VM_HEADER_VALUE);
}
示例#17
0
/**
 * This method is to parse and add the argument attribute to command structure.
 **/
static pj_status_t add_arg_node(pj_cli_t *cli,
				pj_xml_node *xml_node,
				pj_cli_cmd_spec *cmd,
				pj_cli_arg_spec *arg,
				pj_cli_get_dyn_choice get_choice)
{    
    pj_xml_attr *attr;
    pj_status_t status = PJ_SUCCESS;
    pj_xml_node *sub_node = xml_node;

    if (cmd->arg_cnt >= PJ_CLI_MAX_ARGS)
	return PJ_CLI_ETOOMANYARGS;
    
    pj_bzero(arg, sizeof(*arg));
    attr = sub_node->attr_head.next;
    arg->optional = PJ_FALSE;
    arg->validate = PJ_TRUE;
    while (attr != &sub_node->attr_head) {	
	if (!pj_stricmp2(&attr->name, "name")) {
	    pj_strassign(&arg->name, &attr->value);
	} else if (!pj_stricmp2(&attr->name, "id")) {
	    arg->id = pj_strtol(&attr->value);
	} else if (!pj_stricmp2(&attr->name, "type")) {
	    if (!pj_stricmp2(&attr->value, "text")) {
		arg->type = PJ_CLI_ARG_TEXT;
	    } else if (!pj_stricmp2(&attr->value, "int")) {
		arg->type = PJ_CLI_ARG_INT;
	    } else if (!pj_stricmp2(&attr->value, "choice")) {
		/* Get choice value */
		add_choice_node(cli, xml_node, arg, get_choice);
	    } 
	} else if (!pj_stricmp2(&attr->name, "desc")) {
	    pj_strassign(&arg->desc, &attr->value);
	} else if (!pj_stricmp2(&attr->name, "optional")) {
	    if (!pj_strcmp2(&attr->value, "1")) {
		arg->optional = PJ_TRUE;
	    }
	} else if (!pj_stricmp2(&attr->name, "validate")) {
	    if (!pj_strcmp2(&attr->value, "1")) {
		arg->validate = PJ_TRUE;
	    } else {
		arg->validate = PJ_FALSE;
	    }	
	} 
	attr = attr->next;
    }
    cmd->arg_cnt++;
    return status;
}
示例#18
0
static void on_response(pj_http_req *req, const pj_http_resp *resp)
{
    unsigned i;

    PJ_UNUSED_ARG(req);
    PJ_LOG(3,(THIS_FILE, "%.*s %d %.*s", (int)resp->version.slen, resp->version.ptr,
				           resp->status_code,
				           (int)resp->reason.slen, resp->reason.ptr));

    for (i=0; i<resp->headers.count; ++i) {
	const pj_http_header_elmt *h = &resp->headers.header[i];

	if (!pj_stricmp2(&h->name, "Content-Length") ||
	    !pj_stricmp2(&h->name, "Content-Type"))
	{
	    PJ_LOG(3,(THIS_FILE, "%.*s: %.*s",
		      (int)h->name.slen, h->name.ptr,
		      (int)h->value.slen, h->value.ptr));
	}
    }
}
示例#19
0
static void get_opus_channels_and_clock_rate(const pjmedia_codec_fmtp *enc_fmtp,
					     const pjmedia_codec_fmtp *dec_fmtp,
					     unsigned *channel_cnt,
					     unsigned *clock_rate)
{
    unsigned i;
    unsigned enc_channel_cnt = 0, local_channel_cnt = 0;
    unsigned enc_clock_rate = 0, local_clock_rate = 0;

    for (i = 0; i < dec_fmtp->cnt; ++i) {
	if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-maxcapturerate")) {
	    local_clock_rate = (unsigned)pj_strtoul(&dec_fmtp->param[i].val);
	} else if (!pj_stricmp2(&dec_fmtp->param[i].name, "sprop-stereo")) {
	    local_channel_cnt = (unsigned)pj_strtoul(&dec_fmtp->param[i].val);
	    local_channel_cnt = (local_channel_cnt > 0) ? 2 : 1;
	}
    }
    if (!local_clock_rate) local_clock_rate = *clock_rate;
    if (!local_channel_cnt) local_channel_cnt = *channel_cnt;

    for (i = 0; i < enc_fmtp->cnt; ++i) {
	if (!pj_stricmp2(&enc_fmtp->param[i].name, "maxplaybackrate")) {
	    enc_clock_rate = (unsigned)pj_strtoul(&enc_fmtp->param[i].val);
	} else if (!pj_stricmp2(&enc_fmtp->param[i].name, "stereo")) {
	    enc_channel_cnt = (unsigned)pj_strtoul(&enc_fmtp->param[i].val);
	    enc_channel_cnt = (enc_channel_cnt > 0) ? 2 : 1;
	}
    }
    /* The default is a standard mono session with 48000 Hz clock rate
     * (RFC 7587, section 7)
     */
    if (!enc_clock_rate) enc_clock_rate = 48000;
    if (!enc_channel_cnt) enc_channel_cnt = 1;

    *clock_rate = (enc_clock_rate < local_clock_rate) ? enc_clock_rate :
		  local_clock_rate;

    *channel_cnt = (enc_channel_cnt < local_channel_cnt) ? enc_channel_cnt :
		   local_channel_cnt;
}
示例#20
0
/// Resolves the next hop target of the SIP message
void PJUtils::resolve_next_hop(pjsip_tx_data* tdata,
                               int retries,
                               std::vector<AddrInfo>& servers,
                               SAS::TrailId trail)
{
  // Get the next hop URI from the message and parse out the destination, port
  // and transport.
  pjsip_sip_uri* next_hop = (pjsip_sip_uri*)PJUtils::next_hop(tdata->msg);
  std::string name = std::string(next_hop->host.ptr, next_hop->host.slen);
  int port = next_hop->port;
  int transport = -1;
  if (pj_stricmp2(&next_hop->transport_param, "TCP") == 0)
  {
    transport = IPPROTO_TCP;
  }
  else if (pj_stricmp2(&next_hop->transport_param, "UDP") == 0)
  {
    transport = IPPROTO_UDP;
  }

  if (retries == 0)
  {
    // Used default number of retries.
    retries = DEFAULT_RETRIES;
  }

  stack_data.sipresolver->resolve(name,
                                  stack_data.addr_family,
                                  port,
                                  transport,
                                  retries,
                                  servers,
                                  trail);

  LOG_INFO("Resolved destination URI %s to %d servers",
           PJUtils::uri_to_string(PJSIP_URI_IN_ROUTING_HDR,
                                  (pjsip_uri*)next_hop).c_str(),
           servers.size());
}
示例#21
0
文件: sdp.cpp 项目: dyfet/sflphone
void Sdp::getRemoteSdpCryptoFromOffer(const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer)
{
    for (unsigned i = 0; i < remote_sdp->media_count; ++i) {
        pjmedia_sdp_media *media = remote_sdp->media[i];

        for (unsigned j = 0; j < media->attr_count; j++) {
            pjmedia_sdp_attr *attribute = media->attr[j];

            // @TODO our parser require the "a=crypto:" to be present
            if (pj_stricmp2(&attribute->name, "crypto") == 0)
                crypto_offer.push_back("a=crypto:" + std::string(attribute->value.ptr, attribute->value.slen));
        }
    }
}
示例#22
0
static int parse_dtls_attrib(struct ast_sip_session_media *session_media,
	const struct pjmedia_sdp_media *stream)
{
	int i;
	struct ast_rtp_engine_dtls *dtls = ast_rtp_instance_get_dtls(session_media->rtp);

	for (i = 0; i < stream->attr_count; i++) {
		pjmedia_sdp_attr *attr = stream->attr[i];
		pj_str_t *value;

		if (!attr->value.ptr) {
			continue;
		}

		value = pj_strtrim(&attr->value);

		if (!pj_strcmp2(&attr->name, "setup")) {
			if (!pj_stricmp2(value, "active")) {
				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTIVE);
			} else if (!pj_stricmp2(value, "passive")) {
				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_PASSIVE);
			} else if (!pj_stricmp2(value, "actpass")) {
				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_ACTPASS);
			} else if (!pj_stricmp2(value, "holdconn")) {
				dtls->set_setup(session_media->rtp, AST_RTP_DTLS_SETUP_HOLDCONN);
			} else {
				ast_log(LOG_WARNING, "Unsupported setup attribute value '%*s'\n", (int)value->slen, value->ptr);
			}
		} else if (!pj_strcmp2(&attr->name, "connection")) {
			if (!pj_stricmp2(value, "new")) {
				dtls->reset(session_media->rtp);
			} else if (!pj_stricmp2(value, "existing")) {
				/* Do nothing */
			} else {
				ast_log(LOG_WARNING, "Unsupported connection attribute value '%*s'\n", (int)value->slen, value->ptr);
			}
		} else if (!pj_strcmp2(&attr->name, "fingerprint")) {
			char hash_value[256], hash[32];
			char fingerprint_text[value->slen + 1];
			ast_copy_pj_str(fingerprint_text, value, sizeof(fingerprint_text));

			if (sscanf(fingerprint_text, "%31s %255s", hash, hash_value) == 2) {
				if (!strcasecmp(hash, "sha-1")) {
					dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA1, hash_value);
				} else if (!strcasecmp(hash, "sha-256")) {
					dtls->set_fingerprint(session_media->rtp, AST_RTP_DTLS_HASH_SHA256, hash_value);
				} else {
					ast_log(LOG_WARNING, "Unsupported fingerprint hash type '%s'\n",
					hash);
				}
			}
		}
	}
	ast_set_flag(session_media->srtp, AST_SRTP_CRYPTO_OFFER_OK);

	return 0;
}
示例#23
0
文件: sdp.cpp 项目: dyfet/sflphone
void Sdp::setMediaTransportInfoFromRemoteSdp()
{
    if (!activeRemoteSession_) {
        ERROR("Remote sdp is NULL while parsing media");
        return;
    }

    for (unsigned i = 0; i < activeRemoteSession_->media_count; ++i)
        if (pj_stricmp2(&activeRemoteSession_->media[i]->desc.media, "audio") == 0) {
            setRemoteAudioPort(activeRemoteSession_->media[i]->desc.port);
            setRemoteIP(std::string(activeRemoteSession_->conn->addr.ptr, activeRemoteSession_->conn->addr.slen));
            return;
        }

    ERROR("No remote sdp media found in the remote offer");
}
static pjsip_authorization_hdr *get_auth_header(pjsip_rx_data *rdata, char *username,
	size_t username_size, char *realm, size_t realm_size, pjsip_authorization_hdr *start)
{
	pjsip_authorization_hdr *header;

	header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, start);

	if (!header || pj_stricmp2(&header->scheme, "digest")) {
		return NULL;
	}

	ast_copy_pj_str(username, &header->credential.digest.username, username_size);
	ast_copy_pj_str(realm, &header->credential.digest.realm, realm_size);

	return header;
}
示例#25
0
static int get_crypto_idx(const pj_str_t* crypto_name)
{
    int i;
    int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
    
    /* treat unspecified crypto_name as crypto 'NULL' */
    if (crypto_name->slen == 0)
	return 0;

    for (i=0; i<cs_cnt; ++i) {
	if (!pj_stricmp2(crypto_name, crypto_suites[i].name))
	    return i;
    }

    return -1;
}
示例#26
0
/*
 * Verify that valid SIP url is given.
 */
static pj_status_t verify_sip_url(char *url)
{
    pjsip_uri *p;
    pj_pool_t *pool;
    int len = (url ? strlen(url) : 0);

    if (!len) return -1;

    pool = pj_pool_create(global.pf, "check%p", 1024, 0, NULL);
    if (!pool) return -1;

    p = pjsip_parse_uri(pool, url, len, 0);
    if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)
	p = NULL;

    pj_pool_release(pool);
    return p ? 0 : -1;
}
示例#27
0
文件: auth.c 项目: zndxlx/pjsip_r
/*
 * This function will be called to verify that the NONCE given
 * in the message can be accepted. If this callback returns
 * PJ_FALSE, 438 (Stale Nonce) response will be created.
 */
pj_bool_t pj_turn_verify_nonce(const pj_stun_msg *msg,
				       void *user_data,
				       const pj_str_t *realm,
				       const pj_str_t *username,
				       const pj_str_t *nonce)
{
    PJ_UNUSED_ARG(msg);
    PJ_UNUSED_ARG(user_data);
    PJ_UNUSED_ARG(realm);
    PJ_UNUSED_ARG(username);

    if (pj_stricmp2(nonce, THE_NONCE)) {
	LOG((THIS_FILE, "auth error: invalid nonce '%.*s'", 
			(int)nonce->slen, nonce->ptr));
	return PJ_FALSE;
    }

    return PJ_TRUE;
}
示例#28
0
/*!
 * \internal
 * \brief Search list for nth occurrence of specific header.
 */
static pjsip_hdr *find_header(struct hdr_list *list, const char *header_name,
							  int header_number)
{
	struct hdr_list_entry *le;
	pjsip_hdr *hdr = NULL;
	int i = 1;

	if (!list || ast_strlen_zero(header_name) || header_number < 1) {
		return NULL;
	}

	AST_LIST_TRAVERSE(list, le, nextptr) {
		if (pj_stricmp2(&le->hdr->name, header_name) == 0 && i++ == header_number) {
			hdr = le->hdr;
			break;
		}
	}

	return hdr;
}
示例#29
0
/*!
 * \internal
 * \brief Implements PJSIP_HEADER 'remove' by finding the specified header and removing it.
 *
 * Retrieve the header_datastore from the session.  Fail if it doesn't exist.
 * If the header_name is exactly '*', the entire list is simply destroyed.
 * Otherwise search the list for the matching header name which may be a partial name.
 */
static int remove_header(void *obj)
{
	struct header_data *data = obj;
	size_t len = strlen(data->header_name);
	struct hdr_list *list;
	struct hdr_list_entry *le;
	int removed_count = 0;
	RAII_VAR(struct ast_datastore *, datastore,
			 ast_sip_session_get_datastore(data->channel->session, header_datastore.type),
			 ao2_cleanup);

	if (!datastore || !datastore->data) {
		ast_log(AST_LOG_ERROR, "No headers had been previously added to this session.\n");
		return -1;
	}

	list = datastore->data;
	AST_LIST_TRAVERSE_SAFE_BEGIN(list, le, nextptr) {
		if (data->header_name[len - 1] == '*') {
			if (pj_strnicmp2(&le->hdr->name, data->header_name, len - 1) == 0) {
				AST_LIST_REMOVE_CURRENT(nextptr);
				removed_count++;
			}
		} else {
			if (pj_stricmp2(&le->hdr->name, data->header_name) == 0) {
				AST_LIST_REMOVE_CURRENT(nextptr);
				removed_count++;
			}
		}
	}
	AST_LIST_TRAVERSE_SAFE_END;

	if (data->buf && data->len) {
		snprintf(data->buf, data->len, "%d", removed_count);
	}

	return 0;
}
示例#30
0
/*
 * Verify that valid SIP url is given.
 */
static pj_status_t verify_sip_url(const char *c_url)
{
    pjsip_uri *p;
    pj_pool_t *pool;
    char *url;
    int len = (c_url ? pj_ansi_strlen(c_url) : 0);

    if (!len) return -1;

    pool = pj_pool_create(&app.cp.factory, "check%p", 1024, 0, NULL);
    if (!pool) return PJ_ENOMEM;

    url = pj_pool_alloc(pool, len+1);
    pj_ansi_strcpy(url, c_url);
    url[len] = '\0';

    p = pjsip_parse_uri(pool, url, len, 0);
    if (!p || pj_stricmp2(pjsip_uri_get_scheme(p), "sip") != 0)
	p = NULL;

    pj_pool_release(pool);
    return p ? 0 : -1;
}