linkage_descriptor.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /*
  2. * section and descriptor parser
  3. *
  4. * Copyright (C) 2005 Kenneth Aafloy (kenneth@linuxtv.org)
  5. * Copyright (C) 2005 Andrew de Quincey (adq_dvb@lidskialf.net)
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. #ifndef _UCSI_DVB_LINKAGE_DESCRIPTOR
  22. #define _UCSI_DVB_LINKAGE_DESCRIPTOR 1
  23. #ifdef __cplusplus
  24. extern "C"
  25. {
  26. #endif
  27. #include <libucsi/descriptor.h>
  28. #include <libucsi/endianops.h>
  29. #include <libucsi/types.h>
  30. /**
  31. * Possible values for linkage_type.
  32. */
  33. enum {
  34. DVB_LINKAGE_TYPE_INFORMATION = 0x01,
  35. DVB_LINKAGE_TYPE_EPG = 0x02,
  36. DVB_LINKAGE_TYPE_CA_REPLACEMENT = 0x03,
  37. DVB_LINKAGE_TYPE_TS_WITH_BAT_NIT = 0x04,
  38. DVB_LINKAGE_TYPE_SERVICE_REPLACMENT = 0x05,
  39. DVB_LINKAGE_TYPE_DATA_BCAST = 0x06,
  40. DVB_LINKAGE_TYPE_RCS_MAP = 0x07,
  41. DVB_LINKAGE_TYPE_MOBILE_HANDOVER = 0x08,
  42. DVB_LINKAGE_TYPE_SOFTWARE_UPDATE = 0x09,
  43. DVB_LINKAGE_TYPE_TS_WITH_SSU_BAT_NIT = 0x0a,
  44. DVB_LINKAGE_TYPE_IP_MAC_NOTIFICATION = 0x0b,
  45. DVB_LINKAGE_TYPE_TS_WITH_INT_BAT_NIT = 0x0c,
  46. };
  47. /**
  48. * Possible values for hand_over_type.
  49. */
  50. enum {
  51. DVB_HAND_OVER_TYPE_IDENTICAL_NEIGHBOURING_COUNTRY = 0x01,
  52. DVB_HAND_OVER_TYPE_LOCAL_VARIATION = 0x02,
  53. DVB_HAND_OVER_TYPE_ASSOCIATED_SERVICE = 0x03,
  54. };
  55. /**
  56. * Possible values for origin_type.
  57. */
  58. enum {
  59. DVB_ORIGIN_TYPE_NIT = 0x00,
  60. DVB_ORIGIN_TYPE_SDT = 0x01,
  61. };
  62. /**
  63. * dvb_linkage_descriptor structure.
  64. */
  65. struct dvb_linkage_descriptor {
  66. struct descriptor d;
  67. uint16_t transport_stream_id;
  68. uint16_t original_network_id;
  69. uint16_t service_id;
  70. uint8_t linkage_type;
  71. /* uint8_t data[] */
  72. } __ucsi_packed;
  73. /**
  74. * Data for a linkage_type of 0x08.
  75. */
  76. struct dvb_linkage_data_08 {
  77. EBIT3(uint8_t hand_over_type : 4; ,
  78. uint8_t reserved : 3; ,
  79. uint8_t origin_type : 1; );
  80. /* uint16_t network_id if hand_over_type == 1,2,3 */
  81. /* uint16_t initial_service_id if origin_type = 0 */
  82. /* uint8_t data[] */
  83. } __ucsi_packed;
  84. /**
  85. * Data for an linkage_type of 0x0b (IP/MAC Notification Table).
  86. */
  87. struct dvb_linkage_data_0b {
  88. uint8_t platform_id_data_length;
  89. /* struct platform_id ids[] */
  90. } __ucsi_packed;
  91. /**
  92. * Entries in the ids field of a dvb_linkage_data_0b.
  93. */
  94. struct dvb_platform_id {
  95. EBIT2(uint32_t platform_id : 24; ,
  96. uint8_t platform_name_loop_length : 8; );
  97. /* struct platform_name names[] */
  98. } __ucsi_packed;
  99. /**
  100. * Entries in the names field of a dvb_platform_id.
  101. */
  102. struct dvb_platform_name {
  103. iso639lang_t language_code;
  104. uint8_t platform_name_length;
  105. /* uint8_t text[] */
  106. } __ucsi_packed;
  107. /**
  108. * Data for a linkage_type of 0x0c (IP/MAC Notification Table).
  109. */
  110. struct dvb_linkage_data_0c {
  111. uint8_t table_type;
  112. /* uint16_t bouquet_id if table_type == 0x02 */
  113. } __ucsi_packed;
  114. /**
  115. * Process a dvb_linkage_descriptor.
  116. *
  117. * @param d Generic descriptor pointer.
  118. * @return dvb_linkage_descriptor pointer, or NULL on error.
  119. */
  120. static inline struct dvb_linkage_descriptor*
  121. dvb_linkage_descriptor_codec(struct descriptor* d)
  122. {
  123. uint32_t pos = 0;
  124. uint8_t* buf = (uint8_t*) d + 2;
  125. uint32_t len = d->len;
  126. struct dvb_linkage_descriptor *p =
  127. (struct dvb_linkage_descriptor*) d;
  128. if (len < (sizeof(struct dvb_linkage_descriptor) - 2))
  129. return NULL;
  130. bswap16(buf);
  131. bswap16(buf+2);
  132. bswap16(buf+4);
  133. pos += sizeof(struct dvb_linkage_descriptor) - 2;
  134. if (p->linkage_type == 0x08) {
  135. struct dvb_linkage_data_08 *d08;
  136. if ((len - pos) < sizeof(struct dvb_linkage_data_08))
  137. return NULL;
  138. d08 = (struct dvb_linkage_data_08 *) (buf+pos);
  139. pos += sizeof(struct dvb_linkage_data_08);
  140. switch(d08->hand_over_type) {
  141. case 1:
  142. case 2:
  143. case 3:
  144. if ((len - pos) < 2)
  145. return NULL;
  146. bswap16(buf+pos);
  147. pos += 2;
  148. break;
  149. }
  150. if (d08->origin_type == 0) {
  151. if ((len - pos) < 2)
  152. return NULL;
  153. bswap16(buf+pos);
  154. pos+=2;
  155. }
  156. } else if (p->linkage_type == 0x0b) {
  157. uint32_t pos2=0;
  158. struct dvb_linkage_data_0b *l_0b = (struct dvb_linkage_data_0b *) (buf + pos);
  159. if ((len - pos) < sizeof(struct dvb_linkage_data_0b))
  160. return NULL;
  161. pos += sizeof(struct dvb_linkage_data_0b);
  162. if ((len - pos) < l_0b->platform_id_data_length)
  163. return NULL;
  164. while (pos2 < l_0b->platform_id_data_length) {
  165. bswap32(buf + pos + pos2);
  166. struct dvb_platform_id *p_id = (struct dvb_platform_id *) (buf + pos + pos2);
  167. if ((len - pos - pos2) < p_id->platform_name_loop_length)
  168. return NULL;
  169. pos2 += sizeof(struct dvb_platform_id) + p_id->platform_name_loop_length;
  170. }
  171. pos += pos2;
  172. } else if (p->linkage_type == 0x0c) {
  173. struct dvb_linkage_data_0c *l_0c = (struct dvb_linkage_data_0c *) (buf + pos);
  174. if ((len - pos) < sizeof(struct dvb_linkage_data_0c))
  175. return NULL;
  176. pos += sizeof(struct dvb_linkage_data_0c);
  177. if (l_0c->table_type == 0x02) {
  178. if ((len - pos) < 2)
  179. return NULL;
  180. bswap16(buf+pos);
  181. }
  182. }
  183. return (struct dvb_linkage_descriptor*) d;
  184. }
  185. /**
  186. * Accessor for the data field of a dvb_linkage_descriptor.
  187. *
  188. * @param d dvb_linkage_descriptor pointer.
  189. * @return Pointer to the data field.
  190. */
  191. static inline uint8_t *
  192. dvb_linkage_descriptor_data(struct dvb_linkage_descriptor *d)
  193. {
  194. return (uint8_t *) d + sizeof(struct dvb_linkage_descriptor);
  195. }
  196. /**
  197. * Determine the length of the data field of a dvb_linkage_descriptor.
  198. *
  199. * @param d dvb_linkage_descriptor pointer.
  200. * @return Length of the field in bytes.
  201. */
  202. static inline int
  203. dvb_linkage_descriptor_data_length(struct dvb_linkage_descriptor *d)
  204. {
  205. return d->d.len - 7;
  206. }
  207. /**
  208. * Accessor for a dvb_linkage_data_08 pointer.
  209. *
  210. * @param d dvb_linkage_descriptor pointer.
  211. * @return Pointer to the data field.
  212. */
  213. static inline struct dvb_linkage_data_08 *
  214. dvb_linkage_data_08(struct dvb_linkage_descriptor *d)
  215. {
  216. if (d->linkage_type != 0x08)
  217. return NULL;
  218. return (struct dvb_linkage_data_08 *) dvb_linkage_descriptor_data(d);
  219. }
  220. /**
  221. * Accessor for the network_id field of a dvb_linkage_data_08.
  222. *
  223. * @param d dvb_linkage_descriptor pointer
  224. * @param d08 dvb_linkage_data_08 pointer.
  225. * @return network_id, or -1 if not present
  226. */
  227. static inline int
  228. dvb_linkage_data_08_network_id(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08)
  229. {
  230. if (d->linkage_type != 0x08)
  231. return -1;
  232. switch(d08->hand_over_type) {
  233. case 1:
  234. case 2:
  235. case 3:
  236. return *((uint16_t*) ((uint8_t*) d08 + sizeof(struct dvb_linkage_data_08)));
  237. }
  238. return -1;
  239. }
  240. /**
  241. * Accessor for the initial_service_id field of a dvb_linkage_data_08.
  242. *
  243. * @param d dvb_linkage_descriptor pointer
  244. * @param d08 dvb_linkage_data_08 pointer.
  245. * @return initial_service_id, or -1 if not present
  246. */
  247. static inline int
  248. dvb_linkage_data_08_initial_service_id(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08)
  249. {
  250. uint8_t *pos;
  251. if (d->linkage_type != 0x08)
  252. return -1;
  253. if (d08->origin_type != 0)
  254. return -1;
  255. pos = ((uint8_t*) d08) + sizeof(struct dvb_linkage_data_08);
  256. switch(d08->hand_over_type) {
  257. case 1:
  258. case 2:
  259. case 3:
  260. pos +=2;
  261. break;
  262. }
  263. return *((uint16_t*) pos);
  264. }
  265. /**
  266. * Accessor for the data field of a dvb_linkage_data_08.
  267. *
  268. * @param d dvb_linkage_descriptor pointer
  269. * @param d08 dvb_linkage_data_08 pointer.
  270. * @param length Pointer to int destination for data length.
  271. * @return Pointer to the data field, or NULL if invalid
  272. */
  273. static inline uint8_t *
  274. dvb_linkage_data_08_data(struct dvb_linkage_descriptor *d, struct dvb_linkage_data_08 *d08, int *length)
  275. {
  276. uint8_t *pos;
  277. int used = 0;
  278. if (d->linkage_type != 0x08) {
  279. *length = 0;
  280. return NULL;
  281. }
  282. pos = ((uint8_t*) d08) + sizeof(struct dvb_linkage_data_08);
  283. switch(d08->hand_over_type) {
  284. case 1:
  285. case 2:
  286. case 3:
  287. pos += 2;
  288. used += 2;
  289. break;
  290. }
  291. if (d08->origin_type == 0) {
  292. pos+=2;
  293. used+=2;
  294. }
  295. *length = dvb_linkage_descriptor_data_length(d) - (sizeof(struct dvb_linkage_data_08) + used);
  296. return pos;
  297. }
  298. /**
  299. * Accessor for a dvb_linkage_data_0b pointer.
  300. *
  301. * @param d dvb_linkage_descriptor pointer.
  302. * @return Pointer to the data field.
  303. */
  304. static inline struct dvb_linkage_data_0b *
  305. dvb_linkage_data_0b(struct dvb_linkage_descriptor *d)
  306. {
  307. if (d->linkage_type != 0x0b)
  308. return NULL;
  309. return (struct dvb_linkage_data_0b *) dvb_linkage_descriptor_data(d);
  310. }
  311. /**
  312. * Iterator for the platform_id field of a dvb_linkage_data_0b.
  313. *
  314. * @param linkage dvb_linkage_data_0b pointer.
  315. * @param pos Variable containing a pointer to the current dvb_platform_id.
  316. */
  317. #define dvb_linkage_data_0b_platform_id_for_each(linkage, pos) \
  318. for ((pos) = dvb_platform_id_first(linkage); \
  319. (pos); \
  320. (pos) = dvb_platform_id_next(linkage, pos))
  321. /**
  322. * Iterator for the platform_name field of a dvb_platform_id.
  323. *
  324. * @param platid dvb_platform_id pointer.
  325. * @param pos Variable containing a pointer to the current dvb_platform_name.
  326. */
  327. #define dvb_platform_id_platform_name_for_each(platid, pos) \
  328. for ((pos) = dvb_platform_name_first(platid); \
  329. (pos); \
  330. (pos) = dvb_platform_name_next(platid, pos))
  331. /**
  332. * Accessor for the text field of a dvb_platform_name.
  333. *
  334. * @param p dvb_platform_name pointer.
  335. * @return Pointer to the field.
  336. */
  337. static inline uint8_t *
  338. dvb_platform_name_text(struct dvb_platform_name *p)
  339. {
  340. return (uint8_t *) p + sizeof(struct dvb_platform_name);
  341. }
  342. /**
  343. * Accessor for a dvb_linkage_data_0c pointer.
  344. *
  345. * @param d dvb_linkage_descriptor pointer.
  346. * @return Pointer to the data field.
  347. */
  348. static inline struct dvb_linkage_data_0c *
  349. dvb_linkage_data_0c(struct dvb_linkage_descriptor *d)
  350. {
  351. if (d->linkage_type != 0x0c)
  352. return NULL;
  353. return (struct dvb_linkage_data_0c *) dvb_linkage_descriptor_data(d);
  354. }
  355. /**
  356. * Accessor for the bouquet_id field of a dvb_linkage_data_0c if table_id == 0x02.
  357. *
  358. * @param l_0c dvb_linkage_data_0c pointer.
  359. * @return The bouquet field, or -1 on error.
  360. */
  361. static inline int
  362. dvb_linkage_data_0c_bouquet_id(struct dvb_linkage_data_0c *l_0c)
  363. {
  364. if (l_0c->table_type != 0x02)
  365. return -1;
  366. return *((uint16_t *) ((uint8_t*) l_0c + 1));
  367. }
  368. /******************************** PRIVATE CODE ********************************/
  369. static inline struct dvb_platform_id *
  370. dvb_platform_id_first(struct dvb_linkage_data_0b *d)
  371. {
  372. if (d->platform_id_data_length == 0)
  373. return NULL;
  374. return (struct dvb_platform_id *) ((uint8_t *) d + sizeof(struct dvb_linkage_data_0b));
  375. }
  376. static inline struct dvb_platform_id *
  377. dvb_platform_id_next(struct dvb_linkage_data_0b *d,
  378. struct dvb_platform_id *pos)
  379. {
  380. uint8_t *end = (uint8_t *) d + d->platform_id_data_length;
  381. uint8_t *next = (uint8_t *) pos +
  382. sizeof(struct dvb_platform_id) +
  383. pos->platform_name_loop_length;
  384. if (next >= end)
  385. return NULL;
  386. return (struct dvb_platform_id *) next;
  387. }
  388. static inline struct dvb_platform_name *
  389. dvb_platform_name_first(struct dvb_platform_id *p)
  390. {
  391. if (p->platform_name_loop_length == 0)
  392. return NULL;
  393. return (struct dvb_platform_name *) ((uint8_t *) p + sizeof(struct dvb_platform_id));
  394. }
  395. static inline struct dvb_platform_name *
  396. dvb_platform_name_next(struct dvb_platform_id *p,
  397. struct dvb_platform_name *pos)
  398. {
  399. uint8_t *end = (uint8_t *) p + p->platform_name_loop_length;
  400. uint8_t *next = (uint8_t *) pos +
  401. sizeof(struct dvb_platform_name) +
  402. pos->platform_name_length;
  403. if (next >= end)
  404. return NULL;
  405. return (struct dvb_platform_name *) next;
  406. }
  407. #ifdef __cplusplus
  408. }
  409. #endif
  410. #endif