Example #1
0
/*
 * Parse Event header.
 */
static pjsip_hdr *parse_hdr_event(pjsip_parse_ctx *ctx)
{
    pjsip_event_hdr *hdr = pjsip_event_hdr_create(ctx->pool);
    const pj_str_t id_param = { "id", 2 };
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    pj_scan_get(ctx->scanner, &pc->pjsip_TOKEN_SPEC, &hdr->event_type);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &id_param)==0) {
	    hdr->id_param = pvalue;
	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Example #2
0
/*
 * Parse Session-Expires header.
 */
static pjsip_hdr *parse_hdr_se(pjsip_parse_ctx *ctx)
{
    pjsip_sess_expires_hdr *hdr = pjsip_sess_expires_hdr_create(ctx->pool);
    const pjsip_parser_const_t *pc = pjsip_parser_const();
    pj_str_t token;

    pj_scan_get(ctx->scanner, &pc->pjsip_DIGIT_SPEC, &token);
    hdr->sess_expires = pj_strtoul(&token);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &STR_REFRESHER)==0) {
	    hdr->refresher = pvalue;
	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Example #3
0
/*
 * Parse Replaces header.
 */
static pjsip_hdr *parse_hdr_replaces(pjsip_parse_ctx *ctx)
{
    pjsip_replaces_hdr *hdr = pjsip_replaces_hdr_create(ctx->pool);
    const pj_str_t to_tag = { "to-tag", 6 };
    const pj_str_t from_tag = { "from-tag", 8 };
    const pj_str_t early_only_tag = { "early-only", 10 };

    /*pj_scan_get(ctx->scanner, &pjsip_TOKEN_SPEC, &hdr->call_id);*/
    /* Get Call-ID (until ';' is found). using pjsip_TOKEN_SPEC doesn't work
     * because it stops parsing when '@' character is found.
     */
    pj_scan_get_until_ch(ctx->scanner, ';', &hdr->call_id);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &to_tag)==0) {
	    hdr->to_tag = pvalue;
	} else if (pj_stricmp(&pname, &from_tag)==0) {
	    hdr->from_tag = pvalue;
	} else if (pj_stricmp(&pname, &early_only_tag)==0) {
	    hdr->early_only = PJ_TRUE;
	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Example #4
0
static void parse_digest_credential( pj_scanner *scanner, pj_pool_t *pool, 
                                     pjsip_digest_credential *cred)
{
    pj_list_init(&cred->other_param);

    for (;;) {
	pj_str_t name, value;

	pjsip_parse_param_imp(scanner, pool, &name, &value,
			      PJSIP_PARSE_REMOVE_QUOTE);

	if (!pj_stricmp(&name, &pjsip_USERNAME_STR)) {
	    cred->username = value;

	} else if (!pj_stricmp(&name, &pjsip_REALM_STR)) {
	    cred->realm = value;

	} else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {
	    cred->nonce = value;

	} else if (!pj_stricmp(&name, &pjsip_URI_STR)) {
	    cred->uri = value;

	} else if (!pj_stricmp(&name, &pjsip_RESPONSE_STR)) {
	    cred->response = value;

	} else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {
	    cred->algorithm = value;

	} else if (!pj_stricmp(&name, &pjsip_CNONCE_STR)) {
	    cred->cnonce = value;

	} else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {
	    cred->opaque = value;

	} else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {
	    cred->qop = value;

	} else if (!pj_stricmp(&name, &pjsip_NC_STR)) {
	    cred->nc = value;

	} else {
	    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
	    p->name = name;
	    p->value = value;
	    pj_list_insert_before(&cred->other_param, p);
	}

	/* Eat comma */
	if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
	    pj_scan_get_char(scanner);
	else
	    break;
    }
}
Example #5
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;
}
Example #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;
}
Example #7
0
pjsip_hdr* parse_hdr_reject_contact(pjsip_parse_ctx* ctx)
{
  // The Reject-Contact header has the following ABNF:
  //
  // Reject-Contact  =  ("Reject-Contact" / "j") HCOLON rc-value
  //                       *(COMMA rc-value)
  // rc-value        =  "*" *(SEMI rc-params)
  // rc-params       =  feature-param / generic-param
  //
  // But we allow any value for the header (not just *).

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  const pjsip_parser_const_t* pc = pjsip_parser_const();
  pjsip_reject_contact_hdr* hdr = pjsip_reject_contact_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;
  pjsip_param *param;

  // Read and ignore the value.
  pj_str_t header_value;
  pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &header_value);

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

    pjsip_parse_param_imp(scanner, pool, &name, &value, 0);
    param = PJ_POOL_ALLOC_T(pool, pjsip_param);
    param->name = name;
    param->value = value;
    pj_list_insert_before(&hdr->feature_set, param);

    // 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;
}
Example #8
0
static void parse_digest_challenge( pj_scanner *scanner, pj_pool_t *pool, 
                                    pjsip_digest_challenge *chal)
{
    pj_list_init(&chal->other_param);

    for (;;) {
	pj_str_t name, value;

	pjsip_parse_param_imp(scanner, pool, &name, &value,
			      PJSIP_PARSE_REMOVE_QUOTE);

	if (!pj_stricmp(&name, &pjsip_REALM_STR)) {
	    chal->realm = value;

	} else if (!pj_stricmp(&name, &pjsip_DOMAIN_STR)) {
	    chal->domain = value;

	} else if (!pj_stricmp(&name, &pjsip_NONCE_STR)) {
	    chal->nonce = value;

	} else if (!pj_stricmp(&name, &pjsip_OPAQUE_STR)) {
	    chal->opaque = value;

	} else if (!pj_stricmp(&name, &pjsip_STALE_STR)) {
	    if (!pj_stricmp(&value, &pjsip_TRUE_STR) || 
                !pj_stricmp(&value, &pjsip_QUOTED_TRUE_STR))
            {
		chal->stale = 1;
            }

	} else if (!pj_stricmp(&name, &pjsip_ALGORITHM_STR)) {
	    chal->algorithm = value;


	} else if (!pj_stricmp(&name, &pjsip_QOP_STR)) {
	    chal->qop = value;

	} else {
	    pjsip_param *p = PJ_POOL_ALLOC_T(pool, pjsip_param);
	    p->name = name;
	    p->value = value;
	    pj_list_insert_before(&chal->other_param, p);
	}

	/* Eat comma */
	if (!pj_scan_is_eof(scanner) && *scanner->curptr == ',')
	    pj_scan_get_char(scanner);
	else
	    break;
    }
}
Example #9
0
/// Custom parser for Service-Route header.  This is registered with PJSIP when
/// we initialize the stack.
pjsip_hdr* parse_hdr_service_route(pjsip_parse_ctx *ctx)
{
  // The Service-Route header is a comma separated list of name-addrs
  // so we parse it to multiple header structures, using the pjsip_route_hdr
  // structure for each.  Note that Service-Route may have parameters
  // after the name-addr.
  pjsip_route_hdr *first = NULL;
  pj_scanner *scanner = ctx->scanner;

  do
  {
    pjsip_route_hdr *hdr = identity_hdr_create(ctx->pool, STR_SERVICE_ROUTE);
    if (!first)
    {
      first = hdr;
    }
    else
    {
      pj_list_insert_before(first, hdr);
    }
    pjsip_name_addr *temp = pjsip_parse_name_addr_imp(scanner, ctx->pool);

    pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));

    while (*scanner->curptr == ';')
    {
      pj_scan_get_char(scanner);    // Consume ;
      pjsip_param *p = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
      pjsip_parse_param_imp(scanner, ctx->pool, &p->name, &p->value, 0);
      pj_list_insert_before(&hdr->other_param, p);
    }

    if (*scanner->curptr == ',')
    {
      pj_scan_get_char(scanner);
    }
    else
    {
      break;
    }
  } while (1);
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)first;
}
Example #10
0
/// Custom parser for P-Associated-URI header.  This is registered with PJSIP when
/// we initialize the stack.
pjsip_hdr* parse_hdr_p_associated_uri(pjsip_parse_ctx *ctx)
{
  // The P-Associated-URI header is a comma separated list of name-addrs
  // with optional parameters, so we parse it to multiple header structures,
  // using the pjsip_route_hdr structure for each.
  pjsip_route_hdr *first = NULL;
  pj_scanner *scanner = ctx->scanner;

  do
  {
    pjsip_route_hdr *hdr = identity_hdr_create(ctx->pool, STR_P_ASSOCIATED_URI);
    if (!first)
    {
      first = hdr;
    }
    else
    {
      pj_list_insert_before(first, hdr);
    }
    pjsip_name_addr *temp = pjsip_parse_name_addr_imp(scanner, ctx->pool);

    pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));

    while (*scanner->curptr == ';')
    {
      pj_scan_get_char(scanner);    // Consume ;
      pjsip_param *p = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
      pjsip_parse_param_imp(scanner, ctx->pool, &p->name, &p->value, 0);
      pj_list_insert_before(&hdr->other_param, p);
    }

    if (*scanner->curptr == ',')
    {
      pj_scan_get_char(scanner);
    }
    else
    {
      break;
    }
  } while (1);
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)first;
}
Example #11
0
/// Custom parser for P-Served-User.  This is registered with PJSIP when
/// we initialize the stack.
pjsip_hdr* parse_hdr_p_served_user(pjsip_parse_ctx *ctx)
{
  // The P-Served-User header is a single name-addr followed by optional
  // parameters, so we parse it to a single pjsip_route_hdr structure.
  pj_scanner *scanner = ctx->scanner;

  pjsip_route_hdr *hdr = identity_hdr_create(ctx->pool, STR_P_SERVED_USER);
  pjsip_name_addr *temp = pjsip_parse_name_addr_imp(scanner, ctx->pool);
  pj_memcpy(&hdr->name_addr, temp, sizeof(*temp));

  while (*scanner->curptr == ';')
  {
    pj_scan_get_char(scanner);    // Consume ;
    pjsip_param *p = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
    pjsip_parse_param_imp(scanner, ctx->pool, &p->name, &p->value, 0);
    pj_list_insert_before(&hdr->other_param, p);
  }
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
Example #12
0
/*
 * Parse Min-SE header.
 */
static pjsip_hdr *parse_hdr_min_se(pjsip_parse_ctx *ctx)
{
    pjsip_min_se_hdr *hdr = pjsip_min_se_hdr_create(ctx->pool);
    const pjsip_parser_const_t *pc = pjsip_parser_const();
    pj_str_t token;

    pj_scan_get(ctx->scanner, &pc->pjsip_DIGIT_SPEC, &token);
    hdr->min_se = pj_strtoul(&token);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;
	pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	param->name = pname;
	param->value = pvalue;
	pj_list_push_back(&hdr->other_param, param);
    }
    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Example #13
0
/*
 * Parse Subscription-State header.
 */
static pjsip_hdr* parse_hdr_sub_state( pjsip_parse_ctx *ctx )
{
    pjsip_sub_state_hdr *hdr = pjsip_sub_state_hdr_create(ctx->pool);
    const pj_str_t reason = { "reason", 6 },
		   expires = { "expires", 7 },
		   retry_after = { "retry-after", 11 };
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    pj_scan_get(ctx->scanner, &pc->pjsip_TOKEN_SPEC, &hdr->sub_state);

    while (*ctx->scanner->curptr == ';') {
	pj_str_t pname, pvalue;

	pj_scan_get_char(ctx->scanner);
	pjsip_parse_param_imp(ctx->scanner, ctx->pool, &pname, &pvalue, 0);

	if (pj_stricmp(&pname, &reason) == 0) {
	    hdr->reason_param = pvalue;

	} else if (pj_stricmp(&pname, &expires) == 0) {
	    hdr->expires_param = pj_strtoul(&pvalue);

	} else if (pj_stricmp(&pname, &retry_after) == 0) {
	    hdr->retry_after = pj_strtoul(&pvalue);

	} else {
	    pjsip_param *param = PJ_POOL_ALLOC_T(ctx->pool, pjsip_param);
	    param->name = pname;
	    param->value = pvalue;
	    pj_list_push_back(&hdr->other_param, param);
	}
    }

    pjsip_parse_end_hdr_imp( ctx->scanner );
    return (pjsip_hdr*)hdr;
}
Example #14
0
pjsip_hdr* parse_hdr_p_charging_vector(pjsip_parse_ctx* ctx)
{
  // The P-Charging-Vector header has the following ABNF:
  //
  // P-Charging-Vector     = "P-Charging-Vector" HCOLON icid-value
  //                         *(SEMI charge-params)
  // charge-params         = icid-gen-addr / orig-ioi /
  //                         term-ioi / generic-param
  // icid-value            = "icid-value" EQUAL gen-value
  // icid-gen-addr         = "icid-generated-at" EQUAL host
  // orig-ioi              = "orig-ioi" EQUAL gen-value
  // term-ioi              = "term-ioi" EQUAL gen-value

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_p_c_v_hdr* hdr = pjsip_p_c_v_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;

  // Parse the required icid-value parameter first.
  pjsip_parse_param_imp(scanner, pool, &name, &value,
                        PJSIP_PARSE_REMOVE_QUOTE);

  if (!pj_stricmp2(&name, "icid-value")) {
    hdr->icid = value;
  } else {
    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
  }

  for (;;) {
    pj_scan_skip_whitespace(scanner);

    // If we just parsed the last parameter we will have reached the end of the
    // header and have nothing more to do.
    if (pj_scan_is_eof(scanner) ||
        (*scanner->curptr == '\r') ||
        (*scanner->curptr == '\n')) {
      break;
    }

    // There's more content in the header so the next character must be the ";"
    // separator.
    if (*scanner->curptr == ';') {
      pj_scan_get_char(scanner);
    } else {
      PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
    }

    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);

    if (!pj_stricmp2(&name, "orig-ioi")) {
      hdr->orig_ioi = value;
    } else if (!pj_stricmp2(&name, "term-ioi")) {
      hdr->term_ioi = value;
    } else if (!pj_stricmp2(&name, "icid-generated-at")) {
      hdr->icid_gen_addr = value;
    } 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;
}