選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

206 行
6.0KB

  1. #include <map>
  2. #include <memory>
  3. #include <string>
  4. #include "sockutil.h"
  5. #include "sockpair.h"
  6. #include "sys/thread.h"
  7. #include "sys/system.h"
  8. #include "sip-uac.h"
  9. #include "sip-uas.h"
  10. #include "sip-message.h"
  11. #include "sip-transport.h"
  12. #include "sip-timer.h"
  13. #include "port/ip-route.h"
  14. #include "http-parser.h"
  15. #include "http-header-auth.h"
  16. #include "rtsp-media.h"
  17. #include "../test/media/pcm-file-source.h"
  18. #include "../test/media/h264-file-source.h"
  19. #include "../test/rtp-udp-transport.h"
  20. #include "uri-parse.h"
  21. #include "cstringext.h"
  22. #include "base64.h"
  23. #include "sdp.h"
  24. #include "md5.h"
  25. #include <stdint.h>
  26. #include <errno.h>
  27. #define NAME "tao3"
  28. #define HOST "192.168.3.34"
  29. struct sip_uas_test_t
  30. {
  31. socket_t udp;
  32. socklen_t addrlen;
  33. struct sockaddr_storage addr;
  34. http_parser_t* request;
  35. http_parser_t* response;
  36. struct sip_agent_t* sip;
  37. };
  38. struct sip_media_t
  39. {
  40. struct rtsp_media_t medias[3];
  41. int nmedia;
  42. std::shared_ptr<IRTPTransport> transport;
  43. std::shared_ptr<IMediaSource> source;
  44. unsigned short port[2];
  45. };
  46. static int sip_uas_transport_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)
  47. {
  48. struct sip_uas_test_t *test = (struct sip_uas_test_t *)param;
  49. //char p1[1024];
  50. //char p2[1024];
  51. printf("%.*s\n\n", (int)bytes, (const char*)data);
  52. int r = socket_sendto(test->udp, data, bytes, 0, (struct sockaddr*)&test->addr, test->addrlen);
  53. return r == bytes ? 0 : -1;
  54. }
  55. 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)
  56. {
  57. const char* pattern = "v=0\n"
  58. "o=- 0 0 IN IP4 %s\n"
  59. "s=Play\n"
  60. "c=IN IP4 %s\n"
  61. "t=0 0\n"
  62. "m=audio %hu RTP/AVP 8\n"
  63. //"a=rtpmap:96 PS/90000\n"
  64. //"a=fmtp:98 profile-level-id=42800D;packetization-mode=1;sprop-parameter-sets=Z0KADYiLULBLQgAAIygAAr8gCAAAAAAB,aM44gAAAAAE=\n"
  65. ;
  66. char reply[1024];
  67. const cstring_t* h = sip_message_get_header_by_name(req, "Content-Type");
  68. if (0 == cstrcasecmp(h, "Application/SDP"))
  69. {
  70. socklen_t len = 0;
  71. struct sip_media_t* m = new sip_media_t;
  72. m->transport.reset(new RTPUdpTransport());
  73. m->nmedia = rtsp_media_sdp((const char*)data, bytes, m->medias, sizeof(m->medias) / sizeof(m->medias[0]));
  74. assert(m->nmedia > 0);
  75. assert(0 == strcasecmp("IP4", m->medias[0].addrtype) || 0 == strcasecmp("IP6", m->medias[0].addrtype));
  76. m->port[0] = m->medias[0].port[0];
  77. m->port[1] = m->medias[0].nport > 1 ? m->medias[0].port[1] : (m->medias[0].port[0] + 1);
  78. assert(0 == ((RTPUdpTransport*)m->transport.get())->Init(m->medias[0].address, m->port));
  79. m->source.reset(new PCMFileSource("C:\\Users\\Administrator\\sintel-1280.pcm"));
  80. std::string sdp;
  81. m->source->GetSDPMedia(sdp);
  82. sip_uas_add_header(t, "Content-Type", "application/sdp");
  83. sip_uas_add_header(t, "Contact", "sip:" NAME "@" HOST);
  84. snprintf(reply, sizeof(reply), pattern, HOST, HOST, m->port[0]);
  85. assert(0 == sip_uas_reply(t, 200, reply, strlen(reply), param));
  86. *session = m;
  87. return 0;
  88. }
  89. else
  90. {
  91. assert(0);
  92. return 0;
  93. }
  94. }
  95. static int STDCALL rtsp_play_thread(void* param)
  96. {
  97. struct sip_media_t* m = (struct sip_media_t*)param;
  98. m->source->SetTransport("track1", m->transport);
  99. while (1)
  100. {
  101. m->source->Play();
  102. system_sleep(10);
  103. }
  104. delete m;
  105. }
  106. /// @param[in] code 0-ok, other-sip status code
  107. /// @return 0-ok, other-error
  108. 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)
  109. {
  110. struct sip_media_t* m = (struct sip_media_t*)session;
  111. if (200 <= code && code < 300)
  112. {
  113. pthread_t th;
  114. thread_create(&th, rtsp_play_thread, m);
  115. }
  116. else
  117. {
  118. delete m;
  119. assert(0);
  120. }
  121. return 0;
  122. }
  123. /// on terminating a session(dialog)
  124. static int sip_uas_onbye(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  125. {
  126. return sip_uas_reply(t, 200, NULL, 0, param);
  127. }
  128. /// cancel a transaction(should be an invite transaction)
  129. static int sip_uas_oncancel(void* param, const struct sip_message_t* req, struct sip_uas_transaction_t* t, void* session)
  130. {
  131. return sip_uas_reply(t, 200, NULL, 0, param);
  132. }
  133. /// @param[in] expires in seconds
  134. 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)
  135. {
  136. return sip_uas_reply(t, 200, NULL, 0, param);
  137. }
  138. static void sip_uas_loop(struct sip_uas_test_t *test)
  139. {
  140. uint8_t buffer[2 * 1024];
  141. http_parser_t* parser;
  142. do
  143. {
  144. memset(buffer, 0, sizeof(buffer));
  145. test->addrlen = sizeof(test->addr);
  146. int r = socket_recvfrom(test->udp, buffer, sizeof(buffer), 0, (struct sockaddr*)&test->addr, &test->addrlen);
  147. if(-1 == r && EINTR == errno)
  148. continue;
  149. printf("\n%s\n", buffer);
  150. parser = 0 == strncasecmp("SIP", (char*)buffer, 3) ? test->request: test->response;
  151. size_t n = r;
  152. assert(0 == http_parser_input(parser, buffer, &n));
  153. struct sip_message_t* msg = sip_message_create(parser==test->response? SIP_MESSAGE_REQUEST : SIP_MESSAGE_REPLY);
  154. assert(0 == sip_message_load(msg, parser));
  155. assert(0 == sip_agent_input(test->sip, msg, test));
  156. sip_message_destroy(msg);
  157. http_parser_clear(parser);
  158. } while (1);
  159. }
  160. void sip_uas_test2(void)
  161. {
  162. sip_timer_init();
  163. struct sip_uas_handler_t handler;
  164. handler.onregister = sip_uas_onregister;
  165. handler.oninvite = sip_uas_oninvite;
  166. handler.onack = sip_uas_onack;
  167. handler.onbye = sip_uas_onbye;
  168. handler.oncancel = sip_uas_oncancel;
  169. handler.send = sip_uas_transport_send;
  170. struct sip_uas_test_t test;
  171. test.udp = socket_udp();
  172. test.sip = sip_agent_create(&handler);
  173. test.request = http_parser_create(HTTP_PARSER_RESPONSE, NULL, NULL);
  174. test.response = http_parser_create(HTTP_PARSER_REQUEST, NULL, NULL);
  175. socket_bind_any(test.udp, SIP_PORT);
  176. sip_uas_loop(&test);
  177. sip_agent_destroy(test.sip);
  178. socket_close(test.udp);
  179. http_parser_destroy(test.request);
  180. http_parser_destroy(test.response);
  181. sip_timer_cleanup();
  182. }