Example #1
0
int pjsip_reject_contact_hdr_print_on(void* void_hdr,
                                      char* buf,
                                      pj_size_t size)
{
  int printed;
  char *startbuf = buf;
  char *endbuf = buf + size;
  pjsip_reject_contact_hdr* hdr = (pjsip_reject_contact_hdr *)void_hdr;
  const pjsip_parser_const_t *pc = pjsip_parser_const();

  /* Route and Record-Route don't compact forms */
  copy_advance(buf, hdr->name);
  *buf++ = ':';
  *buf++ = ' ';
  *buf++ = '*';

  printed = pjsip_param_print_on(&hdr->feature_set, buf, endbuf-buf,
                                 &pc->pjsip_TOKEN_SPEC,
                                 &pc->pjsip_TOKEN_SPEC, ';');
  if (printed < 0)
  {
    return -1;
  }
  buf += printed;

  return buf-startbuf;
}
static int print_digest_challenge( pjsip_digest_challenge *chal,
				   char *buf, pj_size_t size)
{
    pj_ssize_t printed;
    char *startbuf = buf;
    char *endbuf = buf + size;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    /* Allow empty realm, see http://trac.pjsip.org/repos/ticket/1061 */
    copy_advance_pair_quote(buf, " realm=", 7, chal->realm, '"', '"');
    copy_advance_pair_quote_cond(buf, ",domain=", 8, chal->domain, '"', '"');
    copy_advance_pair_quote_cond(buf, ",nonce=", 7, chal->nonce, '"', '"');
    copy_advance_pair_quote_cond(buf, ",opaque=", 8, chal->opaque, '"', '"');
    if (chal->stale) {
	pj_str_t true_str = { "true", 4 };
	copy_advance_pair(buf, ",stale=", 7, true_str);
    }
    copy_advance_pair(buf, ",algorithm=", 11, chal->algorithm);
    copy_advance_pair_quote_cond(buf, ",qop=", 5, chal->qop, '"', '"');
    
    printed = pjsip_param_print_on(&chal->other_param, buf, endbuf-buf, 
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ',');
    if (printed < 0)
	return -1;
    buf += printed;

    return (int)(buf-startbuf);
}
static int print_digest_credential(pjsip_digest_credential *cred, char *buf, pj_size_t size)
{
    pj_ssize_t printed;
    char *startbuf = buf;
    char *endbuf = buf + size;
    const pjsip_parser_const_t *pc = pjsip_parser_const();
    
    copy_advance_pair_quote_cond(buf, "username="******"', '"');
    copy_advance_pair_quote_cond_always(buf, ", realm=", 8, cred->realm, '"', 
					'"');
    copy_advance_pair_quote(buf, ", nonce=", 8, cred->nonce, '"', '"');
    copy_advance_pair_quote_cond(buf, ", uri=", 6, cred->uri, '"', '"');
    copy_advance_pair_quote(buf, ", response=", 11, cred->response, '"', '"');
    copy_advance_pair(buf, ", algorithm=", 12, cred->algorithm);
    copy_advance_pair_quote_cond(buf, ", cnonce=", 9, cred->cnonce, '"', '"');
    copy_advance_pair_quote_cond(buf, ", opaque=", 9, cred->opaque, '"', '"');
    //Note: there's no dbl-quote in qop in Authorization header 
    // (unlike WWW-Authenticate)
    //copy_advance_pair_quote_cond(buf, ", qop=", 6, cred->qop, '"', '"');
    copy_advance_pair(buf, ", qop=", 6, cred->qop);
    copy_advance_pair(buf, ", nc=", 5, cred->nc);
    
    printed = pjsip_param_print_on(&cred->other_param, buf, endbuf-buf, 
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ',');
    if (printed < 0)
	return -1;
    buf += printed;

    return (int) (buf-startbuf);
}
Example #4
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 #5
0
int pjsip_accept_contact_hdr_print_on(void* void_hdr,
                                      char* buf,
                                      pj_size_t size)
{
  int printed;
  char *startbuf = buf;
  char *endbuf = buf + size;
  pjsip_accept_contact_hdr* hdr = (pjsip_accept_contact_hdr *)void_hdr;
  const pjsip_parser_const_t *pc = pjsip_parser_const();

  /* Route and Record-Route don't compact forms */
  copy_advance(buf, hdr->name);
  copy_advance(buf, pj_str(": *"));

  printed = pjsip_param_print_on(&hdr->feature_set, buf, endbuf-buf,
                                 &pc->pjsip_TOKEN_SPEC,
                                 &pc->pjsip_TOKEN_SPEC, ';');
  if (printed < 0)
  {
    return -1;
  }
  buf += printed;

  if (hdr->explicit_match)
  {
    copy_advance(buf, pj_str(";explicit"));
  }

  if (hdr->required_match)
  {
    copy_advance(buf, pj_str(";require"));
  }

  return buf-startbuf;
}
Example #6
0
int identity_hdr_print(pjsip_routing_hdr* hdr,
                       char* buf,
                       pj_size_t size)
{
  int printed;
  char *startbuf = buf;
  char *endbuf = buf + size;
  const pjsip_parser_const_t *pc = pjsip_parser_const();

  /* Route and Record-Route don't compact forms */
  copy_advance(buf, hdr->name);
  *buf++ = ':';
  *buf++ = ' ';

  printed = pjsip_uri_print(PJSIP_URI_IN_ROUTING_HDR,
                            &hdr->name_addr,
                            buf,
                            endbuf-buf);
  if (printed < 1)
  {
    return -1; // LCOV_EXCL_LINE
  }
  buf += printed;

  printed = pjsip_param_print_on(&hdr->other_param, buf, endbuf-buf,
                                 &pc->pjsip_TOKEN_SPEC,
                                 &pc->pjsip_TOKEN_SPEC, ';');
  if (printed < 0)
  {
    return -1; // LCOV_EXCL_LINE
  }
  buf += printed;

  return buf-startbuf;
}
Example #7
0
/*
 * Min-SE header vptr.
 */
static int min_se_hdr_print(pjsip_min_se_hdr *hdr, 
			    char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    pj_ssize_t printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    /* Print header name and value */
    if ((endbuf - p) < (hdr->name.slen + 16))
	return -1;

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

    printed = pj_utoa(hdr->min_se, p);
    p += printed;

    /* Print generic params */
    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return (int)printed;

    p += printed;
    return (int)(p - buf);
}
Example #8
0
static int replaces_hdr_print( pjsip_replaces_hdr *hdr, 
			       char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    int printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

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

    copy_advance(p, hdr->call_id);
    copy_advance_pair(p, ";to-tag=", 8, hdr->to_tag);
    copy_advance_pair(p, ";from-tag=", 10, hdr->from_tag);

    if (hdr->early_only) {
	const pj_str_t str_early_only = { ";early-only", 11 };
	copy_advance(p, str_early_only);
    }
    
    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return printed;

    p += printed;
    return p - buf;
}
Example #9
0
static void int_parse_hdr_authenticate( pj_scanner *scanner, pj_pool_t *pool, 
					pjsip_www_authenticate_hdr *hdr)
{
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    if (*scanner->curptr == '"') {
	pj_scan_get_quote(scanner, '"', '"', &hdr->scheme);
	hdr->scheme.ptr++;
	hdr->scheme.slen -= 2;
    } else {
	pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &hdr->scheme);
    }

    if (!pj_stricmp(&hdr->scheme, &pjsip_DIGEST_STR)) {

	parse_digest_challenge(scanner, pool, &hdr->challenge.digest);

    } else if (!pj_stricmp(&hdr->scheme, &pjsip_PGP_STR)) {

	parse_pgp_challenge(scanner, pool, &hdr->challenge.pgp);

    } else {
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
    }

    pjsip_parse_end_hdr_imp( scanner );
}
Example #10
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 #11
0
int pjsip_session_expires_hdr_print_on(void* h, char* buf, pj_size_t len)
{
  char* p = buf;
  const pjsip_session_expires_hdr* hdr = (pjsip_session_expires_hdr*)h;
  const pjsip_parser_const_t *pc = pjsip_parser_const();

  // As per pjsip_generic_int_hdr_print, integers are fewer then 15 characters long.
  if ((pj_ssize_t)len < hdr->name.slen + 15)
  {
    return -1;
  }

  pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
  p += hdr->name.slen;
  *p++ = ':';
  *p++ = ' ';
  p += pj_utoa(hdr->expires, p);

  if (hdr->refresher != SESSION_REFRESHER_UNKNOWN)
  {
    // Check the refresher parameter will fit.
    if (buf+len-p < 14)
    {
      return -1;
    }

    // Fill it in
    *p++ = ';';
    pj_memcpy(p, "refresher=", 10);
    p += 10;

    if (hdr->refresher == SESSION_REFRESHER_UAC)
    {
      pj_memcpy(p, "uac", 3);
    }
    else
    {
      pj_memcpy(p, "uas", 3);
    }
    p += 3;
  }

  // Try to add the other params.
  pj_ssize_t printed = pjsip_param_print_on(&hdr->other_param, p, buf+len-p,
                                            &pc->pjsip_TOKEN_SPEC,
                                            &pc->pjsip_TOKEN_SPEC, ';');
  if (printed < 0)
  {
    return -1;
  }
  p += printed;
  *p = '\0';

  return p - buf;
}
Example #12
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 #13
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 #14
0
/* Print tel: URI */
static pj_ssize_t tel_uri_print( pjsip_uri_context_e context,
				 const pjsip_tel_uri *uri, 
				 char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf+size-1;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    PJ_UNUSED_ARG(context);

    /* Print scheme. */
    copy_advance(buf, pc->pjsip_TEL_STR);
    *buf++ = ':';

    /* Print number. */
    copy_advance_escape(buf, uri->number, pjsip_TEL_NUMBER_SPEC);

    /* ISDN sub-address or extension must appear first. */

    /* Extension param. */
    copy_advance_pair_escape(buf, ";ext=", 5, uri->ext_param, 
			     pjsip_TEL_EXT_VALUE_SPEC);

    /* ISDN sub-address. */
    copy_advance_pair_escape(buf, ";isub=", 6, uri->isub_param, 
			     pjsip_TEL_URIC_SPEC);

    /* Followed by phone context, if present. */
    copy_advance_pair_escape(buf, ";phone-context=", 15, uri->context, 
			     pjsip_TEL_PHONE_CONTEXT_SPEC);


    /* Print other parameters. */
    printed = (int)pjsip_param_print_on(&uri->other_param, buf, (endbuf-buf), 
					&pjsip_TEL_PNAME_SPEC, 
					&pjsip_TEL_PVALUE_SPEC, ';');
    if (printed < 0)
	return -1;
    buf += printed;

    *buf = '\0';

    return (buf-startbuf);
}
Example #15
0
/*
 * Session-Expires header vptr.
 */
