support multiple addresses per distributor
Stefan Schuermans

Stefan Schuermans commited on 2017-06-04 19:28:14
Showing 5 changed files, with 63 additions and 15 deletions.

... ...
@@ -17,8 +17,8 @@
17 17
 
18 18
 LIBTARGET := libetherpix
19 19
 VER_MAJ   := 1
20
-VER_MIN   := 1
21
-VER_REV   := 1
20
+VER_MIN   := 2
21
+VER_REV   := 0
22 22
 VERSION   := $(VER_MAJ).$(VER_MIN).$(VER_REV)
23 23
 
24 24
 SRCS    := $(wildcard src/*.c)
... ...
@@ -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