Stefan Schuermans commited on 2017-06-04 19:28:14
Showing 5 changed files, with 63 additions and 15 deletions.
... | ... |
@@ -25,6 +25,8 @@ |
25 | 25 |
* that can be in the system, |
26 | 26 |
* number of distributor addresses |
27 | 27 |
* available */ |
28 |
+#define ETP_DISTRI_MAX_ADDRS (8) /**< maximum number of network address(es) |
|
29 |
+ for a distributor */ |
|
28 | 30 |
#define ETP_OUTPUT_MAX_CNT (128) /**< maximum number of outputs per |
29 | 31 |
* distributor */ |
30 | 32 |
#define ETP_PIXEL_MAX_CNT (1024) /**< maximum number of pixels that can |
... | ... |
@@ -48,8 +48,12 @@ typedef struct etp_pixel_s { |
48 | 48 |
typedef struct etp_distri_s { |
49 | 49 |
unsigned int distri; /**< number of this distributor */ |
50 | 50 |
unsigned int output_cnt; /**< number of outputs of this distributor */ |
51 |
- unsigned int pixel_cnt; /**< number of pixels connected to every output */ |
|
52 |
- struct sockaddr_in addr; /**< network address of distributor */ |
|
51 |
+ unsigned int pixel_cnt; /**< number of pixels connected to each output */ |
|
52 |
+ unsigned int addr_cnt; /**< number of network addresses */ |
|
53 |
+ struct sockaddr_in addrs |
|
54 |
+ [ETP_DISTRI_MAX_ADDRS]; /**< network address(es) of distributor, |
|
55 |
+ * multiple addresses mean the packets are |
|
56 |
+ * sent to each address */ |
|
53 | 57 |
etp_mapping_t mapping[3]; /**< mapping information for red, green |
54 | 58 |
* and blue channel */ |
55 | 59 |
etp_pixel_t *p_pixels; /**< array with information about pixels |
... | ... |
@@ -108,11 +108,8 @@ int etp_config_proc_distri(etp_config_ctx_t *p_ctx, char *p_setting_part2, |
108 | 108 |
p_distri->distri = distri; |
109 | 109 |
p_distri->output_cnt = out; |
110 | 110 |
p_distri->pixel_cnt = pix; |
111 |
- /* initialize address to default */ |
|
112 |
- p_distri->addr.sin_family = AF_INET; |
|
113 |
- p_distri->addr.sin_addr.s_addr = htonl(ETP_DEST_IP_BASE + |
|
114 |
- p_distri->distri * ETP_DEST_IP_STEP); |
|
115 |
- p_distri->addr.sin_port = htons(ETP_DEST_PORT); |
|
111 |
+ /* no network address yet */ |
|
112 |
+ p_distri->addr_cnt = 0; |
|
116 | 113 |
/* initialize mapping information */ |
117 | 114 |
for (i = 0; i < 3; i++) { |
118 | 115 |
p_distri->mapping[i].base = 0.0; |
... | ... |
@@ -205,8 +202,18 @@ int etp_config_proc_distri_addr(etp_config_ctx_t *p_ctx, char *p_setting_part2, |
205 | 202 |
return -1; |
206 | 203 |
} |
207 | 204 |
|
208 |
- /* get address */ |
|
209 |
- if (etp_parse_addr(p_value, &p_distri->addr)) { |
|
205 |
+ /* check if maximum number of addresses reached */ |
|
206 |
+ if (p_distri->addr_cnt >= ETP_DISTRI_MAX_ADDRS) { |
|
207 |
+ if (p_ctx->p_msg_func) |
|
208 |
+ p_ctx->p_msg_func(p_ctx->p_msg_ctx, etp_msg_type_err, |
|
209 |
+ "too many addresses (\"%s\") for distributor with" |
|
210 |
+ " number \"%u\" in line %u of config file\n", |
|
211 |
+ p_value, distri, p_ctx->line_no); |
|
212 |
+ return -1; |
|
213 |
+ } |
|
214 |
+ |
|
215 |
+ /* get address and add it to distributor */ |
|
216 |
+ if (etp_parse_addr(p_value, &p_distri->addrs[p_distri->addr_cnt])) { |
|
210 | 217 |
if (p_ctx->p_msg_func) |
211 | 218 |
p_ctx->p_msg_func(p_ctx->p_msg_ctx, etp_msg_type_err, |
212 | 219 |
"invalid address \"%s\" for distributor with number" |
... | ... |
@@ -214,6 +221,7 @@ int etp_config_proc_distri_addr(etp_config_ctx_t *p_ctx, char *p_setting_part2, |
214 | 221 |
p_value, distri, p_ctx->line_no); |
215 | 222 |
return -1; |
216 | 223 |
} |
224 |
+ ++p_distri->addr_cnt; |
|
217 | 225 |
|
218 | 226 |
return 0; |
219 | 227 |
} |
... | ... |
@@ -636,6 +644,33 @@ int etp_config_proc_line(etp_config_ctx_t *p_ctx, char *p_line) |
636 | 644 |
return etp_config_proc_setting(p_ctx, p_setting, p_value); |
637 | 645 |
} |
638 | 646 |
|
647 |
+/** |
|
648 |
+ * \brief set default addresses of distributors |
|
649 |
+ * \param[in,out] p_ctx context information |
|
650 |
+ */ |
|
651 |
+static void etp_config_set_def_distri_addrs(etp_config_ctx_t *p_ctx) |
|
652 |
+{ |
|
653 |
+ unsigned int distri; |
|
654 |
+ etp_distri_t *p_distri; |
|
655 |
+ |
|
656 |
+ /* set default addresses of distributors */ |
|
657 |
+ for (distri = 0; distri < ETP_DISTRI_MAX_CNT; distri++) { |
|
658 |
+ p_distri = p_ctx->p_display->distri_ptrs[distri]; |
|
659 |
+ if (p_distri) { |
|
660 |
+ |
|
661 |
+ /* no address yet -> use default */ |
|
662 |
+ if (p_distri->addr_cnt == 0) { |
|
663 |
+ p_distri->addr_cnt = 1; |
|
664 |
+ p_distri->addrs[0].sin_family = AF_INET; |
|
665 |
+ p_distri->addrs[0].sin_addr.s_addr = |
|
666 |
+ htonl(ETP_DEST_IP_BASE + p_distri->distri * ETP_DEST_IP_STEP); |
|
667 |
+ p_distri->addrs[0].sin_port = htons(ETP_DEST_PORT); |
|
668 |
+ } |
|
669 |
+ |
|
670 |
+ } // if (p_distri) |
|
671 |
+ } // for (distri ...) |
|
672 |
+} |
|
673 |
+ |
|
639 | 674 |
/** |
640 | 675 |
* \brief process config file |
641 | 676 |
* |
... | ... |
@@ -720,6 +755,9 @@ int etp_config_proc_file(etp_display_t *p_display, |
720 | 755 |
/* close file */ |
721 | 756 |
fclose(file); |
722 | 757 |
|
758 |
+ /* set default addresses of distributors */ |
|
759 |
+ etp_config_set_def_distri_addrs(&ctx); |
|
760 |
+ |
|
723 | 761 |
if (p_msg_func) |
724 | 762 |
p_msg_func(p_msg_ctx, etp_msg_type_info, |
725 | 763 |
"%ux%u input format, %u distributors, %u outputs, %lu pixels\n", |
... | ... |
@@ -275,7 +275,7 @@ void etp_display_data(etp_display_t *p_display, etp_u8_t *p_data, |
275 | 275 |
*/ |
276 | 276 |
void etp_display_send(etp_display_t *p_display) |
277 | 277 |
{ |
278 |
- unsigned int distri; |
|
278 |
+ unsigned int distri, addr_i; |
|
279 | 279 |
etp_distri_t *p_distri; |
280 | 280 |
|
281 | 281 |
/* send data to all distributors */ |
... | ... |
@@ -283,9 +283,13 @@ void etp_display_send(etp_display_t *p_display) |
283 | 283 |
p_distri = p_display->distri_ptrs[distri]; |
284 | 284 |
if (p_distri) { |
285 | 285 |
|
286 |
- /* send message as UDP packet */ |
|
287 |
- sendto(p_display->sock, (char *)p_distri->p_msg_buf, p_distri->msg_len, |
|
288 |
- 0, (struct sockaddr *)&p_distri->addr, sizeof (p_distri->addr)); |
|
286 |
+ /* send message as UDP packet to each address */ |
|
287 |
+ for (addr_i = 0; addr_i < p_distri->addr_cnt; ++addr_i) { |
|
288 |
+ sendto(p_display->sock, |
|
289 |
+ (char *)p_distri->p_msg_buf, p_distri->msg_len, 0, |
|
290 |
+ (struct sockaddr *)&p_distri->addrs[addr_i], |
|
291 |
+ sizeof (p_distri->addrs[addr_i])); |
|
292 |
+ } /* for (addr_i ...) */ |
|
289 | 293 |
|
290 | 294 |
} /* if (p_distri) */ |
291 | 295 |
} /* for (distri ...) */ |
292 | 296 |