コード例 #1
0
ファイル: custom_headers.cpp プロジェクト: jmmL/sprout
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;
}
コード例 #2
0
ファイル: custom_headers.cpp プロジェクト: jmmL/sprout
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;
}
コード例 #3
0
ファイル: sip_auth_parser.c プロジェクト: max3903/SFLphone
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;
    }
}
コード例 #4
0
ファイル: sdp.c プロジェクト: AGProjects/python-sipsimple
PJ_DEF(pj_status_t) pjmedia_sdp_attr_get_rtcp(const pjmedia_sdp_attr *attr,
					      pjmedia_sdp_rtcp_attr *rtcp)
{
    pj_scanner scanner;
    pj_str_t token;
    pj_status_t status = -1;
    PJ_USE_EXCEPTION;

    PJ_ASSERT_RETURN(pj_strcmp2(&attr->name, "rtcp")==0, PJ_EINVALIDOP);

    init_sdp_parser();

    /* fmtp BNF:
     *	a=rtcp:<port> [nettype addrtype address]
     */

    pj_scan_init(&scanner, (char*)attr->value.ptr, attr->value.slen,
		 PJ_SCAN_AUTOSKIP_WS, &on_scanner_error);

    /* Init */
    rtcp->net_type.slen = rtcp->addr_type.slen = rtcp->addr.slen = 0;

    /* Parse */
    PJ_TRY {

	/* Get the port */
	pj_scan_get(&scanner, &cs_token, &token);
	rtcp->port = pj_strtoul(&token);

	/* Have address? */
	if (!pj_scan_is_eof(&scanner)) {

	    /* Get network type */
	    pj_scan_get(&scanner, &cs_token, &rtcp->net_type);

	    /* Get address type */
	    pj_scan_get(&scanner, &cs_token, &rtcp->addr_type);

	    /* Get the address */
	    pj_scan_get(&scanner, &cs_token, &rtcp->addr);

	}

	status = PJ_SUCCESS;

    }
    PJ_CATCH_ANY {
	status = PJMEDIA_SDP_EINRTCP;
    }
    PJ_END;

    pj_scan_fini(&scanner);
    return status;
}
コード例 #5
0
ファイル: sip_auth_parser.c プロジェクト: max3903/SFLphone
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;
    }
}
コード例 #6
0
ファイル: custom_headers.cpp プロジェクト: jmmL/sprout
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;
}
コード例 #7
0
ファイル: xml.c プロジェクト: vinc6nt/p2pnt
/* This is a recursive function! */
static pj_xml_node *xml_parse_node( pj_pool_t *pool, pj_scanner *scanner)
{
    pj_xml_node *node;
    pj_str_t end_name;

    PJ_CHECK_STACK();

    if (*scanner->curptr != '<')
	on_syntax_error(scanner);

    /* Handle Processing Instructino (PI) construct (i.e. "<?") */
    if (*scanner->curptr == '<' && *(scanner->curptr+1) == '?') {
	pj_scan_advance_n(scanner, 2, PJ_FALSE);
	for (;;) {
	    pj_str_t dummy;
	    pj_scan_get_until_ch(scanner, '?', &dummy);
	    if (*scanner->curptr=='?' && *(scanner->curptr+1)=='>') {
		pj_scan_advance_n(scanner, 2, PJ_TRUE);
		break;
	    } else {
		pj_scan_advance_n(scanner, 1, PJ_FALSE);
	    }
	}
	return xml_parse_node(pool, scanner);
    }

    /* Handle comments construct (i.e. "<!") */
    if (pj_scan_strcmp(scanner, "<!", 2) == 0) {
	pj_scan_advance_n(scanner, 2, PJ_FALSE);
	for (;;) {
	    pj_str_t dummy;
	    pj_scan_get_until_ch(scanner, '>', &dummy);
	    if (pj_scan_strcmp(scanner, ">", 1) == 0) {
		pj_scan_advance_n(scanner, 1, PJ_TRUE);
		break;
	    } else {
		pj_scan_advance_n(scanner, 1, PJ_FALSE);
	    }
	}
	return xml_parse_node(pool, scanner);
    }

    /* Alloc node. */
    node = alloc_node(pool);

    /* Get '<' */
    pj_scan_get_char(scanner);

    /* Get node name. */
    pj_scan_get_until_chr( scanner, " />\t", &node->name);

    /* Get attributes. */
    while (*scanner->curptr != '>' && *scanner->curptr != '/') {
	pj_xml_attr *attr = alloc_attr(pool);
	
	pj_scan_get_until_chr( scanner, "=> \t", &attr->name);
	if (*scanner->curptr == '=') {
	    pj_scan_get_char( scanner );
            pj_scan_get_quotes(scanner, "\"'", "\"'", 2, &attr->value);
	    /* remove quote characters */
	    ++attr->value.ptr;
	    attr->value.slen -= 2;
	}
	
	pj_list_push_back( &node->attr_head, attr );
    }

    if (*scanner->curptr == '/') {
	pj_scan_get_char(scanner);
	if (pj_scan_get_char(scanner) != '>')
	    on_syntax_error(scanner);
	return node;
    }

    /* Enclosing bracket. */
    if (pj_scan_get_char(scanner) != '>')
	on_syntax_error(scanner);

    /* Sub nodes. */
    while (*scanner->curptr == '<' && *(scanner->curptr+1) != '/') {
	pj_xml_node *sub_node = xml_parse_node(pool, scanner);
	pj_list_push_back( &node->node_head, sub_node );
    }

    /* Content. */
    if (!pj_scan_is_eof(scanner) && *scanner->curptr != '<') {
	pj_scan_get_until_ch(scanner, '<', &node->content);
    }

    /* Enclosing node. */
    if (pj_scan_get_char(scanner) != '<' || pj_scan_get_char(scanner) != '/')
	on_syntax_error(scanner);

    pj_scan_get_until_chr(scanner, " \t>", &end_name);

    /* Compare name. */
    if (pj_stricmp(&node->name, &end_name) != 0)
	on_syntax_error(scanner);

    /* Enclosing '>' */
    if (pj_scan_get_char(scanner) != '>')
	on_syntax_error(scanner);

    return node;
}
コード例 #8
0
ファイル: sdp.c プロジェクト: tibastral/symphonie
/*
 * Parse SDP message.
 */
PJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,
				       char *buf, pj_size_t len, 
				       pjmedia_sdp_session **p_sdp)
{
    pj_scanner scanner;
    pjmedia_sdp_session *session;
    pjmedia_sdp_media *media = NULL;
    void *attr;
    pjmedia_sdp_conn *conn;
    pj_str_t dummy;
    int cur_name = 254;
    parse_context ctx;
    PJ_USE_EXCEPTION;

    ctx.last_error = PJ_SUCCESS;

    init_sdp_parser();

    pj_scan_init(&scanner, buf, len, 0, &on_scanner_error);
    session = pj_pool_calloc(pool, 1, sizeof(pjmedia_sdp_session));
    PJ_ASSERT_RETURN(session != NULL, PJ_ENOMEM);

    PJ_TRY {
	while (!pj_scan_is_eof(&scanner)) {
		cur_name = *scanner.curptr;
		switch (cur_name) {
		case 'a':
		    attr = parse_attr(pool, &scanner, &ctx);
		    if (attr) {
			if (media) {
			    media->attr[media->attr_count++] = attr;
			} else {
			    session->attr[session->attr_count++] = attr;
			}
		    }
		    break;
		case 'o':
		    parse_origin(&scanner, session, &ctx);
		    break;
		case 's':
		    parse_generic_line(&scanner, &session->name, &ctx);
		    break;
		case 'c':
		    conn = pj_pool_calloc(pool, 1, sizeof(*conn));
		    parse_connection_info(&scanner, conn, &ctx);
		    if (media) {
			media->conn = conn;
		    } else {
			session->conn = conn;
		    }
		    break;
		case 't':
		    parse_time(&scanner, session, &ctx);
		    break;
		case 'm':
		    media = pj_pool_calloc(pool, 1, sizeof(*media));
		    parse_media(&scanner, media, &ctx);
		    session->media[ session->media_count++ ] = media;
		    break;
		case 'v':
		    parse_version(&scanner, &ctx);
		    break;
		case 13:
		    /* Allow empty newline at the end of the message */
		    pj_scan_get_char(&scanner);
		    /* Continue below */
		case 10:
		    pj_scan_get_char(&scanner);
		    if (!pj_scan_is_eof(&scanner)) {
			on_scanner_error(&scanner);
		    }
		    break;
		default:
		    if (cur_name >= 'a' && cur_name <= 'z')
			parse_generic_line(&scanner, &dummy, &ctx);
		    else  {
			ctx.last_error = PJMEDIA_SDP_EINSDP;
			on_scanner_error(&scanner);
		    }
		    break;
		}
	}

	ctx.last_error = PJ_SUCCESS;

    }
    PJ_CATCH(SYNTAX_ERROR) {
	
	char errmsg[PJ_ERR_MSG_SIZE];
	pj_strerror(ctx.last_error, errmsg, sizeof(errmsg));

	PJ_LOG(4, (THIS_FILE, "Error parsing SDP in line %d col %d: %s",
		   scanner.line, pj_scan_get_col(&scanner),
		   errmsg));

	session = NULL;

	pj_assert(ctx.last_error != PJ_SUCCESS);
    }
    PJ_END;

    pj_scan_fini(&scanner);

    *p_sdp = session;
    return ctx.last_error;
}
コード例 #9
0
ファイル: cli.c プロジェクト: ClearwaterCore/pjsip-upstream
/**
 * This method is to parse and add the command attribute to command structure.
 **/
static pj_status_t add_cmd_node(pj_cli_t *cli,				  
				pj_cli_cmd_spec *group,					 
				pj_xml_node *xml_node,
				pj_cli_cmd_handler handler,
				pj_cli_cmd_spec **p_cmd,
				pj_cli_get_dyn_choice get_choice)
{
    pj_xml_node *root = xml_node;
    pj_xml_attr *attr;
    pj_xml_node *sub_node;
    pj_cli_cmd_spec *cmd;
    pj_cli_arg_spec args[PJ_CLI_MAX_ARGS];
    pj_str_t sc[PJ_CLI_MAX_SHORTCUTS];
    pj_status_t status = PJ_SUCCESS;

    if (pj_stricmp2(&root->name, "CMD"))
        return PJ_EINVAL;

    /* Initialize the command spec */
    cmd = PJ_POOL_ZALLOC_T(cli->pool, struct pj_cli_cmd_spec);
    
    /* Get the command attributes */
    attr = root->attr_head.next;
    while (attr != &root->attr_head) {
        if (!pj_stricmp2(&attr->name, "name")) {
            pj_strltrim(&attr->value);
            if (!attr->value.slen || 
		cmd_name_exists(cli, group, &attr->value))                
            {
                return PJ_CLI_EBADNAME;
            }
            pj_strdup(cli->pool, &cmd->name, &attr->value);
        } else if (!pj_stricmp2(&attr->name, "id")) {	    
	    pj_bool_t is_valid = PJ_FALSE;
            if (attr->value.slen) {		
		pj_cli_cmd_id cmd_id = pj_strtol(&attr->value);
		if (!pj_hash_get(cli->cmd_id_hash, &cmd_id, 
		                 sizeof(pj_cli_cmd_id), NULL))
		    is_valid = PJ_TRUE;
	    } 
	    if (!is_valid)
		return PJ_CLI_EBADID;
            cmd->id = (pj_cli_cmd_id)pj_strtol(&attr->value);
        } else if (!pj_stricmp2(&attr->name, "sc")) {
            pj_scanner scanner;
            pj_str_t str;

            PJ_USE_EXCEPTION;

            pj_scan_init(&scanner, attr->value.ptr, attr->value.slen,
                         PJ_SCAN_AUTOSKIP_WS, &on_syntax_error);

            PJ_TRY {
                while (!pj_scan_is_eof(&scanner)) {
                    pj_scan_get_until_ch(&scanner, ',', &str);
                    pj_strrtrim(&str);
                    if (!pj_scan_is_eof(&scanner))
                        pj_scan_advance_n(&scanner, 1, PJ_TRUE);
                    if (!str.slen)
                        continue;

                    if (cmd->sc_cnt >= PJ_CLI_MAX_SHORTCUTS) {
                        PJ_THROW(PJ_CLI_ETOOMANYARGS);
                    }
                    /* Check whether the shortcuts are already used */
                    if (cmd_name_exists(cli, group, &str)) {
                        PJ_THROW(PJ_CLI_EBADNAME);
                    }

                    pj_strassign(&sc[cmd->sc_cnt++], &str);
                }
            }
            PJ_CATCH_ANY {
                pj_scan_fini(&scanner);
                return (PJ_GET_EXCEPTION());
            }
            PJ_END;
            
        } else if (!pj_stricmp2(&attr->name, "desc")) {
コード例 #10
0
ファイル: sdp.c プロジェクト: AGProjects/python-sipsimple
/*
 * Parse SDP message.
 */
PJ_DEF(pj_status_t) pjmedia_sdp_parse( pj_pool_t *pool,
				       char *buf, pj_size_t len, 
				       pjmedia_sdp_session **p_sdp)
{
    pj_scanner scanner;
    pjmedia_sdp_session *session;
    pjmedia_sdp_media *media = NULL;
    pjmedia_sdp_attr *attr;
    pjmedia_sdp_conn *conn;
    pjmedia_sdp_bandw *bandw;
    pj_str_t dummy;
    int cur_name = 254;
    parse_context ctx;
    PJ_USE_EXCEPTION;

    ctx.last_error = PJ_SUCCESS;

    init_sdp_parser();

    pj_scan_init(&scanner, buf, len, 0, &on_scanner_error);
    session = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_session);
    PJ_ASSERT_RETURN(session != NULL, PJ_ENOMEM);

    /* Ignore leading newlines */
    while (*scanner.curptr=='\r' || *scanner.curptr=='\n')
	pj_scan_get_char(&scanner);

    PJ_TRY {
	while (!pj_scan_is_eof(&scanner)) {
		cur_name = *scanner.curptr;
		switch (cur_name) {
		case 'a':
		    attr = parse_attr(pool, &scanner, &ctx);
		    if (attr) {
			if (media) {
			    if (media->attr_count < PJMEDIA_MAX_SDP_ATTR)
				pjmedia_sdp_media_add_attr(media, attr);
			    else
				PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,
					      "Error adding media attribute, "
					      "attribute is ignored"));
			} else {
			    if (session->attr_count < PJMEDIA_MAX_SDP_ATTR)
				pjmedia_sdp_session_add_attr(session, attr);
			    else
				PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,
					      "Error adding session attribute"
					      ", attribute is ignored"));
			}
		    }
		    break;
		case 'o':
		    parse_origin(&scanner, session, &ctx);
		    break;
		case 's':
		    parse_generic_line(&scanner, &session->name, &ctx);
		    break;
		case 'c':
		    conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn);
		    parse_connection_info(&scanner, conn, &ctx);
		    if (media) {
			media->conn = conn;
		    } else {
			session->conn = conn;
		    }
		    break;
		case 't':
		    parse_time(&scanner, session, &ctx);
		    break;
		case 'm':
		    media = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_media);
		    parse_media(&scanner, media, &ctx);
		    if (session->media_count < PJMEDIA_MAX_SDP_MEDIA)
			session->media[ session->media_count++ ] = media;
		    else
			PJ_PERROR(2,(THIS_FILE, PJ_ETOOMANY,
				     "Error adding media, media is ignored"));
		    break;
		case 'v':
		    parse_version(&scanner, &ctx);
		    break;
		case 13:
		case 10:
		    pj_scan_get_char(&scanner);
		    /* Allow empty newlines at the end of the message */
		    while (!pj_scan_is_eof(&scanner)) {
			if (*scanner.curptr != 13 && *scanner.curptr != 10) {
			    ctx.last_error = PJMEDIA_SDP_EINSDP;
			    on_scanner_error(&scanner);
			}
			pj_scan_get_char(&scanner);
		    }
		    break;
		case 'b':
		    bandw = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_bandw);
		    parse_bandwidth_info(&scanner, bandw, &ctx);
		    if (media) {
			if (media->bandw_count < PJMEDIA_MAX_SDP_BANDW)
			    media->bandw[media->bandw_count++] = bandw;
			else
			    PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,
					  "Error adding media bandwidth "
					  "info, info is ignored"));
		    } else {
			if (session->bandw_count < PJMEDIA_MAX_SDP_BANDW)
			    session->bandw[session->bandw_count++] = bandw;
			else
			    PJ_PERROR(2, (THIS_FILE, PJ_ETOOMANY,
					  "Error adding session bandwidth "
					  "info, info is ignored"));
		    }
		    break;
		default:
		    if (cur_name >= 'a' && cur_name <= 'z')
			parse_generic_line(&scanner, &dummy, &ctx);
		    else  {
			ctx.last_error = PJMEDIA_SDP_EINSDP;
			on_scanner_error(&scanner);
		    }
		    break;
		}
	}

	ctx.last_error = PJ_SUCCESS;

    }
    PJ_CATCH_ANY {
	
	char errmsg[PJ_ERR_MSG_SIZE];
	pj_strerror(ctx.last_error, errmsg, sizeof(errmsg));

	PJ_LOG(4, (THIS_FILE, "Error parsing SDP in line %d col %d: %s",
		   scanner.line, pj_scan_get_col(&scanner),
		   errmsg));

	session = NULL;

	pj_assert(ctx.last_error != PJ_SUCCESS);
    }
    PJ_END;

    pj_scan_fini(&scanner);

    if (session)
	apply_media_direction(session);

    *p_sdp = session;
    return ctx.last_error;
}
コード例 #11
0
ファイル: scanner.hpp プロジェクト: max3903/SFLphone
    int eof() const
    {
	return pj_scan_is_eof(&scanner_);
    }