[bTSstream-devel] Add encoder/decoder for DVB Simulcrypt EMMG interface
mbenoit
git at videolan.org
Sun Jan 25 17:42:22 CET 2015
bitstream | branch: master | mbenoit <mbenoit at anevia.com> | Fri Dec 12 10:49:22 2014 +0100| [3037dccb6d856c2a5f445f26be3097ca8627c47c] | committer: Christophe Massiot
Add encoder/decoder for DVB Simulcrypt EMMG interface
Compliant with EMMG<->MUX interface defined in ETSI TS 103 197 V1.3.1 (2003-01)
> http://git.videolan.org/gitweb.cgi/bitstream.git/?a=commit;h=3037dccb6d856c2a5f445f26be3097ca8627c47c
---
dvb/sim.h | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 174 insertions(+)
diff --git a/dvb/sim.h b/dvb/sim.h
index a68955d..e575411 100644
--- a/dvb/sim.h
+++ b/dvb/sim.h
@@ -449,6 +449,180 @@ static inline bool ecmg_validate(uint8_t *p_tlv)
return true;
}
+/*****************************************************************************
+ * EMMG
+ *****************************************************************************/
+/* message types */
+#define EMMG_TYPE_CHANNEL_SETUP 0x0011
+#define EMMG_TYPE_CHANNEL_TEST 0x0012
+#define EMMG_TYPE_CHANNEL_STATUS 0x0013
+#define EMMG_TYPE_CHANNEL_CLOSE 0x0014
+#define EMMG_TYPE_CHANNEL_ERROR 0x0015
+#define EMMG_TYPE_STREAM_SETUP 0x0111
+#define EMMG_TYPE_STREAM_TEST 0x0112
+#define EMMG_TYPE_STREAM_STATUS 0x0113
+#define EMMG_TYPE_STREAM_CLOSEREQ 0x0114
+#define EMMG_TYPE_STREAM_CLOSERESP 0x0115
+#define EMMG_TYPE_STREAM_ERROR 0x0116
+#define EMMG_TYPE_BW_REQ 0x0117
+#define EMMG_TYPE_BW_ALLOC 0x0118
+#define EMMG_TYPE_DATA_PROVISION 0x0211
+
+/* parameter types */
+#define EMMG_PARAM_CLIENTID 0x0001
+#define EMMG_PARAM_SECTIONTSPKT 0x0002
+#define EMMG_PARAM_DATACHANNELID 0x0003
+#define EMMG_PARAM_DATASTREAMID 0x0004
+#define EMMG_PARAM_DATAGRAM 0x0005
+#define EMMG_PARAM_BANDWIDTH 0x0006
+#define EMMG_PARAM_DATATYPE 0x0007
+#define EMMG_PARAM_DATAID 0x0008
+#define EMMG_PARAM_ERRORSTATUS 0x7000
+#define EMMG_PARAM_ERRORINFO 0x7001
+
+static inline void emmg_init(uint8_t *p_tlv)
+{
+ tlv_empty(p_tlv);
+}
+
+TLV_DECLARE_PARAM(emmg, clientid, EMMG_PARAM_CLIENTID, uint32_t, uint32_t)
+TLV_DECLARE_PARAM(emmg, sectiontspkt, EMMG_PARAM_SECTIONTSPKT, uint8_t, uint8_t)
+TLV_DECLARE_PARAM(emmg, datachannelid, EMMG_PARAM_DATACHANNELID, uint16_t, int16_t)
+TLV_DECLARE_PARAM(emmg, datastreamid, EMMG_PARAM_DATASTREAMID, uint16_t, int16_t)
+TLV_DECLARE_PARAM(emmg, bandwidth, EMMG_PARAM_BANDWIDTH, uint16_t, int16_t)
+TLV_DECLARE_PARAM(emmg, datatype, EMMG_PARAM_DATATYPE, uint8_t, int8_t)
+TLV_DECLARE_PARAM(emmg, dataid, EMMG_PARAM_DATAID, uint16_t, uint16_t)
+TLV_DECLARE_PARAM(emmg, errorstatus, EMMG_PARAM_ERRORSTATUS, uint16_t, uint16_t)
+
+static inline bool emmg_validate_param(const uint8_t *p_tlv_n)
+{
+ static const uint16_t pi_emmg_params_minlength[] = {
+ 0, 4, 1, 2, 2, 1, 2, 1, 2
+ };
+ static const uint16_t pi_emmg_params_manlength[] = {
+ 0, 4, 1, 2, 2, 1, 2, 1, 2
+ };
+
+ uint16_t i_type = tlv_get_type(p_tlv_n);
+ uint16_t i_length = tlv_get_length(p_tlv_n);
+
+ if (i_type <= EMMG_PARAM_DATAID && i_type != EMMG_PARAM_DATAGRAM) {
+ if (i_length < pi_emmg_params_minlength[i_type] ||
+ i_length > pi_emmg_params_manlength[i_type])
+ return false;
+
+ } else if (i_type == EMMG_PARAM_ERRORSTATUS) {
+ if (i_length < 2) return false;
+ }
+
+ return true;
+}
+
+static inline bool emmg_validate(uint8_t *p_tlv)
+{
+ static const tlv_param_count_t p_emmg_params_channel_setup[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_SECTIONTSPKT, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_channel_test[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_channel_status[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_SECTIONTSPKT, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_channel_close[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_channel_error[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_ERRORSTATUS, 1, UINT16_MAX}, {0, 0, 0}
+ };
+
+ static const tlv_param_count_t p_emmg_params_stream_setup[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {EMMG_PARAM_DATAID, 1, 1},
+ {EMMG_PARAM_DATATYPE, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_stream_test[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_stream_status[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {EMMG_PARAM_DATAID, 1, 1},
+ {EMMG_PARAM_DATATYPE, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_stream_close[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_stream_error[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {EMMG_PARAM_ERRORSTATUS, 1, UINT16_MAX},
+ {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_bandwidth[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 1, 1},
+ {EMMG_PARAM_DATASTREAMID, 1, 1}, {EMMG_PARAM_BANDWIDTH, 0, 1},
+ {0, 0, 0}
+ };
+ static const tlv_param_count_t p_emmg_params_data_provision[] = {
+ {EMMG_PARAM_CLIENTID, 1, 1}, {EMMG_PARAM_DATACHANNELID, 0, 1},
+ {EMMG_PARAM_DATASTREAMID, 0, 1}, {EMMG_PARAM_DATAID, 1, 1},
+ {EMMG_PARAM_DATAGRAM, 1, UINT16_MAX}, {0, 0, 0}
+ };
+
+ const tlv_param_count_t null_param = {0, 0, 0};
+ const tlv_param_count_t *p_param = &null_param;
+ uint8_t *p_tlv_n;
+ int j = 0;
+
+ switch (tlv_get_type(p_tlv)) {
+ case EMMG_TYPE_CHANNEL_SETUP:
+ p_param = p_emmg_params_channel_setup; break;
+ case EMMG_TYPE_CHANNEL_TEST:
+ p_param = p_emmg_params_channel_test; break;
+ case EMMG_TYPE_CHANNEL_STATUS:
+ p_param = p_emmg_params_channel_status; break;
+ case EMMG_TYPE_CHANNEL_CLOSE:
+ p_param = p_emmg_params_channel_close; break;
+ case EMMG_TYPE_CHANNEL_ERROR:
+ p_param = p_emmg_params_channel_error; break;
+ case EMMG_TYPE_STREAM_SETUP:
+ p_param = p_emmg_params_stream_setup; break;
+ case EMMG_TYPE_STREAM_TEST:
+ p_param = p_emmg_params_stream_test; break;
+ case EMMG_TYPE_STREAM_STATUS:
+ p_param = p_emmg_params_stream_status; break;
+ case EMMG_TYPE_STREAM_CLOSEREQ:
+ case EMMG_TYPE_STREAM_CLOSERESP:
+ p_param = p_emmg_params_stream_close; break;
+ case EMMG_TYPE_STREAM_ERROR:
+ p_param = p_emmg_params_stream_error; break;
+ case EMMG_TYPE_BW_ALLOC:
+ case EMMG_TYPE_BW_REQ:
+ p_param = p_emmg_params_bandwidth; break;
+ case EMMG_TYPE_DATA_PROVISION:
+ p_param = p_emmg_params_data_provision; break;
+ default:
+ break;
+ }
+
+ while (p_param->i_type)
+ if (!tlv_validate_count_param(p_tlv, p_param++))
+ return false;
+
+ while ((p_tlv_n = tlv_get_param(p_tlv, j)) != NULL) {
+ j++;
+ if (!emmg_validate_param(p_tlv_n)) return false;
+ }
+
+ return true;
+}
+
#ifdef __cplusplus
}
#endif
More information about the biTStream-devel
mailing list