static int se_hdr_print(pjsip_sess_expires_hdr *hdr, 
			char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    pj_ssize_t printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();
    const pj_str_t *hname = pjsip_use_compact_form? &hdr->sname : &hdr->name;

    /* Print header name and value */
    if ((endbuf - p) < (hname->slen + 16))
	return -1;

    copy_advance(p, (*hname));
    *p++ = ':';
    *p++ = ' ';

    printed = pj_utoa(hdr->sess_expires, p);
    p += printed;

    /* Print 'refresher' param */
    if (hdr->refresher.slen)
    {
	if  ((endbuf - p) < (STR_REFRESHER.slen + 2 + hdr->refresher.slen))
	    return -1;

	*p++ = ';';
	copy_advance(p, STR_REFRESHER);
	*p++ = '=';
	copy_advance(p, hdr->refresher);
    }

    /* Print generic params */
    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return (int)printed;

    p += printed;
    return (int)(p - buf);
}
Example #16
0
static int pjsip_sub_state_hdr_print(pjsip_sub_state_hdr *hdr, 
				     char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    pj_ssize_t printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

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

    copy_advance_escape(p, hdr->sub_state, pc->pjsip_TOKEN_SPEC);
    copy_advance_pair_escape(p, ";reason=", 8, hdr->reason_param,
			     pc->pjsip_TOKEN_SPEC);
    if (hdr->expires_param >= 0) {
	pj_memcpy(p, ";expires=", 9);
	p += 9;
	printed = pj_utoa(hdr->expires_param, p);
	p += printed;
    }
    if (hdr->retry_after >= 0) {
	pj_memcpy(p, ";retry-after=", 13);
	p += 13;
	printed = pj_utoa(hdr->retry_after, p);
	p += printed;
    }
    
    printed = pjsip_param_print_on( &hdr->other_param, p, endbuf-p, 
				    &pc->pjsip_TOKEN_SPEC,
				    &pc->pjsip_TOKEN_SPEC,
				    ';');
    if (printed < 0)
	return (int)printed;

    p += printed;

    return (int)(p - buf);
}
Example #17
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 #18
0
static int pjsip_event_hdr_print( pjsip_event_hdr *hdr, 
				  char *buf, pj_size_t size)
{
    char *p = buf;
    char *endbuf = buf+size;
    pj_ssize_t printed;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

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

    copy_advance(p, hdr->event_type);
    copy_advance_pair(p, ";id=", 4, hdr->id_param);
    
    printed = pjsip_param_print_on(&hdr->other_param, p, endbuf-p,
				   &pc->pjsip_TOKEN_SPEC, 
				   &pc->pjsip_TOKEN_SPEC, ';');
    if (printed < 0)
	return (int)printed;

    p += printed;
    return (int)(p - buf);
}
Example #19
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 #20
0
static pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,
				    const pjsip_sip_uri *url, 
				    char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf+size;
    const pj_str_t *scheme;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    *buf = '\0';

    /* Print scheme ("sip:" or "sips:") */
    scheme = pjsip_uri_get_scheme(url);
    copy_advance_check(buf, *scheme);
    *buf++ = ':';

    /* Print "user:password@", if any. */
    if (url->user.slen) {
	copy_advance_escape(buf, url->user, pc->pjsip_USER_SPEC);
	if (url->passwd.slen) {
	    *buf++ = ':';
	    copy_advance_escape(buf, url->passwd, pc->pjsip_PASSWD_SPEC);
	}

	*buf++ = '@';
    }

    /* Print host. */
    pj_assert(url->host.slen != 0);
    /* Detect IPv6 IP address */
    if (pj_memchr(url->host.ptr, ':', url->host.slen)) {
	copy_advance_pair_quote_cond(buf, "", 0, url->host, '[', ']');
    } else {
	copy_advance_check(buf, url->host);
    }

    /* Only print port if it is explicitly specified. 
     * Port is not allowed in To and From header.
     */
    /* Unfortunately some UA requires us to send back the port
     * number exactly as it was sent. We don't remember whether an
     * UA has sent us port, so we'll just send the port indiscrimately
     */
    //PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)
    if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) {
	if (endbuf - buf < 10)
	    return -1;

	*buf++ = ':';
	printed = pj_utoa(url->port, buf);
	buf += printed;
    }

    /* User param is allowed in all contexes */
    copy_advance_pair_check(buf, ";user="******";method=", 8, url->method_param, 
				 pc->pjsip_PARAM_CHAR_SPEC);
    }

    /* Transport is not allowed in From/To header. */
    if (context != PJSIP_URI_IN_FROMTO_HDR) {
	copy_advance_pair_escape(buf, ";transport=", 11, url->transport_param,
				 pc->pjsip_PARAM_CHAR_SPEC);
    }

    /* TTL param is not allowed in From, To, Route, and Record-Route header. */
    if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&
	context != PJSIP_URI_IN_ROUTING_HDR) 
    {
	if (endbuf - buf < 15)
	    return -1;
	pj_memcpy(buf, ";ttl=", 5);
	printed = pj_utoa(url->ttl_param, buf+5);
	buf += printed + 5;
    }

    /* maddr param is not allowed in From and To header. */
    if (context != PJSIP_URI_IN_FROMTO_HDR && url->maddr_param.slen) {
	/* Detect IPv6 IP address */
	if (pj_memchr(url->maddr_param.ptr, ':', url->maddr_param.slen)) {
	    copy_advance_pair_quote_cond(buf, ";maddr=", 7, url->maddr_param,
				         '[', ']');
	} else {
	    copy_advance_pair_escape(buf, ";maddr=", 7, url->maddr_param,
				     pc->pjsip_PARAM_CHAR_SPEC);
	}
    }

    /* lr param is not allowed in From, To, and Contact header. */
    if (url->lr_param && context != PJSIP_URI_IN_FROMTO_HDR &&
	context != PJSIP_URI_IN_CONTACT_HDR) 
    {
	pj_str_t lr = { ";lr", 3 };
	if (endbuf - buf < 3)
	    return -1;
	copy_advance_check(buf, lr);
    }

    /* Other param. */
    printed = pjsip_param_print_on(&url->other_param, buf, endbuf-buf, 
				   &pc->pjsip_PARAM_CHAR_SPEC, 
				   &pc->pjsip_PARAM_CHAR_SPEC, ';');
    if (printed < 0)
	return -1;
    buf += printed;

    /* Header param. 
     * Header param is only allowed in these contexts:
     *	- PJSIP_URI_IN_CONTACT_HDR
     *	- PJSIP_URI_IN_OTHER
     */
    if (context == PJSIP_URI_IN_CONTACT_HDR || context == PJSIP_URI_IN_OTHER) {
	printed = pjsip_param_print_on(&url->header_param, buf, endbuf-buf,
				       &pc->pjsip_HDR_CHAR_SPEC, 
				       &pc->pjsip_HDR_CHAR_SPEC, '?');
	if (printed < 0)
	    return -1;
	buf += printed;
    }

    *buf = '\0';
    return buf-startbuf;
}
Example #21
0
static const pj_str_t *tel_uri_get_scheme( const pjsip_tel_uri *uri )
{
    PJ_UNUSED_ARG(uri);
    return &pjsip_parser_const()->pjsip_TEL_STR;
}
Example #22
0
int pjsip_p_c_f_a_hdr_print_on(void *h, char* buf, pj_size_t len)
{
  const pjsip_parser_const_t *pc = pjsip_parser_const();
  pjsip_p_c_f_a_hdr* hdr = (pjsip_p_c_f_a_hdr*)h;
  char* p = buf;

  // Check that at least the header name will fit.
  int needed = 0;
  needed += hdr->name.slen; // Header name
  needed += 2;              // : and space

  if (needed > (pj_ssize_t)len) {
    return -1;
  }

  // Now write the header name out.
  pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
  p += hdr->name.slen;
  *p++ = ':';
  *p++ = ' ';

  // Now try to write out the three parameter lists.  Annoyingly,
  // pjsip_param_print_on() will always print the separator before each
  // parameter, including the first parameter in this case.
  //
  // The P-Charging-Function-Addresses header has no body (technically
  // invalid SIP) and thus we need to print the first parameter without the
  // separator.  Since this first parameter could be in any of the parameter
  // lists, we have to track (with the found_first_param flag) when we've
  // handled it.
  bool found_first_param = false;
  int printed;

  pjsip_param* param_list = NULL;
  for (int i = 0; i < 3; i++) {
    switch (i) {
      case 0:
        param_list = &hdr->ccf;
        break;
      case 1:
        param_list = &hdr->ecf;
        break;
      case 2:
        param_list = &hdr->other_param;
        break;
    }

    if (pj_list_empty(param_list)) {
      continue; // LCOV_EXCL_LINE
    }

    if (found_first_param) {
      // Simply write out the parameters
      printed = pjsip_param_print_on(param_list, p, buf+len-p,
                                     &pc->pjsip_TOKEN_SPEC,
                                     &pc->pjsip_TOKEN_SPEC, ';');
      if (printed < 0) {
        return -1;
      }
      p += printed;
    } else {
      // We print the first parameter manually then print the rest.
      pjsip_param* first_param = param_list->next;
      pj_list_erase(first_param);

      // Check we have space for the first param before printing it out.
      needed = pj_strlen(&first_param->name);
      if (first_param->value.slen) {
        needed += 1 + pj_strlen(&first_param->value);
      }
      if (needed > buf+len-p) {
        pj_list_insert_after(param_list, first_param);
        return -1;
      }

      pj_memcpy(p, first_param->name.ptr, first_param->name.slen);
      p += first_param->name.slen;
      if (first_param->value.slen) {
        *p++ = '=';
        pj_memcpy(p, first_param->value.ptr, first_param->value.slen);
        p += first_param->value.slen;
      }

      // Now print the rest of this parameter list (may be empty).
      printed = pjsip_param_print_on(param_list, p, buf+len-p,
                                     &pc->pjsip_TOKEN_SPEC,
                                     &pc->pjsip_TOKEN_SPEC, ';');
      if (printed < 0) {
        pj_list_insert_after(param_list, first_param);
        return -1;
      }
      p += printed;

      // Finally, restore the first param to the head of the parameter list.
      pj_list_insert_after(param_list, first_param);

      // We've found the first parameter, everything else is simple.
      found_first_param = true;
    }
  }

  *p = '\0';

  return p - buf;
}
Example #23
0
int pjsip_p_c_v_hdr_print_on(void* h, char* buf, pj_size_t len)
{
  const pjsip_parser_const_t *pc = pjsip_parser_const();
  pjsip_p_c_v_hdr* hdr = (pjsip_p_c_v_hdr*)h;
  char* p = buf;

  // Check the fixed parts of the header will fit.
  int needed = 0;
  needed += hdr->name.slen; // Header name
  needed += 2;              // : and space
  needed += 11;             // icid-value=
  needed += 2;              // Quote the icid-value
  needed += hdr->icid.slen; // <icid>
  needed += 1;              // ;
  if (hdr->orig_ioi.slen) {
    needed += 9;              // orig-ioi=
    needed += hdr->orig_ioi.slen; // <orig-ioi>
    needed += 1;              // ;
  }
  if (hdr->term_ioi.slen) {
    needed += 9;              // term-ioi=
    needed += hdr->term_ioi.slen; // <term-ioi>
    needed += 1;              // ;
  }
  if (hdr->icid_gen_addr.slen) {
    needed += 18;              // icid-generated-at=
    needed += hdr->icid_gen_addr.slen; // <icid-generated-at>
  }

  if (needed > (pj_ssize_t)len) {
    return -1;
  }

  // Now write the fixed header out.
  pj_memcpy(p, hdr->name.ptr, hdr->name.slen);
  p += hdr->name.slen;
  *p++ = ':';
  *p++ = ' ';
  pj_memcpy(p, "icid-value=", 11);
  p += 11;
  *p++ = '"';
  pj_memcpy(p, hdr->icid.ptr, hdr->icid.slen);
  p += hdr->icid.slen;
  *p++ = '"';
  if (hdr->orig_ioi.slen) {
    *p++ = ';';
    pj_memcpy(p, "orig-ioi=", 9);
    p += 9;
    pj_memcpy(p, hdr->orig_ioi.ptr, hdr->orig_ioi.slen);
    p += hdr->orig_ioi.slen;
  }
  if (hdr->term_ioi.slen) {
    *p++ = ';';
    pj_memcpy(p, "term-ioi=", 9);
    p += 9;
    pj_memcpy(p, hdr->term_ioi.ptr, hdr->term_ioi.slen);
    p += hdr->term_ioi.slen;
  }
  if (hdr->icid_gen_addr.slen) {
    *p++ = ';';
    pj_memcpy(p, "icid-generated-at=", 18);
    p += 18;
    pj_memcpy(p, hdr->icid_gen_addr.ptr, hdr->icid_gen_addr.slen);
    p += hdr->icid_gen_addr.slen;
  }

  // Attempt to write out the other params.
  pj_ssize_t printed = pjsip_param_print_on(&hdr->other_param, p, buf+len-p,
                                            &pc->pjsip_TOKEN_SPEC,
                                            &pc->pjsip_TOKEN_SPEC, ';');
  if (printed < 0) {
    return -1;
  }
  p += printed;
  *p = '\0';

  return p - buf;
}
Example #24
0
/* Parse tel: URI 
 * THis actually returns (pjsip_tel_uri *) type.
 */
