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.

119 lines
2.8KB

  1. #include "rtmp-internal.h"
  2. #include "rtmp-msgtypeid.h"
  3. #include "rtmp-util.h"
  4. #include <errno.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <assert.h>
  9. #define RTMP_CHUNK_SIZE_MINIMUM 64
  10. #define RTMP_CHUNK_SIZE_MAXIMUM 0x800000
  11. /// 5.4.1. Set Chunk Size (1)
  12. /// @return 0-error, >0-ok
  13. static int rtmp_read_chunk_size(const uint8_t* out, size_t size, uint32_t *chunkSize)
  14. {
  15. if (size >= 4)
  16. {
  17. be_read_uint32(out, chunkSize);
  18. if (*chunkSize < RTMP_CHUNK_SIZE_MINIMUM || *chunkSize > RTMP_CHUNK_SIZE_MAXIMUM)
  19. return 0;
  20. return 4;
  21. }
  22. return 0;
  23. }
  24. /// 5.4.2. Abort Message (2)
  25. /// @return 0-error, >0-ok
  26. static int rtmp_read_abort_message(const uint8_t* out, size_t size, uint32_t* chunkStreamId)
  27. {
  28. if (size >= 4)
  29. {
  30. be_read_uint32(out, chunkStreamId);
  31. return 4;
  32. }
  33. return 0;
  34. }
  35. /// 5.4.3. Acknowledgement (3)
  36. /// @return 0-error, >0-ok
  37. static int rtmp_read_acknowledgement(const uint8_t* out, size_t size, uint32_t* sequenceNumber)
  38. {
  39. if (size >= 4)
  40. {
  41. be_read_uint32(out, sequenceNumber);
  42. return 4;
  43. }
  44. return 0;
  45. }
  46. /// 5.4.4. Window Acknowledgement Size (5)
  47. /// @return 0-error, >0-ok
  48. static int rtmp_read_window_acknowledgement_size(const uint8_t* out, size_t size, uint32_t* windowSize)
  49. {
  50. if (size >= 4)
  51. {
  52. be_read_uint32(out, windowSize);
  53. return 4;
  54. }
  55. return 0;
  56. }
  57. /// 5.4.5. Set Peer Bandwidth (6)
  58. /// @return 0-error, >0-ok
  59. static int rtmp_read_set_peer_bandwidth(const uint8_t* out, size_t size, uint32_t *windowSize, uint8_t *limitType)
  60. {
  61. if (size >= 5)
  62. {
  63. be_read_uint32(out, windowSize);
  64. *limitType = out[4];
  65. return 5;
  66. }
  67. return 0;
  68. }
  69. int rtmp_control_handler(struct rtmp_t* rtmp, const struct rtmp_chunk_header_t* header, const uint8_t* data)
  70. {
  71. uint32_t chunk_stream_id = 0;
  72. assert(2 == header->cid);
  73. switch (header->type)
  74. {
  75. case RTMP_TYPE_SET_CHUNK_SIZE:
  76. assert(4 == header->length);
  77. return rtmp_read_chunk_size(data, header->length, &rtmp->in_chunk_size);
  78. case RTMP_TYPE_ABORT:
  79. assert(4 == header->length);
  80. if (4 == rtmp_read_abort_message(data, header->length, &chunk_stream_id))
  81. {
  82. rtmp->onabort(rtmp->param, chunk_stream_id);
  83. return 4;
  84. }
  85. return 0;
  86. case RTMP_TYPE_ACKNOWLEDGEMENT:
  87. assert(4 == header->length);
  88. return rtmp_read_acknowledgement(data, header->length, &rtmp->sequence_number);
  89. case RTMP_TYPE_WINDOW_ACKNOWLEDGEMENT_SIZE:
  90. assert(4 == header->length);
  91. return rtmp_read_window_acknowledgement_size(data, header->length, &rtmp->window_size);
  92. case RTMP_TYPE_SET_PEER_BANDWIDTH:
  93. assert(5 == header->length);
  94. if (5 == rtmp_read_set_peer_bandwidth(data, header->length, &rtmp->peer_bandwidth, &rtmp->limit_type))
  95. {
  96. rtmp->client.onbandwidth ? rtmp->client.onbandwidth(rtmp->param) : 0;
  97. return 5;
  98. }
  99. return 0;
  100. default:
  101. printf("unknown rtmp protocol control message: %d\n", (int)header->type);
  102. assert(0);
  103. return 0;
  104. }
  105. }