Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

sip-uas-message-test.cpp 11KB

8 månader sedan
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #include "sys/sock.h"
  2. #include "sip-uas.h"
  3. #include "sip-header.h"
  4. #include "sip-dialog.h"
  5. #include "sip-message.h"
  6. #include "sip-timer.h"
  7. #include "sys/system.h"
  8. static struct sip_dialog_t* s_dialog;
  9. static struct sip_message_t* req2sip(const char* req)
  10. {
  11. struct sip_message_t* msg;
  12. msg = sip_message_create(SIP_MESSAGE_REQUEST);
  13. size_t n = strlen(req);
  14. http_parser_t* parser = http_parser_create(HTTP_PARSER_REQUEST, NULL, NULL);
  15. assert(0 == http_parser_input(parser, req, &n) && 0 == n);
  16. assert(0 == sip_message_load(msg, parser));
  17. http_parser_destroy(parser);
  18. return msg;
  19. }
  20. static struct sip_message_t* reply2sip(const char* reply)
  21. {
  22. struct sip_message_t* msg;
  23. msg = sip_message_create(SIP_MESSAGE_REPLY);
  24. size_t n = strlen(reply);
  25. http_parser_t* parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  26. assert(0 == http_parser_input(parser, reply, &n) && 0 == n);
  27. assert(0 == sip_message_load(msg, parser));
  28. http_parser_destroy(parser);
  29. return msg;
  30. }
  31. static int sip_register(struct sip_agent_t* sip)
  32. {
  33. // F1 REGISTER Bob -> Registrar (p213)
  34. const char* f1 = "REGISTER sip:registrar.biloxi.com SIP/2.0\r\n"
  35. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4\r\n"
  36. "Max-Forwards: 70\r\n"
  37. "To: Bob <sip:bob@biloxi.com>\r\n"
  38. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  39. "Call-ID: 843817637684230@998sdasdh09\r\n"
  40. "CSeq: 1826 REGISTER\r\n"
  41. "Contact: <sip:bob@192.0.2.4>\r\n"
  42. "Expires: 7200\r\n"
  43. "Content-Length: 0\r\n\r\n";
  44. f1 = "REGISTER sip:34020000002000000001@192.168.3.50:5060 SIP/2.0\nCall-ID: 936f20ebc489186fe3b0b69982061ec4\nContact: <sip:34020000001320000001@192.168.3.72:5060>\nContent-Length: 0\nCSeq: 1 REGISTER\nExpires: 3600\nFrom: <sip:34020000001320000001@192.168.3.72:5060>;tag=023aa692e3c41bc19ddb16cbf1e730ca\nMax-Forwards: 70\nRoute: <sip:34020000001320000001@192.168.3.50:5060;lr>\nTo: <sip:34020000001320000001@192.168.3.72:5060>\nUser-Agent: SIP UAS V3.0.0.833566\nVia: SIP/2.0/UDP 192.168.3.72:5060;rport;branch=z9hG4bK8a37ad0aa92dcf4b3b56ee2de0553a60\n\n";
  45. // F2 200 OK Registrar -> Bob (p214)
  46. const char* f2 = "SIP/2.0 200 OK\r\n"
  47. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4\r\n"
  48. "To: Bob <sip:bob@biloxi.com>;tag=2493k59kd\r\n"
  49. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  50. "Call-ID: 843817637684230@998sdasdh09\r\n"
  51. "CSeq: 1826 REGISTER\r\n"
  52. "Contact: <sip:bob@192.0.2.4>\r\n"
  53. "Expires: 7200\r\n"
  54. "Content-Length: 0\r\n\r\n";
  55. struct sip_message_t* req = req2sip(f1);
  56. struct sip_message_t* reply = reply2sip(f2);
  57. assert(0 == sip_agent_input(sip, req, sip));
  58. sip_message_destroy(req);
  59. sip_message_destroy(reply);
  60. return 0;
  61. }
  62. static int sip_invite(struct sip_agent_t* sip)
  63. {
  64. // F1 INVITE Alice -> atlanta.com proxy (p214)
  65. const char* f1 = "INVITE sip:bob@biloxi.com SIP/2.0\r\n"
  66. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8\r\n"
  67. "Max-Forwards: 70\r\n"
  68. //"To: Bob <sip:bob@biloxi.com>\r\n"
  69. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  70. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  71. "Call-ID: a84b4c76e66710\r\n"
  72. "CSeq: 314159 INVITE\r\n"
  73. "Contact: <sip:alice@pc33.atlanta.com>\r\n"
  74. "Content-Type: application/sdp\r\n"
  75. "Content-Length: 0\r\n\r\n";
  76. // F2 100 Trying atlanta.com proxy -> Alice (p215)
  77. const char* f2 = "SIP/2.0 100 Trying\r\n"
  78. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  79. "To: Bob <sip:bob@biloxi.com>\r\n"
  80. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  81. "Call-ID: a84b4c76e66710\r\n"
  82. "CSeq: 314159 INVITE\r\n"
  83. "Content-Length: 0\r\n\r\n";
  84. // F8 180 Ringing atlanta.com proxy -> Alice (217)
  85. const char* f8 = "SIP/2.0 180 Ringing\r\n"
  86. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  87. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  88. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  89. "Call-ID: a84b4c76e66710\r\n"
  90. "Contact: <sip:bob@192.0.2.4>\r\n"
  91. "CSeq: 314159 INVITE\r\n"
  92. "Content-Length: 0\r\n\r\n";
  93. // F11 200 OK atlanta.com proxy -> Alice (p218)
  94. const char* f11 = "SIP/2.0 200 OK\r\n"
  95. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  96. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  97. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  98. "Call-ID: a84b4c76e66710\r\n"
  99. "CSeq: 314159 INVITE\r\n"
  100. "Contact: <sip:bob@192.0.2.4>\r\n"
  101. "Content-Type: application/sdp\r\n"
  102. "Content-Length: 0\r\n\r\n";
  103. // F12 ACK Alice -> Bob (p218)
  104. const char* f12 = "ACK sip:bob@192.0.2.4 SIP/2.0\r\n"
  105. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  106. "Max-Forwards: 70\r\n"
  107. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  108. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  109. "Call-ID: a84b4c76e66710\r\n"
  110. "CSeq: 314159 ACK\r\n"
  111. "Content-Length: 0\r\n\r\n";
  112. struct sip_message_t* req = req2sip(f1);
  113. struct sip_message_t* reply100 = reply2sip(f2);
  114. struct sip_message_t* reply180 = reply2sip(f8);
  115. struct sip_message_t* reply200 = reply2sip(f11);
  116. struct sip_message_t* ack = req2sip(f12);
  117. assert(0 == sip_agent_input(sip, req, sip));
  118. assert(0 == sip_agent_input(sip, req, sip));
  119. assert(0 == sip_agent_input(sip, req, sip));
  120. assert(0 == sip_agent_input(sip, ack, sip));
  121. assert(0 == sip_agent_input(sip, ack, sip));
  122. assert(0 == sip_agent_input(sip, ack, sip));
  123. sip_message_destroy(req);
  124. sip_message_destroy(reply100);
  125. sip_message_destroy(reply180);
  126. sip_message_destroy(reply200);
  127. sip_message_destroy(ack);
  128. return 0;
  129. }
  130. static int sip_bye(struct sip_agent_t* sip)
  131. {
  132. //// F13 BYE Bob -> Alice (p218)
  133. //const char* f13 = "BYE sip:alice@pc33.atlanta.com SIP/2.0\r\n"
  134. // "Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10\r\n"
  135. // "Max-Forwards: 70\r\n"
  136. // "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  137. // "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  138. // "Call-ID: a84b4c76e66710\r\n"
  139. // "CSeq: 231 BYE\r\n"
  140. // "Content-Length: 0\r\n\r\n";
  141. //// F14 200 OK Alice -> Bob (p219)
  142. //const char* f14 = "SIP/2.0 200 OK\r\n"
  143. // "Via: SIP/2.0/UDP 192.0.2.4;branch=z9hG4bKnashds10\r\n"
  144. // "From: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  145. // "To: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  146. // "Call-ID: a84b4c76e66710\r\n"
  147. // "CSeq: 231 BYE\r\n"
  148. // "Content-Length: 0\r\n\r\n";
  149. // F13 BYE Alice -> Bob (p218)
  150. const char* f13 = "BYE sip:bob@192.0.2.4 SIP/2.0\r\n"
  151. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  152. "Max-Forwards: 70\r\n"
  153. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  154. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  155. "Call-ID: a84b4c76e66710\r\n"
  156. "CSeq: 314159 BYE\r\n"
  157. "Content-Length: 0\r\n\r\n";
  158. // F14 200 OK Alice -> Bob (p219)
  159. const char* f14 = "SIP/2.0 200 OK\r\n"
  160. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  161. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  162. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  163. "Call-ID: a84b4c76e66710\r\n"
  164. "CSeq: 314159 BYE\r\n"
  165. "Content-Length: 0\r\n\r\n";
  166. struct sip_message_t* req = req2sip(f13);
  167. struct sip_message_t* reply = reply2sip(f14);
  168. assert(0 == sip_agent_input(sip, req, sip));
  169. sip_message_destroy(req);
  170. sip_message_destroy(reply);
  171. return 0;
  172. }
  173. struct sip_session_t
  174. {
  175. struct sip_uas_transaction_t* t;
  176. struct sip_dialog_t* dialog;
  177. };
  178. 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** ptr)
  179. {
  180. struct sip_session_t* session = new struct sip_session_t;
  181. assert(NULL == dialog); // re-invite
  182. //sip_uas_add_header(t, "To", "Bob <sip:bob@biloxi.com>;tag=a6c85cf");
  183. assert(0 == sip_uas_reply(t, 100, NULL, 0, param));
  184. assert(0 == sip_uas_reply(t, 100, NULL, 0, param));
  185. assert(0 == sip_uas_reply(t, 180, NULL, 0, param));
  186. assert(0 == sip_uas_reply(t, 180, NULL, 0, param));
  187. assert(0 == sip_uas_reply(t, 180, NULL, 0, param));
  188. assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
  189. // assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
  190. session->t = t;
  191. *ptr = session;
  192. return 0;
  193. }
  194. 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)
  195. {
  196. char buf[1024];
  197. const char* end = buf + sizeof(buf);
  198. struct cstring_t ptr;
  199. ptr.p = buf;
  200. struct sip_session_t* s = (struct sip_session_t*)session;
  201. struct sip_agent_t* uas = (struct sip_agent_t*)param;
  202. assert(100 <= code && code < 700);
  203. if (200 <= code && code < 300)
  204. {
  205. assert(dialog->state == DIALOG_CONFIRMED);
  206. assert(dialog->secure == 0);
  207. assert(dialog->remote.id == 314159);
  208. ptr.n = sip_contact_write(&dialog->local.uri, buf, end);
  209. assert(0 == cstrcmp(&ptr, "Bob <sip:bob@biloxi.com>;tag=a6c85cf"));
  210. ptr.n = sip_contact_write(&dialog->remote.uri, buf, end);
  211. assert(0 == cstrcmp(&ptr, "Alice <sip:alice@atlanta.com>;tag=1928301774"));
  212. ptr.n = sip_uri_write(&dialog->remote.target, buf, end);
  213. assert(0 == cstrcmp(&ptr, "sip:alice@pc33.atlanta.com"));
  214. assert(0 == cstrcmp(&dialog->callid, "a84b4c76e66710"));
  215. assert(0 == sip_uris_count(&dialog->routers));
  216. s->dialog = dialog;
  217. }
  218. else if (300 <= code && code < 700)
  219. {
  220. delete s;
  221. }
  222. return 0;
  223. }
  224. static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  225. {
  226. struct sip_session_t* s = (struct sip_session_t*)session;
  227. struct sip_agent_t* uas = (struct sip_agent_t*)param;
  228. assert(0 == sip_uas_reply(t, 200, NULL, 0, param));
  229. if(s) delete s;
  230. return 0;
  231. }
  232. static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  233. {
  234. assert(0);
  235. return -1;
  236. }
  237. 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)
  238. {
  239. // assert(expires == 7200);
  240. // assert(0 == strcmp(user, "bob"));
  241. // assert(0 == strcmp(location, "192.0.2.4"));
  242. struct sip_agent_t* uas = (struct sip_agent_t*)param;
  243. return sip_uas_reply(t, 200, NULL, 0, param);
  244. }
  245. 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)
  246. {
  247. return sip_uas_reply(t, 200, NULL, 0, param);
  248. }
  249. 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)
  250. {
  251. printf("==> %.*s\n%.*s\n", (int)url->n, url->p, (int)bytes, (const char*)data);
  252. return 0;
  253. }
  254. // 24 Examples (p213)
  255. void sip_uas_message_test(void)
  256. {
  257. sip_timer_init();
  258. struct sip_uas_handler_t handler;
  259. handler.onregister = sip_uas_onregister;
  260. handler.oninvite = sip_uas_oninvite;
  261. handler.onack = sip_uas_onack;
  262. handler.onbye = sip_uas_onbye;
  263. handler.oncancel = sip_uas_oncancel;
  264. handler.onmessage = sip_uas_onmessage;
  265. handler.send = sip_uas_send;
  266. struct sip_agent_t* sip;
  267. sip = sip_agent_create(&handler);
  268. assert(0 == sip_register(sip));
  269. assert(0 == sip_invite(sip));
  270. assert(0 == sip_bye(sip));
  271. sip_agent_destroy(sip);
  272. sip_timer_cleanup();
  273. }