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.

769 line
26KB

  1. #include "rtp-internal.h"
  2. #include "rtp-util.h"
  3. #include <errno.h>
  4. // https://www.iana.org/assignments/rtcp-xr-block-types/rtcp-xr-block-types.xhtml
  5. /*
  6. BT Name Reference
  7. 1 Loss RLE Report Block [RFC3611]
  8. 2 Duplicate RLE Report Block [RFC3611]
  9. 3 Packet Receipt Times Report Block [RFC3611]
  10. 4 Receiver Reference Time Report Block [RFC3611]
  11. 5 DLRR Report Block [RFC3611]
  12. 6 Statistics Summary Report Block [RFC3611]
  13. 7 VoIP Metrics Report Block [RFC3611]
  14. 8 RTCP XR [RFC5093]
  15. 9 Texas Instruments Extended VoIP Quality Block [http://focus.ti.com/general/docs/bcg/bcgdoccenter.tsp?templateId=6116&navigationId=12078#42][David_Lide]
  16. 10 Post-repair Loss RLE Report Block [RFC5725]
  17. 11 Multicast Acquisition Report Block [RFC6332]
  18. 12 IDMS Report Block [RFC7272]
  19. 13 ECN Summary Report [RFC6679]
  20. 14 Measurement Information Block [RFC6776]
  21. 15 Packet Delay Variation Metrics Block [RFC6798]
  22. 16 Delay Metrics Block [RFC6843]
  23. 17 Burst/Gap Loss Summary Statistics Block [RFC7004]
  24. 18 Burst/Gap Discard Summary Statistics Block [RFC7004]
  25. 19 Frame Impairment Statistics Summary [RFC7004]
  26. 20 Burst/Gap Loss Metrics Block [RFC6958]
  27. 21 Burst/Gap Discard Metrics Block [RFC7003][RFC Errata 3735]
  28. 22 MPEG2 Transport Stream PSI-Independent Decodability Statistics Metrics Block [RFC6990]
  29. 23 De-Jitter Buffer Metrics Block [RFC7005]
  30. 24 Discard Count Metrics Block [RFC7002]
  31. 25 DRLE (Discard RLE Report) [RFC7097]
  32. 26 BDR (Bytes Discarded Report) [RFC7243]
  33. 27 RFISD (RTP Flows Initial Synchronization Delay) [RFC7244]
  34. 28 RFSO (RTP Flows Synchronization Offset Metrics Block) [RFC7244]
  35. 29 MOS Metrics Block [RFC7266]
  36. 30 LCB (Loss Concealment Metrics Block) [RFC7294, Section 4.1]
  37. 31 CSB (Concealed Seconds Metrics Block) [RFC7294, Section 4.1]
  38. 32 MPEG2 Transport Stream PSI Decodability Statistics Metrics Block [RFC7380]
  39. 33 Post-Repair Loss Count Metrics Report Block [RFC7509]
  40. 34 Video Loss Concealment Metric Report Block [RFC7867]
  41. 35 Independent Burst/Gap Discard Metrics Block [RFC8015]
  42. 36-254 Unassigned
  43. 255 Reserved for future extensions [RFC3611]
  44. */
  45. /*
  46. Parameter Reference
  47. pkt-loss-rle [RFC3611]
  48. pkt-dup-rle [RFC3611]
  49. pkt-rcpt-times [RFC3611]
  50. stat-summary [RFC3611]
  51. voip-metrics [RFC3611]
  52. rcvr-rtt [RFC3611]
  53. post-repair-loss-rle [RFC5725]
  54. grp-sync [http://www.etsi.org/deliver/etsi_ts/183000_183099/183063/][ETSI 183 063][Miguel_Angel_Reina_Ortega]
  55. multicast-acq [RFC6332]
  56. ecn-sum [RFC6679]
  57. pkt-dly-var [RFC6798]
  58. delay [RFC6843]
  59. burst-gap-loss-stat [RFC7004]
  60. burst-gap-discard-stat [RFC7004]
  61. frame-impairment-stat [RFC7004]
  62. burst-gap-loss [RFC6958]
  63. burst-gap-discard [RFC7003]
  64. ts-psi-indep-decodability [RFC6990]
  65. de-jitter-buffer [RFC7005]
  66. pkt-discard-count [RFC7002]
  67. discard-rle [RFC7097]
  68. discard-bytes [RFC7243]
  69. rtp-flow-init-syn-delay [RFC7244]
  70. rtp-flow-syn-offset [RFC7244]
  71. mos-metric [RFC7266]
  72. loss-conceal [RFC7294]
  73. conc-sec [RFC7294]
  74. ts-psi-decodability [RFC7380]
  75. post-repair-loss-count [RFC7509]
  76. video-loss-concealment [RFC7867]
  77. ind-burst-gap-discard [RFC8015]
  78. */
  79. static int rtcp_xr_rrt_pack(uint64_t ntp, uint8_t* ptr, uint32_t bytes);
  80. static int rtcp_xr_dlrr_pack(const rtcp_dlrr_t* dlrr, int count, uint8_t* ptr, uint32_t bytes);
  81. static int rtcp_xr_ecn_pack(const rtcp_ecn_t* ecn, uint8_t* ptr, uint32_t bytes);
  82. static int rtcp_xr_lrle_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  83. static int rtcp_xr_drle_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  84. static int rtcp_xr_prt_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  85. static int rtcp_xr_rrt_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  86. static int rtcp_xr_dlrr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  87. static int rtcp_xr_ecn_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes);
  88. // https://www.rfc-editor.org/rfc/rfc3611.html#section-4.1
  89. /*
  90. 0 1 2 3
  91. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  92. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  93. | BT=1 | rsvd. | T | block length |
  94. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  95. | SSRC of source |
  96. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  97. | begin_seq | end_seq |
  98. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  99. | chunk 1 | chunk 2 |
  100. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  101. : ... :
  102. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  103. | chunk n-1 | chunk n |
  104. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  105. */
  106. static int rtcp_xr_lrle_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  107. {
  108. uint32_t i, j;
  109. uint32_t source;
  110. uint32_t len, num;
  111. uint16_t seq, end;
  112. uint32_t chunk;
  113. uint8_t* v, v0[32];
  114. len = nbo_r16(ptr + 2);
  115. if (bytes < 8 || (len + 1) * 4 > bytes)
  116. return -1;
  117. len *= 4; // to bytes
  118. if (len < 8)
  119. return 0;
  120. source = nbo_r32(ptr + 4);
  121. seq = nbo_r16(ptr + 8);
  122. end = nbo_r16(ptr + 10);
  123. num = end - seq;
  124. if ((num + 7) / 8 > sizeof(v0))
  125. {
  126. v = calloc((num + 7) / 8, sizeof(*v));
  127. if (!v) return -ENOMEM;
  128. }
  129. else
  130. {
  131. v = v0;
  132. memset(v, 0, (num + 7) / 8 * sizeof(v[0]));
  133. }
  134. ptr += 8;
  135. len -= 8;
  136. for(i = 0; len > 2; ptr += 2, len -= 2)
  137. {
  138. chunk = nbo_r16(ptr);
  139. if (0 == (0x8000 & chunk))
  140. {
  141. // Run Length Chunk
  142. for (j = 0; j < (chunk & 0x3FFF) && i < num; j++, i++)
  143. {
  144. if(0x4000 & chunk)
  145. v[i/8] |= 1 << (7-(i%8));
  146. }
  147. }
  148. else
  149. {
  150. // Bit Vector Chunk
  151. for (j = 0; j < 15 && i < num; j++, i++)
  152. {
  153. if (chunk & (1 << (14 - j)))
  154. v[i / 8] |= 1 << (7 - (i % 8));
  155. }
  156. }
  157. }
  158. msg->u.xr.u.rle.source = source;
  159. msg->u.xr.u.rle.begin = seq;
  160. msg->u.xr.u.rle.end = end;
  161. msg->u.xr.u.rle.chunk = v;
  162. msg->u.xr.u.rle.count = num;
  163. ctx->handler.on_rtcp(ctx->cbparam, msg);
  164. (void)ctx, (void)header;
  165. if (v && v != v0)
  166. free(v);
  167. return 0;
  168. }
  169. // https://www.rfc-editor.org/rfc/rfc3611.html#section-4.2
  170. /*
  171. 0 1 2 3
  172. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  173. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  174. | BT=2 | rsvd. | T | block length |
  175. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  176. | SSRC of source |
  177. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  178. | begin_seq | end_seq |
  179. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  180. | chunk 1 | chunk 2 |
  181. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  182. : ... :
  183. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  184. | chunk n-1 | chunk n |
  185. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  186. */
  187. static int rtcp_xr_drle_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  188. {
  189. uint32_t i, j;
  190. uint32_t source;
  191. uint32_t len, num;
  192. uint16_t seq, end;
  193. uint32_t chunk;
  194. uint8_t* v, v0[32];
  195. len = nbo_r16(ptr + 2);
  196. if (bytes < 8 || (len + 1) * 4 > bytes)
  197. return -1;
  198. len *= 4; // to bytes
  199. if (len < 8)
  200. return 0;
  201. source = nbo_r32(ptr + 4);
  202. seq = nbo_r16(ptr + 8);
  203. end = nbo_r16(ptr + 10);
  204. num = end - seq;
  205. if ((num + 7) / 8 > sizeof(v0))
  206. {
  207. v = calloc((num + 7) / 8, sizeof(*v));
  208. if (!v) return -ENOMEM;
  209. }
  210. else
  211. {
  212. v = v0;
  213. memset(v, 0, (num + 7) / 8 * sizeof(v[0]));
  214. }
  215. ptr += 8;
  216. len -= 8;
  217. for (i = 0; len > 2; ptr += 2, len -= 2)
  218. {
  219. chunk = nbo_r16(ptr);
  220. if (0 == (0x8000 & chunk))
  221. {
  222. // Run Length Chunk
  223. for (j = 0; j < (chunk & 0x3FFF) && i < num; j++, i++)
  224. {
  225. if (0x4000 & chunk)
  226. v[i / 8] |= 1 << (7 - (i % 8));
  227. }
  228. }
  229. else
  230. {
  231. // Bit Vector Chunk
  232. for (j = 0; j < 15 && i < num; j++, i++)
  233. {
  234. if (chunk & (1 << (14 - j)))
  235. v[i / 8] |= 1 << (7 - (i % 8));
  236. }
  237. }
  238. }
  239. msg->u.xr.u.rle.source = source;
  240. msg->u.xr.u.rle.begin = seq;
  241. msg->u.xr.u.rle.end = end;
  242. msg->u.xr.u.rle.chunk = v;
  243. msg->u.xr.u.rle.count = num;
  244. ctx->handler.on_rtcp(ctx->cbparam, msg);
  245. (void)ctx, (void)header;
  246. if (v && v != v0)
  247. free(v);
  248. return 0;
  249. }
  250. // https://www.rfc-editor.org/rfc/rfc3611.html#section-4.3
  251. /*
  252. 0 1 2 3
  253. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  254. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  255. | BT=3 | rsvd. | T | block length |
  256. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  257. | SSRC of source |
  258. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  259. | begin_seq | end_seq |
  260. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  261. | Receipt time of packet begin_seq |
  262. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  263. | Receipt time of packet (begin_seq + 1) mod 65536 |
  264. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  265. : ... :
  266. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  267. | Receipt time of packet (end_seq - 1) mod 65536 |
  268. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  269. */
  270. static int rtcp_xr_prt_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  271. {
  272. uint32_t i;
  273. uint32_t source;
  274. uint32_t len, num;
  275. uint16_t seq, end;
  276. uint32_t* timestamp, timestamp0[32];
  277. len = nbo_r16(ptr + 2);
  278. if (bytes < 8 || (len + 1) * 4 > bytes)
  279. return -1;
  280. len *= 4; // to bytes
  281. if (len < 8)
  282. return 0;
  283. source = nbo_r32(ptr + 4);
  284. seq = nbo_r16(ptr + 8);
  285. end = nbo_r16(ptr + 10);
  286. num = end - seq;
  287. if (num > sizeof(timestamp0)/sizeof(timestamp0[0]))
  288. {
  289. timestamp = calloc(num, sizeof(*timestamp));
  290. if (!timestamp) return -ENOMEM;
  291. }
  292. else
  293. {
  294. timestamp = timestamp0;
  295. memset(timestamp, 0, num * sizeof(timestamp[0]));
  296. }
  297. ptr += 8;
  298. len -= 8;
  299. for (i = 0; len > 4; ptr += 4, len -= 4)
  300. {
  301. timestamp[i] = nbo_r32(ptr);
  302. }
  303. msg->u.xr.u.prt.source = source;
  304. msg->u.xr.u.prt.begin = seq;
  305. msg->u.xr.u.prt.end = end;
  306. msg->u.xr.u.prt.timestamp = timestamp;
  307. msg->u.xr.u.prt.count = num;
  308. ctx->handler.on_rtcp(ctx->cbparam, msg);
  309. (void)ctx, (void)header;
  310. if (timestamp && timestamp != timestamp0)
  311. free(timestamp);
  312. return 0;
  313. }
  314. // https://www.rfc-editor.org/rfc/rfc3611.html#section-4.4
  315. /*
  316. 0 1 2 3
  317. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  318. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  319. | BT=4 | reserved | block length = 2 |
  320. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  321. | NTP timestamp, most significant word |
  322. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  323. | NTP timestamp, least significant word |
  324. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  325. */
  326. static int rtcp_xr_rrt_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  327. {
  328. uint32_t len;
  329. uint64_t ntp;
  330. len = nbo_r16(ptr + 2);
  331. if (bytes < 12 || (len + 1) * 4 > bytes)
  332. return -1;
  333. ntp = nbo_r32(ptr + 4);
  334. ntp = (ntp << 32) | nbo_r32(ptr + 8);
  335. msg->u.xr.u.rrt = ntp;
  336. ctx->handler.on_rtcp(ctx->cbparam, msg);
  337. (void)ctx, (void)header;
  338. return 0;
  339. }
  340. static int rtcp_xr_rrt_pack(uint64_t ntp, uint8_t* ptr, uint32_t bytes)
  341. {
  342. if (bytes < 12)
  343. return -1;
  344. nbo_w32(ptr, (RTCP_XR_RRT << 24) | 2);
  345. nbo_w32(ptr + 4, (uint32_t)(ntp >> 32));
  346. nbo_w32(ptr + 8, (uint32_t)ntp);
  347. return 12;
  348. }
  349. // https://www.rfc-editor.org/rfc/rfc3611.html#section-4.5
  350. /*
  351. 0 1 2 3
  352. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  353. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  354. | BT=5 | reserved | block length |
  355. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  356. | SSRC_1 (SSRC of first receiver) | sub-
  357. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
  358. | last RR (LRR) | 1
  359. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  360. | delay since last RR (DLRR) |
  361. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  362. | SSRC_2 (SSRC of second receiver) | sub-
  363. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
  364. : ... : 2
  365. +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  366. */
  367. static int rtcp_xr_dlrr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  368. {
  369. uint32_t i;
  370. uint32_t len, num;
  371. rtcp_dlrr_t* dlrr, dlrr0[32];
  372. len = nbo_r16(ptr + 2);
  373. if (bytes < 8 || (len + 1) * 4 > bytes)
  374. return -1;
  375. num = len / 3;
  376. if (num > sizeof(dlrr0))
  377. {
  378. dlrr = calloc(num, sizeof(*dlrr));
  379. if (!dlrr) return -ENOMEM;
  380. }
  381. else
  382. {
  383. dlrr = dlrr0;
  384. memset(dlrr, 0, num * sizeof(dlrr[0]));
  385. }
  386. ptr += 4;
  387. for (i = 0; i < num; i++, ptr += 12)
  388. {
  389. dlrr[i].ssrc = nbo_r32(ptr + 0);
  390. dlrr[i].lrr = nbo_r32(ptr + 4);
  391. dlrr[i].dlrr = nbo_r32(ptr + 8);
  392. }
  393. msg->u.xr.u.dlrr.dlrr = dlrr;
  394. msg->u.xr.u.dlrr.count = num;
  395. ctx->handler.on_rtcp(ctx->cbparam, msg);
  396. (void)ctx, (void)header;
  397. if (dlrr && dlrr != dlrr0)
  398. free(dlrr);
  399. return 0;
  400. }
  401. static int rtcp_xr_dlrr_pack(const rtcp_dlrr_t* dlrr, int count, uint8_t* ptr, uint32_t bytes)
  402. {
  403. int i;
  404. if ((int)bytes < 4 + count * 12)
  405. return - 1;
  406. nbo_w32(ptr, (RTCP_XR_DLRR << 24) | (count * 3));
  407. bytes -= 4;
  408. ptr += 4;
  409. for (i = 0; i < count && bytes >= 12; i++)
  410. {
  411. nbo_w32(ptr, dlrr[i].ssrc);
  412. nbo_w32(ptr + 4, dlrr[i].lrr);
  413. nbo_w32(ptr + 8, dlrr[i].dlrr);
  414. bytes -= 12;
  415. ptr += 12;
  416. }
  417. return 4 + i * 12;
  418. }
  419. // https://www.rfc-editor.org/rfc/rfc7097.html#section-5
  420. // rtcp-xr: discard-rle
  421. /*
  422. 0 1 2 3
  423. 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  424. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  425. | BT=25 |rsvd |E| T | block length |
  426. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  427. | SSRC of source |
  428. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  429. | begin_seq | end_seq |
  430. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  431. | chunk 1 | chunk 2 |
  432. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  433. : ... :
  434. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  435. | chunk n-1 | chunk n |
  436. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  437. */
  438. // https://datatracker.ietf.org/doc/html/rfc7243#section-5
  439. // rtcp-xr: discard-bytes
  440. /*
  441. 0 1 2 3
  442. 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  443. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  444. | BT=26 | I |E|Reserved | Block length=2 |
  445. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  446. | SSRC of source |
  447. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  448. | Number of RTP payload bytes discarded |
  449. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  450. */
  451. // https://www.rfc-editor.org/rfc/rfc6679.html#section-5.2
  452. /*
  453. 0 1 2 3
  454. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  455. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  456. | BT=13 | Reserved | Block Length |
  457. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  458. | SSRC of Media Sender |
  459. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  460. | ECT (0) Counter |
  461. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  462. | ECT (1) Counter |
  463. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  464. | ECN-CE Counter | not-ECT Counter |
  465. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  466. | Lost Packets Counter | Duplication Counter |
  467. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  468. Figure 4: RTCP XR ECN Summary Report
  469. */
  470. static int rtcp_xr_ecn_unpack(struct rtp_context* ctx, const rtcp_header_t* header, struct rtcp_msg_t* msg, const uint8_t* ptr, size_t bytes)
  471. {
  472. uint32_t len;
  473. rtcp_ecn_t ecn;
  474. len = nbo_r16(ptr + 2);
  475. if (bytes < 24 || (len + 1) * 4 > bytes)
  476. return -1;
  477. ecn.ext_highest_seq = nbo_r32(ptr); // ssrc
  478. ecn.ect[0] = nbo_r32(ptr + 4);
  479. ecn.ect[1] = nbo_r32(ptr + 8);
  480. ecn.ect_ce_counter = nbo_r16(ptr + 12);
  481. ecn.not_ect_counter = nbo_r16(ptr + 14);
  482. ecn.lost_packets_counter = nbo_r16(ptr + 16);
  483. ecn.duplication_counter = nbo_r16(ptr + 18);
  484. memcpy(&msg->u.xr.u.ecn, &ecn, sizeof(msg->u.xr.u.ecn));
  485. ctx->handler.on_rtcp(ctx->cbparam, msg);
  486. (void)ctx, (void)header;
  487. return 0;
  488. }
  489. static int rtcp_xr_ecn_pack(const rtcp_ecn_t* ecn, uint8_t* ptr, uint32_t bytes)
  490. {
  491. if (bytes < 24)
  492. return -1;
  493. nbo_w32(ptr, (RTCP_XR_ECN << 24) | 5);
  494. nbo_w32(ptr + 4, ecn->ext_highest_seq);
  495. nbo_w32(ptr + 8, ecn->ect[0]);
  496. nbo_w32(ptr + 12, ecn->ect[1]);
  497. nbo_w16(ptr + 16, ecn->ect_ce_counter);
  498. nbo_w16(ptr + 18, ecn->not_ect_counter);
  499. nbo_w16(ptr + 20, ecn->lost_packets_counter);
  500. nbo_w16(ptr + 22, ecn->duplication_counter);
  501. return 24;
  502. }
  503. /*
  504. 0 1 2 3
  505. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  506. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  507. |V=2|P|reserved | PT=XR=207 | length |
  508. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  509. | SSRC |
  510. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  511. : report blocks :
  512. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  513. 0 1 2 3
  514. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  515. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  516. | BT | type-specific | block length |
  517. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  518. : type-specific block contents :
  519. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  520. */
  521. void rtcp_xr_unpack(struct rtp_context* ctx, const rtcp_header_t* header, const uint8_t* ptr, size_t bytes)
  522. {
  523. int r;
  524. struct rtcp_msg_t msg;
  525. struct rtp_member* sender;
  526. if (bytes < 8 /*sizeof(rtcp_xr_t)*/)
  527. {
  528. assert(0);
  529. return;
  530. }
  531. msg.ssrc = nbo_r32(ptr);
  532. sender = rtp_sender_fetch(ctx, msg.ssrc);
  533. if (!sender) return; // error
  534. assert(sender != ctx->self);
  535. r = 0;
  536. ptr += 4;
  537. bytes -= 4;
  538. while (bytes >= 4)
  539. {
  540. msg.type = RTCP_XR | (ptr[0] << 8);
  541. switch (ptr[0])
  542. {
  543. case RTCP_XR_LRLE:
  544. r = rtcp_xr_lrle_unpack(ctx, header, &msg, ptr, bytes);
  545. break;
  546. case RTCP_XR_DRLE:
  547. r = rtcp_xr_drle_unpack(ctx, header, &msg, ptr, bytes);
  548. break;
  549. case RTCP_XR_PRT:
  550. r = rtcp_xr_prt_unpack(ctx, header, &msg, ptr, bytes);
  551. break;
  552. case RTCP_XR_RRT:
  553. r = rtcp_xr_rrt_unpack(ctx, header, &msg, ptr, bytes);
  554. break;
  555. case RTCP_XR_DLRR:
  556. r = rtcp_xr_dlrr_unpack(ctx, header, &msg, ptr, bytes);
  557. break;
  558. case RTCP_XR_ECN:
  559. r = rtcp_xr_ecn_unpack(ctx, header, &msg, ptr, bytes);
  560. break;
  561. default:
  562. //assert(0);
  563. r = 0; // ignore
  564. break;
  565. }
  566. }
  567. return;
  568. }
  569. int rtcp_xr_pack(struct rtp_context* ctx, uint8_t* data, int bytes, enum rtcp_xr_type_t id, const rtcp_xr_t* xr)
  570. {
  571. int r;
  572. rtcp_header_t header;
  573. (void)ctx;
  574. if (bytes < 4 + 4)
  575. return 4 + 4;
  576. switch (id)
  577. {
  578. case RTCP_XR_RRT:
  579. r = rtcp_xr_rrt_pack(xr->u.rrt, data + 8, bytes - 8);
  580. break;
  581. case RTCP_XR_DLRR:
  582. r = rtcp_xr_dlrr_pack(xr->u.dlrr.dlrr, xr->u.dlrr.count, data + 8, bytes - 8);
  583. break;
  584. case RTCP_XR_ECN:
  585. r = rtcp_xr_ecn_pack(&xr->u.ecn, data + 8, bytes - 8);
  586. break;
  587. case RTCP_XR_LRLE:
  588. case RTCP_XR_DRLE:
  589. case RTCP_XR_PRT:
  590. default:
  591. assert(0);
  592. return -1;
  593. }
  594. header.v = 2;
  595. header.p = 0;
  596. header.pt = RTCP_XR;
  597. header.rc = id;
  598. header.length = (r + 4 + 3) / 4;
  599. nbo_write_rtcp_header(data, &header);
  600. nbo_w32(data + 4, ctx->self->ssrc);
  601. //nbo_w32(data + 4, xr->sender);
  602. //assert(8 == (header.length + 1) * 4);
  603. return header.length * 4 + 4;
  604. }
  605. #if defined(_DEBUG) || defined(DEBUG)
  606. static void rtcp_on_xr_test(void* param, const struct rtcp_msg_t* msg)
  607. {
  608. int r;
  609. static uint8_t buffer[1400];
  610. switch (msg->type & 0xFF)
  611. {
  612. case RTCP_XR:
  613. switch ((msg->type >> 8) & 0xFF)
  614. {
  615. case RTCP_XR_RRT:
  616. assert(0x1234567823456789 == msg->u.xr.u.rrt);
  617. r = rtcp_xr_rrt_pack(msg->u.xr.u.rrt, buffer, sizeof(buffer));
  618. assert(12 == r && 0 == memcmp(buffer, param, r));
  619. break;
  620. case RTCP_XR_DLRR:
  621. assert(1 == msg->u.xr.u.dlrr.count);
  622. assert(0x12345678 == msg->u.xr.u.dlrr.dlrr[0].ssrc && 0x23344556 == msg->u.xr.u.dlrr.dlrr[0].lrr && 0x33343536 == msg->u.xr.u.dlrr.dlrr[0].dlrr);
  623. r = rtcp_xr_dlrr_pack(msg->u.xr.u.dlrr.dlrr, msg->u.xr.u.dlrr.count, buffer, sizeof(buffer));
  624. assert(16 == r && 0 == memcmp(buffer, param, r));
  625. break;
  626. case RTCP_XR_ECN:
  627. r = rtcp_xr_ecn_pack(&msg->u.xr.u.ecn, buffer, sizeof(buffer));
  628. assert(r > 0 && 0 == memcmp(buffer, param, r));
  629. default:
  630. break;
  631. }
  632. break;
  633. default:
  634. assert(0);
  635. }
  636. }
  637. static void rtcp_rtpfb_rrt_test(void)
  638. {
  639. const uint8_t data[] = { 0x04, 0x00, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89 };
  640. struct rtcp_msg_t msg;
  641. struct rtp_context rtp;
  642. rtp.handler.on_rtcp = rtcp_on_xr_test;
  643. rtp.cbparam = (void*)data;
  644. msg.type = (RTCP_XR_RRT << 8) | RTCP_XR;
  645. assert(0 == rtcp_xr_rrt_unpack(&rtp, NULL, &msg, data, sizeof(data)));
  646. }
  647. static void rtcp_rtpfb_dlrr_test(void)
  648. {
  649. const uint8_t data[] = { 0x05, 0x00, 0x00, 0x03, 0x12, 0x34, 0x56, 0x78, 0x23, 0x34, 0x45, 0x56, 0x33, 0x34, 0x35, 0x36 };
  650. struct rtcp_msg_t msg;
  651. struct rtp_context rtp;
  652. rtp.handler.on_rtcp = rtcp_on_xr_test;
  653. rtp.cbparam = (void*)data;
  654. msg.type = (RTCP_XR_DLRR << 8) | RTCP_XR;
  655. assert(0 == rtcp_xr_dlrr_unpack(&rtp, NULL, &msg, data, sizeof(data)));
  656. }
  657. static void rtcp_rtpfb_ecn_test(void)
  658. {
  659. const uint8_t data[] = { 0x00 };
  660. struct rtcp_msg_t msg;
  661. struct rtp_context rtp;
  662. rtp.handler.on_rtcp = rtcp_on_xr_test;
  663. rtp.cbparam = (void*)data;
  664. msg.type = (RTCP_XR_ECN << 8) | RTCP_XR;
  665. assert(0 == rtcp_xr_ecn_unpack(&rtp, NULL, &msg, data, sizeof(data)));
  666. }
  667. void rtcp_xr_test(void)
  668. {
  669. rtcp_rtpfb_rrt_test();
  670. rtcp_rtpfb_dlrr_test();
  671. //rtcp_rtpfb_ecn_test();
  672. }
  673. #endif