1、新建项目 -> 在 "pjproject-2.8" 根目录同级;
2、附加包含目录 "../../pjproject-2.8/pjsip/include/;../../pjproject-2.8/pjlib/include/;../../pjproject-2.8/pjlib-util/include/;../../pjproject-2.8/pjnath/include/"
3、链接器 -> 附加库目录 "../../pjproject-2.8/lib/;../../pjproject-2.8/pjlib/lib/;../../pjproject-2.8/pjlib-util/lib/;../../pjproject-2.8/pjsip/lib/;../../pjproject-2.8/pjnath/lib/"
4、链接器 -> 输入 -> 附加依赖项 " ws2_32.lib;pjlib-i386-Win32-vc14-Debug.lib;pjlib-util-i386-Win32-vc14-Debug.lib;pjnath-i386-Win32-vc14-Debug.lib;pjsip-core-i386-Win32-vc14-Debug.lib;"
5、wireshark抓包: 能看到SIP发送数据,SIP属于OSI的应用层,要求对端能够连接才能看到本条协议数据
6、PJSIP流程:
PJLIB-UTIL初始化 ---> 创建 pool factory ---> 创建SIP endpoint ---> 创建SIP transport ---> 发送短信
7、主要代码说明:
初始化发送内容
status = pjsip_endpt_create_request(sip_endptLocal, &method, &str_target, &str_from, &str_to, &str_from, NULL, -1, &body, &tdata);
if (status != PJ_SUCCESS) {
return status;
}
发送内容
status = pjsip_endpt_send_request_stateless(sip_endptLocal, tdata, "", NULL);
if (status != PJ_SUCCESS) {
return status;
}
8、代码示例
#include "stdafx.h"
#include <pjsip.h>
#include <pjlib-util.h>
#include <pjlib.h>
/* If this macro is set, UDP transport will be initialized at port 5060 */
#define HAS_UDP_TRANSPORT
/* If this macro is set, TCP transport will be initialized at port 5060 */
#define HAS_TCP_TRANSPORT (1 && PJ_HAS_TCP)
/* Log identification */
#define THIS_FILE "sipstateless.c"
/* Global SIP endpoint */
static pjsip_endpoint *sip_endptLocal;
/* What response code to be sent (default is 501/Not Implemented) */
static int code = PJSIP_SC_NOT_IMPLEMENTED;
/* Additional header list */
struct pjsip_hdr hdr_list;
/* usage() */
static void usage(void)
{
puts("Usage:");
puts(" sipstateless [code] [-H HDR] ..");
puts("");
puts("Options:");
puts(" code SIP status code to send (default: 501/Not Implemented");
puts(" -H HDR Specify additional headers to send with response");
puts(" This option may be specified more than once.");
puts(" Example:");
puts(" -H 'Expires: 300' -H 'Contact: <sip:localhost>'");
}
/* Callback to handle incoming requests. */
static pj_bool_t on_rx_request(pjsip_rx_data *rdata)
{
/* Respond (statelessly) all incoming requests (except ACK!)
* with 501 (Not Implemented)
*/
if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD)
{
pjsip_endpt_respond_stateless(sip_endptLocal, rdata, code, NULL, &hdr_list, NULL);
}
return PJ_TRUE;
}
/* Send one stateless request */
static pj_status_t submit_stateless_job(void)
{
pjsip_tx_data *tdata;
pj_status_t status = 0;
pjsip_method method = { PJSIP_OTHER_METHOD,{ "MESSAGE", 7 } };
pj_str_t str_target = pj_str("sip:110@192.168.1.238");
pj_str_t str_from = pj_str("\"Local User\" <sip:sip:110@192.168.1.62>");
pj_str_t str_to = pj_str("\"Remote User\" <sip:sip:110@192.168.1.238:5060>");
pj_str_t str_contact = str_from;
/*status = pjsip_endpt_create_request(sip_endptLocal, &method,
&app.client.dst_uri, &app.local_uri,
&app.client.dst_uri, &app.local_contact,
NULL, -1, NULL, &tdata);*/
status = pjsip_endpt_create_request(sip_endptLocal, &method,
&str_target, &str_from,
&str_to, &str_from,
NULL, -1, NULL, &tdata);
if (status != PJ_SUCCESS) {
//app_perror(THIS_FILE, "Error creating request", status);
//report_completion(701);
return status;
}
status = pjsip_endpt_send_request_stateless(sip_endptLocal, tdata, NULL, NULL);
if (status != PJ_SUCCESS) {
//pjsip_tx_data_dec_ref(tdata);
//app_perror(THIS_FILE, "Error sending stateless request", status);
//report_completion(701);
return status;
}
return PJ_SUCCESS;
}
/*
* main()
*
*/
int main(int argc, char *argv[])
{
pj_caching_pool cp;
pj_pool_t *pool = NULL;
pjsip_module mod_app =
{
NULL,
NULL, /* prev, next. */
{ "mod-app", 7 }, /* Name. */
-1, /* Id */
PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
NULL, /* load() */
NULL, /* start() */
NULL, /* stop() */
NULL, /* unload() */
&on_rx_request, /* on_rx_request() */
NULL, /* on_rx_response() */
NULL, /* on_tx_request. */
NULL, /* on_tx_response() */
NULL, /* on_tsx_state() */
};
int c;
pj_status_t status;
/* Must init PJLIB first: */
status = pj_init();
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
/* Then init PJLIB-UTIL: */
status = pjlib_util_init();
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
/* Must create a pool factory before we can allocate any memory. */
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
/* Create global endpoint: */
{
/* Create the endpoint: */
status = pjsip_endpt_create(&cp.factory, "sipstateless", &sip_endptLocal);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
}
PJ_LOG(4, (THIS_FILE, "Returning %d to incoming requests", code));
pj_in_addr in_addrLocal;
pj_str_t localIp = pj_str("192.168.1.62");
pj_inet_aton(&localIp, &in_addrLocal);
/*
* Add UDP transport, with hard-coded port
*/
#ifdef HAS_UDP_TRANSPORT
{
pj_sockaddr_in addr;
addr.sin_family = pj_AF_INET();
addr.sin_addr = in_addrLocal; //0;
addr.sin_port = pj_htons(5060);
status = pjsip_udp_transport_start(sip_endptLocal, &addr, NULL, 1, NULL);
if (status != PJ_SUCCESS) {
PJ_LOG(3, (THIS_FILE,
"Error starting UDP transport (port in use?)"));
return 1;
}
}
#endif
submit_stateless_job();
//delete in_addr;
/*
* Register our module to receive incoming requests.
*/
status = pjsip_endpt_register_module(sip_endptLocal, &mod_app);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
/* Done. Loop forever to handle incoming events. */
PJ_LOG(3, (THIS_FILE, "Press Ctrl-C to quit.."));
for (;;) {
pjsip_endpt_handle_events(sip_endptLocal, NULL);
}
}