You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
14KB

  1. #include <memory>
  2. #include "sys/sock.h"
  3. #include "sip-uac.h"
  4. #include "sip-message.h"
  5. #include "sip-transport.h"
  6. #include "port/ip-route.h"
  7. #include "http-parser.h"
  8. #include "uri-parse.h"
  9. static struct sip_dialog_t* s_dialog;
  10. static struct sip_subscribe_t* s_subscribe;
  11. static struct sip_message_t* req2sip(const char* req)
  12. {
  13. struct sip_message_t* msg;
  14. msg = sip_message_create(SIP_MESSAGE_REQUEST);
  15. size_t n = strlen(req);
  16. http_parser_t* parser = http_parser_create(HTTP_PARSER_REQUEST, NULL, NULL);
  17. assert(0 == http_parser_input(parser, req, &n) && 0 == n);
  18. assert(0 == sip_message_load(msg, parser));
  19. http_parser_destroy(parser);
  20. return msg;
  21. }
  22. static struct sip_message_t* reply2sip(const char* reply)
  23. {
  24. struct sip_message_t* msg;
  25. msg = sip_message_create(SIP_MESSAGE_REPLY);
  26. size_t n = strlen(reply);
  27. http_parser_t* parser = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  28. assert(0 == http_parser_input(parser, reply, &n) && 0 == n);
  29. assert(0 == sip_message_load(msg, parser));
  30. http_parser_destroy(parser);
  31. return msg;
  32. }
  33. static int sip_uac_transport_via(void* transport, const char* destination, char protocol[16], char local[128], char dns[128])
  34. {
  35. int r;
  36. char ip[65];
  37. u_short port;
  38. struct uri_t* uri;
  39. struct sockaddr_storage ss;
  40. socklen_t len;
  41. len = sizeof(ss);
  42. memset(&ss, 0, sizeof(ss));
  43. strcpy(protocol, "UDP");
  44. uri = uri_parse(destination, strlen(destination));
  45. if (!uri)
  46. return -1; // invalid uri
  47. // TODO: sips port
  48. r = socket_addr_from(&ss, &len, "127.0.0.1" /*uri->host*/, uri->port ? uri->port : SIP_PORT);
  49. if (0 == r)
  50. {
  51. socket_addr_to((struct sockaddr*)&ss, len, ip, &port);
  52. r = ip_route_get(ip, local);
  53. if (0 == r)
  54. {
  55. len = sizeof(ss);
  56. if(0 == socket_addr_from(&ss, &len, local, 0))
  57. socket_addr_name((struct sockaddr*)&ss, len, dns, 128);
  58. if (SIP_PORT != port)
  59. snprintf(local + strlen(local), 128 - strlen(local), ":%hu", port);
  60. if (NULL == strchr(dns, '.'))
  61. snprintf(dns, 128, "%s", local); // don't have valid dns
  62. }
  63. }
  64. uri_free(uri);
  65. return r;
  66. }
  67. static int sip_uac_transport_send(void* transport, const void* data, size_t bytes)
  68. {
  69. //char p1[1024];
  70. //char p2[1024];
  71. ((char*)data)[bytes] = 0;
  72. printf("%s\n", (const char*)data);
  73. struct sip_message_t* msg = req2sip((const char*)data);
  74. struct sip_message_t* req = (struct sip_message_t*)transport;
  75. assert(msg->mode == req->mode && (cstreq(&msg->u.c.method, &req->u.c.method) || 0 == cstrcasecmp(&msg->u.c.method, "ACK")));
  76. // assert(sip_contact_write(&msg->to, p1, p1 + sizeof(p1)) > 0 && sip_contact_write(&req->to, p2, p2 + sizeof(p2)) > 0 && 0 == strcmp(p1, p2));
  77. // assert(sip_contact_write(&msg->from, p1, p1 + sizeof(p1)) > 0 && sip_contact_write(&req->from, p2, p2 + sizeof(p2)) > 0 && 0 == strcmp(p1, p2));
  78. return 0;
  79. }
  80. static int sip_uac_message_oninvite(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_dialog_t* dialog, int code, void** session)
  81. {
  82. s_dialog = dialog;
  83. if (200 <= code && code < 300)
  84. {
  85. *session = NULL;
  86. sip_uac_ack(t, NULL, 0);
  87. }
  88. return 0;
  89. }
  90. static int sip_uac_message_onbye(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  91. {
  92. return 0;
  93. }
  94. static int sip_uac_message_onsubscribe(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, struct sip_subscribe_t* subscribe, int code, void** session)
  95. {
  96. s_subscribe = subscribe;
  97. if (200 <= code && code < 300)
  98. {
  99. *session = NULL;
  100. }
  101. return 0;
  102. }
  103. static int sip_uac_message_onregister(void* param, const struct sip_message_t* reply, struct sip_uac_transaction_t* t, int code)
  104. {
  105. return 0;
  106. }
  107. static void sip_uac_message_register(struct sip_agent_t* sip, struct sip_transport_t* udp)
  108. {
  109. // F1 REGISTER Bob -> Registrar (p213)
  110. const char* f1 = "REGISTER sip:registrar.biloxi.com SIP/2.0\r\n"
  111. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7\r\n"
  112. "Max-Forwards: 70\r\n"
  113. "To: Bob <sip:bob@biloxi.com>\r\n"
  114. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  115. "Call-ID: 843817637684230@998sdasdh09\r\n"
  116. "CSeq: 1826 REGISTER\r\n"
  117. "Contact: <sip:bob@192.0.2.4>\r\n"
  118. "Expires: 7200\r\n"
  119. "Content-Length: 0\r\n\r\n";
  120. // F2 200 OK Registrar -> Bob (p214)
  121. const char* f2 = "SIP/2.0 200 OK\r\n"
  122. "Via: SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7;received=192.0.2.4\r\n"
  123. "To: Bob <sip:bob@biloxi.com>;tag=2493k59kd\r\n"
  124. "From: Bob <sip:bob@biloxi.com>;tag=456248\r\n"
  125. "Call-ID: 843817637684230@998sdasdh09\r\n"
  126. "CSeq: 1826 REGISTER\r\n"
  127. "Contact: <sip:bob@192.0.2.4>\r\n"
  128. "Expires: 7200\r\n"
  129. "Content-Length: 0\r\n\r\n";
  130. struct sip_message_t* req = req2sip(f1);
  131. struct sip_message_t* reply = reply2sip(f2);
  132. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_register(sip, "Bob <sip:bob@biloxi.com>", NULL, 7200, sip_uac_message_onregister, NULL), sip_uac_transaction_release);
  133. //t = sip_uac_register(sip, "Bob <sip:bob@biloxi.com>", "sip:registrar.biloxi.com", 7200, sip_uac_message_onregister, NULL);
  134. sip_uac_add_header(t.get(), "Via", "SIP/2.0/UDP bobspc.biloxi.com:5060;branch=z9hG4bKnashds7");
  135. sip_uac_add_header(t.get(), "CSeq", "1826 REGISTER");// modify cseq.id
  136. assert(0 == sip_uac_send(t.get(), NULL, 0, udp, req));
  137. assert(0 == sip_agent_input(sip, reply, NULL));
  138. sip_message_destroy(req);
  139. sip_message_destroy(reply);
  140. }
  141. static void sip_uac_message_invite(struct sip_agent_t* sip, struct sip_transport_t* udp)
  142. {
  143. // F1 INVITE Alice -> atlanta.com proxy (p214)
  144. const char* f1 = "INVITE sip:bob@biloxi.com SIP/2.0\r\n"
  145. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8\r\n"
  146. "Max-Forwards: 70\r\n"
  147. "To: Bob <sip:bob@biloxi.com>\r\n"
  148. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  149. "Call-ID: a84b4c76e66710\r\n"
  150. "CSeq: 314159 INVITE\r\n"
  151. "Contact: <sip:alice@pc33.atlanta.com>\r\n"
  152. "Content-Type: application/sdp\r\n"
  153. "Content-Length: 0\r\n\r\n";
  154. // F2 100 Trying atlanta.com proxy -> Alice (p215)
  155. const char* f2 = "SIP/2.0 100 Trying\r\n"
  156. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  157. "To: Bob <sip:bob@biloxi.com>\r\n"
  158. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  159. "Call-ID: a84b4c76e66710\r\n"
  160. "CSeq: 314159 INVITE\r\n"
  161. "Content-Length: 0\r\n\r\n";
  162. // F8 180 Ringing atlanta.com proxy -> Alice (217)
  163. const char* f8 = "SIP/2.0 180 Ringing\r\n"
  164. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  165. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  166. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  167. "Call-ID: a84b4c76e66710\r\n"
  168. "Contact: <sip:bob@192.0.2.4>\r\n"
  169. "CSeq: 314159 INVITE\r\n"
  170. "Content-Length: 0\r\n\r\n";
  171. // F11 200 OK atlanta.com proxy -> Alice (p218)
  172. const char* f11 = "SIP/2.0 200 OK\r\n"
  173. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  174. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  175. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  176. "Call-ID: a84b4c76e66710\r\n"
  177. "CSeq: 314159 INVITE\r\n"
  178. "Contact: <sip:bob@192.0.2.4>\r\n"
  179. "Content-Type: application/sdp\r\n"
  180. "Content-Length: 0\r\n\r\n";
  181. // F12 ACK Alice -> Bob (p218)
  182. const char* f12 = "ACK sip:bob@192.0.2.4 SIP/2.0\r\n"
  183. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  184. "Max-Forwards: 70\r\n"
  185. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  186. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  187. "Call-ID: a84b4c76e66710\r\n"
  188. "CSeq: 314159 ACK\r\n"
  189. "Content-Length: 0\r\n\r\n";
  190. const char* f13 = "SIP/2.0 603 Decline\r\n"
  191. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8;received=192.0.2.1\r\n"
  192. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  193. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  194. "Call-ID: a84b4c76e66710\r\n"
  195. "CSeq: 314159 INVITE\r\n"
  196. "Content-Type: application/sdp\r\n"
  197. "Content-Length: 0\r\n\r\n";
  198. struct sip_message_t* req = req2sip(f1);
  199. struct sip_message_t* reply100 = reply2sip(f2);
  200. struct sip_message_t* reply180 = reply2sip(f8);
  201. struct sip_message_t* reply200 = reply2sip(f11);
  202. struct sip_message_t* reply603 = reply2sip(f13);
  203. struct sip_message_t* ack = req2sip(f12);
  204. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_invite(sip, "Alice <sip:alice@atlanta.com>;tag=1928301774", "Bob <sip:bob@biloxi.com>", sip_uac_message_oninvite, NULL), sip_uac_transaction_release);
  205. sip_uac_add_header(t.get(), "Via", "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8");
  206. sip_uac_add_header(t.get(), "Call-ID", "a84b4c76e66710");// modify call-id
  207. sip_uac_add_header(t.get(), "CSeq", "314159 INVITE");// modify cseq.id
  208. sip_uac_add_header(t.get(), "Content-Type", "application/sdp");
  209. sip_uac_add_header_int(t.get(), "Content-Length", 3);
  210. sip_uac_send(t.get(), "sdp", 3, udp, req);
  211. sip_agent_input(sip, reply100, NULL);
  212. sip_agent_input(sip, reply180, NULL);
  213. sip_agent_input(sip, reply100, NULL);
  214. sip_agent_input(sip, reply180, NULL);
  215. // sip_agent_input(sip, reply603);
  216. sip_agent_input(sip, reply200, NULL);
  217. sip_agent_input(sip, reply180, NULL);
  218. sip_agent_input(sip, reply100, NULL);
  219. sip_agent_input(sip, reply200, NULL);
  220. sip_message_destroy(req);
  221. sip_message_destroy(reply100);
  222. sip_message_destroy(reply180);
  223. sip_message_destroy(reply200);
  224. sip_message_destroy(ack);
  225. }
  226. static void sip_uac_message_bye(struct sip_agent_t* sip, struct sip_transport_t* udp)
  227. {
  228. // F13 BYE Alice -> Bob (p218)
  229. const char* f13 = "BYE sip:bob@192.0.2.4 SIP/2.0\r\n"
  230. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  231. "Max-Forwards: 70\r\n"
  232. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  233. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  234. "Call-ID: a84b4c76e66710\r\n"
  235. "CSeq: 314160 BYE\r\n"
  236. "Content-Length: 0\r\n\r\n";
  237. // F14 200 OK Alice -> Bob (p219)
  238. const char* f14 = "SIP/2.0 200 OK\r\n"
  239. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9\r\n"
  240. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  241. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  242. "Call-ID: a84b4c76e66710\r\n"
  243. "CSeq: 314160 BYE\r\n"
  244. "Content-Length: 0\r\n\r\n";
  245. struct sip_message_t* req = req2sip(f13);
  246. struct sip_message_t* reply = reply2sip(f14);
  247. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_bye(sip, s_dialog, sip_uac_message_onbye, NULL), sip_uac_transaction_release);
  248. sip_uac_add_header(t.get(), "Via", "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds9");
  249. sip_uac_add_header_int(t.get(), "Content-Length", 0);
  250. sip_uac_send(t.get(), NULL, 0, udp, req);
  251. sip_agent_input(sip, reply, NULL);
  252. sip_message_destroy(req);
  253. sip_message_destroy(reply);
  254. }
  255. static void sip_uac_message_subscribe(struct sip_agent_t* sip, struct sip_transport_t* udp)
  256. {
  257. const char* f1 = "SUBSCRIBE sip:bob@biloxi.com SIP/2.0\r\n"
  258. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds10\r\n"
  259. "Max-Forwards: 70\r\n"
  260. "To: Bob <sip:bob@biloxi.com>\r\n"
  261. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  262. "Call-ID: a84b4c76e66710\r\n"
  263. "CSeq: 314159 SUBSCRIBE\r\n"
  264. "Contact: <sip:alice@pc33.atlanta.com>\r\n"
  265. "Event: presence\r\n"
  266. "Expires: 60\r\n"
  267. "Content-Type: application/sdp\r\n"
  268. "Content-Length: 0\r\n\r\n";
  269. const char* f2 = "SIP/2.0 200 OK\r\n"
  270. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds10;received=192.0.2.1\r\n"
  271. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  272. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  273. "Call-ID: a84b4c76e66710\r\n"
  274. "CSeq: 314159 SUBSCRIBE\r\n"
  275. "Contact: <sip:bob@192.0.2.4>\r\n"
  276. "Event: presence\r\n"
  277. "Expires: 60\r\n"
  278. "Content-Type: application/sdp\r\n"
  279. "Content-Length: 0\r\n\r\n";
  280. // re-subscribe
  281. const char* f3 = "SUBSCRIBE sip:bob@biloxi.com SIP/2.0\r\n"
  282. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds11\r\n"
  283. "Max-Forwards: 70\r\n"
  284. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  285. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  286. "Call-ID: a84b4c76e66710\r\n"
  287. "CSeq: 314160 SUBSCRIBE\r\n"
  288. "Contact: <sip:alice@pc33.atlanta.com>\r\n"
  289. "Event: presence\r\n"
  290. "Expires: 60\r\n"
  291. "Content-Type: application/sdp\r\n"
  292. "Content-Length: 0\r\n\r\n";
  293. const char* f4 = "SIP/2.0 200 OK\r\n"
  294. "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds11;received=192.0.2.1\r\n"
  295. "To: Bob <sip:bob@biloxi.com>;tag=a6c85cf\r\n"
  296. "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
  297. "Call-ID: a84b4c76e66710\r\n"
  298. "CSeq: 314160 SUBSCRIBE\r\n"
  299. "Contact: <sip:bob@192.0.2.4>\r\n"
  300. "Event: presence\r\n"
  301. "Expires: 60\r\n"
  302. "Content-Type: application/sdp\r\n"
  303. "Content-Length: 0\r\n\r\n";
  304. struct sip_message_t* req = req2sip(f1);
  305. struct sip_message_t* reply200 = reply2sip(f2);
  306. std::shared_ptr<sip_uac_transaction_t> t(sip_uac_subscribe(sip, "Alice <sip:alice@atlanta.com>;tag=1928301774", "Bob <sip:bob@biloxi.com>", "presence", 60, sip_uac_message_onsubscribe, NULL), sip_uac_transaction_release);
  307. sip_uac_add_header(t.get(), "Via", "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds10");
  308. sip_uac_add_header(t.get(), "Call-ID", "a84b4c76e66710");// modify call-id
  309. sip_uac_add_header(t.get(), "CSeq", "314159 SUBSCRIBE");// modify cseq.id
  310. sip_uac_add_header(t.get(), "Content-Type", "application/sdp");
  311. sip_uac_add_header_int(t.get(), "Content-Length", 0);
  312. sip_uac_send(t.get(), "", 0, udp, req);
  313. sip_agent_input(sip, reply200, NULL);
  314. sip_agent_input(sip, reply200, NULL);
  315. sip_message_destroy(req);
  316. sip_message_destroy(reply200);
  317. struct sip_message_t* req2 = req2sip(f3);
  318. struct sip_message_t* reply2 = reply2sip(f4);
  319. std::shared_ptr<sip_uac_transaction_t> t2(sip_uac_resubscribe(sip, s_subscribe, 60, sip_uac_message_onsubscribe, NULL), sip_uac_transaction_release);
  320. sip_uac_add_header(t2.get(), "Via", "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds11");
  321. // sip_uac_add_header(t2.get(), "Call-ID", "a84b4c76e66710");// modify call-id
  322. // sip_uac_add_header(t2.get(), "CSeq", "314160 SUBSCRIBE");// modify cseq.id
  323. sip_uac_add_header(t2.get(), "Content-Type", "application/sdp");
  324. sip_uac_add_header_int(t2.get(), "Content-Length", 0);
  325. sip_uac_send(t2.get(), "", 0, udp, req);
  326. sip_agent_input(sip, reply2, NULL);
  327. sip_agent_input(sip, reply2, NULL);
  328. sip_message_destroy(req2);
  329. sip_message_destroy(reply2);
  330. }
  331. // 24 Examples (p213)
  332. void sip_uac_message_test(void)
  333. {
  334. struct sip_transport_t udp = {
  335. sip_uac_transport_via,
  336. sip_uac_transport_send,
  337. };
  338. struct sip_uas_handler_t handler;
  339. memset(&handler, 0, sizeof(handler));
  340. struct sip_agent_t* sip = sip_agent_create(&handler);
  341. sip_uac_message_register(sip, &udp);
  342. sip_uac_message_invite(sip, &udp);
  343. sip_uac_message_bye(sip, &udp);
  344. sip_uac_message_subscribe(sip, &udp);
  345. sip_agent_destroy(sip);
  346. }