Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

184 wiersze
4.7KB

  1. #include "rtsp-server-aio.h"
  2. #include "aio-socket.h"
  3. #include "sys/atomic.h"
  4. #include "sys/locker.h"
  5. #include "sockutil.h"
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. struct rtsp_udp_transport_t
  10. {
  11. int32_t ref;
  12. int running;
  13. socket_t socket;
  14. aio_socket_t aio;
  15. size_t size; // udp buffer size
  16. struct rtsp_handler_t handler;
  17. void* param;
  18. };
  19. struct rtsp_udp_session_t
  20. {
  21. struct rtsp_udp_transport_t* transport;
  22. struct rtsp_server_t *rtsp;
  23. struct sockaddr_storage addr;
  24. socklen_t addrlen;
  25. };
  26. static void rtsp_transport_udp_release(struct rtsp_udp_transport_t* t);
  27. static void rtsp_transport_udp_recv(struct rtsp_udp_transport_t* t);
  28. static void rtsp_transport_udp_onrecv(void* param, int code, size_t bytes, const struct sockaddr* addr, socklen_t addrlen);
  29. static int rtsp_transport_udp_send(void* param, const void* data, size_t bytes);
  30. void* rtsp_transport_udp_create(const char* ip, int port, struct rtsp_handler_t* handler, void* param)
  31. {
  32. struct rtsp_udp_transport_t* t;
  33. t = (struct rtsp_udp_transport_t*)calloc(1, sizeof(*t));
  34. if (t)
  35. {
  36. t->ref = 1;
  37. t->size = 4 * 1024; // 2k
  38. t->running = 1;
  39. t->param = param;
  40. memcpy(&t->handler, handler, sizeof(t->handler));
  41. handler->send = rtsp_transport_udp_send;
  42. t->socket = socket_udp_bind(0 /*AF_UNSPEC*/, ip, (u_short)port, 0, 1);
  43. if (socket_invalid == t->socket)
  44. {
  45. free(t);
  46. return NULL;
  47. }
  48. t->aio = aio_socket_create(t->socket, 1);
  49. rtsp_transport_udp_recv(t);
  50. }
  51. return t;
  52. }
  53. void rtsp_transport_udp_destroy(void* transport)
  54. {
  55. struct rtsp_udp_transport_t* t;
  56. t = (struct rtsp_udp_transport_t*)transport;
  57. t->running = 0;
  58. rtsp_transport_udp_release(t);
  59. }
  60. static struct rtsp_udp_session_t* rtsp_udp_session_create(struct rtsp_udp_transport_t* t)
  61. {
  62. struct rtsp_udp_session_t* session;
  63. session = (struct rtsp_udp_session_t*)malloc(sizeof(*session) + t->size /*udp recv buffer*/);
  64. if (session)
  65. {
  66. atomic_increment32(&t->ref);
  67. session->transport = t;
  68. }
  69. return session;
  70. }
  71. static void rtsp_udp_session_destroy(struct rtsp_udp_session_t* session)
  72. {
  73. struct rtsp_udp_transport_t* transport;
  74. transport = (struct rtsp_udp_transport_t*)session->transport;
  75. rtsp_transport_udp_release(transport);
  76. // TODO: reuse rtsp server
  77. if (session->rtsp)
  78. {
  79. rtsp_server_destroy(session->rtsp);
  80. session->rtsp = NULL;
  81. }
  82. free(session);
  83. }
  84. static void rtsp_transport_udp_ondestroy(void* param)
  85. {
  86. struct rtsp_udp_transport_t* t;
  87. t = (struct rtsp_udp_transport_t*)param;
  88. free(t);
  89. }
  90. static void rtsp_transport_udp_release(struct rtsp_udp_transport_t* t)
  91. {
  92. if (0 == atomic_decrement32(&t->ref))
  93. {
  94. assert(invalid_aio_socket != t->aio);
  95. aio_socket_destroy(t->aio, rtsp_transport_udp_ondestroy, t);
  96. }
  97. }
  98. static void rtsp_transport_udp_recv(struct rtsp_udp_transport_t* t)
  99. {
  100. void* buffer;
  101. struct rtsp_udp_session_t* session;
  102. session = rtsp_udp_session_create(t);
  103. if (session)
  104. {
  105. buffer = session + 1;
  106. if (!t->running || 0 != aio_socket_recvfrom(t->aio, buffer, t->size, rtsp_transport_udp_onrecv, session))
  107. rtsp_udp_session_destroy(session);
  108. }
  109. else
  110. {
  111. // do nothing
  112. }
  113. }
  114. static void rtsp_transport_udp_onrecv(void* param, int code, size_t bytes, const struct sockaddr* addr, socklen_t addrlen)
  115. {
  116. char ip[65];
  117. unsigned short port;
  118. struct rtsp_udp_session_t* session;
  119. struct rtsp_udp_transport_t* transport;
  120. session = (struct rtsp_udp_session_t*)param;
  121. transport = (struct rtsp_udp_transport_t*)session->transport;
  122. if (0 == code && bytes > 0)
  123. {
  124. size_t remain = bytes;
  125. rtsp_transport_udp_recv(transport); // recv more
  126. socket_addr_to(addr, addrlen, ip, &port);
  127. assert(addrlen <= sizeof(session->addr));
  128. session->addrlen = addrlen < sizeof(session->addr) ? addrlen : sizeof(session->addr);
  129. memcpy(&session->addr, addr, session->addrlen); // save client ip/port
  130. session->rtsp = rtsp_server_create(ip, port, &session->transport->handler, session->transport->param, session);
  131. code = rtsp_server_input(session->rtsp, session + 1, &remain);
  132. }
  133. if (0 != code || bytes < 1)
  134. {
  135. assert(0);
  136. rtsp_udp_session_destroy(session);
  137. }
  138. }
  139. static void rtsp_transport_udp_onsend(void* param, int code, size_t bytes)
  140. {
  141. struct rtsp_udp_session_t* session;
  142. session = (struct rtsp_udp_session_t*)param;
  143. // session->server->onsend(session, code, bytes);
  144. rtsp_udp_session_destroy(session);
  145. }
  146. static int rtsp_transport_udp_send(void* param, const void* data, size_t bytes)
  147. {
  148. int r;
  149. struct rtsp_udp_session_t* session;
  150. struct rtsp_udp_transport_t* transport;
  151. session = (struct rtsp_udp_session_t*)param;
  152. transport = (struct rtsp_udp_transport_t*)session->transport;
  153. if (transport->running)
  154. r = socket_sendto(transport->socket, data, bytes, 0, (struct sockaddr*)&session->addr, session->addrlen);
  155. else
  156. r = -1;
  157. rtsp_transport_udp_onsend(session, r, r);
  158. return 0;
  159. }