Commit 2bfc7f98 authored by Christophe Massiot's avatar Christophe Massiot

* dvb/sim.h: Simplify the API; allow nested TLVs. * examples: Change examples accordingly.

parent 44df2d61
...@@ -31,8 +31,8 @@ extern "C" ...@@ -31,8 +31,8 @@ extern "C"
/***************************************************************************** /*****************************************************************************
* Generic "Type, Length, Value" message * Generic "Type, Length, Value" message
*****************************************************************************/ *****************************************************************************/
#define TLV_HEADER_SIZE 5 #define TLVH_HEADER_SIZE 1
#define TLV_PARAM_SIZE 4 #define TLV_HEADER_SIZE 4
#define TLV_PARAM_EMPTY 0 #define TLV_PARAM_EMPTY 0
#define TLV_PARAM_EMPTY_SIZE 2 #define TLV_PARAM_EMPTY_SIZE 2
...@@ -43,72 +43,55 @@ typedef struct tlv_param_count_t { ...@@ -43,72 +43,55 @@ typedef struct tlv_param_count_t {
uint16_t i_max; uint16_t i_max;
} tlv_param_count_t; } tlv_param_count_t;
static inline void tlv_append_empty(uint8_t *p_tlv) static inline void tlvh_set_version(uint8_t *p_tlv, uint8_t i_version)
{ {
/* prepare a dummy parameter for later appending */ p_tlv[0] = i_version;
p_tlv[TLV_HEADER_SIZE] = TLV_PARAM_EMPTY >> 8;
p_tlv[TLV_HEADER_SIZE + 1] = TLV_PARAM_EMPTY & 0xff;
} }
static inline void tlv_set_version(uint8_t *p_tlv, uint8_t i_version) static inline uint8_t tlvh_get_version(uint8_t *p_tlv)
{ {
p_tlv[0] = i_version; return p_tlv[0];
} }
static inline uint8_t tlv_get_version(uint8_t *p_tlv) static inline uint8_t *tlvh_get_tlv(uint8_t *p_tlv)
{ {
return p_tlv[0]; return p_tlv + 1;
} }
static inline void tlv_set_type(uint8_t *p_tlv, uint16_t i_type) static inline void tlv_set_type(uint8_t *p_tlv, uint16_t i_type)
{ {
p_tlv[1] = i_type >> 8; p_tlv[0] = i_type >> 8;
p_tlv[2] = i_type & 0xff; p_tlv[1] = i_type & 0xff;
} }
static inline uint16_t tlv_get_type(uint8_t *p_tlv) static inline uint16_t tlv_get_type(uint8_t *p_tlv)
{ {
return (p_tlv[1] << 8) | p_tlv[2]; return (p_tlv[0] << 8) | p_tlv[1];
} }
static inline void tlv_set_length(uint8_t *p_tlv, uint16_t i_length) static inline void tlv_set_length(uint8_t *p_tlv, uint16_t i_length)
{ {
p_tlv[3] = i_length >> 8; p_tlv[2] = i_length >> 8;
p_tlv[4] = i_length & 0xff; p_tlv[3] = i_length & 0xff;
} }
static inline uint16_t tlv_get_length(uint8_t *p_tlv) static inline uint16_t tlv_get_length(uint8_t *p_tlv)
{ {
return (p_tlv[3] << 8) | p_tlv[4]; return (p_tlv[2] << 8) | p_tlv[3];
}
static inline void tlvn_set_type(uint8_t *p_tlv_n, uint16_t i_type)
{
p_tlv_n[0] = i_type >> 8;
p_tlv_n[1] = i_type & 0xff;
} }
static inline uint16_t tlvn_get_type(uint8_t *p_tlv_n) static inline void tlv_empty(uint8_t *p_tlv)
{ {
return (p_tlv_n[0] << 8) | p_tlv_n[1]; /* prepare a dummy parameter for later appending */
} p_tlv[TLV_HEADER_SIZE] = TLV_PARAM_EMPTY >> 8;
p_tlv[TLV_HEADER_SIZE + 1] = TLV_PARAM_EMPTY & 0xff;
static inline void tlvn_set_length(uint8_t *p_tlv_n, uint16_t i_length)
{
p_tlv_n[2] = i_length >> 8;
p_tlv_n[3] = i_length & 0xff;
}
static inline uint16_t tlvn_get_length(uint8_t *p_tlv_n)
{
return (p_tlv_n[2] << 8) | p_tlv_n[3];
} }
static inline void tlvn_append_empty(uint8_t *p_tlv_n) static inline void tlv_append_empty(uint8_t *p_tlv)
{ {
uint16_t i_length = tlvn_get_length(p_tlv_n); uint16_t i_length = tlv_get_length(p_tlv);
p_tlv_n[TLV_PARAM_SIZE + i_length] = TLV_PARAM_EMPTY >> 8; p_tlv[TLV_HEADER_SIZE + i_length] = TLV_PARAM_EMPTY >> 8;
p_tlv_n[TLV_PARAM_SIZE + i_length + 1] = TLV_PARAM_EMPTY & 0xff; p_tlv[TLV_HEADER_SIZE + i_length + 1] = TLV_PARAM_EMPTY & 0xff;
} }
static inline uint8_t *tlv_get_param(uint8_t *p_tlv, uint16_t n) static inline uint8_t *tlv_get_param(uint8_t *p_tlv, uint16_t n)
...@@ -118,9 +101,9 @@ static inline uint8_t *tlv_get_param(uint8_t *p_tlv, uint16_t n) ...@@ -118,9 +101,9 @@ static inline uint8_t *tlv_get_param(uint8_t *p_tlv, uint16_t n)
if (p_tlv_n - p_tlv - TLV_HEADER_SIZE > i_tlv_size) return NULL; if (p_tlv_n - p_tlv - TLV_HEADER_SIZE > i_tlv_size) return NULL;
while (n) { while (n) {
if (p_tlv_n + TLV_PARAM_SIZE - p_tlv - TLV_HEADER_SIZE > i_tlv_size) if (p_tlv_n - p_tlv > i_tlv_size)
return NULL; return NULL;
p_tlv_n += TLV_PARAM_SIZE + tlvn_get_length(p_tlv_n); p_tlv_n += TLV_HEADER_SIZE + tlv_get_length(p_tlv_n);
n--; n--;
} }
if (p_tlv_n - p_tlv - TLV_HEADER_SIZE >= i_tlv_size) return NULL; if (p_tlv_n - p_tlv - TLV_HEADER_SIZE >= i_tlv_size) return NULL;
...@@ -131,8 +114,7 @@ static inline bool tlv_validate_param(const uint8_t *p_tlv, ...@@ -131,8 +114,7 @@ static inline bool tlv_validate_param(const uint8_t *p_tlv,
const uint8_t *p_tlv_n, uint16_t i_length) const uint8_t *p_tlv_n, uint16_t i_length)
{ {
uint16_t i_tlv_size = tlv_get_length(p_tlv); uint16_t i_tlv_size = tlv_get_length(p_tlv);
return (p_tlv_n + TLV_PARAM_SIZE + i_length - p_tlv - TLV_HEADER_SIZE return (p_tlv_n + i_length - p_tlv <= i_tlv_size);
<= i_tlv_size);
} }
static inline bool tlv_validate(const uint8_t *p_tlv) static inline bool tlv_validate(const uint8_t *p_tlv)
...@@ -140,10 +122,9 @@ static inline bool tlv_validate(const uint8_t *p_tlv) ...@@ -140,10 +122,9 @@ static inline bool tlv_validate(const uint8_t *p_tlv)
uint16_t i_tlv_size = tlv_get_length(p_tlv); uint16_t i_tlv_size = tlv_get_length(p_tlv);
const uint8_t *p_tlv_n = p_tlv + TLV_HEADER_SIZE; const uint8_t *p_tlv_n = p_tlv + TLV_HEADER_SIZE;
while (p_tlv_n + TLV_PARAM_SIZE - p_tlv - TLV_HEADER_SIZE <= i_tlv_size while (p_tlv_n - p_tlv <= i_tlv_size
&& p_tlv_n + TLV_PARAM_SIZE + tlvn_get_length(p_tlv_n) && p_tlv_n + tlv_get_length(p_tlv_n) - p_tlv <= i_tlv_size)
- p_tlv - TLV_HEADER_SIZE <= i_tlv_size) p_tlv_n += TLV_HEADER_SIZE + tlv_get_length(p_tlv_n);
p_tlv_n += TLV_PARAM_SIZE + tlvn_get_length(p_tlv_n);
return (p_tlv_n - p_tlv - TLV_HEADER_SIZE == i_tlv_size); return (p_tlv_n - p_tlv - TLV_HEADER_SIZE == i_tlv_size);
} }
...@@ -156,7 +137,7 @@ static inline uint8_t *tlv_find_param(uint8_t *p_tlv, uint16_t i_type, ...@@ -156,7 +137,7 @@ static inline uint8_t *tlv_find_param(uint8_t *p_tlv, uint16_t i_type,
while ((p_param = tlv_get_param(p_tlv, j)) != NULL) { while ((p_param = tlv_get_param(p_tlv, j)) != NULL) {
j++; j++;
if (tlvn_get_type(p_param) == i_type) { if (tlv_get_type(p_param) == i_type) {
if (!n) return p_param; if (!n) return p_param;
n--; n--;
} }
...@@ -173,7 +154,7 @@ static inline uint16_t tlv_count_param(uint8_t *p_tlv, uint16_t i_type) ...@@ -173,7 +154,7 @@ static inline uint16_t tlv_count_param(uint8_t *p_tlv, uint16_t i_type)
while ((p_tlv_n = tlv_get_param(p_tlv, j)) != NULL) { while ((p_tlv_n = tlv_get_param(p_tlv, j)) != NULL) {
j++; j++;
if (tlvn_get_type(p_tlv_n) == i_type) if (tlv_get_type(p_tlv_n) == i_type)
i_count++; i_count++;
} }
return i_count; return i_count;
...@@ -194,12 +175,12 @@ static inline bool intf##_append_##name(uint8_t *p_tlv, type i_##name) \ ...@@ -194,12 +175,12 @@ static inline bool intf##_append_##name(uint8_t *p_tlv, type i_##name) \
if (!tlv_validate_param(p_tlv, p_tlv_n, \ if (!tlv_validate_param(p_tlv, p_tlv_n, \
sizeof(type) + TLV_PARAM_EMPTY_SIZE)) \ sizeof(type) + TLV_PARAM_EMPTY_SIZE)) \
return false; \ return false; \
tlvn_set_type(p_tlv_n, param); \ tlv_set_type(p_tlv_n, param); \
tlvn_set_length(p_tlv_n, sizeof(type)); \ tlv_set_length(p_tlv_n, sizeof(type)); \
for (i = 0; i < sizeof(type); i++) \ for (i = 0; i < sizeof(type); i++) \
p_tlv_n[4 + i] = ((utype)(i_##name) >> 8 * (sizeof(type) - i - 1)) \ p_tlv_n[4 + i] = ((utype)(i_##name) >> 8 * (sizeof(type) - i - 1)) \
& 0xff; \ & 0xff; \
tlvn_append_empty(p_tlv_n); \ tlv_append_empty(p_tlv_n); \
return true; \ return true; \
} \ } \
\ \
...@@ -221,10 +202,10 @@ static inline bool tlv_append_data(uint8_t *p_tlv, uint16_t i_type, ...@@ -221,10 +202,10 @@ static inline bool tlv_append_data(uint8_t *p_tlv, uint16_t i_type,
if (!tlv_validate_param(p_tlv, p_tlv_n, if (!tlv_validate_param(p_tlv, p_tlv_n,
i_length + TLV_PARAM_EMPTY_SIZE)) i_length + TLV_PARAM_EMPTY_SIZE))
return false; return false;
tlvn_set_type(p_tlv_n, i_type); tlv_set_type(p_tlv_n, i_type);
tlvn_set_length(p_tlv_n, i_length); tlv_set_length(p_tlv_n, i_length);
memcpy(p_tlv_n + 4, p_data, i_length); memcpy(p_tlv_n + 4, p_data, i_length);
tlvn_append_empty(p_tlv_n); tlv_append_empty(p_tlv_n);
return true; return true;
} }
...@@ -232,7 +213,7 @@ static inline uint8_t *tlv_find_data(uint8_t *p_tlv, uint16_t i_type, ...@@ -232,7 +213,7 @@ static inline uint8_t *tlv_find_data(uint8_t *p_tlv, uint16_t i_type,
uint16_t n, uint16_t *pi_length) uint16_t n, uint16_t *pi_length)
{ {
const uint8_t *p_tlv_n = tlv_find_param(p_tlv, i_type, n); const uint8_t *p_tlv_n = tlv_find_param(p_tlv, i_type, n);
*pi_length = tlvn_get_length(p_tlv_n); *pi_length = tlv_get_length(p_tlv_n);
return p_tlv_n + 4; return p_tlv_n + 4;
} }
...@@ -285,7 +266,7 @@ static inline uint8_t *tlv_find_data(uint8_t *p_tlv, uint16_t i_type, ...@@ -285,7 +266,7 @@ static inline uint8_t *tlv_find_data(uint8_t *p_tlv, uint16_t i_type,
static inline void ecmg_init(uint8_t *p_tlv) static inline void ecmg_init(uint8_t *p_tlv)
{ {
tlv_append_empty(p_tlv); tlv_empty(p_tlv);
} }
TLV_DECLARE_PARAM(ecmg, supercasid, ECMG_PARAM_SUPERCASID, uint32_t, uint32_t) TLV_DECLARE_PARAM(ecmg, supercasid, ECMG_PARAM_SUPERCASID, uint32_t, uint32_t)
...@@ -339,8 +320,8 @@ static inline bool ecmg_validate_param(const uint8_t *p_tlv_n) ...@@ -339,8 +320,8 @@ static inline bool ecmg_validate_param(const uint8_t *p_tlv_n)
/* 0x10 */ 2, 1, 2, 2, 0, 0, 2, 2, /* 0x10 */ 2, 1, 2, 2, 0, 0, 2, 2,
/* 0x18 */ 0, 2 /* 0x18 */ 0, 2
}; };
uint16_t i_type = tlvn_get_type(p_tlv_n); uint16_t i_type = tlv_get_type(p_tlv_n);
uint16_t i_length = tlvn_get_length(p_tlv_n); uint16_t i_length = tlv_get_length(p_tlv_n);
if (i_type <= ECMG_PARAM_ECMID) { if (i_type <= ECMG_PARAM_ECMID) {
if (i_length < pi_ecmg_params_minlength[i_type]) return false; if (i_length < pi_ecmg_params_minlength[i_type]) return false;
......
...@@ -131,14 +131,15 @@ ssize_t write_wrapper(const void *p_buf, size_t i_count) ...@@ -131,14 +131,15 @@ ssize_t write_wrapper(const void *p_buf, size_t i_count)
*****************************************************************************/ *****************************************************************************/
static void send_channel_status(void) static void send_channel_status(void)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_STATUS); tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_STATUS);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_sectiontspkt(p_tlv, 0x0); /* sections */ ecmg_append_sectiontspkt(p_tlv, 0x0); /* sections */
...@@ -153,7 +154,7 @@ static void send_channel_status(void) ...@@ -153,7 +154,7 @@ static void send_channel_status(void)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -161,22 +162,23 @@ static void send_channel_status(void) ...@@ -161,22 +162,23 @@ static void send_channel_status(void)
*****************************************************************************/ *****************************************************************************/
static void send_channel_test(void) static void send_channel_test(void)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
fprintf(stderr, "sending test on channel ID=0x%hx\n", i_channelid); fprintf(stderr, "sending test on channel ID=0x%hx\n", i_channelid);
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_TEST); tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_TEST);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -184,24 +186,25 @@ static void send_channel_test(void) ...@@ -184,24 +186,25 @@ static void send_channel_test(void)
*****************************************************************************/ *****************************************************************************/
static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error) static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
fprintf(stderr, "sending error on channel ID=0x%hx error=0x%hx\n", fprintf(stderr, "sending error on channel ID=0x%hx error=0x%hx\n",
i_wanted_channelid, i_error); i_wanted_channelid, i_error);
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_ERROR); tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_ERROR);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_wanted_channelid); ecmg_append_channelid(p_tlv, i_wanted_channelid);
ecmg_append_errorstatus(p_tlv, i_error); ecmg_append_errorstatus(p_tlv, i_error);
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -209,14 +212,15 @@ static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error) ...@@ -209,14 +212,15 @@ static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error)
*****************************************************************************/ *****************************************************************************/
static void send_stream_status(stream_t *p_stream) static void send_stream_status(stream_t *p_stream)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_STREAM_STATUS); tlv_set_type(p_tlv, ECMG_TYPE_STREAM_STATUS);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, p_stream->i_streamid); ecmg_append_streamid(p_tlv, p_stream->i_streamid);
...@@ -226,7 +230,7 @@ static void send_stream_status(stream_t *p_stream) ...@@ -226,7 +230,7 @@ static void send_stream_status(stream_t *p_stream)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -234,21 +238,22 @@ static void send_stream_status(stream_t *p_stream) ...@@ -234,21 +238,22 @@ static void send_stream_status(stream_t *p_stream)
*****************************************************************************/ *****************************************************************************/
static void send_stream_close(stream_t *p_stream) static void send_stream_close(stream_t *p_stream)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_STREAM_CLOSERESP); tlv_set_type(p_tlv, ECMG_TYPE_STREAM_CLOSERESP);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, p_stream->i_streamid); ecmg_append_streamid(p_tlv, p_stream->i_streamid);
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -256,17 +261,18 @@ static void send_stream_close(stream_t *p_stream) ...@@ -256,17 +261,18 @@ static void send_stream_close(stream_t *p_stream)
*****************************************************************************/ *****************************************************************************/
static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
fprintf(stderr, "sending error on stream ID=0x%hx error=0x%hx\n", fprintf(stderr, "sending error on stream ID=0x%hx error=0x%hx\n",
i_wanted_streamid, i_error); i_wanted_streamid, i_error);
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_STREAM_ERROR); tlv_set_type(p_tlv, ECMG_TYPE_STREAM_ERROR);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, i_wanted_streamid); ecmg_append_streamid(p_tlv, i_wanted_streamid);
...@@ -274,7 +280,7 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) ...@@ -274,7 +280,7 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -283,14 +289,16 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) ...@@ -283,14 +289,16 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
static void send_ecm(stream_t *p_stream, uint16_t i_cp_number, static void send_ecm(stream_t *p_stream, uint16_t i_cp_number,
const uint8_t *p_ecm, uint16_t i_length) const uint8_t *p_ecm, uint16_t i_length)
{ {
uint8_t p_tlv[MAX_TLV_SIZE + i_length]; /* this is oversized */ uint8_t p_tlv_h[MAX_TLV_SIZE + i_length]; /* this is oversized */
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_ECM); tlv_set_type(p_tlv, ECMG_TYPE_ECM);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE + i_length); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE
+ i_length);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, p_stream->i_streamid); ecmg_append_streamid(p_tlv, p_stream->i_streamid);
...@@ -299,7 +307,7 @@ static void send_ecm(stream_t *p_stream, uint16_t i_cp_number, ...@@ -299,7 +307,7 @@ static void send_ecm(stream_t *p_stream, uint16_t i_cp_number,
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -356,7 +364,6 @@ static void handle_channel_setup(uint8_t *p_tlv) ...@@ -356,7 +364,6 @@ static void handle_channel_setup(uint8_t *p_tlv)
return; return;
} }
i_version = tlv_get_version(p_tlv);
i_channelid = i_wanted_channelid; i_channelid = i_wanted_channelid;
i_supercasid = ecmg_find_supercasid(p_tlv, 0); i_supercasid = ecmg_find_supercasid(p_tlv, 0);
...@@ -610,7 +617,8 @@ int main(int i_argc, char **ppsz_argv) ...@@ -610,7 +617,8 @@ int main(int i_argc, char **ppsz_argv)
} }
for ( ; ; ) { for ( ; ; ) {
uint8_t *p_tlv = malloc(TLV_HEADER_SIZE); uint8_t *p_tlv_h = malloc(TLVH_HEADER_SIZE + TLV_HEADER_SIZE);
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint16_t i_type; uint16_t i_type;
fd_set rset; fd_set rset;
struct timeval timeout; struct timeval timeout;
...@@ -631,41 +639,46 @@ int main(int i_argc, char **ppsz_argv) ...@@ -631,41 +639,46 @@ int main(int i_argc, char **ppsz_argv)
continue; continue;
} }
if (read_wrapper(p_tlv, TLV_HEADER_SIZE) <= 0) if (read_wrapper(p_tlv_h, TLVH_HEADER_SIZE + TLV_HEADER_SIZE) <= 0)
return EXIT_FAILURE; return EXIT_FAILURE;
p_tlv = realloc(p_tlv, TLV_HEADER_SIZE + tlv_get_length(p_tlv)); p_tlv_h = realloc(p_tlv_h, TLVH_HEADER_SIZE + TLV_HEADER_SIZE
+ tlv_get_length(p_tlv));
p_tlv = tlvh_get_tlv(p_tlv_h);
if (read_wrapper(p_tlv + TLV_HEADER_SIZE, tlv_get_length(p_tlv)) <= 0) if (read_wrapper(p_tlv + TLV_HEADER_SIZE, tlv_get_length(p_tlv)) <= 0)
return EXIT_FAILURE; return EXIT_FAILURE;
if ((b_init && tlvh_get_version(p_tlv_h) > 3) ||
(!b_init && tlvh_get_version(p_tlv_h) != i_version)) {
send_channel_error(i_channelid, 0x2);
free(p_tlv_h);
continue;
}
i_type = tlv_get_type(p_tlv); i_type = tlv_get_type(p_tlv);
if (!tlv_validate(p_tlv)) { if (!tlv_validate(p_tlv)) {
send_channel_error(i_channelid, 0x1); send_channel_error(i_channelid, 0x1);
free(p_tlv); free(p_tlv_h);
continue; continue;
} }
if (!ecmg_validate(p_tlv)) { if (!ecmg_validate(p_tlv)) {
send_channel_error(i_channelid, 0xf); send_channel_error(i_channelid, 0xf);
free(p_tlv); free(p_tlv_h);
continue; continue;
} }
if (b_init && i_type != ECMG_TYPE_CHANNEL_SETUP) { if (b_init && i_type != ECMG_TYPE_CHANNEL_SETUP) {
send_channel_error(i_channelid, 0x6); send_channel_error(i_channelid, 0x6);
free(p_tlv); free(p_tlv_h);
continue;
}
if (tlv_get_version(p_tlv) > 3) {
send_channel_error(i_channelid, 0x2);
free(p_tlv);
continue; continue;
} }
switch (i_type) { switch (i_type) {
case ECMG_TYPE_CHANNEL_SETUP: case ECMG_TYPE_CHANNEL_SETUP:
if (b_init)
i_version = tlvh_get_version(p_tlv_h);
handle_channel_setup(p_tlv); handle_channel_setup(p_tlv);
break; break;
...@@ -710,7 +723,7 @@ int main(int i_argc, char **ppsz_argv) ...@@ -710,7 +723,7 @@ int main(int i_argc, char **ppsz_argv)
break; break;
} }
free(p_tlv); free(p_tlv_h);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
......
...@@ -115,11 +115,12 @@ ssize_t write_wrapper(const void *p_buf, size_t i_count) ...@@ -115,11 +115,12 @@ ssize_t write_wrapper(const void *p_buf, size_t i_count)
*****************************************************************************/ *****************************************************************************/
static void send_channel_setup(void) static void send_channel_setup(void)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_SETUP); tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_SETUP);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE);
...@@ -129,7 +130,7 @@ static void send_channel_setup(void) ...@@ -129,7 +130,7 @@ static void send_channel_setup(void)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -137,24 +138,25 @@ static void send_channel_setup(void) ...@@ -137,24 +138,25 @@ static void send_channel_setup(void)
*****************************************************************************/ *****************************************************************************/
static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error) static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
fprintf(stderr, "sending error on channel ID=0x%hx error=0x%hx\n", fprintf(stderr, "sending error on channel ID=0x%hx error=0x%hx\n",
i_wanted_channelid, i_error); i_wanted_channelid, i_error);
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_ERROR); tlv_set_type(p_tlv, ECMG_TYPE_CHANNEL_ERROR);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_wanted_channelid); ecmg_append_channelid(p_tlv, i_wanted_channelid);
ecmg_append_errorstatus(p_tlv, i_error); ecmg_append_errorstatus(p_tlv, i_error);
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -162,14 +164,15 @@ static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error) ...@@ -162,14 +164,15 @@ static void send_channel_error(uint16_t i_wanted_channelid, uint16_t i_error)
*****************************************************************************/ *****************************************************************************/
static void send_stream_setup(stream_t *p_stream) static void send_stream_setup(stream_t *p_stream)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_STREAM_SETUP); tlv_set_type(p_tlv, ECMG_TYPE_STREAM_SETUP);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, p_stream->i_streamid); ecmg_append_streamid(p_tlv, p_stream->i_streamid);
...@@ -179,7 +182,7 @@ static void send_stream_setup(stream_t *p_stream) ...@@ -179,7 +182,7 @@ static void send_stream_setup(stream_t *p_stream)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -187,17 +190,18 @@ static void send_stream_setup(stream_t *p_stream) ...@@ -187,17 +190,18 @@ static void send_stream_setup(stream_t *p_stream)
*****************************************************************************/ *****************************************************************************/
static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
fprintf(stderr, "sending error on stream ID=0x%hx error=0x%hx\n", fprintf(stderr, "sending error on stream ID=0x%hx error=0x%hx\n",
i_wanted_streamid, i_error); i_wanted_streamid, i_error);
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_STREAM_ERROR); tlv_set_type(p_tlv, ECMG_TYPE_STREAM_ERROR);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE - TLV_HEADER_SIZE - TLVH_HEADER_SIZE);
ecmg_append_channelid(p_tlv, i_channelid); ecmg_append_channelid(p_tlv, i_channelid);
ecmg_append_streamid(p_tlv, i_wanted_streamid); ecmg_append_streamid(p_tlv, i_wanted_streamid);
...@@ -205,7 +209,7 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) ...@@ -205,7 +209,7 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -213,12 +217,13 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error) ...@@ -213,12 +217,13 @@ static void send_stream_error(uint16_t i_wanted_streamid, uint16_t i_error)
*****************************************************************************/ *****************************************************************************/
static void send_cw(stream_t *p_stream) static void send_cw(stream_t *p_stream)
{ {
uint8_t p_tlv[MAX_TLV_SIZE]; uint8_t p_tlv_h[MAX_TLV_SIZE];
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint8_t *p_tlv_n; uint8_t *p_tlv_n;
int i; int i;
tlvh_set_version(p_tlv_h, i_version);
ecmg_init(p_tlv); ecmg_init(p_tlv);
tlv_set_version(p_tlv, i_version);
tlv_set_type(p_tlv, ECMG_TYPE_CW); tlv_set_type(p_tlv, ECMG_TYPE_CW);
/* length will be written at the end */ /* length will be written at the end */
tlv_set_length(p_tlv, MAX_TLV_SIZE); tlv_set_length(p_tlv, MAX_TLV_SIZE);
...@@ -245,7 +250,7 @@ static void send_cw(stream_t *p_stream) ...@@ -245,7 +250,7 @@ static void send_cw(stream_t *p_stream)
p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0); p_tlv_n = tlv_find_param(p_tlv, TLV_PARAM_EMPTY, 0);
tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE); tlv_set_length(p_tlv, p_tlv_n - p_tlv - TLV_HEADER_SIZE);
write_wrapper(p_tlv, p_tlv_n - p_tlv); write_wrapper(p_tlv_h, p_tlv_n - p_tlv_h);
} }
/***************************************************************************** /*****************************************************************************
...@@ -483,7 +488,8 @@ int main(int i_argc, char **ppsz_argv) ...@@ -483,7 +488,8 @@ int main(int i_argc, char **ppsz_argv)
send_channel_setup(); send_channel_setup();
for ( ; ; ) { for ( ; ; ) {
uint8_t *p_tlv = malloc(TLV_HEADER_SIZE); uint8_t *p_tlv_h = malloc(TLVH_HEADER_SIZE + TLV_HEADER_SIZE);
uint8_t *p_tlv = tlvh_get_tlv(p_tlv_h);
uint16_t i_type; uint16_t i_type;
fd_set rset; fd_set rset;
struct timeval timeout; struct timeval timeout;
...@@ -500,36 +506,38 @@ int main(int i_argc, char **ppsz_argv) ...@@ -500,36 +506,38 @@ int main(int i_argc, char **ppsz_argv)
goto no_packet; goto no_packet;
} }
if (read_wrapper(p_tlv, TLV_HEADER_SIZE) <= 0) if (read_wrapper(p_tlv_h, TLVH_HEADER_SIZE + TLV_HEADER_SIZE) <= 0)
return EXIT_FAILURE; return EXIT_FAILURE;
p_tlv = realloc(p_tlv, TLV_HEADER_SIZE + tlv_get_length(p_tlv)); p_tlv_h = realloc(p_tlv_h, TLVH_HEADER_SIZE + TLV_HEADER_SIZE
+ tlv_get_length(p_tlv));
p_tlv = tlvh_get_tlv(p_tlv_h);
if (read_wrapper(p_tlv + TLV_HEADER_SIZE, tlv_get_length(p_tlv)) <= 0) if (read_wrapper(p_tlv + TLV_HEADER_SIZE, tlv_get_length(p_tlv)) <= 0)
return EXIT_FAILURE; return EXIT_FAILURE;
if (tlvh_get_version(p_tlv_h) != i_version) {
send_channel_error(i_channelid, 0x2);
free(p_tlv_h);
exit(EXIT_FAILURE);
}
i_type = tlv_get_type(p_tlv); i_type = tlv_get_type(p_tlv);
if (!tlv_validate(p_tlv)) { if (!tlv_validate(p_tlv)) {
send_channel_error(i_channelid, 0x1); send_channel_error(i_channelid, 0x1);
free(p_tlv); free(p_tlv_h);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (!ecmg_validate(p_tlv)) { if (!ecmg_validate(p_tlv)) {
send_channel_error(i_channelid, 0xf); send_channel_error(i_channelid, 0xf);
free(p_tlv); free(p_tlv_h);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (b_init && i_type != ECMG_TYPE_CHANNEL_STATUS) { if (b_init && i_type != ECMG_TYPE_CHANNEL_STATUS) {
send_channel_error(i_channelid, 0x6); send_channel_error(i_channelid, 0x6);
free(p_tlv); free(p_tlv_h);
exit(EXIT_FAILURE);
}
if (tlv_get_version(p_tlv) > 3) {
send_channel_error(i_channelid, 0x2);
free(p_tlv);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
...@@ -567,9 +575,9 @@ int main(int i_argc, char **ppsz_argv) ...@@ -567,9 +575,9 @@ int main(int i_argc, char **ppsz_argv)
break; break;
} }
free(p_tlv);
no_packet: no_packet:
free(p_tlv_h);
if (!b_init) { if (!b_init) {
time_t i_time = time(NULL); time_t i_time = time(NULL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment