在 SIP 中,用户 URI 描述是最基本的一项信息,也有相应的格式,先看看这个是怎样解析的吧。
实际上在好的工程下面都有完备的单元测试代码,同样在 PJSIP 中也是能找到相关的测试代码,我们可以打开 pjproject-1.10\pjsip\src\test\uri_test.c
在代码中举例出不下 38 种 URI 格式,用以程序分析,可见仅仅一个字符串解析,这个工程也是做的相当严谨。
在本工程中可以有如下收获,对以后的分析也是很重要的。
测试框架
为了让测试更加简单,更加有效,PJSIP中使用了一个很好的测试框架。本测试的入口函数是 uri_test 是为 test.c 中调用
在 test.c 中使用了宏 DO_TEST 简单封装了一个测试接口。并通过测试接口的反回值进行测试正确性验证。
在本测试中使用了查表法进行测试用例的扩充。
在测试后还进行了简单的统计。
最后输入出信息是以 HTML 格式输出,更容易查阅。
查表法用例
查表法的使用,更方便测试用例的扩充。
与平台无关性编程
以 PJLIB 为基础,进行了平台无关性编程,能够让测试在不同平台上有效快速的运行。
pjsip_sip_uri 格式
通过不同的测试用例,也学到了最为关键的 pjsip_sip_uri 结构体的格式。
/**
* SIP and SIPS URL scheme.
*/
typedef struct pjsip_sip_uri
{
pjsip_uri_vptr *vptr; /**< Pointer to virtual function table.*/
pj_str_t user; /**< Optional user part. */
pj_str_t passwd; /**< Optional password part. */
pj_str_t host; /**< Host part, always exists. */
int port; /**< Optional port number, or zero. */
pj_str_t user_param; /**< Optional user parameter */
pj_str_t method_param; /**< Optional method parameter. */
pj_str_t transport_param; /**< Optional transport parameter. */
int ttl_param; /**< Optional TTL param, or -1. */
int lr_param; /**< Optional loose routing param, or zero */
pj_str_t maddr_param; /**< Optional maddr param */
pjsip_param other_param; /**< Other parameters grouped together. */
pjsip_param header_param; /**< Optional header parameter. */
} pjsip_sip_uri;
注释写的很清楚,但是还是要说一下,并且拿出代码中测试的最长的一个 URI 来对照
sip:user:password@localhost:5060;transport=tcp;user=ip;ttl=255;lr=1;maddr=127.0.0.1;method=ACK;pickup=hurry;message=I%20am%20sorry?Subject=Hello%20There&Server=SIP%20Server
user | user |
passwd | password |
host | localhost |
port | 5060 |
user_param | ip |
method_param | ACK |
transport_param | tcp |
ttl_param | 255 |
lr_param | 1 |
maddr_param | 127.0.0.1 |
other_param | pickup, message |
header_param | Subject, Server |
由此可见一些规律
- sip: 打头
- 用分号进行分割
- 除第一段后每段都可以用 key=value 的样式进行填充
- 有些 key 是固定的,其它的 key 可以扩展,会放到 other_param 中
- 最后可以带 ? 附加更多的信息,此信息会放到 header_param 中
相信我们知道了这些,这个 URI 的分析也就很清楚了,同进更明白 SIP 中的 URI 可以如何的扩充自己的参数。
最后留下一个疑问?
他的结构体中第一行 pjsip_uri_vptr *vptr; /**< Pointer to virtual function table.*/ 是用来做什么呢, 后面分析!