rename lighthouse host app to "led_strip" as it is not related to
authorNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 9 Feb 2023 02:03:27 +0000 (03:03 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 9 Feb 2023 02:03:27 +0000 (03:03 +0100)
current lighthouse target app.

30 files changed:
host/led_strip/.gitignore [new file with mode: 0644]
host/led_strip/Basic_UDP_Protocol.txt [new file with mode: 0644]
host/led_strip/Makefile [new file with mode: 0644]
host/led_strip/dtplug_protocol_defs.h [new symlink]
host/led_strip/dtplug_protocol_host.c [new file with mode: 0644]
host/led_strip/dtplug_protocol_host.h [new file with mode: 0644]
host/led_strip/handlers.c [new file with mode: 0644]
host/led_strip/handlers.h [new file with mode: 0644]
host/led_strip/list.h [new file with mode: 0644]
host/led_strip/main.c [new file with mode: 0644]
host/led_strip/questions.pl [new file with mode: 0755]
host/led_strip/serial_utils.c [new file with mode: 0644]
host/led_strip/serial_utils.h [new file with mode: 0644]
host/led_strip/sock_utils.c [new file with mode: 0644]
host/led_strip/sock_utils.h [new file with mode: 0644]
host/lighthouse/.gitignore [deleted file]
host/lighthouse/Basic_UDP_Protocol.txt [deleted file]
host/lighthouse/Makefile [deleted file]
host/lighthouse/dtplug_protocol_defs.h [deleted symlink]
host/lighthouse/dtplug_protocol_host.c [deleted file]
host/lighthouse/dtplug_protocol_host.h [deleted file]
host/lighthouse/handlers.c [deleted file]
host/lighthouse/handlers.h [deleted file]
host/lighthouse/list.h [deleted file]
host/lighthouse/main.c [deleted file]
host/lighthouse/questions.pl [deleted file]
host/lighthouse/serial_utils.c [deleted file]
host/lighthouse/serial_utils.h [deleted file]
host/lighthouse/sock_utils.c [deleted file]
host/lighthouse/sock_utils.h [deleted file]

diff --git a/host/led_strip/.gitignore b/host/led_strip/.gitignore
new file mode 100644 (file)
index 0000000..47548e5
--- /dev/null
@@ -0,0 +1 @@
+protocol_bridge
diff --git a/host/led_strip/Basic_UDP_Protocol.txt b/host/led_strip/Basic_UDP_Protocol.txt
new file mode 100644 (file)
index 0000000..a713df3
--- /dev/null
@@ -0,0 +1,22 @@
+# Basic control protocol for LightHouse over UDP.
+# Should be replaced by MQTT in the future
+
+# Set Led
+SL addr branche [ledx R G B] [ledy R G B] [....]
+# addr : 0 -> 16K (0 == broadcast)
+# branche : 0 - 64 (port * 32 + pin)
+# led : 0 -> 255
+# R, G et B : 0 -> 255
+
+# Get Leds info
+GI
+# Replies :
+GI addr branche nbleds
+
+# Get Leds Colors
+GLC addr branche
+# Reply :
+GLC addr branche [R G B] [R G B] ....
+
+
+
diff --git a/host/led_strip/Makefile b/host/led_strip/Makefile
new file mode 100644 (file)
index 0000000..fdafb8f
--- /dev/null
@@ -0,0 +1,32 @@
+#CROSS_COMPILE ?= arm-linux-gnueabihf-
+CC = $(CROSS_COMPILE)gcc
+
+CFLAGS = -Wall -O2 -Wextra -DHOST_HAS_STDINT
+
+EXEC = protocol_bridge
+
+all: $(EXEC)
+
+
+OBJDIR = objs
+SRC = $(shell find . -name \*.c)
+OBJS = ${SRC:%.c=${OBJDIR}/%.o}
+INCLUDES = includes/
+
+${OBJDIR}/%.o: %.c
+       @mkdir -p $(dir $@)
+       @echo "-- compiling" $<
+       @$(CC) -MMD -MP -MF ${OBJDIR}/$*.d $(CFLAGS) $< -c -o $@ -I$(INCLUDES)
+
+$(EXEC): $(OBJS)
+       @echo "Linking $@ ..."
+       @$(CC) $(LDFLAGS) -o $@ $(OBJS)
+       @echo Done.
+
+
+clean:
+       find ${OBJDIR} -name "*.o" -exec rm {} \;
+       find ${OBJDIR} -name "*.d" -exec rm {} \;
+
+mrproper: clean
+       rm -f $(EXEC)
diff --git a/host/led_strip/dtplug_protocol_defs.h b/host/led_strip/dtplug_protocol_defs.h
new file mode 120000 (symlink)
index 0000000..62c8622
--- /dev/null
@@ -0,0 +1 @@
+../../../../include/lib/protocols/dtplug/defs.h
\ No newline at end of file
diff --git a/host/led_strip/dtplug_protocol_host.c b/host/led_strip/dtplug_protocol_host.c
new file mode 100644 (file)
index 0000000..1505d31
--- /dev/null
@@ -0,0 +1,236 @@
+/****************************************************************************
+ *   dtplug_protocol_host.c
+ *
+ *
+ * Copyright 2013-2015 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* Host side implementation of the DTPlug communication protocol */
+
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "dtplug_protocol_host.h"
+
+
+/******************************************************************************/
+/* Handle packet reception, including checksums */
+/* 'sum' is used to sum all the received characters, and if the last byte of sum is 0 for each
+ *   part (header and data) then the packet is valid.
+ * 'full_size' is the size of the whole packet, including header, updated as soon as the header
+ *   is checked and valid
+ *
+ * This function must be called for every received character.
+ * If the character is part of a packet but the packet is being built, then the function returns 0.
+ * When the character is the last one of a valid packet, then the function returns the packet size
+ *   and the packet in rx_data->rx_packet is valid.
+ * If the character is the last one of a packet which has an invalid data checksum, this function
+ *   returns -2 and the data is lost.
+ * If the character is not part of a packet it returns -1. The character may then be part of
+ *   a debug message (and displayed by the host), or any other kind of communication.
+ * When a set of consecutive characters have been used to build a packet but the packet is
+ *   not valid due to header error, then the function returns -3 (checksum error) or -4 (data size
+ *   error). The data in rx_data->rx_packet is the received data but is not valid.
+ *   The corresponding data size is always sizeof(struct header).
+ */
+int dtplug_protocol_decode(uint8_t c, struct line_transceiver* rx_data)
+{
+       struct header* info = (struct header*)(&(rx_data->rx_packet));
+       int ret = 0;
+
+       /* Do not start reception before receiving the packet start character */
+       if ((rx_data->rx_ptr == 0) && (c != FIRST_PACKET_CHAR)) {
+               return -1;
+       }
+
+       /* Store the new byte in the packet */
+       ((uint8_t*)(&(rx_data->rx_packet)))[rx_data->rx_ptr++] = c;
+       rx_data->sum += c;
+
+       /* Is this packet valid ? (at end of header reception) */
+       if (rx_data->rx_ptr == sizeof(struct header)) {
+               /* Checksum OK ? */
+               if (rx_data->sum != 0) {
+                       rx_data->errors_count++;
+                       ret = -3;
+                       goto next_packet;
+               }
+               /* Start the new checksum for data (if any) */
+               rx_data->sum = 0;
+
+               rx_data->full_size = sizeof(struct header);
+               /* If the packet is not a quick data or error packet it has a data part. Get it's size */
+               if (!(info->seq_num & QUICK_DATA_PACKET) && !(info->seq_num & PACKET_IS_ERROR)) {
+                       rx_data->full_size += (info->data.size & PKT_SIZE_MASK); /* Don't care about big packets here */
+                       /* Make sure the packet will fit in the buffer */
+                       if (rx_data->full_size > sizeof(struct packet)) {
+                               rx_data->errors_count++;
+                               ret = -4;
+                               goto next_packet;
+                       }
+               }
+       }
+
+       /* Did we receive the whole packet ? */
+       if (rx_data->rx_ptr == rx_data->full_size) {
+               /* From here on, the packet is valid, we can provide some feedback */
+               /* Check data checksum if we have a normal data packet */
+               if (!(info->seq_num & QUICK_DATA_PACKET) && !(info->seq_num & PACKET_IS_ERROR)) {
+                       if (rx_data->sum != info->data.checksum) {
+                               rx_data->errors_count++;
+                               ret = -2;
+                               goto next_packet;
+                       }
+               }
+               /* Count received packets */
+               rx_data->packet_rx_count++;
+               ret = rx_data->full_size;
+               /* And get ready to receive the next packet */
+               goto next_packet;
+       }
+
+       return 0;
+
+next_packet:
+#ifdef DEBUG
+       printf("Current rx pointer: %d, packet full size: %d\n", rx_data->rx_ptr, rx_data->full_size);
+       printf("Packets received count: %d, packets errors: %d\n",
+                               rx_data->packet_rx_count, rx_data->errors_count);
+       if (rx_data->rx_ptr >= sizeof(struct header)) {
+               struct header* h = info;
+               printf("Pkt: type: %d, seq: %d, err: %d, quick: %d\n", h->type, (h->seq_num & 0x1F),
+                                               (h->seq_num & PACKET_IS_ERROR), (h->seq_num & QUICK_DATA_PACKET));
+               if (!(h->seq_num & QUICK_DATA_PACKET) && !(h->seq_num & PACKET_IS_ERROR)) {
+                       printf("Pkt: data_size: %d, data_cksum: 0x%02x\n", h->data.size, h->data.checksum);
+                       printf("rx_data_cksum: 0x%02x\n", rx_data->sum);
+               }
+       }
+#endif
+       /* Wether the packet was OK or not doesn't matter, go on for a new one :) */
+       rx_data->full_size = 0;
+       rx_data->rx_ptr = 0;
+       rx_data->sum = 0;
+       return ret;
+}
+
+
+/******************************************************************************/
+/* This function handles sending packets to slave
+ * It returns the number of bytes of data sent.
+ */
+int host_send_packet(struct line_transceiver* slave, uint8_t type, uint32_t size, uint8_t* data, int need_reply)
+{
+       struct packet cmd;
+       struct header* cmd_info = &(cmd.info);
+       unsigned int i = 0, sent = 0, len = sizeof(struct header);
+       uint8_t sum = 0;
+       unsigned int data_send_size = size, data_sent = 0;
+
+       /* Loop to send all data, possibly split in several packets */
+       do {
+               memset(&cmd, 0, sizeof(struct packet));
+               if (data_send_size > PACKET_DATA_SIZE) {
+                       data_send_size = PACKET_DATA_SIZE;
+               }
+               /* Set packet header */
+               cmd_info->start = FIRST_PACKET_CHAR;
+               cmd_info->type = type;
+               cmd_info->seq_num = (slave->sequence_number++ & SEQUENCE_MASK);
+               /* Set the need reply bit only on the last packet */
+               if ((need_reply != 0) && ((data_sent + data_send_size) == size)) {
+                       cmd_info->seq_num |= PACKET_NEEDS_REPLY;
+               }
+               /* Setup data */
+               if (data != NULL) {
+                       /* Only use quick data packet for short packet, not continued data */
+                       if (size && (size <= 2)) {
+                               cmd_info->seq_num |= QUICK_DATA_PACKET;
+                               cmd_info->quick_data[0] = data[0];
+                               if (size == 2) {
+                                       cmd_info->seq_num |= QUICK_DATA_PACKET_TWO_BYTES;
+                                       cmd_info->quick_data[1] = data[1];
+                               }
+                       } else {
+                               /* Copy data, compute checksum (also OK for a data_send_size of 0) */
+                               for (i = 0; i < data_send_size; i++) {
+                                       cmd.data[i] = data[i];
+                                       sum += data[i]; /* Build checksum */
+                               }
+                               /* And update header information */
+                               cmd_info->data.size = data_send_size;
+                               /* Will this packet be continued in the following one ? */
+                               if (data_send_size < (size - data_sent)) {
+                                       cmd_info->data.size |= BIG_DATA_PKT;
+                               }
+                               cmd_info->data.checksum = sum;
+                               /* Update length of data to send on serial link */
+                               len += data_send_size;
+                       }
+               }
+
+               /* Compute header checksum */
+               sum = 0;
+               cmd_info->checksum = 0;
+               for (i = 0; i < sizeof(struct header); i++) {
+                       sum += ((uint8_t*)cmd_info)[i];
+               }
+               cmd_info->checksum = ((uint8_t)(256 - sum));
+
+               /* And send the packet on the serial link */
+               while (sent < len) {
+                       int ret = write(slave->fd, (((char*)(&cmd)) + sent), (len - sent));
+                       if (ret >= 0) {
+                               sent += ret;
+                       } else {
+                               /* Sending error ... */
+                               /* FIXME : handle / report errors */
+                               return data_sent;
+                       }
+               }
+               data_sent += data_send_size;
+
+               /* Need to send more ? */
+               if (data && (data_sent <= size)) {
+                       /* Move data pointer */
+                       data += data_send_size;
+                       /* Update size to send. check against PACKET_DATA_SIZE is done at beginning of loop */
+                       data_send_size = (size - data_sent);
+                       /* Set packet type to continued data packet for following packets */
+                       type = PKT_TYPE_CONTINUED_DATA;
+                       /* And prepare sending of the next packet (reset internal loop counters) */
+                       sum = 0;
+                       len = sizeof(struct header);
+                       sent = 0;
+               } else {
+                       /* No data, everything got sent */
+                       data_send_size = 0;
+               }
+       } while (data_send_size != 0);
+
+       return data_sent;
+}
+
+
diff --git a/host/led_strip/dtplug_protocol_host.h b/host/led_strip/dtplug_protocol_host.h
new file mode 100644 (file)
index 0000000..23cd3f4
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+ *   dtplug_protocol_host.h
+ *
+ *
+ * Copyright 2013-2015 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* Host side implementation of the DTPlug communication protocol */
+
+#ifndef DTPLUG_PROTOCOL_HOST_H
+#define DTPLUG_PROTOCOL_HOST_H
+
+
+#include <stdint.h>
+#include "dtplug_protocol_defs.h"
+
+
+/******************************************************************************/
+/* Handle packet reception, including checksums */
+/* 'sum' is used to sum all the received characters, and if the last byte of sum is 0 for each
+ *   part (header and data) then the packet is valid.
+ * 'full_size' is the size of the whole packet, including header, updated as soon as the header
+ *   is checked and valid
+ */
+struct line_transceiver {
+       int fd;
+       /* The packet being built */
+       struct packet rx_packet;
+       /* Sequence number for this line */
+       uint8_t sequence_number;
+       /* Packet building data */
+       uint8_t rx_ptr;
+       uint8_t sum;
+       uint8_t full_size;
+       /* packet counts */
+       uint32_t packet_rx_count;
+       uint32_t packet_tx_count;
+       uint32_t errors_count;
+};
+
+/* This function must be called for every received character.
+ * If the character is part of a packet but the packet is being built, then the function returns 0.
+ * When the character is the last one of a valid packet, then the function returns the packet size
+ *   and the packet in rx_data->rx_packet is valid.
+ * If the character is the last one of a packet which has an invalid data checksum, this function
+ *   returns -2 and the data is lost.
+ * If the character is not part of a packet it returns -1. The character may then be part of
+ *   a debug message (and displayed by the host), or any other kind of communication.
+ * When a set of consecutive characters have been used to build a packet but the packet is
+ *   not valid due to header error, then the function returns -3 (checksum error) or -4 (data size
+ *   error). The data in rx_data->rx_packet is the received data but is not valid.
+ *   The corresponding data size is always sizeof(struct header).
+ */
+int dtplug_protocol_decode(uint8_t c, struct line_transceiver* rx_data);
+
+/* This function handles sending packets to slave
+ * It returns the number of bytes of data sent.
+ */
+int host_send_packet(struct line_transceiver* slave, uint8_t type, uint32_t size,  uint8_t* data, int need_reply);
+
+
+#endif /* DTPLUG_PROTOCOL_HOST_H */
+
diff --git a/host/led_strip/handlers.c b/host/led_strip/handlers.c
new file mode 100644 (file)
index 0000000..c9dc1f9
--- /dev/null
@@ -0,0 +1,255 @@
+/****************************************************************************
+ *  LightHouse UDP to RF Sub1GHz module bridge.
+ *
+ *   handlers.c
+ *
+ *
+ * Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* This protocol handler is designed to run on a host. */
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include "list.h"
+#include "dtplug_protocol_host.h"
+
+
+#define BUFF_LEN 60
+
+struct info_data {
+       struct list_head head;
+       int type;  /* Information type */
+       int addr;  /* Source address */
+       int function;  /* Information function */
+       int number;    /* Information number */
+       int value; /* Information */
+       struct timeval last_update;   /* Information timestamp */
+};
+
+
+struct list_head* all_info = NULL;
+int nb_info = 0;
+
+int create_info(int type, int addr, int func, int num)
+{
+       struct info_data* addinfo = malloc(sizeof(struct info_data));
+
+       if (addinfo == NULL) {
+               return -1;
+       }
+
+       if (all_info == NULL) {
+               all_info = &(addinfo->head);
+               INIT_LIST_HEAD(&(addinfo->head));
+       } else {
+               list_add_tail(&addinfo->head, all_info);
+       }
+       addinfo->type = type;
+       addinfo->addr = addr;
+       addinfo->function = func;
+       addinfo->number = num;
+       nb_info++;
+
+       return 0;
+}
+
+void delete_info(struct info_data* oldinfo)
+{
+       if (oldinfo == NULL) {
+               return;
+       }
+       list_del(&(oldinfo->head));
+       if (list_empty(all_info)) {
+               all_info = NULL;
+       }
+       free(oldinfo);
+       nb_info--;
+}
+
+/* Find exactly matching information */
+struct info_data* find_info(int type, int addr, int func, int num)
+{
+       struct info_data* info = NULL;
+       if (all_info == NULL) {
+               return NULL;
+       }
+       list_for_each_entry(info, all_info, head) {
+               if ((info->type == type) && (info->addr == addr) && (info->function == func) && (info->number == num)) {
+                       return info;
+               }
+       }
+       return info;
+}
+/* TOTO : find all info_data matching given criteria */
+
+
+
+int handle_module_data(struct line_transceiver* slave)
+{
+       struct header* head = &(slave->rx_packet.info);
+       /* If this packet holds no valid data, it indicates that there are errors */
+       if (head->seq_num & PACKET_IS_ERROR) {
+               printf("Received a packet indicating errors (%d - %d)\n",
+                                        head->err.error_code, head->err.info);
+               /* Request the list of errors */
+               host_send_packet(slave, PKT_TYPE_GET_ERRORS, 0, NULL, 1);
+               return 0;
+       }
+       /* Move data from "QUICK_DATA_PACKET" packets to the data part of the packet for easy handling */
+       if (head->seq_num & QUICK_DATA_PACKET) {
+               slave->rx_packet.data[0] = head->quick_data[0];
+               slave->rx_packet.data[1] = head->quick_data[1];
+               if (head->seq_num & QUICK_DATA_PACKET_ONE_BYTE) {
+                       head->data.size = 1;
+               } else {
+                       head->data.size = 2;
+               }
+       }
+
+       switch (head->type) {
+               case PKT_TYPE_PING:
+                       break;
+
+               case PKT_TYPE_GET_BOARD_INFO:
+                       break;
+
+               case PKT_TYPE_GET_NUM_PACKETS:
+                       break;
+
+               case PKT_TYPE_GET_ERRORS:
+                       /* FIXME */
+                       printf("Received error list: ... implement error decoding.\n");
+                       break;
+
+               case PKT_TYPE_GET_NUM_ERRORS:
+                       /* FIXME */
+                       printf("Received number of errors: %d.\n", 0);
+                       break;
+       
+               case PKT_TYPE_CONTINUED_DATA:
+                       break;
+       
+               case PKT_TYPE_GET_TEMPERATURE:
+                       {
+                               struct info_data* info = find_info('T', 0, 0, 0); /* FIXME */
+                               uint16_t* tmp = (uint16_t*)(&(slave->rx_packet.data[0]));
+                               gettimeofday(&(info->last_update), NULL);
+                               info->value = (int16_t)ntohs(tmp[0]);
+                       }
+                       break;
+       
+               case PKT_TYPE_GET_ADC_VALUE:
+                       break;
+
+               default:
+                       printf("Received packet type %d. Not handled.\n", head->type);
+                       break;
+       }
+       return 0;
+}
+
+#define REP_SIZE_MAX  1024
+
+int handle_udp_request(char* buf, int len, struct sockaddr* addr, socklen_t addr_len,
+                                                int sock, struct line_transceiver* slave)
+{
+       struct info_data* info = NULL;
+       if ((len == 0) || (buf == NULL)) {
+               return -1;
+       }
+       if (buf[0] == 'G') {
+               char obuf[REP_SIZE_MAX];
+               int len = 0;
+               /* GET command : Return the last updated value with the update timestamp */
+               switch (buf[1]) {
+                       case 'L':
+                               info = find_info('L', 0, 0, 0); /* FIXME */
+                               if (info != NULL) {
+                                       len = snprintf(obuf, REP_SIZE_MAX, "GL %d %d %d : %d at %ld.%03ld",
+                                                       info->addr, info->function, info->number, info->value,
+                                                       info->last_update.tv_sec, (info->last_update.tv_usec / 1000));
+                               }
+                               break;
+                       case 'I':
+                               list_for_each_entry(info, all_info, head) {
+                                       if (info->type == 'I') {
+                                               len = snprintf(obuf, REP_SIZE_MAX, "GI: %d %d %d\n",
+                                                       info->addr, info->function, info->value);
+                                               sendto(sock, obuf, len, 0, addr, addr_len);
+                                       }
+                               }
+                               break;
+               }
+               sendto(sock, obuf, len, 0, addr, addr_len);
+               printf("Handled GET request type: %c\n", buf[1]);
+       } else if (buf[0] == 'U') {
+               uint8_t num = 0;
+               /* Request a value update */
+               switch (buf[1]) {
+                       case 'T':
+                               host_send_packet(slave, PKT_TYPE_START_TEMP_CONVERSION, 0, NULL, 0);
+                               usleep(200 * 1000); /* Temp conversion at 11 bits resolution is about 160ms */
+                               host_send_packet(slave, PKT_TYPE_GET_TEMPERATURE, 0, NULL, 1);
+                               break;
+                       case 'A':
+                               num = (uint8_t)(strtoul(&buf[2], NULL, 10) & 0xFF);
+                               host_send_packet(slave, PKT_TYPE_GET_ADC_VALUE, 1, &num, 1);
+                               break;
+               }
+               printf("Handled UPDATE request type: %c\n", buf[1]);
+       } else if (buf[0] == 'S') {
+               /* Send new values to the micro-controller */
+               uint8_t obuf[BUFF_LEN];
+               char* tmp = NULL;
+               int i = 0;
+
+               switch (buf[1]) {
+                       case 'L': /* FIXME */
+                               obuf[0] = (strtoul(&buf[2], &tmp, 10) & 0xFF); /* Address */
+                               obuf[1] = (strtoul(tmp, &tmp, 10) & 0x3F); /* Function */
+                               for (i = 2; ((i < (BUFF_LEN - 4)) && (tmp < buf + len)); i += 4) {
+                                       obuf[i] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Number */
+                                       obuf[i + 1] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Red Value */
+                                       obuf[i + 2] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Green Value */
+                                       obuf[i + 3] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Blue Value */
+                               }
+                               host_send_packet(slave, PKT_TYPE_SET_RGB_LED, i, obuf, 0);
+                               break;
+               }
+               printf("Handled SET request type: %c\n", buf[1]);
+       } else {
+               printf("Unhandled request type: '0x%02x'\n", buf[0]);
+               return -2;
+       }
+
+       return 0;
+}
+
+
+
diff --git a/host/led_strip/handlers.h b/host/led_strip/handlers.h
new file mode 100644 (file)
index 0000000..0956385
--- /dev/null
@@ -0,0 +1,47 @@
+/****************************************************************************
+ *  LightHouse UDP to RF Sub1GHz module bridge.
+ *
+ *   handlers.h
+ *
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* This protocol handler is designed to run on a host replacing the DTPlug,
+ * but should be easy to use as a source for the protocol handling code for
+ * the DTPlug itself.
+ */
+
+#ifndef HANDLERS_H
+#define HANDLERS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include "dtplug_protocol_host.h"
+
+
+
+int handle_module_data(struct line_transceiver* slave);
+
+
+int handle_udp_request(char* buf, int len, struct sockaddr* addr, socklen_t addr_len,
+                                               int sock, struct line_transceiver* slave);
+
+
+#endif /* HANDLERS_H */
diff --git a/host/led_strip/list.h b/host/led_strip/list.h
new file mode 100644 (file)
index 0000000..1be8f9a
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * list.h
+ *
+ * This code is from the linux kernel. It is a very simple and powerfull doubly
+ *   linked list implementation.
+ * Not everything has been taken from the original file.
+ */
+
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+
+/* linux/kernel.h */
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({          \
+    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+    (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+
+/* linux/stddef.h */
+
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+
+
+/* linux/list.h */
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+       struct list_head *next, *prev;
+};
+
+/*
+ * These are non-NULL pointers that will result in page faults
+ * under normal circumstances, used to verify that nobody uses
+ * non-initialized list entries.
+ */
+#define LIST_POISON1  ((void *) 0x00100100)
+#define LIST_POISON2  ((void *) 0x00200200)
+
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+       struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+       list->next = list;
+       list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+                             struct list_head *prev,
+                             struct list_head *next)
+{
+       next->prev = new;
+       new->next = next;
+       new->prev = prev;
+       prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+       __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+       next->prev = prev;
+       prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void __list_del_entry(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+}
+
+static inline void list_del(struct list_head *entry)
+{
+       __list_del(entry->prev, entry->next);
+       entry->next = LIST_POISON1;
+       entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+                               const struct list_head *head)
+{
+       return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+       return head->next == head;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:       the &struct list_head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+       container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:       the list head to take the element from.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+       list_entry((ptr)->next, type, member)
+
+/**
+ * list_last_entry - get the last element from a list
+ * @ptr:       the list head to take the element from.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_last_entry(ptr, type, member) \
+       list_entry((ptr)->prev, type, member)
+
+/**
+ * list_next_entry - get the next element in list
+ * @pos:       the type * to cursor
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_next_entry(pos, member) \
+       list_entry((pos)->member.next, typeof(*(pos)), member)
+
+/**
+ * list_for_each_entry -       iterate over list of given type
+ * @pos:       the type * to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)                         \
+       for (pos = list_first_entry(head, typeof(*pos), member);        \
+            &pos->member != (head);                                    \
+            pos = list_next_entry(pos, member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:    the type * to use as a loop cursor.
+ * @n:      another type * to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)          \
+       for (pos = list_first_entry(head, typeof(*pos), member),    \
+               n = list_next_entry(pos, member);           \
+                &pos->member != (head);                    \
+                pos = n, n = list_next_entry(n, member))
+
+#endif  /* _LINUX_LIST_H */
diff --git a/host/led_strip/main.c b/host/led_strip/main.c
new file mode 100644 (file)
index 0000000..11bd805
--- /dev/null
@@ -0,0 +1,271 @@
+/****************************************************************************
+ *  LightHouse UDP to RF Sub1GHz module bridge.
+ *
+ *   main.c
+ *
+ *
+ * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+/* this protocol handler is designed to run on a host replacing the DTPlug,
+ * but should be easy to use as a source for the protocol handling code for
+ * the DTPlug itself.
+ */
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include "dtplug_protocol_host.h"
+#include "serial_utils.h"
+#include "sock_utils.h"
+#include "handlers.h"
+
+
+#define BUF_SIZE  1024
+
+#define PROG_NAME  "DTPlug protocol test bridge"
+#define VERSION  "0.1"
+
+
+void help(char *prog_name)
+{
+       fprintf(stderr, "---------------- "PROG_NAME" --------------------------------\n");
+       fprintf(stderr, "Usage: %s [options]\n" \
+               "  Available options:\n" \
+               "  \t -p | --port : Start listening for messages on this port\n" \
+               "  \t -d | --device : Serial device to use for serial communication with the module\n" \
+               "  \t -h | --help : Print this help\n" \
+               "  \t -v | --version : Print programm version\n" \
+               "  All other arguments are data for the command, handled depending on the command.\n", prog_name);
+       fprintf(stderr, "-----------------------------------------------------------------------\n");
+}
+
+
+int main(int argc, char* argv[])
+{
+       /* Serial */
+       char* device = NULL;
+       struct line_transceiver slave;
+       /* TCP Server */
+       int port = -1;
+       int server_socket = -1;
+       /* For select */
+       struct timeval next_periodic_round;
+       struct timeval period;
+       fd_set read_fds;
+       int max_fd = 0;
+
+       while(1) {
+               int option_index = 0;
+               int c = 0;
+
+               struct option long_options[] = {
+                       {"port", required_argument, 0, 'p'},
+                       {"device", required_argument, 0, 'd'},
+                       {"help", no_argument, 0, 'h'},
+                       {"version", no_argument, 0, 'v'},
+                       {0, 0, 0, 0}
+               };
+
+               c = getopt_long(argc, argv, "p:d:hv", long_options, &option_index);
+
+               /* no more options to parse */
+               if (c == -1) break;
+               switch (c) {
+                       /* a, board address */
+                       case 'p':
+                               port = strtoul(optarg, NULL, 0);
+                               break;
+
+                       /* c, command */
+                       case 'd':
+                               device = optarg;
+                               break;
+
+                       /* v, version */
+                       case 'v':
+                               printf("%s Version %s\n", PROG_NAME, VERSION);
+                               return 0;
+                               break;
+
+                       /* h, help */
+                       case 'h':
+                       default:
+                               help(argv[0]);
+                               return 0;
+               }
+       }
+
+
+       /* Need Serial port and destination file as parameter */
+       if ((port == -1) || (device == NULL)) {
+               printf("Error, need both serial (tty) device and IP port number\n");
+               help(argv[0]);
+               return -1;
+       }
+
+       /* Open tty */
+       memset(&slave, 0, sizeof(struct line_transceiver));
+       slave.fd = serial_setup(device);
+       if (slave.fd < 0) {
+               printf("Unable to open specified serial port %s\n", device);
+               return -2;
+       }
+
+       /* Create UDP server socket */
+       server_socket = create_bound_udp_socket(port, NULL);
+       if (server_socket <= 0) {
+               printf("Unable to open the server UDP socket on port %d\n", port);
+               return -3;
+       }
+
+       /* ************************************************* */
+       /* Initial FD set setup */
+       FD_ZERO(&read_fds);
+       FD_SET(STDIN_FILENO, &read_fds);   /* Add stdin */
+       FD_SET(slave.fd, &read_fds);  /* Serial link */
+       FD_SET(server_socket, &read_fds);  /* New connexions */
+       max_fd = server_socket + 1;  /* No close, this one is the last open, so it's the higest */
+
+       /* Periodic actions setup */
+       gettimeofday(&next_periodic_round, NULL);
+       period.tv_sec = 1; /* "Timer" granularitu is 1 second */
+       period.tv_usec = 0;
+       timeradd(&next_periodic_round, &period, &next_periodic_round);
+
+
+       /* ************************************************* */
+       /* And never stop handling data ! */
+       while (1) {
+               int nb = 0, len = 0, ret = 0;
+               struct timeval timeout;
+               struct timeval now;
+               fd_set tmp_read_fds = read_fds;
+               char buf[BUF_SIZE];
+
+               /* Send periodic requests for temperature */
+               gettimeofday(&now, NULL);
+               
+               if (timercmp(&now, &next_periodic_round, >=)) {
+                       timeout.tv_sec = 0;
+                       timeout.tv_usec = 0;
+               } else {
+                       timersub(&next_periodic_round, &now, &timeout);
+               }
+
+               /* select() call .... be kind to other processes */
+               nb = select(max_fd, &tmp_read_fds, NULL, NULL, &timeout);
+               /* Errors here are bad ones .. exit ?? */
+               if (nb < 0) {
+                       perror ("select failed");
+                       printf("Error: select failed, this is critical.\n");
+                       return -10;
+               }
+               /* In case of timeout ... perform periodic actions if a period has been defined */
+               if (nb == 0) {
+                       int misses = 0;
+                       /* Setup next periodic request date */
+                       timeradd(&next_periodic_round, &period, &next_periodic_round);
+                       gettimeofday(&now, NULL);
+                       /* Did we miss some rounds ? */
+                       while (timercmp(&now, &next_periodic_round, >=)) {
+                               /* Count misses (and catch up) */
+                               timeradd(&next_periodic_round, &period, &next_periodic_round);
+                               misses++;
+                       }
+                       /* FIXME : parse the list of periodic actions for new packets */
+                       continue;
+               }
+
+               /* Data from Ethernet side */
+               if (FD_ISSET(server_socket, &tmp_read_fds)) {
+                       struct sockaddr_in addr;
+                       socklen_t addr_len = sizeof(struct sockaddr_in);
+
+                       /* Receive the new data */
+                       memset(buf, 0, BUF_SIZE);
+                       len = recvfrom(server_socket, buf, BUF_SIZE, 0, (struct sockaddr *)&addr, &addr_len);
+                       if (len > 0) {
+                               handle_udp_request(buf, len, (struct sockaddr *)&addr, addr_len, server_socket, &slave);
+                       } else {
+                               /* Wait .. we received something but nothing came in ? */
+                               perror("UDP receive error");
+                               printf("\nError on UDP packet reception (ret: %d)\n", len);
+                       }
+               }
+
+               /* Read user input if any */
+        if (FD_ISSET(STDIN_FILENO, &tmp_read_fds)) {
+            memset(buf, 0, BUF_SIZE);
+            len = read(STDIN_FILENO, buf, BUF_SIZE);
+                       /* Do not know how to handle it yet, nothing defined. */
+               }
+
+               /* Handle module messages */
+               if (FD_ISSET(slave.fd, &tmp_read_fds)) {
+                       int idx = 0;
+                       memset(buf, 0, BUF_SIZE);
+                       /* Get serial data and try to build a packet */
+                       len = read(slave.fd, buf, BUF_SIZE);
+                       if (len < 0) {
+                               perror("serial read error");
+                               /* FIXME : handle errors */
+                       } else if (len == 0) {
+                               /* Wait .. we received something but nothing came in ? */
+                               printf("\nError, got activity on serial link, but no data ...\n");
+                       }
+                       while (idx < len) {
+                               ret = dtplug_protocol_decode(buf[idx], &slave);
+                               /* Check return code to know if we have a valid packet */
+                               if (ret == -1) {
+                                       /* Anything that's not part of a packet is printed as is (debug output) */
+                                       printf("%c", buf[idx]);
+                               } else if (ret < 0) {
+                                       printf("\nError in received packet. (ret: %d)\n", ret);
+                                       /* FIXME : dump packet for debugging */
+                               } else if (ret == 0) {
+                                       /* Packet is being built */
+                               } else {
+                                       /* Valid packet received */
+                                       handle_module_data(&slave);
+                               }
+                               idx++;
+                       }
+               }
+
+       } /* End of infinite loop */
+
+       close(slave.fd);
+       close(server_socket);
+       return 0;
+}
+
+
diff --git a/host/led_strip/questions.pl b/host/led_strip/questions.pl
new file mode 100755 (executable)
index 0000000..abbb320
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+# Author : Nathael Pajani
+# Copyright 2015 Nathael Pajani <nathael.pajani@techno-innov.fr>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+use IO::Socket::INET;
+use Scalar::Util qw(looks_like_number);
+
+
+#######################################
+# Base package parts
+my $server = 'localhost';
+
+
+# UDP Helper
+sub send_to {
+       my ($port, $request, $type) = @_;
+       my $socket = new IO::Socket::INET(Proto => 'udp');
+       my $servaddr = sockaddr_in($port, inet_aton($server));
+       $socket->send($request, 0, $servaddr);
+       unless ($request =~ /G/) {
+               print "Request sent.\n";
+               return;
+       }
+       my $data;
+       $socket->recv($data, 1024, 0);
+       print "Reply: $data\n";
+       $socket->close();
+}
+
+
+#######################################
+my ($port, $req, $type, @args) = @ARGV;
+
+unless (defined($port) && looks_like_number($port) && defined($req) && defined($type)) {
+       print "Usage: $0 port request type [red green blue] ...\n";
+       exit 1;
+}
+
+my $full = "$req$type ";
+my $sep = ' ';
+foreach (@args) {
+       $full .= "$sep";
+       $full .= "$_";
+       #$sep = ', ';
+}
+print "Req to $port : $full\n";
+
+send_to($port, $full, $type);
+
diff --git a/host/led_strip/serial_utils.c b/host/led_strip/serial_utils.c
new file mode 100644 (file)
index 0000000..5e17e42
--- /dev/null
@@ -0,0 +1,59 @@
+/*********************************************************************
+ *
+ *   Serial utility functions
+ *
+ *
+ * Copyright 2012-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *********************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+
+#define SERIAL_BAUD  B115200
+
+
+int serial_setup(char* name)
+{
+       struct termios tio;
+       int fd = -1;
+
+       /* Open serial port */
+       fd = open(name, O_RDWR);
+       if (fd < 0) {
+               perror("Unable to open communication with companion chip");
+               return -1;
+       }
+       /* Setup serial port */
+       memset(&tio, 0, sizeof(tio));
+       tio.c_cflag = CS8 | CREAD | CLOCAL;     /* 8n1, see termios.h for more information */
+       tio.c_cc[VMIN] = 1;
+       tio.c_cc[VTIME] = 5;
+       cfsetospeed(&tio, SERIAL_BAUD);
+       cfsetispeed(&tio, SERIAL_BAUD);
+       tcsetattr(fd, TCSANOW, &tio);
+
+       return fd;
+}
+
diff --git a/host/led_strip/serial_utils.h b/host/led_strip/serial_utils.h
new file mode 100644 (file)
index 0000000..7c17bcf
--- /dev/null
@@ -0,0 +1,32 @@
+/*********************************************************************
+ *
+ *   Serial utility functions
+ *
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *********************************************************************/
+#ifndef SERIAL_UTILS_H
+#define SERIAL_UTILS_H
+
+/* Setup serial comunication, using name if given or saved name if name is NULL
+ *  SERIAL_BAUD  B38400
+ *  c_cflag  (CS7 | PARENB | CREAD | CLOCAL) (7e1)
+ */
+int serial_setup(char* name);
+
+#endif /* SERIAL_UTILS_H */
+
diff --git a/host/led_strip/sock_utils.c b/host/led_strip/sock_utils.c
new file mode 100644 (file)
index 0000000..aa24cfa
--- /dev/null
@@ -0,0 +1,200 @@
+/*****************************************************************************
+ *
+ * socket utils
+ *
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *****************************************************************************/
+
+#include <stdio.h>  /* perror */
+#include <string.h> /* memset */
+#include <unistd.h> /* close, fcntl */
+#include <fcntl.h>  /* F_SETFL and O_NONBLOCK for fcntl */
+
+/* For socket stuff */
+#include <sys/types.h> /* For portability for socket stuff */
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h> /* For TCP_NODELAY to disable nagle algorithm */
+
+
+/* This is used to allow quicker sending of small packets on wires */
+static void sox_disable_nagle_algorithm(int socket)
+{
+       const int on = 1;
+       setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof( int ));
+}
+
+/* Creates a TCP socket on the specified "port", bind to port and setup to
+ * accept connections with listen, with up to "nb_pending" pending connections
+ * in the queue.
+ * Returns the socket, after disabling nagle algorithm.
+ * If "our" is not null, it will be used to store the listening socket information.
+ * If "port" is 0, then "our" must contain all requiered information for bind call.
+ */
+int socket_tcp_server(int port, int nb_pending, struct sockaddr_in* our)
+{
+       struct sockaddr_in local;
+       struct sockaddr_in* tmp;
+       int s;
+       int optval = 1;
+
+       if (our == NULL ) {
+               tmp = &local;
+               if (port == 0) {
+                       fprintf(stderr, "No port and no address information provided, won't be able to bind, aborting\n");
+                       return -1;
+               }
+       } else {
+               tmp = our;
+       }
+
+       if (port != 0) {
+               memset(tmp, 0, sizeof(struct sockaddr_in));
+               tmp->sin_family = AF_INET;
+               tmp->sin_addr.s_addr = htonl(INADDR_ANY);
+               tmp->sin_port = htons((short)port);
+       }
+
+       if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+               perror("Unable to create TCP socket");
+               return -1;
+       }
+
+       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
+               perror("Unable to set reuseaddress on socket");
+               goto err_close;
+       }
+       if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(int)) == -1) {
+               perror("Unable to set keepalive on socket");
+               goto err_close;
+       }
+
+       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
+               perror("Unable to bind TCP port");
+               goto err_close;
+       }
+
+       if (listen(s, nb_pending)) {
+               perror("Unable to listen to TCP port");
+               goto err_close;
+       }
+
+       sox_disable_nagle_algorithm(s);
+       return s;
+
+err_close:
+       close(s);
+       return -1;
+}
+
+
+/* Creates an UDP socket on the specified "port" and bind to port but no specific interface.
+ * Returns the socket.
+ * If "our" is not null, it will be used to store the listening socket information.
+ * "port" must not be 0..
+ */
+int create_bound_udp_socket(int port, struct sockaddr_in* our)
+{
+       struct sockaddr_in local;
+       struct sockaddr_in* tmp;
+       int s;
+       int optval = 1;
+
+       if (port == 0) {
+               return -1;
+       }
+
+       if (our == NULL ) {
+               tmp = &local;
+       } else {
+               tmp = our;
+       }
+
+       memset(tmp, 0, sizeof(struct sockaddr_in));
+       tmp->sin_family = AF_INET;
+       tmp->sin_addr.s_addr = htonl(INADDR_ANY);
+       tmp->sin_port = htons((short)port);
+
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("Unable to create UDP socket");
+               return -1;
+       }
+
+       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
+               perror("Unable to set reuseaddress on socket");
+               goto err_close;
+       }
+
+       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
+               perror("Unable to bind UDP port");
+               goto err_close;
+       }
+
+       return s;
+
+err_close:
+       close(s);
+       return -1;
+}
+
+
+
+/* Creates an UDP socket bound to no specific interface.
+ * The kernel choses the port to bind to.
+ * Returns the socket.
+ */
+int create_broadcast_udp_socket(void)
+{
+       struct sockaddr_in local;
+       struct sockaddr_in* tmp = &local;
+       int s;
+       int optval = 1;
+
+       memset(tmp, 0, sizeof(struct sockaddr_in));
+       tmp->sin_family = AF_INET;
+       tmp->sin_addr.s_addr = htonl(INADDR_ANY);
+       tmp->sin_port = 0;
+
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               perror("Unable to create UDP socket");
+               return -1;
+       }
+
+       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
+               perror("Unable to set reuseaddress on socket");
+               goto err_close;
+       }
+
+       if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *)&optval, sizeof(int)) == -1) {
+               perror("Unable to set broadcast on socket");
+               goto err_close;
+       }
+
+       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
+               perror("Unable to bind UDP port");
+               goto err_close;
+       }
+
+       return s;
+
+err_close:
+       close(s);
+       return -1;
+}
+
+
diff --git a/host/led_strip/sock_utils.h b/host/led_strip/sock_utils.h
new file mode 100644 (file)
index 0000000..576fb4d
--- /dev/null
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ *
+ * socket utils
+ *
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *****************************************************************************/
+
+#ifndef SOCK_UTILS_H
+#define SOCK_UTILS_H
+
+#include <netinet/in.h> /* struct sockaddr_in */
+
+/* Creates a socket on the specified "port", bind to port and setup to
+   accept connections with listen, with up to "nb_pending" pending connections
+   in the queue.
+   Returns the socket, after disabling nagle algorithm.
+   If "our" is not null, it will be used to store the listening socket information.
+ */
+int socket_tcp_server(int port, int nb_pending, struct sockaddr_in* our);
+
+
+/* Creates an UDP socket on the specified "port" and bind to port but no specific interface.
+ * Returns the socket.
+ * If "our" is not null, it will be used to store the listening socket information.
+ * "port" must not be 0..
+ */
+int create_bound_udp_socket(int port, struct sockaddr_in* our);
+
+
+/* Creates an UDP socket bound to no specific interface.
+ * The kernel choses the port to bind to.
+ * Returns the socket.
+ */
+int create_broadcast_udp_socket(void);
+
+#endif /* SOCK_UTILS_H */
+
diff --git a/host/lighthouse/.gitignore b/host/lighthouse/.gitignore
deleted file mode 100644 (file)
index 47548e5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-protocol_bridge
diff --git a/host/lighthouse/Basic_UDP_Protocol.txt b/host/lighthouse/Basic_UDP_Protocol.txt
deleted file mode 100644 (file)
index a713df3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# Basic control protocol for LightHouse over UDP.
-# Should be replaced by MQTT in the future
-
-# Set Led
-SL addr branche [ledx R G B] [ledy R G B] [....]
-# addr : 0 -> 16K (0 == broadcast)
-# branche : 0 - 64 (port * 32 + pin)
-# led : 0 -> 255
-# R, G et B : 0 -> 255
-
-# Get Leds info
-GI
-# Replies :
-GI addr branche nbleds
-
-# Get Leds Colors
-GLC addr branche
-# Reply :
-GLC addr branche [R G B] [R G B] ....
-
-
-
diff --git a/host/lighthouse/Makefile b/host/lighthouse/Makefile
deleted file mode 100644 (file)
index fdafb8f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#CROSS_COMPILE ?= arm-linux-gnueabihf-
-CC = $(CROSS_COMPILE)gcc
-
-CFLAGS = -Wall -O2 -Wextra -DHOST_HAS_STDINT
-
-EXEC = protocol_bridge
-
-all: $(EXEC)
-
-
-OBJDIR = objs
-SRC = $(shell find . -name \*.c)
-OBJS = ${SRC:%.c=${OBJDIR}/%.o}
-INCLUDES = includes/
-
-${OBJDIR}/%.o: %.c
-       @mkdir -p $(dir $@)
-       @echo "-- compiling" $<
-       @$(CC) -MMD -MP -MF ${OBJDIR}/$*.d $(CFLAGS) $< -c -o $@ -I$(INCLUDES)
-
-$(EXEC): $(OBJS)
-       @echo "Linking $@ ..."
-       @$(CC) $(LDFLAGS) -o $@ $(OBJS)
-       @echo Done.
-
-
-clean:
-       find ${OBJDIR} -name "*.o" -exec rm {} \;
-       find ${OBJDIR} -name "*.d" -exec rm {} \;
-
-mrproper: clean
-       rm -f $(EXEC)
diff --git a/host/lighthouse/dtplug_protocol_defs.h b/host/lighthouse/dtplug_protocol_defs.h
deleted file mode 120000 (symlink)
index 62c8622..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../include/lib/protocols/dtplug/defs.h
\ No newline at end of file
diff --git a/host/lighthouse/dtplug_protocol_host.c b/host/lighthouse/dtplug_protocol_host.c
deleted file mode 100644 (file)
index 1505d31..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/****************************************************************************
- *   dtplug_protocol_host.c
- *
- *
- * Copyright 2013-2015 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ****************************************************************************/
-
-
-/* Host side implementation of the DTPlug communication protocol */
-
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#include "dtplug_protocol_host.h"
-
-
-/******************************************************************************/
-/* Handle packet reception, including checksums */
-/* 'sum' is used to sum all the received characters, and if the last byte of sum is 0 for each
- *   part (header and data) then the packet is valid.
- * 'full_size' is the size of the whole packet, including header, updated as soon as the header
- *   is checked and valid
- *
- * This function must be called for every received character.
- * If the character is part of a packet but the packet is being built, then the function returns 0.
- * When the character is the last one of a valid packet, then the function returns the packet size
- *   and the packet in rx_data->rx_packet is valid.
- * If the character is the last one of a packet which has an invalid data checksum, this function
- *   returns -2 and the data is lost.
- * If the character is not part of a packet it returns -1. The character may then be part of
- *   a debug message (and displayed by the host), or any other kind of communication.
- * When a set of consecutive characters have been used to build a packet but the packet is
- *   not valid due to header error, then the function returns -3 (checksum error) or -4 (data size
- *   error). The data in rx_data->rx_packet is the received data but is not valid.
- *   The corresponding data size is always sizeof(struct header).
- */
-int dtplug_protocol_decode(uint8_t c, struct line_transceiver* rx_data)
-{
-       struct header* info = (struct header*)(&(rx_data->rx_packet));
-       int ret = 0;
-
-       /* Do not start reception before receiving the packet start character */
-       if ((rx_data->rx_ptr == 0) && (c != FIRST_PACKET_CHAR)) {
-               return -1;
-       }
-
-       /* Store the new byte in the packet */
-       ((uint8_t*)(&(rx_data->rx_packet)))[rx_data->rx_ptr++] = c;
-       rx_data->sum += c;
-
-       /* Is this packet valid ? (at end of header reception) */
-       if (rx_data->rx_ptr == sizeof(struct header)) {
-               /* Checksum OK ? */
-               if (rx_data->sum != 0) {
-                       rx_data->errors_count++;
-                       ret = -3;
-                       goto next_packet;
-               }
-               /* Start the new checksum for data (if any) */
-               rx_data->sum = 0;
-
-               rx_data->full_size = sizeof(struct header);
-               /* If the packet is not a quick data or error packet it has a data part. Get it's size */
-               if (!(info->seq_num & QUICK_DATA_PACKET) && !(info->seq_num & PACKET_IS_ERROR)) {
-                       rx_data->full_size += (info->data.size & PKT_SIZE_MASK); /* Don't care about big packets here */
-                       /* Make sure the packet will fit in the buffer */
-                       if (rx_data->full_size > sizeof(struct packet)) {
-                               rx_data->errors_count++;
-                               ret = -4;
-                               goto next_packet;
-                       }
-               }
-       }
-
-       /* Did we receive the whole packet ? */
-       if (rx_data->rx_ptr == rx_data->full_size) {
-               /* From here on, the packet is valid, we can provide some feedback */
-               /* Check data checksum if we have a normal data packet */
-               if (!(info->seq_num & QUICK_DATA_PACKET) && !(info->seq_num & PACKET_IS_ERROR)) {
-                       if (rx_data->sum != info->data.checksum) {
-                               rx_data->errors_count++;
-                               ret = -2;
-                               goto next_packet;
-                       }
-               }
-               /* Count received packets */
-               rx_data->packet_rx_count++;
-               ret = rx_data->full_size;
-               /* And get ready to receive the next packet */
-               goto next_packet;
-       }
-
-       return 0;
-
-next_packet:
-#ifdef DEBUG
-       printf("Current rx pointer: %d, packet full size: %d\n", rx_data->rx_ptr, rx_data->full_size);
-       printf("Packets received count: %d, packets errors: %d\n",
-                               rx_data->packet_rx_count, rx_data->errors_count);
-       if (rx_data->rx_ptr >= sizeof(struct header)) {
-               struct header* h = info;
-               printf("Pkt: type: %d, seq: %d, err: %d, quick: %d\n", h->type, (h->seq_num & 0x1F),
-                                               (h->seq_num & PACKET_IS_ERROR), (h->seq_num & QUICK_DATA_PACKET));
-               if (!(h->seq_num & QUICK_DATA_PACKET) && !(h->seq_num & PACKET_IS_ERROR)) {
-                       printf("Pkt: data_size: %d, data_cksum: 0x%02x\n", h->data.size, h->data.checksum);
-                       printf("rx_data_cksum: 0x%02x\n", rx_data->sum);
-               }
-       }
-#endif
-       /* Wether the packet was OK or not doesn't matter, go on for a new one :) */
-       rx_data->full_size = 0;
-       rx_data->rx_ptr = 0;
-       rx_data->sum = 0;
-       return ret;
-}
-
-
-/******************************************************************************/
-/* This function handles sending packets to slave
- * It returns the number of bytes of data sent.
- */
-int host_send_packet(struct line_transceiver* slave, uint8_t type, uint32_t size, uint8_t* data, int need_reply)
-{
-       struct packet cmd;
-       struct header* cmd_info = &(cmd.info);
-       unsigned int i = 0, sent = 0, len = sizeof(struct header);
-       uint8_t sum = 0;
-       unsigned int data_send_size = size, data_sent = 0;
-
-       /* Loop to send all data, possibly split in several packets */
-       do {
-               memset(&cmd, 0, sizeof(struct packet));
-               if (data_send_size > PACKET_DATA_SIZE) {
-                       data_send_size = PACKET_DATA_SIZE;
-               }
-               /* Set packet header */
-               cmd_info->start = FIRST_PACKET_CHAR;
-               cmd_info->type = type;
-               cmd_info->seq_num = (slave->sequence_number++ & SEQUENCE_MASK);
-               /* Set the need reply bit only on the last packet */
-               if ((need_reply != 0) && ((data_sent + data_send_size) == size)) {
-                       cmd_info->seq_num |= PACKET_NEEDS_REPLY;
-               }
-               /* Setup data */
-               if (data != NULL) {
-                       /* Only use quick data packet for short packet, not continued data */
-                       if (size && (size <= 2)) {
-                               cmd_info->seq_num |= QUICK_DATA_PACKET;
-                               cmd_info->quick_data[0] = data[0];
-                               if (size == 2) {
-                                       cmd_info->seq_num |= QUICK_DATA_PACKET_TWO_BYTES;
-                                       cmd_info->quick_data[1] = data[1];
-                               }
-                       } else {
-                               /* Copy data, compute checksum (also OK for a data_send_size of 0) */
-                               for (i = 0; i < data_send_size; i++) {
-                                       cmd.data[i] = data[i];
-                                       sum += data[i]; /* Build checksum */
-                               }
-                               /* And update header information */
-                               cmd_info->data.size = data_send_size;
-                               /* Will this packet be continued in the following one ? */
-                               if (data_send_size < (size - data_sent)) {
-                                       cmd_info->data.size |= BIG_DATA_PKT;
-                               }
-                               cmd_info->data.checksum = sum;
-                               /* Update length of data to send on serial link */
-                               len += data_send_size;
-                       }
-               }
-
-               /* Compute header checksum */
-               sum = 0;
-               cmd_info->checksum = 0;
-               for (i = 0; i < sizeof(struct header); i++) {
-                       sum += ((uint8_t*)cmd_info)[i];
-               }
-               cmd_info->checksum = ((uint8_t)(256 - sum));
-
-               /* And send the packet on the serial link */
-               while (sent < len) {
-                       int ret = write(slave->fd, (((char*)(&cmd)) + sent), (len - sent));
-                       if (ret >= 0) {
-                               sent += ret;
-                       } else {
-                               /* Sending error ... */
-                               /* FIXME : handle / report errors */
-                               return data_sent;
-                       }
-               }
-               data_sent += data_send_size;
-
-               /* Need to send more ? */
-               if (data && (data_sent <= size)) {
-                       /* Move data pointer */
-                       data += data_send_size;
-                       /* Update size to send. check against PACKET_DATA_SIZE is done at beginning of loop */
-                       data_send_size = (size - data_sent);
-                       /* Set packet type to continued data packet for following packets */
-                       type = PKT_TYPE_CONTINUED_DATA;
-                       /* And prepare sending of the next packet (reset internal loop counters) */
-                       sum = 0;
-                       len = sizeof(struct header);
-                       sent = 0;
-               } else {
-                       /* No data, everything got sent */
-                       data_send_size = 0;
-               }
-       } while (data_send_size != 0);
-
-       return data_sent;
-}
-
-
diff --git a/host/lighthouse/dtplug_protocol_host.h b/host/lighthouse/dtplug_protocol_host.h
deleted file mode 100644 (file)
index 23cd3f4..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
- *   dtplug_protocol_host.h
- *
- *
- * Copyright 2013-2015 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ****************************************************************************/
-
-
-/* Host side implementation of the DTPlug communication protocol */
-
-#ifndef DTPLUG_PROTOCOL_HOST_H
-#define DTPLUG_PROTOCOL_HOST_H
-
-
-#include <stdint.h>
-#include "dtplug_protocol_defs.h"
-
-
-/******************************************************************************/
-/* Handle packet reception, including checksums */
-/* 'sum' is used to sum all the received characters, and if the last byte of sum is 0 for each
- *   part (header and data) then the packet is valid.
- * 'full_size' is the size of the whole packet, including header, updated as soon as the header
- *   is checked and valid
- */
-struct line_transceiver {
-       int fd;
-       /* The packet being built */
-       struct packet rx_packet;
-       /* Sequence number for this line */
-       uint8_t sequence_number;
-       /* Packet building data */
-       uint8_t rx_ptr;
-       uint8_t sum;
-       uint8_t full_size;
-       /* packet counts */
-       uint32_t packet_rx_count;
-       uint32_t packet_tx_count;
-       uint32_t errors_count;
-};
-
-/* This function must be called for every received character.
- * If the character is part of a packet but the packet is being built, then the function returns 0.
- * When the character is the last one of a valid packet, then the function returns the packet size
- *   and the packet in rx_data->rx_packet is valid.
- * If the character is the last one of a packet which has an invalid data checksum, this function
- *   returns -2 and the data is lost.
- * If the character is not part of a packet it returns -1. The character may then be part of
- *   a debug message (and displayed by the host), or any other kind of communication.
- * When a set of consecutive characters have been used to build a packet but the packet is
- *   not valid due to header error, then the function returns -3 (checksum error) or -4 (data size
- *   error). The data in rx_data->rx_packet is the received data but is not valid.
- *   The corresponding data size is always sizeof(struct header).
- */
-int dtplug_protocol_decode(uint8_t c, struct line_transceiver* rx_data);
-
-/* This function handles sending packets to slave
- * It returns the number of bytes of data sent.
- */
-int host_send_packet(struct line_transceiver* slave, uint8_t type, uint32_t size,  uint8_t* data, int need_reply);
-
-
-#endif /* DTPLUG_PROTOCOL_HOST_H */
-
diff --git a/host/lighthouse/handlers.c b/host/lighthouse/handlers.c
deleted file mode 100644 (file)
index c9dc1f9..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
- *  LightHouse UDP to RF Sub1GHz module bridge.
- *
- *   handlers.c
- *
- *
- * Copyright 2016 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ****************************************************************************/
-
-
-/* This protocol handler is designed to run on a host. */
-
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include "list.h"
-#include "dtplug_protocol_host.h"
-
-
-#define BUFF_LEN 60
-
-struct info_data {
-       struct list_head head;
-       int type;  /* Information type */
-       int addr;  /* Source address */
-       int function;  /* Information function */
-       int number;    /* Information number */
-       int value; /* Information */
-       struct timeval last_update;   /* Information timestamp */
-};
-
-
-struct list_head* all_info = NULL;
-int nb_info = 0;
-
-int create_info(int type, int addr, int func, int num)
-{
-       struct info_data* addinfo = malloc(sizeof(struct info_data));
-
-       if (addinfo == NULL) {
-               return -1;
-       }
-
-       if (all_info == NULL) {
-               all_info = &(addinfo->head);
-               INIT_LIST_HEAD(&(addinfo->head));
-       } else {
-               list_add_tail(&addinfo->head, all_info);
-       }
-       addinfo->type = type;
-       addinfo->addr = addr;
-       addinfo->function = func;
-       addinfo->number = num;
-       nb_info++;
-
-       return 0;
-}
-
-void delete_info(struct info_data* oldinfo)
-{
-       if (oldinfo == NULL) {
-               return;
-       }
-       list_del(&(oldinfo->head));
-       if (list_empty(all_info)) {
-               all_info = NULL;
-       }
-       free(oldinfo);
-       nb_info--;
-}
-
-/* Find exactly matching information */
-struct info_data* find_info(int type, int addr, int func, int num)
-{
-       struct info_data* info = NULL;
-       if (all_info == NULL) {
-               return NULL;
-       }
-       list_for_each_entry(info, all_info, head) {
-               if ((info->type == type) && (info->addr == addr) && (info->function == func) && (info->number == num)) {
-                       return info;
-               }
-       }
-       return info;
-}
-/* TOTO : find all info_data matching given criteria */
-
-
-
-int handle_module_data(struct line_transceiver* slave)
-{
-       struct header* head = &(slave->rx_packet.info);
-       /* If this packet holds no valid data, it indicates that there are errors */
-       if (head->seq_num & PACKET_IS_ERROR) {
-               printf("Received a packet indicating errors (%d - %d)\n",
-                                        head->err.error_code, head->err.info);
-               /* Request the list of errors */
-               host_send_packet(slave, PKT_TYPE_GET_ERRORS, 0, NULL, 1);
-               return 0;
-       }
-       /* Move data from "QUICK_DATA_PACKET" packets to the data part of the packet for easy handling */
-       if (head->seq_num & QUICK_DATA_PACKET) {
-               slave->rx_packet.data[0] = head->quick_data[0];
-               slave->rx_packet.data[1] = head->quick_data[1];
-               if (head->seq_num & QUICK_DATA_PACKET_ONE_BYTE) {
-                       head->data.size = 1;
-               } else {
-                       head->data.size = 2;
-               }
-       }
-
-       switch (head->type) {
-               case PKT_TYPE_PING:
-                       break;
-
-               case PKT_TYPE_GET_BOARD_INFO:
-                       break;
-
-               case PKT_TYPE_GET_NUM_PACKETS:
-                       break;
-
-               case PKT_TYPE_GET_ERRORS:
-                       /* FIXME */
-                       printf("Received error list: ... implement error decoding.\n");
-                       break;
-
-               case PKT_TYPE_GET_NUM_ERRORS:
-                       /* FIXME */
-                       printf("Received number of errors: %d.\n", 0);
-                       break;
-       
-               case PKT_TYPE_CONTINUED_DATA:
-                       break;
-       
-               case PKT_TYPE_GET_TEMPERATURE:
-                       {
-                               struct info_data* info = find_info('T', 0, 0, 0); /* FIXME */
-                               uint16_t* tmp = (uint16_t*)(&(slave->rx_packet.data[0]));
-                               gettimeofday(&(info->last_update), NULL);
-                               info->value = (int16_t)ntohs(tmp[0]);
-                       }
-                       break;
-       
-               case PKT_TYPE_GET_ADC_VALUE:
-                       break;
-
-               default:
-                       printf("Received packet type %d. Not handled.\n", head->type);
-                       break;
-       }
-       return 0;
-}
-
-#define REP_SIZE_MAX  1024
-
-int handle_udp_request(char* buf, int len, struct sockaddr* addr, socklen_t addr_len,
-                                                int sock, struct line_transceiver* slave)
-{
-       struct info_data* info = NULL;
-       if ((len == 0) || (buf == NULL)) {
-               return -1;
-       }
-       if (buf[0] == 'G') {
-               char obuf[REP_SIZE_MAX];
-               int len = 0;
-               /* GET command : Return the last updated value with the update timestamp */
-               switch (buf[1]) {
-                       case 'L':
-                               info = find_info('L', 0, 0, 0); /* FIXME */
-                               if (info != NULL) {
-                                       len = snprintf(obuf, REP_SIZE_MAX, "GL %d %d %d : %d at %ld.%03ld",
-                                                       info->addr, info->function, info->number, info->value,
-                                                       info->last_update.tv_sec, (info->last_update.tv_usec / 1000));
-                               }
-                               break;
-                       case 'I':
-                               list_for_each_entry(info, all_info, head) {
-                                       if (info->type == 'I') {
-                                               len = snprintf(obuf, REP_SIZE_MAX, "GI: %d %d %d\n",
-                                                       info->addr, info->function, info->value);
-                                               sendto(sock, obuf, len, 0, addr, addr_len);
-                                       }
-                               }
-                               break;
-               }
-               sendto(sock, obuf, len, 0, addr, addr_len);
-               printf("Handled GET request type: %c\n", buf[1]);
-       } else if (buf[0] == 'U') {
-               uint8_t num = 0;
-               /* Request a value update */
-               switch (buf[1]) {
-                       case 'T':
-                               host_send_packet(slave, PKT_TYPE_START_TEMP_CONVERSION, 0, NULL, 0);
-                               usleep(200 * 1000); /* Temp conversion at 11 bits resolution is about 160ms */
-                               host_send_packet(slave, PKT_TYPE_GET_TEMPERATURE, 0, NULL, 1);
-                               break;
-                       case 'A':
-                               num = (uint8_t)(strtoul(&buf[2], NULL, 10) & 0xFF);
-                               host_send_packet(slave, PKT_TYPE_GET_ADC_VALUE, 1, &num, 1);
-                               break;
-               }
-               printf("Handled UPDATE request type: %c\n", buf[1]);
-       } else if (buf[0] == 'S') {
-               /* Send new values to the micro-controller */
-               uint8_t obuf[BUFF_LEN];
-               char* tmp = NULL;
-               int i = 0;
-
-               switch (buf[1]) {
-                       case 'L': /* FIXME */
-                               obuf[0] = (strtoul(&buf[2], &tmp, 10) & 0xFF); /* Address */
-                               obuf[1] = (strtoul(tmp, &tmp, 10) & 0x3F); /* Function */
-                               for (i = 2; ((i < (BUFF_LEN - 4)) && (tmp < buf + len)); i += 4) {
-                                       obuf[i] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Number */
-                                       obuf[i + 1] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Red Value */
-                                       obuf[i + 2] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Green Value */
-                                       obuf[i + 3] = (strtoul(tmp, &tmp, 10) & 0xFF); /* Blue Value */
-                               }
-                               host_send_packet(slave, PKT_TYPE_SET_RGB_LED, i, obuf, 0);
-                               break;
-               }
-               printf("Handled SET request type: %c\n", buf[1]);
-       } else {
-               printf("Unhandled request type: '0x%02x'\n", buf[0]);
-               return -2;
-       }
-
-       return 0;
-}
-
-
-
diff --git a/host/lighthouse/handlers.h b/host/lighthouse/handlers.h
deleted file mode 100644 (file)
index 0956385..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/****************************************************************************
- *  LightHouse UDP to RF Sub1GHz module bridge.
- *
- *   handlers.h
- *
- *
- * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ****************************************************************************/
-
-
-/* This protocol handler is designed to run on a host replacing the DTPlug,
- * but should be easy to use as a source for the protocol handling code for
- * the DTPlug itself.
- */
-
-#ifndef HANDLERS_H
-#define HANDLERS_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include "dtplug_protocol_host.h"
-
-
-
-int handle_module_data(struct line_transceiver* slave);
-
-
-int handle_udp_request(char* buf, int len, struct sockaddr* addr, socklen_t addr_len,
-                                               int sock, struct line_transceiver* slave);
-
-
-#endif /* HANDLERS_H */
diff --git a/host/lighthouse/list.h b/host/lighthouse/list.h
deleted file mode 100644 (file)
index 1be8f9a..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * list.h
- *
- * This code is from the linux kernel. It is a very simple and powerfull doubly
- *   linked list implementation.
- * Not everything has been taken from the original file.
- */
-
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-
-/* linux/kernel.h */
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- * @ptr:    the pointer to the member.
- * @type:   the type of the container struct this is embedded in.
- * @member: the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({          \
-    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-    (type *)( (char *)__mptr - offsetof(type,member) );})
-
-
-
-/* linux/stddef.h */
-
-#ifdef __compiler_offsetof
-#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-
-
-/* linux/list.h */
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
-       struct list_head *next, *prev;
-};
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized list entries.
- */
-#define LIST_POISON1  ((void *) 0x00100100)
-#define LIST_POISON2  ((void *) 0x00200200)
-
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-       struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
-{
-       list->next = list;
-       list->prev = list;
-}
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
-                             struct list_head *prev,
-                             struct list_head *next)
-{
-       next->prev = new;
-       new->next = next;
-       new->prev = prev;
-       prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
-       __list_add(new, head, head->next);
-}
-
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
-       __list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
-       next->prev = prev;
-       prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty() on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void __list_del_entry(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-}
-
-static inline void list_del(struct list_head *entry)
-{
-       __list_del(entry->prev, entry->next);
-       entry->next = LIST_POISON1;
-       entry->prev = LIST_POISON2;
-}
-
-/**
- * list_is_last - tests whether @list is the last entry in list @head
- * @list: the entry to test
- * @head: the head of the list
- */
-static inline int list_is_last(const struct list_head *list,
-                               const struct list_head *head)
-{
-       return list->next == head;
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
-       return head->next == head;
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr:       the &struct list_head pointer.
- * @type:      the type of the struct this is embedded in.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
-       container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr:       the list head to take the element from.
- * @type:      the type of the struct this is embedded in.
- * @member:    the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
-       list_entry((ptr)->next, type, member)
-
-/**
- * list_last_entry - get the last element from a list
- * @ptr:       the list head to take the element from.
- * @type:      the type of the struct this is embedded in.
- * @member:    the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_last_entry(ptr, type, member) \
-       list_entry((ptr)->prev, type, member)
-
-/**
- * list_next_entry - get the next element in list
- * @pos:       the type * to cursor
- * @member:    the name of the list_struct within the struct.
- */
-#define list_next_entry(pos, member) \
-       list_entry((pos)->member.next, typeof(*(pos)), member)
-
-/**
- * list_for_each_entry -       iterate over list of given type
- * @pos:       the type * to use as a loop cursor.
- * @head:      the head for your list.
- * @member:    the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member)                         \
-       for (pos = list_first_entry(head, typeof(*pos), member);        \
-            &pos->member != (head);                                    \
-            pos = list_next_entry(pos, member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos:    the type * to use as a loop cursor.
- * @n:      another type * to use as temporary storage
- * @head:   the head for your list.
- * @member: the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)          \
-       for (pos = list_first_entry(head, typeof(*pos), member),    \
-               n = list_next_entry(pos, member);           \
-                &pos->member != (head);                    \
-                pos = n, n = list_next_entry(n, member))
-
-#endif  /* _LINUX_LIST_H */
diff --git a/host/lighthouse/main.c b/host/lighthouse/main.c
deleted file mode 100644 (file)
index 11bd805..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/****************************************************************************
- *  LightHouse UDP to RF Sub1GHz module bridge.
- *
- *   main.c
- *
- *
- * Copyright 2013-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ****************************************************************************/
-
-
-/* this protocol handler is designed to run on a host replacing the DTPlug,
- * but should be easy to use as a source for the protocol handling code for
- * the DTPlug itself.
- */
-
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <string.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include "dtplug_protocol_host.h"
-#include "serial_utils.h"
-#include "sock_utils.h"
-#include "handlers.h"
-
-
-#define BUF_SIZE  1024
-
-#define PROG_NAME  "DTPlug protocol test bridge"
-#define VERSION  "0.1"
-
-
-void help(char *prog_name)
-{
-       fprintf(stderr, "---------------- "PROG_NAME" --------------------------------\n");
-       fprintf(stderr, "Usage: %s [options]\n" \
-               "  Available options:\n" \
-               "  \t -p | --port : Start listening for messages on this port\n" \
-               "  \t -d | --device : Serial device to use for serial communication with the module\n" \
-               "  \t -h | --help : Print this help\n" \
-               "  \t -v | --version : Print programm version\n" \
-               "  All other arguments are data for the command, handled depending on the command.\n", prog_name);
-       fprintf(stderr, "-----------------------------------------------------------------------\n");
-}
-
-
-int main(int argc, char* argv[])
-{
-       /* Serial */
-       char* device = NULL;
-       struct line_transceiver slave;
-       /* TCP Server */
-       int port = -1;
-       int server_socket = -1;
-       /* For select */
-       struct timeval next_periodic_round;
-       struct timeval period;
-       fd_set read_fds;
-       int max_fd = 0;
-
-       while(1) {
-               int option_index = 0;
-               int c = 0;
-
-               struct option long_options[] = {
-                       {"port", required_argument, 0, 'p'},
-                       {"device", required_argument, 0, 'd'},
-                       {"help", no_argument, 0, 'h'},
-                       {"version", no_argument, 0, 'v'},
-                       {0, 0, 0, 0}
-               };
-
-               c = getopt_long(argc, argv, "p:d:hv", long_options, &option_index);
-
-               /* no more options to parse */
-               if (c == -1) break;
-               switch (c) {
-                       /* a, board address */
-                       case 'p':
-                               port = strtoul(optarg, NULL, 0);
-                               break;
-
-                       /* c, command */
-                       case 'd':
-                               device = optarg;
-                               break;
-
-                       /* v, version */
-                       case 'v':
-                               printf("%s Version %s\n", PROG_NAME, VERSION);
-                               return 0;
-                               break;
-
-                       /* h, help */
-                       case 'h':
-                       default:
-                               help(argv[0]);
-                               return 0;
-               }
-       }
-
-
-       /* Need Serial port and destination file as parameter */
-       if ((port == -1) || (device == NULL)) {
-               printf("Error, need both serial (tty) device and IP port number\n");
-               help(argv[0]);
-               return -1;
-       }
-
-       /* Open tty */
-       memset(&slave, 0, sizeof(struct line_transceiver));
-       slave.fd = serial_setup(device);
-       if (slave.fd < 0) {
-               printf("Unable to open specified serial port %s\n", device);
-               return -2;
-       }
-
-       /* Create UDP server socket */
-       server_socket = create_bound_udp_socket(port, NULL);
-       if (server_socket <= 0) {
-               printf("Unable to open the server UDP socket on port %d\n", port);
-               return -3;
-       }
-
-       /* ************************************************* */
-       /* Initial FD set setup */
-       FD_ZERO(&read_fds);
-       FD_SET(STDIN_FILENO, &read_fds);   /* Add stdin */
-       FD_SET(slave.fd, &read_fds);  /* Serial link */
-       FD_SET(server_socket, &read_fds);  /* New connexions */
-       max_fd = server_socket + 1;  /* No close, this one is the last open, so it's the higest */
-
-       /* Periodic actions setup */
-       gettimeofday(&next_periodic_round, NULL);
-       period.tv_sec = 1; /* "Timer" granularitu is 1 second */
-       period.tv_usec = 0;
-       timeradd(&next_periodic_round, &period, &next_periodic_round);
-
-
-       /* ************************************************* */
-       /* And never stop handling data ! */
-       while (1) {
-               int nb = 0, len = 0, ret = 0;
-               struct timeval timeout;
-               struct timeval now;
-               fd_set tmp_read_fds = read_fds;
-               char buf[BUF_SIZE];
-
-               /* Send periodic requests for temperature */
-               gettimeofday(&now, NULL);
-               
-               if (timercmp(&now, &next_periodic_round, >=)) {
-                       timeout.tv_sec = 0;
-                       timeout.tv_usec = 0;
-               } else {
-                       timersub(&next_periodic_round, &now, &timeout);
-               }
-
-               /* select() call .... be kind to other processes */
-               nb = select(max_fd, &tmp_read_fds, NULL, NULL, &timeout);
-               /* Errors here are bad ones .. exit ?? */
-               if (nb < 0) {
-                       perror ("select failed");
-                       printf("Error: select failed, this is critical.\n");
-                       return -10;
-               }
-               /* In case of timeout ... perform periodic actions if a period has been defined */
-               if (nb == 0) {
-                       int misses = 0;
-                       /* Setup next periodic request date */
-                       timeradd(&next_periodic_round, &period, &next_periodic_round);
-                       gettimeofday(&now, NULL);
-                       /* Did we miss some rounds ? */
-                       while (timercmp(&now, &next_periodic_round, >=)) {
-                               /* Count misses (and catch up) */
-                               timeradd(&next_periodic_round, &period, &next_periodic_round);
-                               misses++;
-                       }
-                       /* FIXME : parse the list of periodic actions for new packets */
-                       continue;
-               }
-
-               /* Data from Ethernet side */
-               if (FD_ISSET(server_socket, &tmp_read_fds)) {
-                       struct sockaddr_in addr;
-                       socklen_t addr_len = sizeof(struct sockaddr_in);
-
-                       /* Receive the new data */
-                       memset(buf, 0, BUF_SIZE);
-                       len = recvfrom(server_socket, buf, BUF_SIZE, 0, (struct sockaddr *)&addr, &addr_len);
-                       if (len > 0) {
-                               handle_udp_request(buf, len, (struct sockaddr *)&addr, addr_len, server_socket, &slave);
-                       } else {
-                               /* Wait .. we received something but nothing came in ? */
-                               perror("UDP receive error");
-                               printf("\nError on UDP packet reception (ret: %d)\n", len);
-                       }
-               }
-
-               /* Read user input if any */
-        if (FD_ISSET(STDIN_FILENO, &tmp_read_fds)) {
-            memset(buf, 0, BUF_SIZE);
-            len = read(STDIN_FILENO, buf, BUF_SIZE);
-                       /* Do not know how to handle it yet, nothing defined. */
-               }
-
-               /* Handle module messages */
-               if (FD_ISSET(slave.fd, &tmp_read_fds)) {
-                       int idx = 0;
-                       memset(buf, 0, BUF_SIZE);
-                       /* Get serial data and try to build a packet */
-                       len = read(slave.fd, buf, BUF_SIZE);
-                       if (len < 0) {
-                               perror("serial read error");
-                               /* FIXME : handle errors */
-                       } else if (len == 0) {
-                               /* Wait .. we received something but nothing came in ? */
-                               printf("\nError, got activity on serial link, but no data ...\n");
-                       }
-                       while (idx < len) {
-                               ret = dtplug_protocol_decode(buf[idx], &slave);
-                               /* Check return code to know if we have a valid packet */
-                               if (ret == -1) {
-                                       /* Anything that's not part of a packet is printed as is (debug output) */
-                                       printf("%c", buf[idx]);
-                               } else if (ret < 0) {
-                                       printf("\nError in received packet. (ret: %d)\n", ret);
-                                       /* FIXME : dump packet for debugging */
-                               } else if (ret == 0) {
-                                       /* Packet is being built */
-                               } else {
-                                       /* Valid packet received */
-                                       handle_module_data(&slave);
-                               }
-                               idx++;
-                       }
-               }
-
-       } /* End of infinite loop */
-
-       close(slave.fd);
-       close(server_socket);
-       return 0;
-}
-
-
diff --git a/host/lighthouse/questions.pl b/host/lighthouse/questions.pl
deleted file mode 100755 (executable)
index abbb320..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use warnings;
-
-# Author : Nathael Pajani
-# Copyright 2015 Nathael Pajani <nathael.pajani@techno-innov.fr>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-
-use IO::Socket::INET;
-use Scalar::Util qw(looks_like_number);
-
-
-#######################################
-# Base package parts
-my $server = 'localhost';
-
-
-# UDP Helper
-sub send_to {
-       my ($port, $request, $type) = @_;
-       my $socket = new IO::Socket::INET(Proto => 'udp');
-       my $servaddr = sockaddr_in($port, inet_aton($server));
-       $socket->send($request, 0, $servaddr);
-       unless ($request =~ /G/) {
-               print "Request sent.\n";
-               return;
-       }
-       my $data;
-       $socket->recv($data, 1024, 0);
-       print "Reply: $data\n";
-       $socket->close();
-}
-
-
-#######################################
-my ($port, $req, $type, @args) = @ARGV;
-
-unless (defined($port) && looks_like_number($port) && defined($req) && defined($type)) {
-       print "Usage: $0 port request type [red green blue] ...\n";
-       exit 1;
-}
-
-my $full = "$req$type ";
-my $sep = ' ';
-foreach (@args) {
-       $full .= "$sep";
-       $full .= "$_";
-       #$sep = ', ';
-}
-print "Req to $port : $full\n";
-
-send_to($port, $full, $type);
-
diff --git a/host/lighthouse/serial_utils.c b/host/lighthouse/serial_utils.c
deleted file mode 100644 (file)
index 5e17e42..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*********************************************************************
- *
- *   Serial utility functions
- *
- *
- * Copyright 2012-2014 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *********************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <termios.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-
-#define SERIAL_BAUD  B115200
-
-
-int serial_setup(char* name)
-{
-       struct termios tio;
-       int fd = -1;
-
-       /* Open serial port */
-       fd = open(name, O_RDWR);
-       if (fd < 0) {
-               perror("Unable to open communication with companion chip");
-               return -1;
-       }
-       /* Setup serial port */
-       memset(&tio, 0, sizeof(tio));
-       tio.c_cflag = CS8 | CREAD | CLOCAL;     /* 8n1, see termios.h for more information */
-       tio.c_cc[VMIN] = 1;
-       tio.c_cc[VTIME] = 5;
-       cfsetospeed(&tio, SERIAL_BAUD);
-       cfsetispeed(&tio, SERIAL_BAUD);
-       tcsetattr(fd, TCSANOW, &tio);
-
-       return fd;
-}
-
diff --git a/host/lighthouse/serial_utils.h b/host/lighthouse/serial_utils.h
deleted file mode 100644 (file)
index 7c17bcf..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*********************************************************************
- *
- *   Serial utility functions
- *
- *
- * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *********************************************************************/
-#ifndef SERIAL_UTILS_H
-#define SERIAL_UTILS_H
-
-/* Setup serial comunication, using name if given or saved name if name is NULL
- *  SERIAL_BAUD  B38400
- *  c_cflag  (CS7 | PARENB | CREAD | CLOCAL) (7e1)
- */
-int serial_setup(char* name);
-
-#endif /* SERIAL_UTILS_H */
-
diff --git a/host/lighthouse/sock_utils.c b/host/lighthouse/sock_utils.c
deleted file mode 100644 (file)
index aa24cfa..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*****************************************************************************
- *
- * socket utils
- *
- *
- * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *****************************************************************************/
-
-#include <stdio.h>  /* perror */
-#include <string.h> /* memset */
-#include <unistd.h> /* close, fcntl */
-#include <fcntl.h>  /* F_SETFL and O_NONBLOCK for fcntl */
-
-/* For socket stuff */
-#include <sys/types.h> /* For portability for socket stuff */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* For TCP_NODELAY to disable nagle algorithm */
-
-
-/* This is used to allow quicker sending of small packets on wires */
-static void sox_disable_nagle_algorithm(int socket)
-{
-       const int on = 1;
-       setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof( int ));
-}
-
-/* Creates a TCP socket on the specified "port", bind to port and setup to
- * accept connections with listen, with up to "nb_pending" pending connections
- * in the queue.
- * Returns the socket, after disabling nagle algorithm.
- * If "our" is not null, it will be used to store the listening socket information.
- * If "port" is 0, then "our" must contain all requiered information for bind call.
- */
-int socket_tcp_server(int port, int nb_pending, struct sockaddr_in* our)
-{
-       struct sockaddr_in local;
-       struct sockaddr_in* tmp;
-       int s;
-       int optval = 1;
-
-       if (our == NULL ) {
-               tmp = &local;
-               if (port == 0) {
-                       fprintf(stderr, "No port and no address information provided, won't be able to bind, aborting\n");
-                       return -1;
-               }
-       } else {
-               tmp = our;
-       }
-
-       if (port != 0) {
-               memset(tmp, 0, sizeof(struct sockaddr_in));
-               tmp->sin_family = AF_INET;
-               tmp->sin_addr.s_addr = htonl(INADDR_ANY);
-               tmp->sin_port = htons((short)port);
-       }
-
-       if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-               perror("Unable to create TCP socket");
-               return -1;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
-               perror("Unable to set reuseaddress on socket");
-               goto err_close;
-       }
-       if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(int)) == -1) {
-               perror("Unable to set keepalive on socket");
-               goto err_close;
-       }
-
-       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
-               perror("Unable to bind TCP port");
-               goto err_close;
-       }
-
-       if (listen(s, nb_pending)) {
-               perror("Unable to listen to TCP port");
-               goto err_close;
-       }
-
-       sox_disable_nagle_algorithm(s);
-       return s;
-
-err_close:
-       close(s);
-       return -1;
-}
-
-
-/* Creates an UDP socket on the specified "port" and bind to port but no specific interface.
- * Returns the socket.
- * If "our" is not null, it will be used to store the listening socket information.
- * "port" must not be 0..
- */
-int create_bound_udp_socket(int port, struct sockaddr_in* our)
-{
-       struct sockaddr_in local;
-       struct sockaddr_in* tmp;
-       int s;
-       int optval = 1;
-
-       if (port == 0) {
-               return -1;
-       }
-
-       if (our == NULL ) {
-               tmp = &local;
-       } else {
-               tmp = our;
-       }
-
-       memset(tmp, 0, sizeof(struct sockaddr_in));
-       tmp->sin_family = AF_INET;
-       tmp->sin_addr.s_addr = htonl(INADDR_ANY);
-       tmp->sin_port = htons((short)port);
-
-       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-               perror("Unable to create UDP socket");
-               return -1;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
-               perror("Unable to set reuseaddress on socket");
-               goto err_close;
-       }
-
-       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
-               perror("Unable to bind UDP port");
-               goto err_close;
-       }
-
-       return s;
-
-err_close:
-       close(s);
-       return -1;
-}
-
-
-
-/* Creates an UDP socket bound to no specific interface.
- * The kernel choses the port to bind to.
- * Returns the socket.
- */
-int create_broadcast_udp_socket(void)
-{
-       struct sockaddr_in local;
-       struct sockaddr_in* tmp = &local;
-       int s;
-       int optval = 1;
-
-       memset(tmp, 0, sizeof(struct sockaddr_in));
-       tmp->sin_family = AF_INET;
-       tmp->sin_addr.s_addr = htonl(INADDR_ANY);
-       tmp->sin_port = 0;
-
-       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-               perror("Unable to create UDP socket");
-               return -1;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) == -1) {
-               perror("Unable to set reuseaddress on socket");
-               goto err_close;
-       }
-
-       if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *)&optval, sizeof(int)) == -1) {
-               perror("Unable to set broadcast on socket");
-               goto err_close;
-       }
-
-       if (bind(s, (struct sockaddr *)tmp, sizeof(struct sockaddr_in)) < 0) {
-               perror("Unable to bind UDP port");
-               goto err_close;
-       }
-
-       return s;
-
-err_close:
-       close(s);
-       return -1;
-}
-
-
diff --git a/host/lighthouse/sock_utils.h b/host/lighthouse/sock_utils.h
deleted file mode 100644 (file)
index 576fb4d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*****************************************************************************
- *
- * socket utils
- *
- *
- * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- *****************************************************************************/
-
-#ifndef SOCK_UTILS_H
-#define SOCK_UTILS_H
-
-#include <netinet/in.h> /* struct sockaddr_in */
-
-/* Creates a socket on the specified "port", bind to port and setup to
-   accept connections with listen, with up to "nb_pending" pending connections
-   in the queue.
-   Returns the socket, after disabling nagle algorithm.
-   If "our" is not null, it will be used to store the listening socket information.
- */
-int socket_tcp_server(int port, int nb_pending, struct sockaddr_in* our);
-
-
-/* Creates an UDP socket on the specified "port" and bind to port but no specific interface.
- * Returns the socket.
- * If "our" is not null, it will be used to store the listening socket information.
- * "port" must not be 0..
- */
-int create_bound_udp_socket(int port, struct sockaddr_in* our);
-
-
-/* Creates an UDP socket bound to no specific interface.
- * The kernel choses the port to bind to.
- * Returns the socket.
- */
-int create_broadcast_udp_socket(void);
-
-#endif /* SOCK_UTILS_H */
-