static void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,
			    pj_bool_t parse_params)
{
    pjsip_tel_uri *uri;
    pj_str_t token;
    int skip_ws = scanner->skip_ws;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    scanner->skip_ws = 0;

    /* Parse scheme. */
    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &token);
    if (pj_scan_get_char(scanner) != ':')
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
    if (pj_stricmp_alnum(&token, &pc->pjsip_TEL_STR) != 0)
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);

    /* Create URI */
    uri = pjsip_tel_uri_create(pool);

    /* Get the phone number. */
#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
    pj_scan_get_unescape(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
#else
    pj_scan_get(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
    uri->number = pj_str_unescape(pool, &uri->number);
#endif

    /* Get all parameters. */
    if (parse_params && *scanner->curptr==';') {
	pj_str_t pname, pvalue;
	const pjsip_parser_const_t *pc = pjsip_parser_const();

	do {
	    /* Eat the ';' separator. */
	    pj_scan_get_char(scanner);

	    /* Get pname. */
	    pj_scan_get(scanner, &pc->pjsip_PARAM_CHAR_SPEC, &pname);

	    if (*scanner->curptr == '=') {
		pj_scan_get_char(scanner);

#		if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
		    pj_scan_get_unescape(scanner, 
					 &pjsip_TEL_PARSING_PVALUE_SPEC_ESC,
					 &pvalue);
#		else
		    pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC, 
				&pvalue);
		    pvalue = pj_str_unescape(pool, &pvalue);
#		endif

	    } else {
		pvalue.slen = 0;
		pvalue.ptr = NULL;
	    }

	    /* Save the parameters. */
	    if (pj_stricmp_alnum(&pname, &pjsip_ISUB_STR)==0) {
		uri->isub_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_EXT_STR)==0) {
		uri->ext_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_PH_CTX_STR)==0) {
		uri->context = pvalue;
	    } else {
		pjsip_param *param = PJ_POOL_ALLOC_T(pool, pjsip_param);
		param->name = pname;
		param->value = pvalue;
		pj_list_insert_before(&uri->other_param, param);
	    }

	} while (*scanner->curptr==';');
    }

    scanner->skip_ws = skip_ws;
    pj_scan_skip_whitespace(scanner);
    return uri;
}
Example #25
0
static pj_ssize_t pjsip_url_print(  pjsip_uri_context_e context,
                                    const pjsip_sip_uri *url,
                                    char *buf, pj_size_t size)
{
    int printed;
    char *startbuf = buf;
    char *endbuf = buf+size;
    const pj_str_t *scheme;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    *buf = '\0';

    /* Print scheme ("sip:" or "sips:") */
    scheme = pjsip_uri_get_scheme(url);
    copy_advance_check(buf, *scheme);
    *buf++ = ':';

    /* Print "user:password@", if any. */
    if (url->user.slen) {
        copy_advance_escape(buf, url->user, pc->pjsip_USER_SPEC);
        if (url->passwd.slen) {
            *buf++ = ':';
            copy_advance_escape(buf, url->passwd, pc->pjsip_PASSWD_SPEC);
        }

        *buf++ = '@';
    }

    /* Print host. */
    pj_assert(url->host.slen != 0);
    /* Detect IPv6 IP address */
    if (pj_memchr(url->host.ptr, ':', url->host.slen)) {
        copy_advance_pair_quote_cond(buf, "", 0, url->host, '[', ']');
    } else {
        copy_advance_check(buf, url->host);
    }

    /* Only print port if it is explicitly specified.
     * Port is not allowed in To and From header, see Table 1 in
     * RFC 3261 Section 19.1.1
     */
    /* Note: ticket #1141 adds run-time setting to allow port number to
     * appear in From/To header. Default is still false.
     */
    if (url->port &&
            (context != PJSIP_URI_IN_FROMTO_HDR ||
             pjsip_cfg()->endpt.allow_port_in_fromto_hdr))
    {
        if (endbuf - buf < 10)
            return -1;

        *buf++ = ':';
        printed = pj_utoa(url->port, buf);
        buf += printed;
    }

    /* User param is allowed in all contexes */
    copy_advance_pair_check(buf, ";user="******";method=", 8, url->method_param,
                                 pc->pjsip_PARAM_CHAR_SPEC);
    }

    /* Transport is not allowed in From/To header. */
    if (context != PJSIP_URI_IN_FROMTO_HDR) {
        copy_advance_pair_escape(buf, ";transport=", 11, url->transport_param,
                                 pc->pjsip_PARAM_CHAR_SPEC);
    }

    /* TTL param is not allowed in From, To, Route, and Record-Route header. */
    if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&
            context != PJSIP_URI_IN_ROUTING_HDR)
    {
        if (endbuf - buf < 15)
            return -1;
        pj_memcpy(buf, ";ttl=", 5);
        printed = pj_utoa(url->ttl_param, buf+5);
        buf += printed + 5;
    }

    /* maddr param is not allowed in From and To header. */
    if (context != PJSIP_URI_IN_FROMTO_HDR && url->maddr_param.slen) {
        /* Detect IPv6 IP address */
        if (pj_memchr(url->maddr_param.ptr, ':', url->maddr_param.slen)) {
            copy_advance_pair_quote_cond(buf, ";maddr=", 7, url->maddr_param,
                                         '[', ']');
        } else {
            copy_advance_pair_escape(buf, ";maddr=", 7, url->maddr_param,
                                     pc->pjsip_PARAM_CHAR_SPEC);
        }
    }

    /* lr param is not allowed in From, To, and Contact header. */
    if (url->lr_param && context != PJSIP_URI_IN_FROMTO_HDR &&
            context != PJSIP_URI_IN_CONTACT_HDR)
    {
        pj_str_t lr = { ";lr", 3 };
        if (endbuf - buf < 3)
            return -1;
        copy_advance_check(buf, lr);
    }

    /* Other param. */
    printed = pjsip_param_print_on(&url->other_param, buf, endbuf-buf,
                                   &pc->pjsip_PARAM_CHAR_SPEC,
                                   &pc->pjsip_PARAM_CHAR_SPEC, ';');
    if (printed < 0)
        return -1;
    buf += printed;

    /* Header param.
     * Header param is only allowed in these contexts:
     *	- PJSIP_URI_IN_CONTACT_HDR
     *	- PJSIP_URI_IN_OTHER
     */
    if (context == PJSIP_URI_IN_CONTACT_HDR || context == PJSIP_URI_IN_OTHER) {
        printed = pjsip_param_print_on(&url->header_param, buf, endbuf-buf,
                                       &pc->pjsip_HDR_CHAR_SPEC,
                                       &pc->pjsip_HDR_CHAR_SPEC, '?');
        if (printed < 0)
            return -1;
        buf += printed;
    }

    *buf = '\0';
    return buf-startbuf;
}