Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

sip-message-test.cpp 31KB

před 8 měsíci
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. #include <memory>
  2. #include <string>
  3. #include <algorithm>
  4. #include "sys/sock.h"
  5. #include "sys/system.h"
  6. #include "sip-uac.h"
  7. #include "sip-uas.h"
  8. #include "sip-header.h"
  9. #include "sip-dialog.h"
  10. #include "sip-message.h"
  11. #include "sip-transport.h"
  12. extern "C" {
  13. #include "../src/uac/sip-uac-transaction.h"
  14. #include "../src/uas/sip-uas-transaction.h"
  15. }
  16. #include "port/ip-route.h"
  17. #include "http-parser.h"
  18. #include "uri-parse.h"
  19. #include "aio-timeout.h"
  20. struct sip_message_test_t
  21. {
  22. struct sip_agent_t* sip;
  23. struct sip_transport_t udp;
  24. struct sip_dialog_t* dialog;
  25. std::shared_ptr<struct sip_uas_transaction_t> st;
  26. char buf[1024];
  27. };
  28. static struct sip_message_t* req2sip(const char* req)
  29. {
  30. struct sip_message_t* msg;
  31. msg = sip_message_create(SIP_MESSAGE_REQUEST);
  32. size_t n = strlen(req);
  33. http_parser_t* parser = http_parser_create(HTTP_PARSER_REQUEST, NULL, NULL);
  34. assert(0 == http_parser_input(parser, req, &n) && 0 == n);
  35. assert(0 == sip_message_load(msg, parser));
  36. http_parser_destroy(parser);
  37. return msg;
  38. }
  39. static struct sip_message_t* reply2sip(const char* reply)
  40. {
  41. struct sip_message_t* msg;
  42. msg = sip_message_create(SIP_MESSAGE_REPLY);
  43. size_t n = strlen(reply);
  44. http_parser_t* parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  45. assert(0 == http_parser_input(parser, reply, &n) && 0 == n);
  46. assert(0 == sip_message_load(msg, parser));
  47. http_parser_destroy(parser);
  48. return msg;
  49. }
  50. static int sip_uac_test_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
  51. {
  52. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  53. test->dialog = dialog;
  54. if (200 <= code && code < 300)
  55. {
  56. *session = test;
  57. sip_uac_ack(t, NULL, 0);
  58. }
  59. return 0;
  60. }
  61. static int sip_uac_test_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, int code, void** session)
  62. {
  63. return 0;
  64. }
  65. static int sip_uac_test_onreply(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  66. {
  67. return 0;
  68. }
  69. static inline struct sip_uac_transaction_t* sip_uac_transaction_create1(struct sip_agent_t* sip, struct sip_message_t* req)
  70. {
  71. struct sip_uac_transaction_t* t;
  72. t = sip_uac_transaction_create(sip, req);
  73. t->onreply = sip_uac_test_onreply;
  74. t->param = NULL;
  75. return t;
  76. }
  77. static inline struct sip_uac_transaction_t* sip_uac_transaction_create2(struct sip_message_test_t* test, struct sip_message_t* req)
  78. {
  79. struct sip_uac_transaction_t* t;
  80. t = sip_uac_transaction_create(test->sip, req);
  81. t->oninvite = sip_uac_test_oninvite;
  82. t->param = test;
  83. return t;
  84. }
  85. static inline struct sip_uac_transaction_t* sip_uac_transaction_create3(struct sip_agent_t* sip, struct sip_message_t* req)
  86. {
  87. struct sip_uac_transaction_t* t;
  88. t = sip_uac_transaction_create(sip, req);
  89. t->onsubscribe = sip_uac_test_onsubscribe;
  90. t->param = NULL;
  91. return t;
  92. }
  93. static int sip_uac_transport_via(void* transport, const char* destination, char protocol[16], char local[128], char dns[128])
  94. {
  95. int r;
  96. char ip[65];
  97. u_short port;
  98. struct uri_t* uri;
  99. struct sockaddr_storage ss;
  100. socklen_t len;
  101. len = sizeof(ss);
  102. memset(&ss, 0, sizeof(ss));
  103. strcpy(protocol, "UDP");
  104. uri = uri_parse(destination, strlen(destination));
  105. if (!uri)
  106. return -1; // invalid uri
  107. // TODO: sips port
  108. r = socket_addr_from(&ss, &len, "127.0.0.1" /*uri->host*/, uri->port ? uri->port : SIP_PORT);
  109. if (0 == r)
  110. {
  111. socket_addr_to((struct sockaddr*)&ss, len, ip, &port);
  112. r = ip_route_get(ip, local);
  113. if (0 == r)
  114. {
  115. len = sizeof(ss);
  116. if (0 == socket_addr_from(&ss, &len, local, 0))
  117. socket_addr_name((struct sockaddr*)&ss, len, dns, 128);
  118. if (SIP_PORT != port)
  119. snprintf(local + strlen(local), 128 - strlen(local), ":%hu", port);
  120. if (NULL == strchr(dns, '.'))
  121. snprintf(dns, 128, "%s", local); // don't have valid dns
  122. }
  123. }
  124. uri_free(uri);
  125. return r;
  126. }
  127. static int sip_uac_transport_send(void* transport, const void* data, size_t bytes)
  128. {
  129. struct sip_message_test_t* test = (struct sip_message_test_t*)transport;
  130. snprintf(test->buf, sizeof(test->buf)-1, "%.*s", (int)bytes, (const char*)data);
  131. printf("%.*s\n", (int)bytes, (const char*)data);
  132. return 0;
  133. }
  134. static int sip_uas_send(void* param, const struct cstring_t* /*protocol*/, const struct cstring_t* url, const struct cstring_t* /*received*/, int /*rport*/, const void* data, int bytes)
  135. {
  136. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  137. snprintf(test->buf, sizeof(test->buf)-1, "%.*s", (int)bytes, (const char*)data);
  138. printf("==> %.*s\n%.*s\n", (int)url->n, url->p, (int)bytes, (const char*)data);
  139. return 0;
  140. }
  141. static int sip_test_register(struct sip_message_test_t* alice, struct sip_message_test_t *bob)
  142. {
  143. // F1 REGISTER Bob -> Registrar (p213)
  144. const char* f1 = "REGISTER sip:registrar.biloxi.com SIP/2.0\r\n"
  145. "To: Bob <sip:bob@biloxi.com>\r\n"
  146. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  147. "Call-ID: 843817637684230@998sdasdh09\r\n"
  148. "CSeq: 1826 REGISTER\r\n"
  149. "Max-Forwards: 70\r\n"
  150. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7\r\n"
  151. "Contact: <sip:bob@192.0.2.4>\r\n"
  152. "Expires: 7200\r\n"
  153. "Content-Length: 0\r\n\r\n";
  154. // F2 200 OK Registrar -> Bob (p214)
  155. const char* f2 = "SIP/2.0 200 OK\r\n"
  156. "To: Bob <sip:bob@biloxi.com>;tag=2493k59kd\r\n"
  157. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  158. "Call-ID: 843817637684230@998sdasdh09\r\n"
  159. "CSeq: 1826 REGISTER\r\n"
  160. "Max-Forwards: 70\r\n"
  161. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4\r\n"
  162. "Contact: <sip:bob@192.0.2.4>\r\n"
  163. "Expires: 7200\r\n"
  164. "Content-Length: 0\r\n\r\n";
  165. struct sip_message_t* req = req2sip(f1);
  166. struct sip_message_t* reply = reply2sip(f2);
  167. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create1(bob->sip, req), sip_uac_transaction_release);
  168. assert(0 == sip_uac_send(t.get(), NULL, 0, &bob->udp, bob) && 0 == strcmp(bob->buf, f1));
  169. assert(0 == sip_agent_set_rport(req, "192.0.2.4", -1));
  170. assert(0 == sip_agent_input(alice->sip, req, alice));
  171. sip_message_add_header(alice->st->reply, "To", "Bob <sip:bob@biloxi.com>;tag=2493k59kd"); // modify to.tag
  172. sip_message_add_header(alice->st->reply, "Contact", "<sip:bob@192.0.2.4>");
  173. sip_message_add_header(alice->st->reply, "Expires", "7200");
  174. assert(0 == sip_uas_reply(alice->st.get(), 200, NULL, 0, alice) && 0 == strcmp(alice->buf, f2));
  175. assert(0 == sip_agent_input(bob->sip, reply, bob));
  176. //sip_message_destroy(req); // delete by uac transaction
  177. sip_message_destroy(reply);
  178. return 0;
  179. }
  180. static int sip_test_invite(struct sip_message_test_t* alice, struct sip_message_test_t *bob)
  181. {
  182. // F1 INVITE Alice -> atlanta.com proxy (p214)
  183. const char* f1 = "INVITE sip:bob@biloxi.com SIP/2.0\r\n"
  184. "To: Bob <sip:bob@biloxi.com>\r\n"
  185. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  186. "Call-ID: a84b4c76e66710\r\n"
  187. "CSeq: 314159 INVITE\r\n"
  188. "Max-Forwards: 70\r\n"
  189. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8\r\n"
  190. "Contact: <sip:alice@pc33.atlanta.com>\r\n"
  191. "Content-Type: application/sdp\r\n"
  192. "Content-Length: 0\r\n\r\n";
  193. // F2 100 Trying atlanta.com proxy -> Alice (p215)
  194. const char* f2 = "SIP/2.0 100 Trying\r\n"
  195. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  196. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  197. "Call-ID: a84b4c76e66710\r\n"
  198. "CSeq: 314159 INVITE\r\n"
  199. "Max-Forwards: 70\r\n"
  200. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  201. "Contact: <sip:bob@192.0.2.4>\r\n"
  202. "Content-Length: 0\r\n\r\n";
  203. // F8 180 Ringing atlanta.com proxy -> Alice (217)
  204. const char* f8 = "SIP/2.0 180 Ringing\r\n"
  205. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  206. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  207. "Call-ID: a84b4c76e66710\r\n"
  208. "CSeq: 314159 INVITE\r\n"
  209. "Max-Forwards: 70\r\n"
  210. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  211. "Contact: <sip:bob@192.0.2.4>\r\n"
  212. "Content-Length: 0\r\n\r\n";
  213. // F11 200 OK atlanta.com proxy -> Alice (p218)
  214. const char* f11 = "SIP/2.0 200 OK\r\n"
  215. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  216. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  217. "Call-ID: a84b4c76e66710\r\n"
  218. "CSeq: 314159 INVITE\r\n"
  219. "Max-Forwards: 70\r\n"
  220. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  221. "Contact: <sip:bob@192.0.2.4>\r\n"
  222. //"Content-Type: application/sdp\r\n"
  223. "Content-Length: 0\r\n\r\n";
  224. // F12 ACK Alice -> Bob (p218)
  225. const char* f12 = "ACK sip:bob@192.0.2.4 SIP/2.0\r\n"
  226. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  227. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  228. "Call-ID: a84b4c76e66710\r\n"
  229. "CSeq: 314159 ACK\r\n"
  230. "Max-Forwards: 70\r\n"
  231. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  232. "Content-Length: 0\r\n\r\n";
  233. const char* f13 = "SIP/2.0 603 Decline\r\n"
  234. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  235. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  236. "Call-ID: a84b4c76e66710\r\n"
  237. "CSeq: 314159 INVITE\r\n"
  238. "Max-Forwards: 70\r\n"
  239. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  240. "Content-Type: application/sdp\r\n"
  241. "Content-Length: 0\r\n\r\n";
  242. struct sip_message_t* req = req2sip(f1);
  243. struct sip_message_t* reply100 = reply2sip(f2);
  244. struct sip_message_t* reply180 = reply2sip(f8);
  245. struct sip_message_t* reply200 = reply2sip(f11);
  246. struct sip_message_t* reply603 = reply2sip(f13);
  247. struct sip_message_t* ack = req2sip(f12);
  248. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create2(alice, req), sip_uac_transaction_release);
  249. assert(0 == sip_uac_send(t.get(), NULL, 0, &alice->udp, alice) && 0 == strcmp(alice->buf, f1));
  250. sip_agent_set_rport(req, "192.0.2.1", -1);
  251. assert(0 == sip_agent_input(bob->sip, req, bob));
  252. assert(0 == sip_agent_input(bob->sip, req, bob));
  253. assert(0 == sip_agent_input(bob->sip, req, bob));
  254. assert(0 == sip_agent_input(bob->sip, req, bob));
  255. sip_message_add_header(bob->st->reply, "To", "Bob <sip:bob@biloxi.com>;tag=a6c85cf"); // modify to.tag
  256. sip_message_add_header(bob->st->reply, "Contact", "<sip:bob@192.0.2.4>");
  257. assert(0 == sip_uas_reply(bob->st.get(), 100, NULL, 0, bob) && 0 == strcmp(bob->buf, f2));
  258. assert(0 == sip_agent_input(alice->sip, reply100, alice));
  259. assert(0 == sip_uas_reply(bob->st.get(), 180, NULL, 0, bob) && 0 == strcmp(bob->buf, f8));
  260. assert(0 == sip_agent_input(alice->sip, reply180, alice));
  261. assert(0 == sip_uas_reply(bob->st.get(), 100, NULL, 0, bob) && 0 == strcmp(bob->buf, f2));
  262. assert(0 == sip_agent_input(alice->sip, reply100, alice));
  263. assert(0 == sip_uas_reply(bob->st.get(), 180, NULL, 0, bob) && 0 == strcmp(bob->buf, f8));
  264. assert(0 == sip_agent_input(alice->sip, reply180, alice));
  265. //assert(0 == sip_uas_reply(bob->st, 603, NULL, 0));
  266. //assert(0 == sip_agent_input(alice->sip, reply603));
  267. assert(0 == sip_uas_reply(bob->st.get(), 200, NULL, 0, bob) && 0 == strcmp(bob->buf, f11));
  268. assert(0 == sip_agent_input(alice->sip, reply200, alice) /*&& 0 == strcmp(alice->buf, f12)*/ ); // The branch parameter is different for INVITE and ACK message sent By UAC
  269. assert(0 == sip_agent_input(alice->sip, reply180, alice));
  270. assert(0 == sip_agent_input(alice->sip, reply100, alice));
  271. assert(0 == sip_agent_input(alice->sip, reply200, alice));
  272. assert(0 == sip_agent_input(bob->sip, ack, bob));
  273. assert(0 == sip_agent_input(bob->sip, ack, bob));
  274. assert(0 == sip_agent_input(bob->sip, ack, bob));
  275. //sip_message_destroy(req); // delete by uac transaction
  276. sip_message_destroy(reply100);
  277. sip_message_destroy(reply180);
  278. sip_message_destroy(reply200);
  279. sip_message_destroy(reply603);
  280. sip_message_destroy(ack);
  281. return 0;
  282. }
  283. static int sip_test_message(struct sip_message_test_t* alice, struct sip_message_test_t* bob)
  284. {
  285. // https://tools.ietf.org/html/rfc3428#page-11
  286. // F1 MESSAGE Bob -> Alice
  287. const char* f1 = "MESSAGE sip:alice@atlanta.com SIP/2.0\n"
  288. "Via: SIP/2.0/TCP biloxi.com;branch=z9hG4bK776sgdkse\n"
  289. "Max-Forwards: 70\n"
  290. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  291. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  292. "Call-ID: asd88asd77a@1.2.3.4\n"
  293. "CSeq: 1 MESSAGE\n"
  294. "Content-Type: text/plain\n\n";
  295. //"Content-Length: 18\n"
  296. //"\r\n"
  297. //"Watson, come here.";
  298. const char* f2 = "MESSAGE sip:user2@domain.com SIP/2.0\r\n"
  299. "Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds\r\n"
  300. "Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse; received=1.2.3.4\r\n"
  301. "Max-Forwards: 69\r\n"
  302. "From: sip:user1@domain.com;tag=49394\r\n"
  303. "To: sip:user2@domain.com\r\n"
  304. "Call-ID: asd88asd77a@1.2.3.4\r\n"
  305. "CSeq: 1 MESSAGE\r\n"
  306. "Content-Type: text/plain\r\n"
  307. "Content-Length: 18\r\n"
  308. "\r\n"
  309. "Watson, come here.";
  310. const char* f3 = "SIP/2.0 200 OK\r\n"
  311. "Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds; received=192.0.2.1\r\n"
  312. "Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse; received=1.2.3.4\r\n"
  313. "From: sip:user1@domain.com;tag=49394\r\n"
  314. "To: sip:user2@domain.com;tag=ab8asdasd9\r\n"
  315. "Call-ID: asd88asd77a@1.2.3.4\r\n"
  316. "CSeq: 1 MESSAGE\r\n"
  317. "Content-Length: 0\r\n\r\n";
  318. // F2 200 OK Alice -> Bob
  319. const char* f4 = "SIP/2.0 200 OK\r\n"
  320. "Via: SIP/2.0/TCP biloxi.com;branch=z9hG4bK776sgdkse; received=1.2.3.4\r\n"
  321. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  322. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  323. "Call-ID: asd88asd77a@1.2.3.4\r\n"
  324. "CSeq: 1 MESSAGE\r\n"
  325. "Content-Length: 0\r\n\r\n";
  326. struct sip_message_t* req = req2sip(f1);
  327. struct sip_message_t* reply = reply2sip(f4);
  328. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create1(bob->sip, req), sip_uac_transaction_release);
  329. assert(0 == sip_uac_send(t.get(), "Watson, come here.", 18, &bob->udp, bob));
  330. assert(0 == sip_agent_input(alice->sip, req, alice));
  331. assert(0 == sip_uas_reply(alice->st.get(), 200, NULL, 0, alice));
  332. assert(0 == sip_agent_input(bob->sip, reply, bob));
  333. //sip_message_destroy(req); // delete by uac transaction
  334. sip_message_destroy(reply);
  335. return 0;
  336. }
  337. static int sip_test_dialog_message(struct sip_message_test_t* alice, struct sip_message_test_t* bob)
  338. {
  339. // https://tools.ietf.org/html/rfc3428#page-11
  340. // F1 MESSAGE Bob -> Alice
  341. const char* f1 = "MESSAGE sip:alice@atlanta.com SIP/2.0\n"
  342. "Via: SIP/2.0/TCP biloxi.com;branch=z9hG4bK776sgdkse2\n"
  343. "Max-Forwards: 70\n"
  344. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  345. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  346. "Call-ID: a84b4c76e66710\r\n"
  347. "CSeq: 1 MESSAGE\n"
  348. "Content-Type: text/plain\n\n";
  349. //"Content-Length: 18\n"
  350. //"\r\n"
  351. //"Watson, come here.";
  352. // F2 200 OK Alice -> Bob
  353. const char* f2 = "SIP/2.0 200 OK\r\n"
  354. "Via: SIP/2.0/TCP biloxi.com;branch=z9hG4bK776sgdkse; received=1.2.3.4\r\n"
  355. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  356. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  357. "Call-ID: a84b4c76e66710\r\n"
  358. "CSeq: 1 MESSAGE\r\n"
  359. "Content-Length: 0\r\n\r\n";
  360. struct sip_message_t* req = req2sip(f1);
  361. struct sip_message_t* reply = reply2sip(f2);
  362. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create1(bob->sip, req), sip_uac_transaction_release);
  363. assert(0 == sip_uac_send(t.get(), "Watson, come here.", 18, &bob->udp, bob));
  364. assert(0 == sip_agent_input(alice->sip, req, alice));
  365. assert(0 == sip_uas_reply(alice->st.get(), 200, NULL, 0, alice));
  366. assert(0 == sip_agent_input(bob->sip, reply, bob));
  367. //sip_message_destroy(req); // delete by uac transaction
  368. sip_message_destroy(reply);
  369. return 0;
  370. }
  371. static int sip_test_notify(struct sip_message_test_t* alice, struct sip_message_test_t* bob)
  372. {
  373. // https://tools.ietf.org/html/rfc3428#page-11
  374. // F1 SUBSCRIBE Alice -> Bob
  375. const char* f1 = "SUBSCRIBE sip:bob@biloxi.com;user=phone SIP/2.0\n"
  376. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  377. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  378. "Call-ID: a84b4c76e66710\n"
  379. "CSeq: 314160 SUBSCRIBE\n"
  380. "Max-Forwards: 70\n"
  381. "Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7\n"
  382. "Contact: <sip:150@10.135.0.12;line=16172>;+sip.instance=\"<urn:uuid:0d9a008d-0355-0024-0000-000276f3d796>\"\n"
  383. "Event: message-summary\n"
  384. "Allow-Events: dialog,message-summary\n"
  385. "Accept: application/simple-message-summary\n"
  386. "Allow: INVITE, CANCEL, BYE, ACK, REGISTER, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE, INFO, PRACK, UPDATE\n"
  387. "Expires: 240\n"
  388. "Supported: replaces,100rel\n"
  389. "User-Agent: Wildix W-AIR 03.55.00.24 9c7514340722 02:76:f3:d7:96\n"
  390. "Content-Length: 0\n\n";
  391. const char* f2 = "SIP/2.0 200 OK\n"
  392. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  393. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  394. "Call-ID: a84b4c76e66710\n"
  395. "CSeq: 314160 SUBSCRIBE\n"
  396. "Max-Forwards: 70\n"
  397. //"Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7;rport=5060\n"
  398. "Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7\n"
  399. "Contact: <sip:vmaccess*150@mypbx.wildixin.com:5060;user=phone>\n"
  400. "Expires: 240\n"
  401. "Server: Wildix GW-4.2.5.35963\n"
  402. "Content-Length: 0\n\n";
  403. const char* f3 = "NOTIFY sip:alice@atlanta.com;line=16172 SIP/2.0\n"
  404. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  405. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  406. "Call-ID: a84b4c76e66710\n"
  407. "CSeq: 2 NOTIFY\n"
  408. "Max-Forwards: 70\n"
  409. "Via: SIP/2.0/UDP 10.135.0.1;branch=z9hG4bK1308.a003bf56000000000000000000000000.0\n"
  410. "Contact: <sip:vmaccess*150@mypbx.wildixin.com:5060;user=phone>\n"
  411. "Event: message-summary\n"
  412. "Subscription-State: active;expires=240\n"
  413. "User-Agent: Wildix GW-4.2.5.35963\n"
  414. "Content-Type: application/simple-message-summary\n"
  415. //"Content-Length: 90\n"
  416. "\n";
  417. const char* f3message =
  418. "Messages-Waiting: yes\n"
  419. "Message-Account: sip:vmaccess*150@wildix\n"
  420. "Voice-Message: 1/0 (1/0)";
  421. const char* f4 = "SIP/2.0 200 OK\n"
  422. "To: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  423. "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  424. "Call-ID: a84b4c76e66710\n"
  425. "CSeq: 2 NOTIFY\n"
  426. "Max-Forwards: 70\n"
  427. "Via: SIP/2.0/UDP 10.135.0.1;branch=z9hG4bK1308.a003bf56000000000000000000000000.0\n"
  428. "Event: message-summary\n"
  429. "Subscription-State: active;expires=240\n"
  430. "User-Agent: Wildix W-AIR 03.55.00.24 9c7514340722\n"
  431. "Content-Length: 0\n\n";
  432. const char* f5 = "SUBSCRIBE sip:bob@biloxi.com;user=phone SIP/2.0\n"
  433. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  434. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  435. "Call-ID: a84b4c76e66710\n"
  436. "CSeq: 314161 SUBSCRIBE\n"
  437. "Max-Forwards: 70\n"
  438. "Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7.1\n"
  439. "Contact: <sip:150@10.135.0.12;line=16172>;+sip.instance=\"<urn:uuid:0d9a008d-0355-0024-0000-000276f3d796>\"\n"
  440. "Event: message-summary\n"
  441. "Allow-Events: dialog,message-summary\n"
  442. "Accept: application/simple-message-summary\n"
  443. "Allow: INVITE, CANCEL, BYE, ACK, REGISTER, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE, INFO, PRACK, UPDATE\n"
  444. "Expires: 0\n"
  445. "Supported: replaces,100rel\n"
  446. "User-Agent: Wildix W-AIR 03.55.00.24 9c7514340722 02:76:f3:d7:96\n"
  447. "Content-Length: 0\n\n";
  448. const char* f6 = "SIP/2.0 200 OK\n"
  449. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\n"
  450. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\n"
  451. "Call-ID: a84b4c76e66710\n"
  452. "CSeq: 314161 SUBSCRIBE\n"
  453. "Max-Forwards: 70\n"
  454. //"Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7.1;rport=5060\n"
  455. "Via: SIP/2.0/UDP 10.135.0.12:5060;branch=z9hG4bKtrxftxslfcy3aagf3c9s7.1\n"
  456. "Contact: <sip:vmaccess*150@mypbx.wildixin.com:5060;user=phone>\n"
  457. "Expires: 0\n"
  458. "Server: Wildix GW-4.2.5.35963\n"
  459. "Content-Length: 0\n\n";
  460. struct sip_message_t* req = req2sip(f1);
  461. struct sip_message_t* reply = reply2sip(f2);
  462. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create3(alice->sip, req), sip_uac_transaction_release);
  463. assert(0 == sip_uac_send(t.get(), NULL, 0, &alice->udp, alice));
  464. std::string s(alice->buf); memset(alice->buf, 0, sizeof(alice->buf)); std::copy_if(s.begin(), s.end(), alice->buf, [](char c){return c!='\r';});
  465. assert(0 == strcmp(alice->buf, f1));
  466. assert(0 == sip_agent_input(bob->sip, req, bob));
  467. sip_message_add_header(bob->st->reply, "Expires", "240");
  468. sip_message_add_header(bob->st->reply, "Contact", "<sip:vmaccess*150@mypbx.wildixin.com:5060;user=phone>");
  469. sip_message_add_header(bob->st->reply, "Server", "Wildix GW-4.2.5.35963");
  470. assert(0 == sip_uas_reply(bob->st.get(), 200, NULL, 0, bob));
  471. std::string s2(bob->buf); memset(bob->buf, 0, sizeof(bob->buf)); std::copy_if(s2.begin(), s2.end(), bob->buf, [](char c){return c!='\r';});
  472. assert(0 == strcmp(bob->buf, f2));
  473. assert(0 == sip_agent_input(alice->sip, reply, alice));
  474. struct sip_message_t* req2 = req2sip(f3);
  475. struct sip_message_t* reply2 = reply2sip(f4);
  476. std::shared_ptr<sip_uac_transaction_t> t2(sip_uac_transaction_create1(bob->sip, req2), sip_uac_transaction_release);
  477. assert(0 == sip_uac_send(t2.get(), f3message, strlen(f3message), &bob->udp, bob));
  478. std::string s3(bob->buf); memset(bob->buf, 0, sizeof(bob->buf)); std::copy_if(s3.begin(), s3.end(), bob->buf, [](char c){return c!='\r';});
  479. assert(0 == strncmp(bob->buf, f3, strlen(f3)-1)); // miss content-length
  480. assert(0 == sip_agent_input(alice->sip, req2, alice));
  481. sip_message_add_header(alice->st->reply, "Event", "message-summary");
  482. sip_message_add_header(alice->st->reply, "Subscription-State", "active;expires=240");
  483. sip_message_add_header(alice->st->reply, "User-Agent", "Wildix W-AIR 03.55.00.24 9c7514340722");
  484. assert(0 == sip_uas_reply(alice->st.get(), 200, NULL, 0, alice));
  485. std::string s4(alice->buf); memset(alice->buf, 0, sizeof(alice->buf)); std::copy_if(s4.begin(), s4.end(), alice->buf, [](char c){return c!='\r';});
  486. assert(0 == strcmp(alice->buf, f4));
  487. assert(0 == sip_agent_input(bob->sip, reply2, bob));
  488. struct sip_message_t* req3 = req2sip(f5);
  489. struct sip_message_t* reply3 = reply2sip(f6);
  490. std::shared_ptr<sip_uac_transaction_t> t3(sip_uac_transaction_create3(alice->sip, req3), sip_uac_transaction_release);
  491. assert(0 == sip_uac_send(t3.get(), NULL, 0, &alice->udp, alice));
  492. std::string s5(alice->buf); memset(alice->buf, 0, sizeof(alice->buf)); std::copy_if(s5.begin(), s5.end(), alice->buf, [](char c){return c!='\r';});
  493. assert(0 == strcmp(alice->buf, f5));
  494. assert(0 == sip_agent_input(bob->sip, req3, bob));
  495. sip_message_add_header(bob->st->reply, "Expires", "0");
  496. sip_message_add_header(bob->st->reply, "Contact", "<sip:vmaccess*150@mypbx.wildixin.com:5060;user=phone>");
  497. sip_message_add_header(bob->st->reply, "Server", "Wildix GW-4.2.5.35963");
  498. assert(0 == sip_uas_reply(bob->st.get(), 200, NULL, 0, bob));
  499. std::string s6(bob->buf); memset(bob->buf, 0, sizeof(bob->buf)); std::copy_if(s6.begin(), s6.end(), bob->buf, [](char c){return c!='\r';});
  500. assert(0 == strcmp(bob->buf, f6));
  501. assert(0 == sip_agent_input(alice->sip, reply3, alice));
  502. //sip_message_destroy(req); // delete by uac transaction
  503. //sip_message_destroy(req2); // delete by uac transaction
  504. //sip_message_destroy(req3); // delete by uac transaction
  505. sip_message_destroy(reply);
  506. sip_message_destroy(reply2);
  507. sip_message_destroy(reply3);
  508. return 0;
  509. }
  510. static int sip_test_bye(struct sip_message_test_t* alice, struct sip_message_test_t *bob)
  511. {
  512. //// F13 BYE Bob -> Alice (p218)
  513. //const char* f13 = "BYE sip:alice@pc33.atlanta.com SIP/2.0\r\n"
  514. // "Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10\r\n"
  515. // "Max-Forwards: 70\r\n"
  516. // "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  517. // "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  518. // "Call-ID: a84b4c76e66710\r\n"
  519. // "CSeq: 231 BYE\r\n"
  520. // "Content-Length: 0\r\n\r\n";
  521. //// F14 200 OK Alice -> Bob (p219)
  522. //const char* f14 = "SIP/2.0 200 OK\r\n"
  523. // "Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10\r\n"
  524. // "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  525. // "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  526. // "Call-ID: a84b4c76e66710\r\n"
  527. // "CSeq: 231 BYE\r\n"
  528. // "Content-Length: 0\r\n\r\n";
  529. // F13 BYE Alice -> Bob (p218)
  530. const char* f13 = "BYE sip:bob@192.0.2.4 SIP/2.0\r\n"
  531. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  532. "Max-Forwards: 70\r\n"
  533. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  534. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  535. "Call-ID: a84b4c76e66710\r\n"
  536. "CSeq: 314160 BYE\r\n"
  537. "Content-Length: 0\r\n\r\n";
  538. // F14 200 OK Alice -> Bob (p219)
  539. const char* f14 = "SIP/2.0 200 OK\r\n"
  540. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  541. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  542. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  543. "Call-ID: a84b4c76e66710\r\n"
  544. "CSeq: 314160 BYE\r\n"
  545. "Content-Length: 0\r\n\r\n";
  546. struct sip_message_t* req = req2sip(f13);
  547. struct sip_message_t* reply = reply2sip(f14);
  548. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_transaction_create1(alice->sip, req), sip_uac_transaction_release);
  549. //std::shared_ptr<sip_uac_transaction_t> t(sip_uac_bye(alice->sip, alice->dialog, sip_uac_test_onreply, NULL), sip_uac_transaction_release);
  550. //sip_uac_add_header(t.get(), "Via", "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9");
  551. assert(0 == sip_uac_send(t.get(), NULL, 0, &alice->udp, alice));
  552. assert(0 == sip_agent_input(bob->sip, req, bob));
  553. assert(0 == sip_uas_reply(bob->st.get(), 200, NULL, 0, bob));
  554. assert(0 == sip_agent_input(alice->sip, reply, alice));
  555. //sip_message_destroy(req); // delete by uac transaction
  556. sip_message_destroy(reply);
  557. return 0;
  558. }
  559. static int sip_uas_oninvite(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, struct sip_dialog_t* dialog, const void* data, int bytes, void** session)
  560. {
  561. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  562. test->dialog = dialog;
  563. sip_uas_transaction_addref(t);
  564. test->st.reset(t, sip_uas_transaction_release);
  565. *session = test;
  566. return 0;
  567. }
  568. static int sip_uas_onack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, int code, const void* data, int bytes)
  569. {
  570. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  571. sip_uas_transaction_addref(t);
  572. test->st.reset(t, sip_uas_transaction_release);
  573. return 0;
  574. }
  575. static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  576. {
  577. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  578. sip_uas_transaction_addref(t);
  579. test->st.reset(t, sip_uas_transaction_release);
  580. return 0;
  581. }
  582. static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  583. {
  584. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  585. sip_uas_transaction_addref(t);
  586. test->st.reset(t, sip_uas_transaction_release);
  587. return 0;
  588. }
  589. static int sip_uas_onprack(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
  590. {
  591. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  592. sip_uas_transaction_addref(t);
  593. test->st.reset(t, sip_uas_transaction_release);
  594. return 0;
  595. }
  596. static int sip_uas_onupdate(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const void* data, int bytes)
  597. {
  598. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  599. sip_uas_transaction_addref(t);
  600. test->st.reset(t, sip_uas_transaction_release);
  601. return 0;
  602. }
  603. static int sip_uas_oninfo(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, struct sip_dialog_t* dialog, const struct cstring_t* package, const void* data, int bytes)
  604. {
  605. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  606. sip_uas_transaction_addref(t);
  607. test->st.reset(t, sip_uas_transaction_release);
  608. return 0;
  609. }
  610. static int sip_uas_onregister(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const char* user, const char* location, int expires)
  611. {
  612. assert(expires == 7200);
  613. assert(0 == strcmp(user, "bob"));
  614. assert(0 == strcmp(location, "192.0.2.4"));
  615. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  616. sip_uas_transaction_addref(t);
  617. test->st.reset(t, sip_uas_transaction_release);
  618. return 0;
  619. }
  620. static int sip_uas_onmessage(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const void* payload, int bytes)
  621. {
  622. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  623. sip_uas_transaction_addref(t);
  624. test->st.reset(t, sip_uas_transaction_release);
  625. return 0;
  626. }
  627. static int sip_uas_onsubscribe(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, sip_subscribe_t* subscribe, void** sub)
  628. {
  629. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  630. sip_uas_transaction_addref(t);
  631. test->st.reset(t, sip_uas_transaction_release);
  632. //assert(0 == sip_uas_reply(t, 200, NULL, 0));
  633. //std::shared_ptr<sip_uac_transaction_t> notify(sip_uac_notify(test->sip, subscribe, "active", sip_uac_test_onreply, test), sip_uac_transaction_release);
  634. //assert(0 == sip_uac_send(notify.get(), NULL, 0, &test->udp, test));
  635. *sub = test;
  636. return 0;
  637. }
  638. static int sip_uas_onnotify(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session, const struct cstring_t* event)
  639. {
  640. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  641. sip_uas_transaction_addref(t);
  642. test->st.reset(t, sip_uas_transaction_release);
  643. return 0;
  644. }
  645. static int sip_uas_onpublish(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, const struct cstring_t* event)
  646. {
  647. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  648. sip_uas_transaction_addref(t);
  649. test->st.reset(t, sip_uas_transaction_release);
  650. return 0;
  651. }
  652. static int sip_uas_onrefer(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  653. {
  654. struct sip_message_test_t* test = (struct sip_message_test_t*)param;
  655. sip_uas_transaction_addref(t);
  656. test->st.reset(t, sip_uas_transaction_release);
  657. return 0;
  658. }
  659. // 24 Examples (p213)
  660. void sip_message_test(void)
  661. {
  662. struct sip_uas_handler_t handler = {
  663. sip_uas_send,
  664. sip_uas_onregister,
  665. sip_uas_oninvite,
  666. sip_uas_onack,
  667. sip_uas_onprack,
  668. sip_uas_onupdate,
  669. sip_uas_oninfo,
  670. sip_uas_onbye,
  671. sip_uas_oncancel,
  672. sip_uas_onsubscribe,
  673. sip_uas_onnotify,
  674. sip_uas_onpublish,
  675. sip_uas_onmessage,
  676. sip_uas_onrefer,
  677. };
  678. struct sip_message_test_t alice, bob;
  679. alice.udp = bob.udp = {
  680. sip_uac_transport_via,
  681. sip_uac_transport_send,
  682. };
  683. alice.sip = sip_agent_create(&handler);
  684. bob.sip = sip_agent_create(&handler);
  685. assert(0 == sip_test_register(&alice, &bob));
  686. assert(0 == sip_test_message(&alice, &bob));
  687. assert(0 == sip_test_invite(&alice, &bob));
  688. assert(0 == sip_test_dialog_message(&alice, &bob));
  689. assert(0 == sip_test_notify(&alice, &bob));
  690. assert(0 == sip_test_bye(&alice, &bob));
  691. sip_agent_destroy(alice.sip);
  692. sip_agent_destroy(bob.sip);
  693. }