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.

177 wiersze
4.4KB

  1. #include "rtsp-server-aio.h"
  2. #include "aio-transport.h"
  3. #include "rtp-over-rtsp.h"
  4. #include "sys/sock.h"
  5. #include "sys/atomic.h"
  6. #include "sys/system.h"
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <assert.h>
  10. #include <errno.h>
  11. #define TIMEOUT_RECV 65000
  12. #define TIMEOUT_SEND 10000
  13. struct rtsp_session_t
  14. {
  15. socket_t socket;
  16. aio_transport_t* aio;
  17. struct rtp_over_rtsp_t rtp;
  18. int rtsp_need_more_data;
  19. uint8_t buffer[4 * 1024];
  20. struct rtsp_server_t *rtsp;
  21. struct sockaddr_storage addr;
  22. socklen_t addrlen;
  23. void (*onerror)(void* param, rtsp_server_t* rtsp, int code);
  24. void (*onrtp)(void* param, uint8_t channel, const void* data, uint16_t bytes);
  25. void* param;
  26. };
  27. static void rtsp_session_ondestroy(void* param)
  28. {
  29. struct rtsp_session_t *session;
  30. session = (struct rtsp_session_t *)param;
  31. // user call rtsp_server_destroy
  32. if (session->rtsp)
  33. {
  34. rtsp_server_destroy(session->rtsp);
  35. session->rtsp = NULL;
  36. }
  37. if (session->rtp.data)
  38. {
  39. assert(session->rtp.capacity > 0);
  40. free(session->rtp.data);
  41. session->rtp.data = NULL;
  42. session->rtp.capacity = 0;
  43. }
  44. #if defined(_DEBUG) || defined(DEBUG)
  45. memset(session, 0xCC, sizeof(*session));
  46. #endif
  47. free(session);
  48. }
  49. static void rtsp_session_onrecv(void* param, int code, size_t bytes)
  50. {
  51. size_t remain;
  52. const uint8_t* p, *end;
  53. struct rtsp_session_t *session;
  54. session = (struct rtsp_session_t *)param;
  55. if (0 == code && 0 == bytes)
  56. code = ECONNRESET;
  57. if (0 == code)
  58. {
  59. p = session->buffer;
  60. end = session->buffer + bytes;
  61. do
  62. {
  63. if (0 == session->rtsp_need_more_data && ('$' == *p || 0 != session->rtp.state))
  64. {
  65. p = rtp_over_rtsp(&session->rtp, p, end);
  66. }
  67. else
  68. {
  69. remain = end - p;
  70. code = rtsp_server_input(session->rtsp, p, &remain);
  71. session->rtsp_need_more_data = code;
  72. if (0 == code)
  73. {
  74. // TODO: pipeline remain data
  75. assert(bytes > remain);
  76. assert(0 == remain || '$' == *(end - remain));
  77. }
  78. p = end - remain;
  79. }
  80. } while (p < end && 0 == code);
  81. if (code >= 0)
  82. {
  83. // need more data
  84. code = aio_transport_recv(session->aio, session->buffer, sizeof(session->buffer));
  85. }
  86. }
  87. // error or peer closed
  88. if (0 != code || 0 == bytes)
  89. {
  90. session->onerror(session->param, session->rtsp, code ? code : ECONNRESET);
  91. aio_transport_destroy(session->aio);
  92. }
  93. }
  94. static void rtsp_session_onsend(void* param, int code, size_t bytes)
  95. {
  96. struct rtsp_session_t *session;
  97. session = (struct rtsp_session_t *)param;
  98. // session->server->onsend(session, code, bytes);
  99. if (0 != code)
  100. {
  101. session->onerror(session->param, session->rtsp, code);
  102. aio_transport_destroy(session->aio);
  103. }
  104. (void)bytes;
  105. }
  106. static int rtsp_session_send(void* ptr, const void* data, size_t bytes)
  107. {
  108. struct rtsp_session_t *session;
  109. session = (struct rtsp_session_t *)ptr;
  110. //return aio_tcp_transport_send(session->aio, data, bytes);
  111. // TODO: send multiple rtp packet once time
  112. return bytes == socket_send(session->socket, data, bytes, 0) ? 0 : -1;
  113. }
  114. int rtsp_transport_tcp_create(socket_t socket, const struct sockaddr* addr, socklen_t addrlen, struct aio_rtsp_handler_t* handler, void* param)
  115. {
  116. char ip[65];
  117. unsigned short port;
  118. struct rtsp_session_t *session;
  119. struct rtsp_handler_t rtsphandler;
  120. struct aio_transport_handler_t h;
  121. memset(&h, 0, sizeof(h));
  122. h.ondestroy = rtsp_session_ondestroy;
  123. h.onrecv = rtsp_session_onrecv;
  124. h.onsend = rtsp_session_onsend;
  125. memcpy(&rtsphandler, &handler->base, sizeof(rtsphandler));
  126. rtsphandler.send = rtsp_session_send;
  127. session = (struct rtsp_session_t*)calloc(1, sizeof(*session));
  128. if (!session) return -ENOMEM;
  129. session->socket = socket;
  130. socket_addr_to(addr, addrlen, ip, &port);
  131. assert(addrlen <= sizeof(session->addr));
  132. session->addrlen = addrlen < sizeof(session->addr) ? addrlen : sizeof(session->addr);
  133. memcpy(&session->addr, addr, session->addrlen); // save client ip/port
  134. session->param = param;
  135. session->onerror = handler->onerror;
  136. session->aio = aio_transport_create(socket, &h, session);
  137. session->rtsp = rtsp_server_create(ip, port, &rtsphandler, param, session); // reuse-able, don't need create in every link
  138. if (!session->rtsp || !session->aio)
  139. {
  140. rtsp_session_ondestroy(session);
  141. return -ENOMEM;
  142. }
  143. session->rtp.param = param;
  144. session->rtp.onrtp = handler->onrtp;
  145. aio_transport_set_timeout(session->aio, TIMEOUT_RECV, TIMEOUT_SEND);
  146. if (0 != aio_transport_recv(session->aio, session->buffer, sizeof(session->buffer)))
  147. {
  148. rtsp_session_ondestroy(session);
  149. return -ENOTCONN;
  150. }
  151. return 0;
  152. }