diff --git a/include/greybus-manifest.h b/include/greybus-manifest.h deleted file mode 100644 index da5a43a5cffa31228ae756e3d0555969cd7bfaba..0000000000000000000000000000000000000000 --- a/include/greybus-manifest.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2014-2015 Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __GREYBUS_MANIFEST_H -#define __GREYBUS_MANIFEST_H - -#include <stdint.h> - -#ifndef __u8 -#define __u8 uint8_t -#endif - -#ifndef __le16 -#define __le16 uint16_t -#endif - -#ifndef __le32 -#define __le32 uint32_t -#endif - -#ifndef __le64 -#define __le64 uint64_t -#endif - -#ifndef __packed -#define __packed __attribute__((packed)) -#endif - -/* Greybus version with which this header complies */ -#define GREYBUS_VERSION_MAJOR 0x00 -#define GREYBUS_VERSION_MINOR 0x01 - -enum greybus_descriptor_type { - GREYBUS_TYPE_INVALID = 0x00, - GREYBUS_TYPE_INTERFACE = 0x01, - GREYBUS_TYPE_STRING = 0x02, - GREYBUS_TYPE_BUNDLE = 0x03, - GREYBUS_TYPE_CPORT = 0x04, - GREYBUS_TYPE_MIKROBUS = 0x05, - GREYBUS_TYPE_PROPERTY = 0x06, - GREYBUS_TYPE_DEVICE = 0x07, -}; - -enum greybus_protocol { - GREYBUS_PROTOCOL_CONTROL = 0x00, - GREYBUS_PROTOCOL_AP = 0x01, - GREYBUS_PROTOCOL_GPIO = 0x02, - GREYBUS_PROTOCOL_I2C = 0x03, - GREYBUS_PROTOCOL_UART = 0x04, - GREYBUS_PROTOCOL_HID = 0x05, - GREYBUS_PROTOCOL_USB = 0x06, - GREYBUS_PROTOCOL_SDIO = 0x07, - GREYBUS_PROTOCOL_POWER_SUPPLY = 0x08, - GREYBUS_PROTOCOL_PWM = 0x09, - /* 0x0a is unused */ - GREYBUS_PROTOCOL_SPI = 0x0b, - GREYBUS_PROTOCOL_DISPLAY = 0x0c, - GREYBUS_PROTOCOL_CAMERA_MGMT = 0x0d, - GREYBUS_PROTOCOL_SENSOR = 0x0e, - GREYBUS_PROTOCOL_LIGHTS = 0x0f, - GREYBUS_PROTOCOL_VIBRATOR = 0x10, - GREYBUS_PROTOCOL_LOOPBACK = 0x11, - GREYBUS_PROTOCOL_AUDIO_MGMT = 0x12, - GREYBUS_PROTOCOL_AUDIO_DATA = 0x13, - GREYBUS_PROTOCOL_SVC = 0x14, - GREYBUS_PROTOCOL_FIRMWARE = 0x15, - GREYBUS_PROTOCOL_CAMERA_DATA = 0x16, - /* ... */ - GREYBUS_PROTOCOL_RAW = 0xfe, - GREYBUS_PROTOCOL_VENDOR = 0xff, -}; - -enum greybus_class_type { - GREYBUS_CLASS_CONTROL = 0x00, - GREYBUS_CLASS_AP = 0x01, - GREYBUS_CLASS_GPIO = 0x02, - GREYBUS_CLASS_I2C = 0x03, - GREYBUS_CLASS_UART = 0x04, - GREYBUS_CLASS_HID = 0x05, - GREYBUS_CLASS_USB = 0x06, - GREYBUS_CLASS_SDIO = 0x07, - GREYBUS_CLASS_POWER_SUPPLY = 0x08, - GREYBUS_CLASS_PWM = 0x09, - /* 0x0a is unused */ - GREYBUS_CLASS_SPI = 0x0b, - GREYBUS_CLASS_DISPLAY = 0x0c, - GREYBUS_CLASS_CAMERA = 0x0d, - GREYBUS_CLASS_SENSOR = 0x0e, - GREYBUS_CLASS_LIGHTS = 0x0f, - GREYBUS_CLASS_VIBRATOR = 0x10, - GREYBUS_CLASS_LOOPBACK = 0x11, - GREYBUS_CLASS_AUDIO = 0x12, - /* 0x13 is unused */ - GREYBUS_CLASS_SVC = 0x14, - GREYBUS_CLASS_FIRMWARE = 0x15, - /* ... */ - GREYBUS_CLASS_RAW = 0xfe, - GREYBUS_CLASS_VENDOR = 0xff, -}; - -/* - * The string in a string descriptor is not NUL-terminated. The - * size of the descriptor will be rounded up to a multiple of 4 - * bytes, by padding the string with 0x00 bytes if necessary. - */ -struct greybus_descriptor_string { - __u8 length; - __u8 id; - __u8 string[0]; -} __packed; - -/* - * An interface descriptor describes information about an interface as a whole, - * *not* the functions within it. - */ -struct greybus_descriptor_interface { - __u8 vendor_stringid; - __u8 product_stringid; - __u8 pad[2]; -} __packed; - -/* - * An bundle descriptor defines an identification number and a class for - * each bundle. - * - * @id: Uniquely identifies a bundle within a interface, its sole purpose is to - * allow CPort descriptors to specify which bundle they are associated with. - * The first bundle will have id 0, second will have 1 and so on. - * - * The largest CPort id associated with an bundle (defined by a - * CPort descriptor in the manifest) is used to determine how to - * encode the device id and module number in UniPro packets - * that use the bundle. - * - * @class: It is used by kernel to know the functionality provided by the - * bundle and will be matched against drivers functinality while probing greybus - * driver. It should contain one of the values defined in - * 'enum greybus_class_type'. - * - */ -struct greybus_descriptor_bundle { - __u8 id; /* interface-relative id (0..) */ - __u8 class; - __u8 pad[2]; -} __packed; - -/* - * A CPort descriptor indicates the id of the bundle within the - * module it's associated with, along with the CPort id used to - * address the CPort. The protocol id defines the format of messages - * exchanged using the CPort. - */ -struct greybus_descriptor_cport { - __le16 id; - __u8 bundle; - __u8 protocol_id; /* enum greybus_protocol */ -} __packed; - -/* - * A mikrobus descriptor is used to describe the details - * about the bus configuration for the add-on board - * connected to the mikrobus port. - */ -struct greybus_descriptor_mikrobus { - __u8 pin_state[12]; -} __packed; - -/* - * A property descriptor is used to pass named properties - * to device drivers through the unified device properties - * interface under linux/property.h - */ -struct greybus_descriptor_property { - __u8 length; - __u8 id; - __u8 propname_stringid; - __u8 type; - __u8 value[0]; -} __packed; - -/* - * A device descriptor is used to describe the - * details required by a add-on board device - * driver. - */ -struct greybus_descriptor_device { - __u8 id; - __u8 driver_stringid; - __u8 protocol; - __u8 reg; - __le32 max_speed_hz; - __u8 irq; - __u8 irq_type; - __u8 mode; - __u8 prop_link; - __u8 gpio_link; - __u8 reg_link; - __u8 clock_link; - __u8 pad[1]; -} __packed; - -struct greybus_descriptor_header { - __le16 size; - __u8 type; /* enum greybus_descriptor_type */ - __u8 pad; -} __packed; - -struct greybus_descriptor { - struct greybus_descriptor_header header; - union { - struct greybus_descriptor_string string; - struct greybus_descriptor_interface interface; - struct greybus_descriptor_bundle bundle; - struct greybus_descriptor_cport cport; - struct greybus_descriptor_mikrobus mikrobus; - struct greybus_descriptor_property property; - struct greybus_descriptor_device device; - }; -} __packed; - -struct greybus_manifest_header { - __le16 size; - __u8 version_major; - __u8 version_minor; -} __packed; - -struct greybus_manifest { - struct greybus_manifest_header header; - struct greybus_descriptor descriptors[0]; -} __packed; - -#endif /* __GREYBUS_MANIFEST_H */ diff --git a/include/manifest.h b/include/manifest.h deleted file mode 100644 index c7f3aa9eff1275dbf8cd30e26bb018787316611b..0000000000000000000000000000000000000000 --- a/include/manifest.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MANIFEST_H -#define MANIFEST_H - -#include "greybus-manifest.h" -#include <stdint.h> -#include <zephyr/sys/slist.h> - -struct gb_cport { - sys_snode_t node; - int id; - int bundle; - int protocol; -}; - -sys_slist_t gb_manifest_get_cports(void *, size_t); - -void gb_cports_free(sys_slist_t); - -#endif diff --git a/include/node_handler.h b/include/node_handler.h deleted file mode 100644 index ae6857f421268d28ec6995d71f240ae8aaa90f20..0000000000000000000000000000000000000000 --- a/include/node_handler.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file contains functions for managing the nodes. - */ - -#ifndef NODE_HANDLER_H -#define NODE_HANDLER_H - -#include <stdint.h> -#include "error_handling.h" -#include <zephyr/net/socket.h> - -/* - * Queue a new node to be setup. This function is async and thus does not do the - * setup itself. This will only add the node to global queue. - * - * @param IPv6 address of the node. - * @param cport number to connect to. - * - * @return 0 if success, negative for failure. - */ -int node_handler_setup_node_queue(const struct in6_addr *, uint8_t); - -#endif diff --git a/include/node_table.h b/include/node_table.h deleted file mode 100644 index 23a40fb2f2e54181a0f144728f3961d08d07c336..0000000000000000000000000000000000000000 --- a/include/node_table.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is ment to hold functions to maintain a table of active nodes. - * THe functions defined here are thread safe. - */ - -#ifndef NODE_TABLE_H -#define NODE_TABLE_H - -#include <stdbool.h> -#include <zephyr/net/net_ip.h> -#include <zephyr/net/socket.h> - -#define MAX_NODE_TABLE_LEN CONFIG_BEAGLEPLAY_GREYBUS_MAX_NODES - -/* - * Add a new node to the table. - * - * @param addr: IPV6 address of node. - * - * @returns 0 if successful, negative in case of error - */ -int node_table_add_node(const struct in6_addr *); - -/* - * Check if a node is already present in the table - * - * @param addr: IPV6 address of node. - * - * @returns true if successful, false in case of error - */ -bool node_table_is_active_by_addr(const struct in6_addr *); - -/* - * Remove the node from node table. This also closes all the cports for this - * node. - * - * @param addr: IPV6 address of node. - * - * @returns 0 if successful, negative in case of error - */ -int node_table_remove_node_by_addr(const struct in6_addr *); - -/* - * Allocate memory for the cports for a node. - * - * @param addr: IPV6 address of node. - * @param num_cports: number of cports. Note, this should not include Cport0. - * - * @returns 0 if successful, negative in case of error - */ -int node_table_alloc_cports_by_addr(const struct in6_addr *, size_t); - -/* - * Add Cport to a node in the table. - * - * @param sock: Socket for Cport0. - * @param sock: Socket to access the cport. - * @param cport_num: The cport to add the address to. - * - * @returns 0 if successful, negative in case of error - */ -int node_table_add_cport_by_cport0(int, int, size_t); - -/* - * Add Cport to a node in the table. - * - * @param sock: Socket for Cport0. - * @param sock: Socket to access the cport. - * @param cport_num: The cport to add the address to. - * - * @returns sock if successful, negative in case of error - */ -int node_table_add_cport_by_addr(const struct in6_addr *, int, size_t); - -/* - * Make a Cport inactive. - * If the cport is Cport0, this will also remove the node. - * - * @param sock: Socket to access the cport - * - * @returns 0 if successful, negative in case of error - */ -int node_table_remove_cport_by_socket(int); - -/* - * Get all cports(sockets) that are currently in the table - * - * @param array: array to copy cports to. - * @param array_len: length of array. - * - * @returns the number of cports write. - */ -size_t node_table_get_all_cports(int *, size_t); - -/* - * Get pollfd for all cports - * - * @param array: pollfd array to copy cports to. - * @param array_len: length of array. - * - * @returns the number of cports write. - */ -size_t node_table_get_all_cports_pollfd(struct zsock_pollfd *, size_t); - -/* - * Get node IPV6 address by CPort0 - * - * @param cport0 - * @param IPV6 address - * - * @return 0 in case of success. Neagaive in case of error - */ -int node_table_get_addr_by_cport0(int, struct in6_addr *); - -#endif diff --git a/prj.conf b/prj.conf index f70d3d2021803df1f999560415e381899b2312c1..1c80e815031a6f4fd1086ad2220d7cdfde23a93f 100644 --- a/prj.conf +++ b/prj.conf @@ -85,3 +85,4 @@ CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE=1024 # Application Config CONFIG_BEAGLEPLAY_GREYBUS_MAX_NODES=32 +CONFIG_BEAGLEPLAY_HDLC_MAX_BLOCK_SIZE=512 diff --git a/src/main.c b/src/main.c index e40f6f0d23a5b0c018ddc77c144b1770816b27e1..5dbd788db84ea8e24eefb008e97f53acf04a0237 100644 --- a/src/main.c +++ b/src/main.c @@ -26,13 +26,8 @@ LOG_MODULE_REGISTER(cc1352_greybus, CONFIG_BEAGLEPLAY_GREYBUS_LOG_LEVEL); -static void node_discovery_entry(void *, void *, void *); static void apbridge_entry(void *, void *, void *); -// Thread responsible for beagleconnect node discovery. -K_THREAD_DEFINE(node_discovery, 1024, node_discovery_entry, NULL, NULL, NULL, 4, - 0, 0); - K_THREAD_DEFINE(apbridge, 2048, apbridge_entry, NULL, NULL, NULL, 5, 0, 0); static void apbridge_entry(void *p1, void *p2, void *p3) { @@ -76,38 +71,6 @@ static int get_all_nodes(struct in6_addr *node_array, return 1; } -static void node_discovery_entry(void *p1, void *p2, void *p3) { - int ret; - struct in6_addr node_array[MAX_GREYBUS_NODES]; - struct gb_interface *intf; - - // Wait until SVC is ready - while (!svc_is_ready()) { - k_sleep(K_MSEC(1000)); - } - - while (1) { - ret = get_all_nodes(node_array, MAX_GREYBUS_NODES); - if (ret < 0) { - LOG_WRN("Failed to get greybus nodes"); - continue; - } - // LOG_INF("Discoverd %u nodes", ret); - - for (size_t i = 0; i < ret; ++i) { - intf = node_find_by_addr(&node_array[i]); - if (intf == NULL) { - intf = node_create_interface(&node_array[i]); - svc_send_module_inserted(intf->id); - } - } - - // Put the thread to sleep for an interval - // LOG_DBG("Going to sleep"); - k_msleep(NODE_DISCOVERY_INTERVAL); - } -} - static void serial_callback(const struct device *dev, void *user_data) { hdlc_rx_submit(); } @@ -115,6 +78,8 @@ static void serial_callback(const struct device *dev, void *user_data) { void main(void) { int ret; struct gb_connection *conn; + struct in6_addr node_array[MAX_GREYBUS_NODES]; + struct gb_interface *intf; LOG_INF("Starting BeaglePlay Greybus"); @@ -145,5 +110,27 @@ void main(void) { svc_send_version(); - k_sleep(K_FOREVER); + // Wait until SVC is ready + while (!svc_is_ready()) { + k_sleep(K_MSEC(NODE_DISCOVERY_INTERVAL)); + } + + while (1) { + ret = get_all_nodes(node_array, MAX_GREYBUS_NODES); + if (ret < 0) { + LOG_WRN("Failed to get greybus nodes"); + continue; + } + + for (size_t i = 0; i < ret; ++i) { + intf = node_find_by_addr(&node_array[i]); + if (intf == NULL) { + intf = node_create_interface(&node_array[i]); + svc_send_module_inserted(intf->id); + } + } + + // Put the thread to sleep for an interval + k_msleep(NODE_DISCOVERY_INTERVAL); + } } diff --git a/src/manifest.c b/src/manifest.c deleted file mode 100644 index a0afc2020a2df640c2c8c12d1ceebe5502136897..0000000000000000000000000000000000000000 --- a/src/manifest.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "manifest.h" -#include "zephyr/sys/slist.h" -#include <zephyr/kernel.h> -#include <zephyr/logging/log.h> -#include <zephyr/sys/byteorder.h> - -LOG_MODULE_DECLARE(cc1352_greybus, CONFIG_BEAGLEPLAY_GREYBUS_LOG_LEVEL); - -static struct gb_cport *gb_cport_alloc(sys_slist_t *list) { - struct gb_cport *cport = k_malloc(sizeof(struct gb_cport)); - sys_slist_append(list, &cport->node); - return cport; -} - -static void gb_cport_dealloc(struct gb_cport *cport) { k_free(cport); } - -sys_slist_t gb_manifest_get_cports(void *data, size_t manifest_size) { - struct greybus_manifest *manifest = data; - struct greybus_manifest_header *header = &manifest->header; - struct greybus_descriptor *desc; - size_t size = header->size; - int desc_size; - sys_slist_t cports; - sys_slist_init(&cports); - struct gb_cport *cport; - - LOG_DBG("Manifest Size: %u", size); - LOG_DBG("Manifest version: %u.%u", header->version_major, - header->version_minor); - - if (size > manifest_size) { - LOG_ERR("Manifest size larger than supplied payload"); - goto early_fail; - } - - desc = (struct greybus_descriptor *)(header + 1); - size -= sizeof(*header); - while (size) { - if (desc->header.type == GREYBUS_TYPE_CPORT) { - cport = gb_cport_alloc(&cports); - cport->id = desc->cport.id; - cport->bundle = desc->cport.bundle; - cport->protocol = desc->cport.protocol_id; - } - desc_size = desc->header.size; - desc = (struct greybus_descriptor *)((char *)desc + desc_size); - size -= desc_size; - } - -early_fail: - return cports; -} - -void gb_cports_free(sys_slist_t list) { - struct gb_cport *cport, *cport_safe; - SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&list, cport, cport_safe, node) { - sys_slist_remove(&list, NULL, &cport->node); - gb_cport_dealloc(cport); - } -} diff --git a/src/node_handler.c b/src/node_handler.c deleted file mode 100644 index c55b106291f5931ee2368b008039c910b609cce6..0000000000000000000000000000000000000000 --- a/src/node_handler.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "node_handler.h" -#include "node_table.h" -#include "svc.h" -#include "zephyr/kernel.h" -#include "zephyr/net/net_ip.h" -#include <zephyr/logging/log.h> - -#define GB_TRANSPORT_TCPIP_BASE_PORT 4242 - -LOG_MODULE_DECLARE(cc1352_greybus, CONFIG_BEAGLEPLAY_GREYBUS_LOG_LEVEL); - -static void node_setup_work_handler(struct k_work *); - -K_WORK_DEFINE(node_setup_work, node_setup_work_handler); - -struct gb_cport_connection { - struct in6_addr addr; - uint8_t cport_num; -}; - -K_MSGQ_DEFINE(node_setup_queue, sizeof(struct gb_cport_connection), 10, 4); - -static int connect_to_node(const struct sockaddr *addr) { - int ret, sock; - size_t addr_size; - - if (addr->sa_family == AF_INET6) { - sock = zsock_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - addr_size = sizeof(struct sockaddr_in6); - } else { - sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - addr_size = sizeof(struct sockaddr_in); - } - - if (sock < 0) { - LOG_WRN("Failed to create socket %d", errno); - goto fail; - } - - LOG_INF("Trying to connect to node from socket %d", sock); - ret = zsock_connect(sock, addr, addr_size); - - if (ret) { - LOG_WRN("Failed to connect to node %d", errno); - goto fail; - } - - LOG_INF("Connected to Greybus Node"); - return sock; - -fail: - zsock_close(sock); - return -1; -} - -void node_setup(struct in6_addr *node_ip_addr, uint8_t cport_num) { - struct sockaddr_in6 node_addr; - int ret; - - memcpy(&node_addr.sin6_addr, node_ip_addr, sizeof(struct in6_addr)); - node_addr.sin6_family = AF_INET6; - node_addr.sin6_scope_id = 0; - node_addr.sin6_port = htons(GB_TRANSPORT_TCPIP_BASE_PORT + cport_num); - - ret = connect_to_node((struct sockaddr *)&node_addr); - if (ret < 0) { - LOG_WRN("Failed to connect to node"); - goto fail; - } - - ret = node_table_add_cport_by_addr(&node_addr.sin6_addr, ret, cport_num); - if (ret < 0) { - LOG_WRN("Failed to add cport %u to node table with error %d", cport_num, ret); - goto fail; - } - LOG_DBG("Added Cport %u", cport_num); - - // Create an Interface - - return; - -fail: - if (cport_num == 0) { - node_table_remove_node_by_addr(&node_addr.sin6_addr); - } -} - -static void node_setup_work_handler(struct k_work *work) { - struct gb_cport_connection cport; - while (k_msgq_get(&node_setup_queue, &cport, K_NO_WAIT) == 0) { - node_setup(&cport.addr, cport.cport_num); - } -} - -int node_handler_setup_node_queue(const struct in6_addr *addr, - uint8_t cport_num) { - struct gb_cport_connection cport; - memcpy(&cport.addr, addr, sizeof(struct in6_addr)); - cport.cport_num = cport_num; - k_msgq_put(&node_setup_queue, &cport, K_FOREVER); - k_work_submit(&node_setup_work); - - return SUCCESS; -} diff --git a/src/node_table.c b/src/node_table.c deleted file mode 100644 index ad168a34eabc9623fc5e3fd2a6fd26f82aec81e5..0000000000000000000000000000000000000000 --- a/src/node_table.c +++ /dev/null @@ -1,310 +0,0 @@ -#include "node_table.h" -#include "error_handling.h" -#include <zephyr/kernel.h> -#include <zephyr/logging/log.h> -#include <zephyr/net/socket.h> -#include <zephyr/sys/dlist.h> -#include <zephyr/sys/mutex.h> - -LOG_MODULE_DECLARE(cc1352_greybus, CONFIG_BEAGLEPLAY_GREYBUS_LOG_LEVEL); - -K_MUTEX_DEFINE(nodes_table_mutex); - -struct node_table_item { - struct in6_addr addr; - int cport0; - size_t num_cports; /* Number of cports. This does not include Cport0 */ - int *cports; -}; - -static struct node_table_item nodes_table[MAX_NODE_TABLE_LEN]; -static size_t nodes_pos = 0; - -static int sock_addr_cmp_addr(const struct in6_addr *sa, - const struct in6_addr *sb) { - return memcmp(sa, sb, sizeof(struct in6_addr)); -} - -static int find_node_by_addr(const struct in6_addr *node_addr) { - for (size_t i = 0; i < nodes_pos; ++i) { - if (sock_addr_cmp_addr(node_addr, &nodes_table[i].addr) == 0) { - return i; - } - } - return -1; -} - -static int find_node_by_cport0(const int cport0) { - for (size_t i = 0; i < nodes_pos; ++i) { - if (nodes_table[i].cport0 == cport0) { - return i; - } - } - return -1; -} - -static void deinit_node(struct node_table_item *node) { - size_t i; - // Close all the sockets - if (node->cport0 >= 0) { - zsock_close(node->cport0); - } - for (i = 0; i < node->num_cports; ++i) { - if (node->cports[i] >= 0) { - zsock_close(node->cports[i]); - } - } - k_free(node->cports); -} - -static void remove_node_by_pos(const size_t pos) { - deinit_node(&nodes_table[pos]); - - nodes_pos--; - if (pos != nodes_pos) { - memcpy(&nodes_table[pos], &nodes_table[nodes_pos], - sizeof(struct node_table_item)); - } -} - -int node_table_add_node(const struct in6_addr *node_addr) { - if (nodes_pos >= MAX_NODE_TABLE_LEN) { - LOG_WRN("Reached max greybus nodes limit"); - return -E_TABLE_FULL; - } - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - memcpy(&nodes_table[nodes_pos].addr, node_addr, sizeof(struct in6_addr)); - nodes_table[nodes_pos].cport0 = -1; - nodes_table[nodes_pos].num_cports = 0; - nodes_table[nodes_pos].cports = NULL; - nodes_pos++; - k_mutex_unlock(&nodes_table_mutex); - - return SUCCESS; -} - -bool node_table_is_active_by_addr(const struct in6_addr *node_addr) { - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - bool ret = find_node_by_addr(node_addr) >= 0; - k_mutex_unlock(&nodes_table_mutex); - - return ret; -} - -int node_table_remove_node_by_addr(const struct in6_addr *node_addr) { - int ret; - if (nodes_pos <= 0) { - return -E_EMPTY; - } - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - int pos = find_node_by_addr(node_addr); - if (pos < 0) { - ret = -E_NOT_FOUND; - goto early_fail; - } - - remove_node_by_pos(pos); - k_mutex_unlock(&nodes_table_mutex); - - return SUCCESS; - -early_fail: - k_mutex_unlock(&nodes_table_mutex); - return ret; -} - -int node_table_alloc_cports_by_addr(const struct in6_addr *node_addr, - size_t num_cports) { - size_t i; - int ret; - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - int pos = find_node_by_addr(node_addr); - if (pos < 0) { - ret = -E_NOT_FOUND; - goto early_fail; - } - - nodes_table[pos].cports = k_malloc(sizeof(int) * num_cports); - if (nodes_table[pos].cports == NULL) { - ret = -E_NO_HEAP_MEM; - goto early_fail; - } - - // Set all sockets to be invalid for now. - for (i = 0; i < num_cports; ++i) { - nodes_table[pos].cports[i] = -1; - } - - nodes_table[pos].num_cports = num_cports; - - k_mutex_unlock(&nodes_table_mutex); - return SUCCESS; - -early_fail: - k_mutex_unlock(&nodes_table_mutex); - return ret; -} - -int node_table_add_cport_by_cport0(int cport0, int sock, size_t cport_num) { - int ret; - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - int pos = find_node_by_cport0(cport0); - if (pos == -1) { - ret = -E_NOT_FOUND; - goto early_fail; - } - - if (nodes_table[pos].num_cports <= 0) { - LOG_WRN("Cports for socket %d have not been initialized", cport0); - ret = -E_UNINITIALIZED_CPORT; - goto early_fail; - } - - if (nodes_table[pos].num_cports < cport_num) { - LOG_WRN("Cport num %u exceeds the allocated cports", cport_num); - ret = -E_INVALID_CPORT_ALLOC; - goto early_fail; - } - - nodes_table[pos].cports[cport_num - 1] = sock; - - k_mutex_unlock(&nodes_table_mutex); - return SUCCESS; - -early_fail: - k_mutex_unlock(&nodes_table_mutex); - return ret; -} - -int node_table_remove_cport_by_socket(int sock) { - size_t i, j; - if (nodes_pos <= 0) { - return -E_NOT_FOUND; - } - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - for (i = 0; i < nodes_pos; ++i) { - if (nodes_table[i].cport0 == sock) { - // Remove node - remove_node_by_pos(i); - goto success; - } - - for (j = 0; j < nodes_table[i].num_cports; ++j) { - if (nodes_table[i].cports[j] == sock) { - // Remove cport - zsock_close(nodes_table[i].cports[j]); - nodes_table[i].cports[j] = -1; - goto success; - } - } - } - - k_mutex_unlock(&nodes_table_mutex); - return -E_NOT_FOUND; - -success: - k_mutex_unlock(&nodes_table_mutex); - return SUCCESS; -} - -size_t node_table_get_all_cports(int *arr, size_t arr_len) { - size_t i, j; - size_t count = 0; - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - for (i = 0; i < nodes_pos && count < arr_len; ++i) { - if (nodes_table[i].cport0 >= 0) { - arr[count] = nodes_table[i].cport0; - count++; - } - - for (j = 0; j < nodes_table[i].num_cports && count < arr_len; ++j) { - if (nodes_table[i].cports[j] >= 0) { - arr[count] = nodes_table[i].cports[j]; - count++; - } - } - } - - k_mutex_unlock(&nodes_table_mutex); - return count; -} - -size_t node_table_get_all_cports_pollfd(struct zsock_pollfd *arr, - size_t arr_len) { - size_t i, j; - size_t count = 0; - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - for (i = 0; i < nodes_pos && count < arr_len; ++i) { - if (nodes_table[i].cport0 >= 0) { - arr[count].fd = nodes_table[i].cport0; - count++; - } - - for (j = 0; j < nodes_table[i].num_cports && count < arr_len; ++j) { - if (nodes_table[i].cports[j] >= 0) { - arr[count].fd = nodes_table[i].cports[j]; - count++; - } - } - } - - k_mutex_unlock(&nodes_table_mutex); - return count; -} - -int node_table_add_cport_by_addr(const struct in6_addr *node_addr, int sock, - size_t cport_num) { - int ret; - - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - int pos = find_node_by_addr(node_addr); - if (pos < 0) { - ret = -E_NOT_FOUND; - goto early_fail; - } - - if (cport_num == 0) { - nodes_table[pos].cport0 = sock; - goto success; - } - - if (nodes_table[pos].num_cports < cport_num) { - ret = -E_INVALID_CPORT_ALLOC; - goto early_fail; - } - - nodes_table[pos].cports[cport_num - 1] = sock; - -success: - k_mutex_unlock(&nodes_table_mutex); - return sock; - -early_fail: - k_mutex_unlock(&nodes_table_mutex); - return ret; -} - - -int node_table_get_addr_by_cport0(int cport0, struct in6_addr *addr) { - int ret = SUCCESS; - k_mutex_lock(&nodes_table_mutex, K_FOREVER); - int pos = find_node_by_cport0(cport0); - if (pos < 0) { - ret = -E_NOT_FOUND; - goto early_fail; - } - - memcpy(addr, &nodes_table[pos].addr, sizeof(struct in6_addr)); - -early_fail: - k_mutex_unlock(&nodes_table_mutex); - return ret; -} -