/** * This software is subject to the ANT+ Shared Source License * www.thisisant.com/swlicenses * Copyright (c) Dynastream Innovations, Inc. 2015 * 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 Dynastream nor the names of its * contributors may be used to endorse or promote products * derived from this software without specific prior * written permission. * * The following actions are prohibited: * 1) Redistribution of source code containing the ANT+ Network * Key. The ANT+ Network Key is available to ANT+ Adopters. * Please refer to http://thisisant.com to become an ANT+ * Adopter and access the key. * * 2) Reverse engineering, decompilation, and/or disassembly of * software provided in binary form under this license. * * 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 HEREBY * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. * */ /**@file * @brief Device registry used in the scan and forward demo * * @defgroup ant_scan_and_forward_example ANT Scan and Forward Demo * @{ * @ingroup nrf_ant_scan_and_forward * */ #include "deviceregistry.h" #include "commands.h" #define NODE_ID_TO_INDEX_CONVERT(node_id) (node_id % MAX_DEVICES) /**< Hash function */ static deviceregistry_t device_registry; /**< Device resistry of all nodes */ /** @brief Initializes entries in the device registry to invalid * * @param[in] p_device Pointer to device to initialize */ static void dr_init_device(device_t * p_device) { p_device->node_id = NODE_ID_INVALID; p_device->ant_channel = ANT_CHANNEL_NOT_CONNECTED; p_device->last_message_sequence_received = 0; p_device->application_state = 0; } void dr_init(void) { device_registry.count = 0; for (int i = 0; i < MAX_DEVICES; i++) { dr_init_device(&device_registry.devices[i]); } } bool dr_device_add(uint8_t node_id) { uint8_t index = MAX_DEVICES; // Specifed maximum total number in the array uint8_t start = NODE_ID_TO_INDEX_CONVERT(node_id); // Start index of the array uint8_t id; for (int i = 0; i < MAX_DEVICES; i++ ) { id = device_registry.devices[(start + i) % MAX_DEVICES].node_id; if (id == node_id) // If this node already exists, return false. { return false; } if (id == NODE_ID_INVALID) // If we found a place to put it { // Find the best place to put this node (the place closest to the hash function result) index = (start + i) % MAX_DEVICES; break; } } if (index == MAX_DEVICES) { return false; } device_registry.devices[index].node_id = node_id; device_registry.count++; return true; } bool dr_device_remove(uint8_t node_id) { uint8_t index = NODE_ID_TO_INDEX_CONVERT(node_id); uint8_t start = index; for (int i = 0; i < MAX_DEVICES; i++ ) { if (device_registry.devices[(start + i) % MAX_DEVICES].node_id == node_id) { // Remove the device dr_init_device(&device_registry.devices[index]); device_registry.count--; return true; } else index++; } return false; } bool dr_is_full(void) { return (device_registry.count >= MAX_DEVICES); } device_t * dr_device_get(uint8_t node_id) { uint8_t index = NODE_ID_TO_INDEX_CONVERT(node_id); uint8_t start = index; for (int i = 0; i < MAX_DEVICES; i++ ) { if (device_registry.devices[(start + i) % MAX_DEVICES].node_id == node_id) { return &(device_registry.devices[(start + i) % MAX_DEVICES]); } else { index++; } } return NULL; // Doesnt exist } device_t * dr_device_at_index_get(uint8_t index) { return &(device_registry.devices[index]); } bool dr_device_exists(uint8_t node_id) { uint8_t start = NODE_ID_TO_INDEX_CONVERT(node_id); for (int i = 0; i < MAX_DEVICES; i++ ) { if (device_registry.devices[(start + i) % MAX_DEVICES].node_id == node_id) { return true; } } return false; } bool dr_device_at_index_exists(uint8_t index) { return (device_registry.devices[index].node_id != NODE_ID_INVALID ? true : false); } uint8_t dr_index_of_node_get(uint8_t node_id) { uint8_t start = NODE_ID_TO_INDEX_CONVERT(node_id); for (int i = 0; i < MAX_DEVICES; i++ ) { if (device_registry.devices[(start + i) % MAX_DEVICES].node_id == node_id) { return (start + i) % MAX_DEVICES; } } return 0; } /** *@} **/