From 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 23 Aug 2018 17:08:59 +0200 Subject: o Initial import. --- .../components/iot/medium/ble_ncfgs/ble_ncfgs.c | 516 ++++++++++ .../components/iot/medium/ble_ncfgs/ble_ncfgs.h | 194 ++++ .../iot/medium/commissioning/commissioning.c | 1077 ++++++++++++++++++++ .../iot/medium/commissioning/commissioning.h | 207 ++++ .../components/iot/medium/ipv6_medium.h | 238 +++++ .../components/iot/medium/ipv6_medium_ble.c | 689 +++++++++++++ .../components/iot/medium/ipv6_medium_ble.h | 100 ++ .../iot/medium/ipv6_medium_platform_dummy.h | 54 + 8 files changed, 3075 insertions(+) create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h create mode 100644 thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium') diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c new file mode 100644 index 0000000..241ec48 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c @@ -0,0 +1,516 @@ +/** + * Copyright (c) 2015-2017 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifdef COMMISSIONING_ENABLED + +#include +#include "ble_ncfgs.h" +#include "app_error.h" +#include "ble.h" +#include "nordic_common.h" + +/**@brief NCFGS database encapsulation. */ +typedef struct +{ + uint16_t service_handle; + ble_gatts_char_handles_t ssid_handles; + ble_gatts_char_handles_t keys_store_handles; + ble_gatts_char_handles_t ctrlp_handles; +} ble_database_t; + +static ble_ncfgs_state_t m_service_state = NCFGS_STATE_IDLE; /**< Module state value. */ +static ble_ncfgs_evt_handler_t m_app_evt_handler; /**< Parent module callback function. */ +static ble_database_t m_database; /**< GATT handles database. */ +static uint8_t m_ctrlp_value_buffer[NCFGS_CTRLP_VALUE_LEN]; /**< Stores received Control Point value before parsing. */ +static ble_ncfgs_data_t m_ncfgs_data; /**< Stores all values written by the peer device. */ + +#if NCFGS_CONFIG_LOG_ENABLED + +#define NRF_LOG_MODULE_NAME ble_ncfgs + +#define NRF_LOG_LEVEL NCFGS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NCFGS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR NCFGS_CONFIG_DEBUG_COLOR + +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +#define NCFGS_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */ +#define NCFGS_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */ +#define NCFGS_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */ + +#define NCFGS_ENTRY() NCFGS_TRC(">> %s", __func__) +#define NCFGS_EXIT() NCFGS_TRC("<< %s", __func__) + +#else // NCFGS_CONFIG_LOG_ENABLED + +#define NCFGS_TRC(...) /**< Disables traces. */ +#define NCFGS_DUMP(...) /**< Disables dumping of octet streams. */ +#define NCFGS_ERR(...) /**< Disables error logs. */ + +#define NCFGS_ENTRY(...) +#define NCFGS_EXIT(...) + +#endif // NCFGS_CONFIG_LOG_ENABLED + +/**@brief Function for adding the SSID Store characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t add_ssid_characteristic(ble_uuid_t * p_srv_uuid) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t char_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0x00, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + + memset(&attr_md, 0x00, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + attr_md.wr_auth = 1; + attr_md.vloc = BLE_GATTS_VLOC_USER; + + memset(&attr_char_value, 0x00, sizeof(attr_char_value)); + + char_uuid.type = p_srv_uuid->type; + char_uuid.uuid = BLE_UUID_NCFGS_SSID_CHAR; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = NCFGS_SSID_MAX_LEN; + attr_char_value.init_offs = 0; + attr_char_value.max_len = NCFGS_SSID_MAX_LEN; + attr_char_value.p_value = &m_ncfgs_data.ssid_from_router.ssid[0]; + + return sd_ble_gatts_characteristic_add(m_database.service_handle, + &char_md, + &attr_char_value, + &m_database.ssid_handles); +} + + +/**@brief Function for adding the Keys Store characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t add_keys_store_characteristic(ble_uuid_t * p_srv_uuid) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t char_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0x00, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + + memset(&attr_md, 0x00, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + attr_md.wr_auth = 1; + attr_md.vloc = BLE_GATTS_VLOC_USER; + + memset(&attr_char_value, 0x00, sizeof(attr_char_value)); + + char_uuid.type = p_srv_uuid->type; + char_uuid.uuid = BLE_UUID_NCFGS_KEYS_STORE_CHAR; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = NCFGS_KEYS_MAX_LEN; + attr_char_value.init_offs = 0; + attr_char_value.max_len = NCFGS_KEYS_MAX_LEN; + attr_char_value.p_value = &m_ncfgs_data.keys_from_router.keys[0]; + + return sd_ble_gatts_characteristic_add(m_database.service_handle, + &char_md, + &attr_char_value, + &m_database.keys_store_handles); +} + + +/**@brief Function for adding the Control Point characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t add_ip_cfg_cp_characteristic(ble_uuid_t * p_srv_uuid) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t char_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0x00, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + + memset(&attr_md, 0x00, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + attr_md.wr_auth = 1; + attr_md.vloc = BLE_GATTS_VLOC_USER; + + memset(&attr_char_value, 0x00, sizeof(attr_char_value)); + + char_uuid.type = p_srv_uuid->type; + char_uuid.uuid = BLE_UUID_NCFGS_CTRLPT_CHAR; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = NCFGS_CTRLP_VALUE_LEN; + attr_char_value.init_offs = 0; + attr_char_value.max_len = NCFGS_CTRLP_VALUE_LEN; + attr_char_value.p_value = &m_ctrlp_value_buffer[0]; + + return sd_ble_gatts_characteristic_add(m_database.service_handle, + &char_md, + &attr_char_value, + &m_database.ctrlp_handles); +} + + +/**@brief Function for creating the GATT database. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t ble_ncfgs_create_database(void) +{ + uint32_t err_code = NRF_SUCCESS; + + // Add service. + ble_uuid_t service_uuid; + + const ble_uuid128_t base_uuid128 = + { + { + 0x73, 0x3E, 0x2D, 0x02, 0xB7, 0x6B, 0xBE, 0xBE, \ + 0xE5, 0x4F, 0x40, 0x8F, 0x00, 0x00, 0x20, 0x54 + } + }; + + service_uuid.uuid = BLE_UUID_NODE_CFG_SERVICE; + + err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, \ + &service_uuid, \ + &m_database.service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = add_ssid_characteristic(&service_uuid); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = add_keys_store_characteristic(&service_uuid); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = add_ip_cfg_cp_characteristic(&service_uuid); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + return err_code; +} + + +uint32_t ble_ncfgs_init(ble_ncfgs_evt_handler_t ble_ncfgs_cb) +{ + NCFGS_ENTRY(); + uint32_t err_code; + memset(&m_ncfgs_data, 0x00, sizeof(m_ncfgs_data)); + + m_app_evt_handler = ble_ncfgs_cb; + + err_code = ble_ncfgs_create_database(); + NCFGS_EXIT(); + return err_code; +} + + +/**@brief Function for decoding the Control Point characteristic value. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t ctrlp_value_decode(const ble_evt_t * p_ble_evt) +{ + uint16_t wr_req_value_len = \ + p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len; + + memcpy(m_ctrlp_value_buffer, \ + p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data, \ + wr_req_value_len); + + m_ncfgs_data.ctrlp_value.opcode = \ + (ble_ncfgs_opcode_t)m_ctrlp_value_buffer[0]; + memcpy((void *)&m_ncfgs_data.ctrlp_value.delay_sec, \ + &m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN], \ + sizeof(uint32_t)); + m_ncfgs_data.ctrlp_value.delay_sec = \ + HTONL(m_ncfgs_data.ctrlp_value.delay_sec); + memcpy((void *)&m_ncfgs_data.ctrlp_value.duration_sec, \ + &m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN+NCFGS_CTRLP_DELAY_LEN], \ + sizeof(uint32_t)); + m_ncfgs_data.ctrlp_value.duration_sec = \ + HTONL(m_ncfgs_data.ctrlp_value.duration_sec); + m_ncfgs_data.ctrlp_value.state_on_failure = \ + (state_on_failure_t)m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN+ \ + NCFGS_CTRLP_DELAY_LEN+ \ + NCFGS_CTRLP_DURATION_LEN]; + + if ((m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_NO_CHANGE) && \ + (m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_PWR_OFF) && \ + (m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_CONFIG_MODE)) + { + return NRF_ERROR_INVALID_DATA; + } + + uint16_t id_data_len = wr_req_value_len - NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN; + if (id_data_len != 0) + { + m_ncfgs_data.id_data.identity_data_len = id_data_len; + + memcpy(m_ncfgs_data.id_data.identity_data, \ + &m_ctrlp_value_buffer[NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN], \ + id_data_len); + } + + return NRF_SUCCESS; +} + + +void ble_ncfgs_ble_evt_handler(const ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + { + if (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == \ + BLE_GATTS_OP_WRITE_REQ) + { + uint16_t wr_req_handle = \ + p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.handle; + uint16_t wr_req_value_len = \ + p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len; + + ble_gatts_rw_authorize_reply_params_t reply_params; + memset(&reply_params, 0x00, sizeof(reply_params)); + + reply_params.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply_params.params.write.update = 1; + reply_params.params.write.offset = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.offset; + reply_params.params.write.len = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len; + reply_params.params.write.p_data = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data; + + if (wr_req_handle == m_database.ssid_handles.value_handle) + { + NCFGS_TRC("> wr_req: ssid_handle"); + + if ((wr_req_value_len > NCFGS_SSID_MAX_LEN) || \ + (wr_req_value_len < NCFGS_SSID_MIN_LEN)) + { + reply_params.params.write.gatt_status = \ + BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + } + else + { + m_ncfgs_data.ssid_from_router.ssid_len = wr_req_value_len; + m_service_state |= NCFGS_STATE_SSID_WRITTEN; + + reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + + UNUSED_RETURN_VALUE( \ + sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle, \ + &reply_params)); + NCFGS_TRC("< wr_req: ssid_handle"); + return; + } + + else if (wr_req_handle == m_database.keys_store_handles.value_handle) + { + NCFGS_TRC("> wr_req: keys_store_handle"); + + if (wr_req_value_len > NCFGS_KEYS_MAX_LEN) + { + reply_params.params.write.gatt_status = \ + BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + } + else + { + m_ncfgs_data.keys_from_router.keys_len = wr_req_value_len; + m_service_state |= NCFGS_STATE_KEYS_STORE_WRITTEN; + reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + + UNUSED_RETURN_VALUE( \ + sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle, \ + &reply_params)); + NCFGS_TRC("< wr_req: keys_store_handle"); + return; + } + + else if (wr_req_handle == m_database.ctrlp_handles.value_handle) + { + NCFGS_TRC("> wr_req: ctrlp_handle"); + + bool notify_app = false; + + if ((wr_req_value_len > NCFGS_CTRLP_VALUE_LEN) || \ + (wr_req_value_len < NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN)) + { + reply_params.params.write.gatt_status = \ + BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + } + else + { + ble_ncfgs_opcode_t opcode_in = (ble_ncfgs_opcode_t) \ + p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data[0]; + + reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + if ((opcode_in != NCFGS_OPCODE_GOTO_JOINING_MODE) && \ + (opcode_in != NCFGS_OPCODE_GOTO_CONFIG_MODE) && \ + (opcode_in != NCFGS_OPCODE_GOTO_IDENTITY_MODE)) + { + reply_params.params.write.gatt_status = APP_GATTERR_UNKNOWN_OPCODE; + } + + if (opcode_in == NCFGS_OPCODE_GOTO_JOINING_MODE) + { + if (!((m_service_state & NCFGS_STATE_SSID_WRITTEN) && \ + (m_service_state & NCFGS_STATE_KEYS_STORE_WRITTEN))) + { + reply_params.params.write.gatt_status = APP_GATTERR_NOT_CONFIGURED; + } + } + + if (reply_params.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + uint32_t err_code = ctrlp_value_decode(p_ble_evt); + if (err_code != NRF_SUCCESS) + { + reply_params.params.write.gatt_status = \ + APP_GATTERR_INVALID_ATTR_VALUE; + } + else + { + notify_app = true; + } + } + } + + UNUSED_RETURN_VALUE(sd_ble_gatts_rw_authorize_reply( + p_ble_evt->evt.gap_evt.conn_handle, + &reply_params)); + + if (notify_app == true) + { + NCFGS_TRC("> do notify parent"); + + m_app_evt_handler(&m_ncfgs_data); + + NCFGS_TRC("< do notify parent"); + } + NCFGS_TRC("< wr_req: ctrlp_handle"); + } + else + { + // Invalid handle. + reply_params.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_HANDLE; + UNUSED_RETURN_VALUE(sd_ble_gatts_rw_authorize_reply( + p_ble_evt->evt.gap_evt.conn_handle, &reply_params)); + } + } + + break; + } + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + { + ble_gap_data_length_params_t dl_params; + + // Clearing the struct will effectively set members to @ref BLE_GAP_DATA_LENGTH_AUTO. + memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t)); + UNUSED_RETURN_VALUE(sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL)); + break; + } + + case BLE_GAP_EVT_PHY_UPDATE_REQUEST: + { + NCFGS_TRC("> PHY update request."); + + ble_gap_phys_t const phys = + { + .rx_phys = BLE_GAP_PHY_AUTO, + .tx_phys = BLE_GAP_PHY_AUTO, + }; + + UNUSED_RETURN_VALUE(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); + + NCFGS_TRC("< PHY update request."); + break; + } + + default: + { + break; + } + } +} + +#endif // COMMISSIONING_ENABLED diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h new file mode 100644 index 0000000..b59495d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_ncfgs Node Configuration Service + * @{ + * @ingroup iot_sdk_common + * @brief Node Configuration Service module. + * + * @details The Node Configuration Service allows configuration of the node during commissioning. + * During initialization it adds the Node Configuration Service and the corresponding + * characteristics to the BLE GATT database. It decodes and checks the received values + * and then passes them to the parent module. + */ + +#ifndef BLE_NODE_CFG_H__ +#define BLE_NODE_CFG_H__ + +#include +#include "ble.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_UUID_NODE_CFG_SERVICE 0x7799 +#define BLE_UUID_NCFGS_SSID_CHAR 0x77A9 +#define BLE_UUID_NCFGS_KEYS_STORE_CHAR 0x77B9 +#define BLE_UUID_NCFGS_CTRLPT_CHAR 0x77C9 + +#define APP_GATTERR_NOT_CONFIGURED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1 /**< ATT Error: Node configuration incomplete. */ +#define APP_GATTERR_UNKNOWN_OPCODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< ATT Error: Unknown opcode. */ +#define APP_GATTERR_INVALID_ATTR_VALUE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 3 /**< ATT Error: Invalid attribute value. */ + +#define NCFGS_SSID_MIN_LEN 6 /**< SSID minimum length. */ +#define NCFGS_SSID_MAX_LEN 16 /**< SSID maximum length. */ +#define NCFGS_KEYS_MAX_LEN 16 /**< Keys maximum length. */ +#define NCFGS_IDENTITY_DATA_MAX_LEN 8 /**< Identity data maximum length. */ + +#define NCFGS_CTRLP_OPCODE_LEN 1 /**< Ctrlp: Opcode value length. */ +#define NCFGS_CTRLP_DELAY_LEN 4 /**< Ctrlp: Length of action delay value. */ +#define NCFGS_CTRLP_DURATION_LEN 4 /**< Ctrlp: Length of next mode duration value. */ +#define NCFGS_CTRLP_STATE_ON_FAILURE_LEN 1 /**< Ctrlp: Length of state-on-failure value. */ + +#define NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN (NCFGS_CTRLP_OPCODE_LEN + \ + NCFGS_CTRLP_DELAY_LEN + \ + NCFGS_CTRLP_DURATION_LEN + \ + NCFGS_CTRLP_STATE_ON_FAILURE_LEN) /**< Ctrlp: Total length of all values except identity data. */ +#define NCFGS_CTRLP_VALUE_LEN (NCFGS_CTRLP_OPCODE_LEN + \ + NCFGS_CTRLP_DELAY_LEN + \ + NCFGS_CTRLP_DURATION_LEN + \ + NCFGS_CTRLP_STATE_ON_FAILURE_LEN + \ + NCFGS_IDENTITY_DATA_MAX_LEN) /**< Ctrlp: Total length of all values. */ + +#define HTONL(val) ((((uint32_t) (val) & 0xff000000) >> 24) | \ + (((uint32_t) (val) & 0x00ff0000) >> 8) | \ + (((uint32_t) (val) & 0x0000ff00) << 8) | \ + (((uint32_t) (val) & 0x000000ff) << 24)) + +/**@brief Node Configuration Service control point opcode values. */ +typedef enum +{ + NCFGS_OPCODE_GOTO_JOINING_MODE = 0x01, + NCFGS_OPCODE_GOTO_CONFIG_MODE = 0x02, + NCFGS_OPCODE_GOTO_IDENTITY_MODE = 0x03 +} ble_ncfgs_opcode_t; + +/**@brief Node Configuration Service configuration states. */ +typedef enum +{ + NCFGS_STATE_IDLE = 0x00, + NCFGS_STATE_SSID_WRITTEN = 0x01, + NCFGS_STATE_KEYS_STORE_WRITTEN = 0x02 +} ble_ncfgs_state_t; + +/**@brief Node Configuration Service state-on-failure values. */ +typedef enum +{ + NCFGS_SOF_NO_CHANGE = 0x00, + NCFGS_SOF_PWR_OFF = 0x01, + NCFGS_SOF_CONFIG_MODE = 0x02 +} state_on_failure_t; + +/**@brief Structure for storing keys received from the peer. */ +typedef struct __attribute__ ((__packed__)) +{ + uint8_t keys_len; + uint8_t keys[NCFGS_KEYS_MAX_LEN]; // Keys received from the router. +} keys_store_t; + +/**@brief Structure for storing the SSID received from the peer. */ +typedef struct __attribute__ ((__packed__)) +{ + uint8_t ssid_len; + uint8_t ssid[NCFGS_SSID_MAX_LEN]; // SSID received from the router. +} ssid_store_t; + +/**@brief Structure for storing the identity data from the peer. */ +typedef struct __attribute__ ((__packed__)) +{ + uint8_t identity_data_len; + uint8_t identity_data[NCFGS_IDENTITY_DATA_MAX_LEN]; // Custom node identifier data. +} id_data_store_t; + +/**@brief Structure for control point value. */ +typedef struct __attribute__ ((__packed__)) +{ + ble_ncfgs_opcode_t opcode; // Mode to start. + uint32_t delay_sec; // Delay before entering >Opcode< mode. + uint32_t duration_sec; // General timeout for >Opcode< mode. + state_on_failure_t state_on_failure; // Mode to enter if >Opcode< mode fails (times out). +} ble_ncfgs_ctrlp_value_t; + +/**@brief Structure for storing Node Configuration Service characteristic values. */ +typedef struct __attribute__ ((__packed__)) +{ + ble_ncfgs_ctrlp_value_t ctrlp_value; + ssid_store_t ssid_from_router; // SSID received from the peer. + keys_store_t keys_from_router; // Keys received from the peer. + id_data_store_t id_data; // Identity data received from the peer. +} ble_ncfgs_data_t; + +/**@brief Function for handling BLE events. + * + * @details This function must be called from the BLE stack event dispatcher + * to handle BLE events that are relevant for the Node Configuration Service module. + * It propagates an event to the parent layer if the Control Point characteristic + * was successfully written. + * + * @param[in] p_ble_evt BLE stack event. + */ +void ble_ncfgs_ble_evt_handler(const ble_evt_t * p_ble_evt); + +/**@brief Node Configuration Service event handler type. */ +typedef void (*ble_ncfgs_evt_handler_t) (ble_ncfgs_data_t * ncfgs_data); + +/**@brief Function for initializing the Node Configuration Service module. + * + * @details Interface for the Commissioning module to create a GATT database to + * allow for node configuration. + * + * @param[in] ble_ncfgs_cb Function to be called in case of an error. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ble_ncfgs_init(ble_ncfgs_evt_handler_t ble_ncfgs_cb); + +#ifdef __cplusplus +} +#endif + +#endif // BLE_NODE_CFG_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c new file mode 100644 index 0000000..4ea6884 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c @@ -0,0 +1,1077 @@ +/** + * Copyright (c) 2015-2017 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifdef COMMISSIONING_ENABLED + +#include +#include "boards.h" +#include "ble_hci.h" +#include "nrf_soc.h" +#include "app_error.h" +#include "fds.h" +#include "ble_advdata.h" +#include "commissioning.h" +#include "nordic_common.h" +#include "ble_srv_common.h" +#include "sdk_config.h" + +#define MINIMUM_ACTION_DELAY 2 /**< Delay before executing an action after the control point was written (in seconds). */ + +#define SEC_PARAM_BOND 0 /**< Perform bonding. */ +#define SEC_PARAM_MITM 1 /**< Man In The Middle protection required (applicable when display module is detected). */ +#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_KEYBOARD_ONLY /**< Display I/O capabilities. */ +#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ +#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ +#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ + +#define COMM_FDS_FILE_ID 0xCAFE /**< The ID of the file that the record belongs to. */ +#define COMM_FDS_RECORD_KEY 0xBEAF /**< The record key of FDS record that keeps node settings. */ + +#define NUMBER_OF_COMMISSIONING_TIMERS 4 +#define TIMER_INDEX_DELAYED_ACTION 0 +#define TIMER_INDEX_CONFIG_MODE 1 +#define TIMER_INDEX_JOINING_MODE 2 +#define TIMER_INDEX_IDENTITY_MODE 3 + +#define SEC_TO_MILLISEC(PARAM) (PARAM * 1000) + +static commissioning_settings_t m_node_settings; /**< All node settings as configured through the Node Configuration Service. */ +static commissioning_evt_handler_t m_commissioning_evt_handler; /**< Commissioning event handler of the parent layer. */ +static bool m_power_off_on_failure = false; /**< Power off on failure setting from the last NCFGS event. */ +static commissioning_timer_t m_commissioning_timers[NUMBER_OF_COMMISSIONING_TIMERS]; + +static ipv6_medium_ble_gap_params_t m_config_mode_gap_params; /**< Advertising parameters in Config mode. */ +static ipv6_medium_ble_adv_params_t m_config_mode_adv_params; /**< GAP parameters in Config mode. */ + +static ipv6_medium_ble_gap_params_t m_joining_mode_gap_params; /**< Advertising parameters in Joining mode. */ +static ipv6_medium_ble_adv_params_t m_joining_mode_adv_params; /**< GAP parameters in Joining mode. */ + +static ble_uuid_t m_config_mode_adv_uuids[] = \ + { + {BLE_UUID_NODE_CFG_SERVICE, \ + BLE_UUID_TYPE_VENDOR_BEGIN} + }; /**< Config mode: List of available service UUIDs in advertisement data. */ + +static ble_uuid_t m_joining_mode_adv_uuids[] = \ + { + {BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE} + }; /**< Joining mode: List of available service UUIDs in advertisement data. */ + +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the active connection. */ +static uint8_t m_current_mode = NODE_MODE_NONE; /**< Current mode value. */ +static uint8_t m_next_mode = NODE_MODE_NONE; /**< Value of the mode the node will enter when the timeout handler of m_delayed_action_timer is triggered. */ + +#if (FDS_ENABLED == 1) +static fds_record_desc_t m_fds_record_desc; /**< Descriptor of FDS record. */ +#endif + +#define COMM_ENABLE_LOGS 1 /**< Set to 0 to disable debug trace in the module. */ + +#if COMMISSIONING_CONFIG_LOG_ENABLED + +#define NRF_LOG_MODULE_NAME commissioning + +#define NRF_LOG_LEVEL COMMISSIONING_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR COMMISSIONING_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR COMMISSIONING_CONFIG_DEBUG_COLOR + +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +#define COMM_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */ +#define COMM_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */ +#define COMM_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */ + +#define COMM_ENTRY() COMM_TRC(">> %s", __func__) +#define COMM_EXIT() COMM_TRC("<< %s", __func__) + +#else // COMMISSIONING_CONFIG_LOG_ENABLED + +#define COMM_TRC(...) /**< Disables traces. */ +#define COMM_DUMP(...) /**< Disables dumping of octet streams. */ +#define COMM_ERR(...) /**< Disables error logs. */ + +#define COMM_ENTRY(...) +#define COMM_EXIT(...) + +#endif // COMMISSIONING_CONFIG_LOG_ENABLED + + +/**@brief Function for validating all node settings. + */ +static bool settings_are_valid() +{ + uint8_t tmp = m_node_settings.poweron_mode; + if (tmp == 0xFF) + { + return false; + } + else + { + return true; + } +} + +#if (FDS_ENABLED == 1) +/**@brief Function for updating the node settings in persistent memory. + */ +static uint32_t persistent_settings_update(void) +{ + uint32_t err_code; + + fds_find_token_t token; + memset(&token, 0, sizeof(token)); + + fds_record_t record; + memset(&record, 0, sizeof(record)); + + record.file_id = COMM_FDS_FILE_ID; + record.key = COMM_FDS_RECORD_KEY; + record.data.p_data = &m_node_settings; + record.data.length_words = ALIGN_NUM(4, sizeof(commissioning_settings_t))/sizeof(uint32_t); + + // Try to find FDS record with node settings. + err_code = fds_record_find(COMM_FDS_FILE_ID, COMM_FDS_RECORD_KEY, &m_fds_record_desc, &token); + if (err_code == FDS_SUCCESS) + { + err_code = fds_record_update(&m_fds_record_desc, &record); + } + else + { + + err_code = fds_record_write(&m_fds_record_desc, &record); + } + + if (err_code == FDS_ERR_NO_SPACE_IN_FLASH) + { + // Run garbage collector to reclaim the flash space that is occupied by records that have been deleted, + // or that failed to be completely written due to, for example, a power loss. + err_code = fds_gc(); + } + + return err_code; +} + + +/**@brief Function for loading node settings from the persistent memory. + */ +static void persistent_settings_load(void) +{ + uint32_t err_code = FDS_SUCCESS; + fds_flash_record_t record; + + fds_find_token_t token; + memset(&token, 0, sizeof(token)); + + // Try to find FDS record with node settings. + err_code = fds_record_find(COMM_FDS_FILE_ID, COMM_FDS_RECORD_KEY, &m_fds_record_desc, &token); + if (err_code == FDS_SUCCESS) + { + err_code = fds_record_open(&m_fds_record_desc, &record); + if (err_code == FDS_SUCCESS) + { + if (record.p_data) + { + memcpy(&m_node_settings, record.p_data, sizeof(m_node_settings)); + } + } + } +} + + +/**@brief Function for clearing node settings from the persistent memory. + */ +static void persistent_settings_clear(void) +{ + fds_record_delete(&m_fds_record_desc); +} + +/**@brief Function for handling File Data Storage events. + */ +static void persistent_settings_cb(fds_evt_t const * p_evt) +{ + if (p_evt->id == FDS_EVT_GC) + { + if (settings_are_valid()) + { + persistent_settings_update(); + } + } +} + + +/**@brief Function for initializing the File Data Storage module. + */ +static uint32_t persistent_settings_init(void) +{ + uint32_t err_code; + + err_code = fds_init(); + if (err_code == FDS_SUCCESS) + { + err_code = fds_register(persistent_settings_cb); + } + + return err_code; +} +#endif + + +/**@brief Function for setting advertisement parameters in Config mode. + */ +static void config_mode_adv_params_set(void) +{ + COMM_ENTRY(); + memset(&m_config_mode_adv_params, 0x00, sizeof(m_config_mode_adv_params)); + + m_config_mode_adv_params.advdata.name_type = BLE_ADVDATA_FULL_NAME; + m_config_mode_adv_params.advdata.include_appearance = false; + m_config_mode_adv_params.advdata.flags = \ + BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + m_config_mode_adv_params.advdata.uuids_complete.uuid_cnt = \ + sizeof(m_config_mode_adv_uuids) / sizeof(m_config_mode_adv_uuids[0]); + m_config_mode_adv_params.advdata.uuids_complete.p_uuids = m_config_mode_adv_uuids; + m_config_mode_adv_params.advdata.p_manuf_specific_data = NULL; + + if (m_node_settings.id_data_store.identity_data_len > 0) + { + m_config_mode_adv_params.sr_man_specific_data.data.size = \ + m_node_settings.id_data_store.identity_data_len; + m_config_mode_adv_params.sr_man_specific_data.data.p_data = \ + m_node_settings.id_data_store.identity_data; + m_config_mode_adv_params.sr_man_specific_data.company_identifier = \ + COMPANY_IDENTIFIER; + m_config_mode_adv_params.srdata.p_manuf_specific_data = \ + &m_config_mode_adv_params.sr_man_specific_data; + } + else + { + m_config_mode_adv_params.srdata.p_manuf_specific_data = NULL; + } + + m_config_mode_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; + m_config_mode_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement. + m_config_mode_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY; + m_config_mode_adv_params.advparams.interval = CONFIG_MODE_ADV_ADV_INTERVAL; + m_config_mode_adv_params.advparams.duration = CONFIG_MODE_ADV_TIMEOUT; + + COMM_EXIT(); +} + + +/**@brief Function for setting GAP parameters in Config mode. + */ +static void config_mode_gap_params_set(void) +{ + COMM_ENTRY(); + + memset(&m_config_mode_gap_params, 0x00, sizeof(m_config_mode_gap_params)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_config_mode_gap_params.sec_mode); + + m_config_mode_gap_params.p_dev_name = (const uint8_t *)CONFIG_MODE_DEVICE_NAME; + m_config_mode_gap_params.dev_name_len = strlen(CONFIG_MODE_DEVICE_NAME); + + m_config_mode_gap_params.gap_conn_params.min_conn_interval = \ + (uint16_t)CONFIG_MODE_MIN_CONN_INTERVAL; + m_config_mode_gap_params.gap_conn_params.max_conn_interval = \ + (uint16_t)CONFIG_MODE_MAX_CONN_INTERVAL; + m_config_mode_gap_params.gap_conn_params.slave_latency = CONFIG_MODE_SLAVE_LATENCY; + m_config_mode_gap_params.gap_conn_params.conn_sup_timeout = CONFIG_MODE_CONN_SUP_TIMEOUT; + + COMM_EXIT(); +} + + +/**@brief Function for setting advertisement parameters in Joining mode. + */ +static void joining_mode_adv_params_set(void) +{ + COMM_ENTRY(); + + memset(&m_joining_mode_adv_params, 0x00, sizeof(m_joining_mode_adv_params)); + + if (m_node_settings.ssid_store.ssid_len > 0) + { + m_joining_mode_adv_params.adv_man_specific_data.data.size = \ + m_node_settings.ssid_store.ssid_len; + m_joining_mode_adv_params.adv_man_specific_data.data.p_data = \ + m_node_settings.ssid_store.ssid; + m_joining_mode_adv_params.adv_man_specific_data.company_identifier = \ + COMPANY_IDENTIFIER; + } + + m_joining_mode_adv_params.advdata.name_type = BLE_ADVDATA_NO_NAME; + m_joining_mode_adv_params.advdata.include_appearance = false; + m_joining_mode_adv_params.advdata.flags = \ + BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + m_joining_mode_adv_params.advdata.uuids_complete.uuid_cnt = \ + sizeof(m_joining_mode_adv_uuids) / sizeof(m_joining_mode_adv_uuids[0]); + m_joining_mode_adv_params.advdata.uuids_complete.p_uuids = m_joining_mode_adv_uuids; + if (m_node_settings.ssid_store.ssid_len > 0) + { + m_joining_mode_adv_params.advdata.p_manuf_specific_data = \ + &m_joining_mode_adv_params.adv_man_specific_data; + } + else + { + m_joining_mode_adv_params.advdata.p_manuf_specific_data = NULL; + } + + if (m_node_settings.id_data_store.identity_data_len > 0) + { + m_joining_mode_adv_params.sr_man_specific_data.data.size = \ + m_node_settings.id_data_store.identity_data_len; + m_joining_mode_adv_params.sr_man_specific_data.data.p_data = \ + m_node_settings.id_data_store.identity_data; + m_joining_mode_adv_params.sr_man_specific_data.company_identifier = \ + COMPANY_IDENTIFIER; + m_joining_mode_adv_params.srdata.p_manuf_specific_data = \ + &m_joining_mode_adv_params.sr_man_specific_data; + } + else + { + m_joining_mode_adv_params.srdata.p_manuf_specific_data = NULL; + } + + m_joining_mode_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; + m_joining_mode_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement. + m_joining_mode_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY; + m_joining_mode_adv_params.advparams.interval = APP_ADV_ADV_INTERVAL; + m_joining_mode_adv_params.advparams.duration = APP_ADV_DURATION; + + COMM_EXIT(); +} + + +/**@brief Function for setting GAP parameters in Joining mode. + */ +static void joining_mode_gap_params_set(void) +{ + COMM_ENTRY(); + + memset(&m_joining_mode_gap_params, 0x00, sizeof(m_joining_mode_gap_params)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_joining_mode_gap_params.sec_mode); + + m_joining_mode_gap_params.appearance = BLE_APPEARANCE_UNKNOWN; + + m_joining_mode_gap_params.p_dev_name = (const uint8_t *)DEVICE_NAME; + m_joining_mode_gap_params.dev_name_len = strlen(DEVICE_NAME); + + m_joining_mode_gap_params.gap_conn_params.min_conn_interval = \ + (uint16_t)JOINING_MODE_MIN_CONN_INTERVAL; + m_joining_mode_gap_params.gap_conn_params.max_conn_interval = \ + (uint16_t)JOINING_MODE_MAX_CONN_INTERVAL; + m_joining_mode_gap_params.gap_conn_params.slave_latency = JOINING_MODE_SLAVE_LATENCY; + m_joining_mode_gap_params.gap_conn_params.conn_sup_timeout = JOINING_MODE_CONN_SUP_TIMEOUT; + + COMM_EXIT(); +} + + +/**@brief Function for starting a timer in the Commissioning module. + * + */ +static void commissioning_timer_start(uint8_t index, uint32_t timeout_sec) +{ + m_commissioning_timers[index].is_timer_running = true; + m_commissioning_timers[index].current_value_sec = timeout_sec; +} + + +/**@brief Function for stopping and re-setting a timer in the Commissioning module. + * + */ +static void commissioning_timer_stop_reset(uint8_t index) +{ + m_commissioning_timers[index].is_timer_running = false; + m_commissioning_timers[index].current_value_sec = 0x00; +} + + +void commissioning_node_mode_change(uint8_t new_mode) +{ + COMM_ENTRY(); + + commissioning_evt_t commissioning_evt; + memset(&commissioning_evt, 0x00, sizeof(commissioning_evt)); + commissioning_evt.p_commissioning_settings = &m_node_settings; + commissioning_evt.power_off_enable_requested = m_power_off_on_failure; + + commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION); + commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE); + commissioning_timer_stop_reset(TIMER_INDEX_JOINING_MODE); + + config_mode_gap_params_set(); + config_mode_adv_params_set(); + joining_mode_gap_params_set(); + joining_mode_adv_params_set(); + + m_current_mode = new_mode; + + switch (m_current_mode) + { + case NODE_MODE_CONFIG: + { + commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_CONFIG_MODE_ENTER; + m_commissioning_evt_handler(&commissioning_evt); + + // Start Configuration mode timer. + COMM_TRC("Config mode timeout: %ld seconds", m_node_settings.config_mode_to); + commissioning_timer_start(TIMER_INDEX_CONFIG_MODE, m_node_settings.config_mode_to); + + break; + } + case NODE_MODE_JOINING: + { + commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_JOINING_MODE_ENTER; + m_commissioning_evt_handler(&commissioning_evt); + + // Start Joining mode timer. + COMM_TRC("Joining mode timeout: %ld seconds", m_node_settings.joining_mode_to); + commissioning_timer_start(TIMER_INDEX_JOINING_MODE, m_node_settings.joining_mode_to); + + break; + } + case NODE_MODE_IDENTITY: + { + commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_IDENTITY_MODE_ENTER; + m_commissioning_evt_handler(&commissioning_evt); + + // Start Identity mode timer. + COMM_TRC("Identity mode timeout: %ld seconds", m_node_settings.id_mode_to); + commissioning_timer_start(TIMER_INDEX_IDENTITY_MODE, m_node_settings.id_mode_to); + + break; + } + default: + { + break; + } + } + + COMM_EXIT(); +} + + +/**@brief Function for handling the Delayed action timer timeout. + * + * @details This function will be called each time the delayed action timer expires. + * + */ +static void action_timeout_handler(void) +{ + COMM_ENTRY(); + + commissioning_node_mode_change(m_next_mode); + + COMM_EXIT(); +} + + +/**@brief Function for handling the Config mode timer timeout. + * + * @details This function will be called each time the Config mode timer expires. + * + */ +static void config_mode_timeout_handler(void) +{ + COMM_ENTRY(); + + switch (m_node_settings.config_mode_failure) + { + case NCFGS_SOF_NO_CHANGE: + // Fall-through. + case NCFGS_SOF_CONFIG_MODE: + { + commissioning_node_mode_change(NODE_MODE_CONFIG); + + break; + } + case NCFGS_SOF_PWR_OFF: + { + LEDS_OFF(LEDS_MASK); + // The main timer in Config mode timed out, power off. + UNUSED_VARIABLE(sd_power_system_off()); + + break; + } + } + + COMM_EXIT(); +} + + +/**@brief Function for handling the Joining mode timer timeout. + * + * @details This function will be called each time the Joining mode timer expires. + * + */ +void joining_mode_timeout_handler(void) +{ + COMM_ENTRY(); + + switch (m_node_settings.joining_mode_failure) + { + case NCFGS_SOF_NO_CHANGE: + { + commissioning_node_mode_change(NODE_MODE_JOINING); + break; + } + case NCFGS_SOF_PWR_OFF: + { + LEDS_OFF(LEDS_MASK); + + UNUSED_VARIABLE(sd_power_system_off()); + break; + } + case NCFGS_SOF_CONFIG_MODE: + { + commissioning_node_mode_change(NODE_MODE_CONFIG); + break; + } + } + + COMM_EXIT(); +} + + +/**@brief Function for handling the Identity mode timer timeout. + * + * @details This function will be called each time the Identity mode timer expires. + * + */ +void identity_mode_timeout_handler(void) +{ + COMM_ENTRY(); + + commissioning_evt_t commissioning_evt; + memset(&commissioning_evt, 0x00, sizeof(commissioning_evt)); + commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_IDENTITY_MODE_EXIT; + + m_commissioning_evt_handler(&commissioning_evt); + + COMM_EXIT(); +} + + +void commissioning_joining_mode_timer_ctrl( \ + joining_mode_timer_ctrl_cmd_t joining_mode_timer_ctrl_cmd) +{ + switch (joining_mode_timer_ctrl_cmd) + { + case JOINING_MODE_TIMER_STOP_RESET: + { + commissioning_timer_stop_reset(TIMER_INDEX_JOINING_MODE); + + break; + } + case JOINING_MODE_TIMER_START: + { + commissioning_timer_start(TIMER_INDEX_JOINING_MODE, m_node_settings.joining_mode_to); + + break; + } + } +} + + +void commissioning_gap_params_get(ipv6_medium_ble_gap_params_t ** pp_node_gap_params) +{ + switch (m_current_mode) + { + case NODE_MODE_JOINING: + { + *pp_node_gap_params = &m_joining_mode_gap_params; + + break; + } + case NODE_MODE_IDENTITY: + // Fall-through. + case NODE_MODE_CONFIG: + { + *pp_node_gap_params = &m_config_mode_gap_params; + + break; + } + } +} + + +void commissioning_adv_params_get(ipv6_medium_ble_adv_params_t ** pp_node_adv_params) +{ + switch (m_current_mode) + { + case NODE_MODE_JOINING: + { + *pp_node_adv_params = &m_joining_mode_adv_params; + + break; + } + case NODE_MODE_IDENTITY: + // Fall-through. + case NODE_MODE_CONFIG: + { + *pp_node_adv_params = &m_config_mode_adv_params; + + break; + } + } +} + + +/**@brief Function for reading all node settings from the persistent storage. + */ +static void read_node_settings(void) +{ + memset(&m_node_settings, 0x00, sizeof(m_node_settings)); + +#if (FDS_ENABLED == 1) + persistent_settings_load(); +#endif // FDS_ENABLED + + if (m_node_settings.ssid_store.ssid_len > NCFGS_SSID_MAX_LEN) + { + m_node_settings.ssid_store.ssid_len = 0; + } + if (m_node_settings.keys_store.keys_len > NCFGS_KEYS_MAX_LEN) + { + m_node_settings.keys_store.keys_len = 0; + } + if (m_node_settings.id_data_store.identity_data_len > NCFGS_IDENTITY_DATA_MAX_LEN) + { + m_node_settings.id_data_store.identity_data_len = 0; + } + + // The duration of each mode needs to be at least 10 second. + m_node_settings.joining_mode_to = \ + (m_node_settings.joining_mode_to < 10) ? 10 : m_node_settings.joining_mode_to; + m_node_settings.config_mode_to = \ + (m_node_settings.config_mode_to < 10) ? 10 : m_node_settings.config_mode_to; + m_node_settings.id_mode_to = \ + (m_node_settings.id_mode_to < 10) ? 10 : m_node_settings.id_mode_to; +} + +#if (COMM_ENABLE_LOGS == 1) +/**@brief Function for printing all node settings. + */ +static void print_node_settings(void) +{ + COMM_TRC(""); + COMM_TRC(" Commissioning settings in memory:"); + COMM_TRC(" Start mode: %5d", m_node_settings.poweron_mode); + COMM_TRC(" Mode if Joining Mode fails: %5d", m_node_settings.joining_mode_failure); + COMM_TRC(" General timeout in Joining Mode: %5ld", m_node_settings.joining_mode_to); + COMM_TRC(" Mode if Configuration Mode fails: %5d", m_node_settings.config_mode_failure); + COMM_TRC("General timeout in Configuration Mode: %5ld", m_node_settings.config_mode_to); + COMM_TRC(" Identity Mode duration: %5ld", m_node_settings.id_mode_to); + COMM_TRC(" Stored Keys length: %5d", m_node_settings.keys_store.keys_len); + COMM_TRC(" Stored Keys:"); + uint8_t ii; + for (ii=0; iiheader.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + { + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION); + commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE); + + break; + } + case BLE_GAP_EVT_DISCONNECTED: + { + m_conn_handle = BLE_CONN_HANDLE_INVALID; + if (m_current_mode == NODE_MODE_CONFIG) + { + commissioning_timer_start(TIMER_INDEX_CONFIG_MODE, \ + m_node_settings.config_mode_to); + } + if (m_current_mode == NODE_MODE_JOINING) + { + commissioning_timer_start(TIMER_INDEX_JOINING_MODE, \ + m_node_settings.joining_mode_to); + } + + break; + } + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + { + if (m_current_mode == NODE_MODE_JOINING) + { + // If passkey is shorter than BLE_GAP_PASSKEY_LEN, add '0' character. + if (m_node_settings.keys_store.keys_len < BLE_GAP_PASSKEY_LEN) + { + memset(&m_node_settings.keys_store.keys[m_node_settings.keys_store.keys_len], \ + '0', BLE_GAP_PASSKEY_LEN - m_node_settings.keys_store.keys_len); + } + + // Short passkey to 6-length character. + m_node_settings.keys_store.keys[BLE_GAP_PASSKEY_LEN] = 0; + + COMM_TRC("Stored passkey is: %s", m_node_settings.keys_store.keys); + + err_code = sd_ble_gap_auth_key_reply(m_conn_handle, \ + BLE_GAP_AUTH_KEY_TYPE_PASSKEY, \ + m_node_settings.keys_store.keys); + APP_ERROR_CHECK(err_code); + } + + break; + } + case BLE_GAP_EVT_AUTH_STATUS: + { + if (m_current_mode == NODE_MODE_JOINING) + { + COMM_TRC("Status of authentication: %08x", \ + p_ble_evt->evt.gap_evt.params.auth_status.auth_status); + } + + break; + } + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + { + if (m_current_mode == NODE_MODE_JOINING) + { + ble_gap_sec_params_t sec_param; + ble_gap_sec_keyset_t keys_exchanged; + + memset(&sec_param, 0, sizeof(ble_gap_sec_params_t)); + memset(&keys_exchanged, 0, sizeof(ble_gap_sec_keyset_t)); + + sec_param.bond = SEC_PARAM_BOND; + sec_param.oob = SEC_PARAM_OOB; + sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; + sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; + sec_param.mitm = SEC_PARAM_MITM; + sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; + + err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_SEC_STATUS_SUCCESS, + &sec_param, + &keys_exchanged); + APP_ERROR_CHECK(err_code); + } + + break; + } + default: + { + break; + } + } +} + + +void on_ble_ncfgs_evt(ble_ncfgs_data_t * ncfgs_data) +{ + COMM_ENTRY(); + + commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION); + commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE); + + uint32_t mode_duration_sec; + mode_duration_sec = ncfgs_data->ctrlp_value.duration_sec; + mode_duration_sec = (mode_duration_sec == 0) ? 1 : mode_duration_sec; + + switch (ncfgs_data->ctrlp_value.opcode) + { + case NCFGS_OPCODE_GOTO_JOINING_MODE: + { + m_next_mode = NODE_MODE_JOINING; + + m_node_settings.joining_mode_to = mode_duration_sec; + m_node_settings.joining_mode_failure = ncfgs_data->ctrlp_value.state_on_failure; + + /* This code will get executed in two scenarios: + - if the previous mode was Config mode and now we are ready to connect to the router, or + - if the previous mode was Joining mode and the state on failure was set to No Change. + */ + if (m_node_settings.joining_mode_failure == NCFGS_SOF_NO_CHANGE) + { + m_node_settings.poweron_mode = NODE_MODE_JOINING; + } + else + { + // If the state on failure is NOT No Change, start next time in Config mode. + m_node_settings.poweron_mode = NODE_MODE_CONFIG; + } + + if (m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF) + { + COMM_TRC("Will power off on failure."); + m_power_off_on_failure = true; // The assert handler will power off the system. + } + + break; + } + case NCFGS_OPCODE_GOTO_CONFIG_MODE: + { + m_next_mode = NODE_MODE_CONFIG; + + m_node_settings.config_mode_to = mode_duration_sec; + m_node_settings.config_mode_failure = ncfgs_data->ctrlp_value.state_on_failure; + + /* The node is about to enter Config mode. Regardless of what the state on failure + setting is (No Change or Pwr Off or Cfg Mode), the poweron_mode value should be Cfg Mode. */ + m_node_settings.poweron_mode = NODE_MODE_CONFIG; + + if (m_node_settings.config_mode_failure == NCFGS_SOF_PWR_OFF) + { + COMM_TRC("Will power off on failure."); + m_power_off_on_failure = true; // The assert handler will power off the system. + } + + break; + } + case NCFGS_OPCODE_GOTO_IDENTITY_MODE: + { + m_next_mode = NODE_MODE_IDENTITY; + + m_node_settings.id_mode_to = mode_duration_sec; + + break; + } + default: + { + break; + } + } + + memcpy(&m_node_settings.ssid_store, &ncfgs_data->ssid_from_router, sizeof(ssid_store_t)); + memcpy(&m_node_settings.keys_store, &ncfgs_data->keys_from_router, sizeof(keys_store_t)); + memcpy(&m_node_settings.id_data_store, &ncfgs_data->id_data, sizeof(id_data_store_t)); + +#if (COMM_ENABLE_LOGS == 1) + print_node_settings(); +#endif // (COMM_ENABLE_LOGS == 1) + +#if (FDS_ENABLED == 1) + uint32_t err_code = persistent_settings_update(); + APP_ERROR_CHECK(err_code); +#endif // FDS_ENABLED + + uint32_t action_delay_written = ncfgs_data->ctrlp_value.delay_sec; + // Set the timeout value to at least MINIMUM_ACTION_DELAY second(s). + // This is to make sure that storing settings in the persistent + // storage completes before activating the next mode. + action_delay_written = (action_delay_written < MINIMUM_ACTION_DELAY) ? \ + MINIMUM_ACTION_DELAY : action_delay_written; + + COMM_TRC("Action delay: %ld seconds.", action_delay_written); + commissioning_timer_start(TIMER_INDEX_DELAYED_ACTION, action_delay_written); + + COMM_EXIT(); +} + + +void commissioning_time_tick(iot_timer_time_in_ms_t wall_clock_value) +{ + UNUSED_PARAMETER(wall_clock_value); + uint8_t index; + + for (index=0; indexcommissioning_evt_handler; + m_power_off_on_failure = false; + + // Initialize Commissioning timers. + + commissioning_timers_init(); + + // Initialize GATT server. + + err_code = ble_ncfgs_init(on_ble_ncfgs_evt); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + +#if (FDS_ENABLED == 1) + err_code = persistent_settings_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } +#endif + + // Read application settings from persistent storage. + read_node_settings(); + +#if (COMM_ENABLE_LOGS == 1) + print_node_settings(); +#endif // (COMM_ENABLE_LOGS == 1) + + if (!settings_are_valid()) // If the settings are invalid for any reason go to Config mode. + { + COMM_ERR("Invalid settings!"); + + commissioning_settings_clear(); + + memset(&m_node_settings, 0x00, sizeof(m_node_settings)); + m_node_settings.config_mode_to = 300; + + *p_poweron_state = NODE_MODE_CONFIG; + } + else + { + if (m_node_settings.poweron_mode == NODE_MODE_JOINING) + { + /* This code will get executed in two scenarios: + - if the previous mode was Config mode and now we are ready to connect to the router, or + - if the previous mode was Joining mode and the state on failure was set to No Change. + */ + if ((m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF) || \ + (m_node_settings.joining_mode_failure == NCFGS_SOF_CONFIG_MODE)) + { + // If the state on failure is NOT No Change, start next time in Config mode. + m_node_settings.poweron_mode = NODE_MODE_CONFIG; +#if (FDS_ENABLED == 1) + err_code = persistent_settings_update(); + APP_ERROR_CHECK(err_code); +#endif // FDS_ENABLED + } + + if (m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF) + { + COMM_TRC("Will power off on failure."); + m_power_off_on_failure = true; // The assert handler will power off the system. + } + + *p_poweron_state = NODE_MODE_JOINING; + } + else + { + /* The app is about to enter Config mode. Regardless of what the state on failure + setting is (No Change or Pwr Off or Cfg Mode), the poweron_mode value should remain the same. */ + + if (m_node_settings.config_mode_failure == NCFGS_SOF_PWR_OFF) + { + COMM_TRC("Will power off on failure."); + m_power_off_on_failure = true; // The assert handler will power off the system. + } + + *p_poweron_state = NODE_MODE_CONFIG; + } + } + + // Set advertising and GAP parameters. + config_mode_gap_params_set(); + config_mode_adv_params_set(); + joining_mode_gap_params_set(); + joining_mode_adv_params_set(); + + COMM_EXIT(); + return err_code; +} + +#endif // COMMISSIONING_ENABLED diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h new file mode 100644 index 0000000..777f60e --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2015-2017 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup commissioning_module Commissioning Module + * @{ + * @ingroup iot_sdk_common + * @brief Commissioning module. + * + * @details Enables commissioning of the node by managing transitions between the Config, Joining, and + * Identity modes. In Config mode the node can be configured with the settings required to + * join the network in Joining mode. The Identity mode can be requested to make the node + * easily recognizable for the user. + * The settings managed by the module are stored in persistent storage. + */ + +#ifndef COMMISSIONING_H__ +#define COMMISSIONING_H__ + +#include +#include +#include "ble_ncfgs.h" +#include "iot_timer.h" +#include "ipv6_medium_ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define COMMISSIONING_TICK_INTERVAL_SEC 1 /**< Interval between periodic callbacks to the Commissioning module. */ + +#define COMMISSIONING_EVT_CONFIG_MODE_ENTER 0x01 /**< Indicates that the medium entered mode for commissioning configuration. */ +#define COMMISSIONING_EVT_JOINING_MODE_ENTER 0x02 /**< Indicates that the medium exited mode for commissioning configuration. */ +#define COMMISSIONING_EVT_IDENTITY_MODE_ENTER 0x03 /**< Indicates that identity mode was requested. */ +#define COMMISSIONING_EVT_IDENTITY_MODE_EXIT 0x04 /**< Indicates that the node should stop using any features associated with the Identity mode. */ + +#define NODE_MODE_NONE 0x00 /**< Node mode: before initialization. */ +#define NODE_MODE_JOINING 0x01 /**< Node mode: joining the network. */ +#define NODE_MODE_CONFIG 0x02 /**< Node mode: configuration. */ +#define NODE_MODE_IDENTITY 0x03 /**< Node mode: conspicuous for the user. */ + +/**@brief Joining mode timer control commands. */ +typedef enum +{ + JOINING_MODE_TIMER_START = 0x01, + JOINING_MODE_TIMER_STOP_RESET = 0x02 +} joining_mode_timer_ctrl_cmd_t; + +/**@brief Structure for storing all settings necessary for commissioning. */ +typedef struct __attribute__ ((__packed__)) __attribute__((aligned)) +{ + uint8_t poweron_mode; // Checked at startup to enter correct mode. + state_on_failure_t joining_mode_failure; // Mode to enter if Joining mode fails. + uint32_t joining_mode_to; // General timeout in Joining mode. + state_on_failure_t config_mode_failure; // Mode to enter if Config mode fails. + uint32_t config_mode_to; // General timeout in Config mode. + uint32_t id_mode_to; // Duration of Identity Mode. + ssid_store_t ssid_store; // SSID received from the router. + keys_store_t keys_store; // Keys received from the router. + id_data_store_t id_data_store; // Custom node identifier data. +} commissioning_settings_t; + +/**@brief Commissioning module event handler type. */ +typedef void (*commissioning_timeout_handler_t)(void); + +/**@brief Structure for creating timers in the Commissioning module. */ +typedef struct +{ + bool is_timer_running; + uint32_t current_value_sec; + commissioning_timeout_handler_t timeout_handler; +} commissioning_timer_t; + +/**@brief Structure of events passed by the Commissioning module to the parent layer. */ +typedef struct +{ + uint8_t commissioning_evt_id; + bool power_off_enable_requested; + commissioning_settings_t * p_commissioning_settings; +} commissioning_evt_t; + +/**@brief Function for handling BLE events. + * + * @details This function must be called from the BLE stack event dispatcher + * to handle BLE events that are relevant for the Commissioning module. + * + * @param[in] p_ble_evt BLE stack event. + */ +void commissioning_ble_evt_handler(const ble_evt_t * p_ble_evt); + +/**@brief Commissioning module event handler type. */ +typedef void (*commissioning_evt_handler_t)(commissioning_evt_t * p_commissioning_evt); + +/**@brief Structure for initialization parameters of the Commissioning module. */ +typedef struct +{ + commissioning_evt_handler_t commissioning_evt_handler; +} commissioning_init_params_t; + +/**@brief Function for initializing the Commissioning module. + * + * @details Initializes the Node Configuration Service module to create the GATT database. + * Loads previously stored node settings from the persistent storage and if + * the settings are valid, sets up the node to start in the right mode. + * + * @param[in] p_init_param Pointer to the initialization parameters. + * @param[out] p_poweron_state Pointer to the value of the mode that should be started. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t commissioning_init(commissioning_init_params_t * p_init_param, + uint8_t * p_poweron_state); + +/**@brief Function for advancing the node to a new mode. + * + * @details Stops and starts app timers appropriate for the mode requested. + * Propagates the mode change event to the parent layer. + * + * @param[in] new_mode New mode to start. + * + */ +void commissioning_node_mode_change(uint8_t new_mode); + +/**@brief Function for getting the address of GAP parameters for the active mode. + * + * @param[out] pp_node_gap_params Address of GAP parameters for the active mode. + * + */ +void commissioning_gap_params_get(ipv6_medium_ble_gap_params_t ** pp_node_gap_params); + +/**@brief Function for getting the address of advertising parameters for the active mode. + * + * @param[out] pp_node_adv_params Address of advertising parameters for the active mode. + * + */ +void commissioning_adv_params_get(ipv6_medium_ble_adv_params_t ** pp_node_adv_params); + +/**@brief Function for clearing all node settings from the persistent storage. + * + * @details Calls the appropriate persistent storage interface function to clear + * all commissioning-related settings from the persistent storage. + * + */ +void commissioning_settings_clear(void); + +/**@brief Function for controlling the joining mode timer from the parent layer(s). + * + * @details If the Joining mode timer reaches zero, the node must enter the + * state-on-failure, as set by the user. This function allows the + * application designer to control the Joining mode timer from the + * application layer. + */ +void commissioning_joining_mode_timer_ctrl( + joining_mode_timer_ctrl_cmd_t joining_mode_timer_ctrl_cmd); + +/**@brief Commissioning time tick used for measuring delays and time between events. + * + * @param[in] wall_clock_value Wall clock value from the IoT Timer module. + */ +void commissioning_time_tick(iot_timer_time_in_ms_t wall_clock_value); + +#ifdef __cplusplus +} +#endif + +#endif // COMMISSIONING_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h new file mode 100644 index 0000000..064737d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ipv6_medium IPv6 Medium + * @{ + * @ingroup iot_sdk_common + * @brief IPv6 Medium Interface. + * + * @details Implementation-agnostic interface of the physical transport that + * facilitates IPv6 traffic. + */ + +#ifndef IPV6_MEDIUM_H__ +#define IPV6_MEDIUM_H__ + +#include +#include +#include "ipv6_medium_platform.h" +#include "iot_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EUI_48_SIZE 6 /**< Size of a 48-bit Extended Unique Identifier in bytes. */ + +#define IPV6_MEDIUM_ID_ANY 0x00 /**< Indicates invalid physical transport type. */ +#define IPV6_MEDIUM_ID_BLE 0x01 /**< Indicates that the physical transport is BLE. */ +#define IPV6_MEDIUM_ID_802154 0x02 /**< Indicates that the physical transport is 802.15.4. */ + +#define IPV6_MEDIUM_EVT_CONN_DOWN 0x01 /**< Indicates that a connection is established. */ +#define IPV6_MEDIUM_EVT_CONN_UP 0x02 /**< Indicates that a connection is torn down. */ +#define IPV6_MEDIUM_EVT_CONNECTABLE_MODE_ENTER 0x01 /**< Indicates that the medium entered connectable mode. */ +#define IPV6_MEDIUM_EVT_CONNECTABLE_MODE_EXIT 0x02 /**< Indicates that the medium exited connectable mode. */ +#define IPV6_MEDIUM_EVT_MAC_ADDRESS_CHANGED 0x03 /**< Indicates that the device has a new MAC address. */ +#define IPV6_MEDIUM_EVT_PHY_SPECIFIC 0xFF /**< Indicates miscellaneous event from the physical layer. */ + +/**@brief IPv6 medium instance identifier type. */ +typedef uint32_t ipv6_medium_instance_id_t; + +/**@brief Type of IPv6 medium type. */ +typedef uint8_t ipv6_medium_type_t; + +/**@brief IPv6 medium instance type. */ +typedef struct +{ + ipv6_medium_instance_id_t ipv6_medium_instance_id; + ipv6_medium_type_t ipv6_medium_instance_type; +} ipv6_medium_instance_t; + +/**@brief EUI-48 value type. */ +typedef struct +{ + uint8_t identifier[EUI_48_SIZE]; /**< 48-bit identifier. */ +} eui48_t; + +/**@brief Type of IPv6 medium event parameters. */ +typedef struct +{ + ipv6_medium_instance_t ipv6_medium_instance_id; + uint8_t ipv6_medium_evt_id; + ipv6_medium_cb_params_union_t medium_specific; +} ipv6_medium_evt_t; + +/**@brief Type of IPv6 medium error parameters. */ +typedef struct +{ + ipv6_medium_instance_t ipv6_medium_instance_id; + uint32_t error_label; + ipv6_medium_err_params_union_t medium_specific; +} ipv6_medium_error_t; + +/**@brief IPv6 medium event handler type. */ +typedef void (*ipv6_medium_evt_handler_t)(ipv6_medium_evt_t * p_ipv6_medium_evt); + +/**@brief IPv6 medium error handler type. */ +typedef void (*ipv6_medium_error_handler_t)(ipv6_medium_error_t * p_ipv6_medium_error); + +#ifdef COMMISSIONING_ENABLED +/**@brief Commissioning mode control commands. */ +typedef enum +{ + CMD_IDENTITY_MODE_EXIT = 0x00, + CMD_IDENTITY_MODE_ENTER = 0x01 +} mode_control_cmd_t; + +/**@brief Commissioning: Identity mode control callback function type. */ +typedef void (*commissioning_id_mode_cb_t)(mode_control_cmd_t control_command); + +/**@brief Commissioning: Power off on failure control callback function type. */ +typedef void (*commissioning_poweroff_cb_t)(bool do_poweroff_on_failure); +#endif // COMMISSIONING_ENABLED + +/**@brief Structure for initialization parameters of the IPv6 medium. */ +typedef struct +{ + ipv6_medium_evt_handler_t ipv6_medium_evt_handler; + ipv6_medium_error_handler_t ipv6_medium_error_handler; +#ifdef COMMISSIONING_ENABLED + commissioning_id_mode_cb_t commissioning_id_mode_cb; + commissioning_poweroff_cb_t commissioning_power_off_cb; +#endif // COMMISSIONING_ENABLED +} ipv6_medium_init_params_t; + +/**@brief Function for initializing the IPv6 medium. + * + * @details Initializes the IPv6 medium module. + * Performs all setup necessary that is specific to the implementation. + * + * @param[in] p_init_param Pointer to the initialization parameters. + * @param[in] desired_medium_type Value of the desired medium type. + * @param[out] p_new_medium_instance Pointer to the new medium instance initialized. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_init(ipv6_medium_init_params_t * p_init_param, + ipv6_medium_type_t desired_medium_type, + ipv6_medium_instance_t * p_new_medium_instance); + +/**@brief Function for entering connectible mode. + * + * @details Requests the IPv6 medium to enter connectible mode. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_connectable_mode_enter(ipv6_medium_instance_id_t ipv6_medium_instance_id); + +/**@brief Function for exiting connectible mode. + * + * @details Requests the IPv6 medium to exit connectible mode. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_connectable_mode_exit(ipv6_medium_instance_id_t ipv6_medium_instance_id); + +/**@brief Function for getting the 48-bit Extended Unique Identifier. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * @param[out] p_ipv6_medium_eui48 Pointer to the EUI-48 value. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_eui48_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, + eui48_t * p_ipv6_medium_eui48); + +/**@brief Function for setting the 48-bit Extended Unique Identifier. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * @param[in] p_ipv6_medium_eui48 Pointer to the EUI-48 value. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_eui48_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, + eui48_t * p_ipv6_medium_eui48); + +/**@brief Function for getting the 64-bit Extended Unique Identifier. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * @param[out] p_ipv6_medium_eui64 Pointer to the EUI-64 value. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_eui64_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, + eui64_t * p_ipv6_medium_eui64); + +/**@brief Function for setting the 64-bit Extended Unique Identifier. + * + * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance. + * @param[in] p_ipv6_medium_eui64 Pointer to the EUI-64 value. + * + * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated + * error code is returned. + * + */ +uint32_t ipv6_medium_eui64_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, + eui64_t * p_ipv6_medium_eui64); + +#ifdef __cplusplus +} +#endif + +#endif // IPV6_MEDIUM_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c new file mode 100644 index 0000000..0d0a415 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c @@ -0,0 +1,689 @@ +/** + * Copyright (c) 2015-2018 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "boards.h" +#include "ipv6_medium.h" +#include "ipv6_medium_ble.h" +#include "ble_advdata.h" +#include "ble_hci.h" +#include "ble_srv_common.h" +#include "ble_ipsp.h" +#include "sdk_config.h" +#include "nrf_sdm.h" +#include "nrf_sdh.h" +#include "nrf_sdh_ble.h" +#ifdef COMMISSIONING_ENABLED +#include "commissioning.h" +#endif // COMMISSIONING_ENABLED + +#define PUBLIC_BLE_GAP_ADDR_CREATE_FROM_EUI64(ble_gap_addr, eui64, ble_gap_addr_type) \ + ble_gap_addr[0] = eui64[7]; \ + ble_gap_addr[1] = eui64[6]; \ + ble_gap_addr[2] = eui64[5]; \ + ble_gap_addr[3] = eui64[2]; \ + ble_gap_addr[4] = eui64[1]; \ + ble_gap_addr[5] = 0x00; \ + ble_gap_addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + +#define IOT_TIMER_DISABLE_API_PARAM_CHECK 0 + +#if (IOT_TIMER_DISABLE_API_PARAM_CHECK == 0) + +#define NULL_PARAM_CHECK(PARAM) \ + if ((PARAM) == NULL) \ + { \ + return (NRF_ERROR_NULL); \ + } + +#else // IOT_TIMER_DISABLE_API_PARAM_CHECK + +#define NULL_PARAM_CHECK(PARAM) + +#endif //IOT_TIMER_DISABLE_API_PARAM_CHECK + +#define BLE_IPV6_MEDIUM_BLE_OBSERVER_PRIO 1 /**< BLE observer priority. */ +#define BLE_IPSP_TAG 35 /**< Identifies the L2CAP configuration used with SoftDevice. */ + + +static ipv6_medium_instance_id_t m_module_instance_id = 0x01; /**< Module instance identifier. As of today, only a single instance is supported. */ +static ipv6_medium_evt_handler_t m_ipv6_medium_evt_handler; /**< Pointer to the event handler procedure of the parent layer. */ +static ipv6_medium_error_handler_t m_ipv6_medium_error_handler; /**< Pointer to the error handler procedure of the parent layer. */ +static ble_gap_addr_t m_local_ble_addr; /**< Local BT device address. */ +static ipv6_medium_ble_gap_params_t * m_p_node_gap_params; /**< Pointer to advertising parameters to be used. */ +static ipv6_medium_ble_adv_params_t * m_p_node_adv_params; /**< Pointer to GAP parameters to be used. */ + +#ifndef COMMISSIONING_ENABLED +static ipv6_medium_ble_gap_params_t m_gap_params; /**< Advertising parameters w/o commissioning. */ +static ipv6_medium_ble_adv_params_t m_adv_params; /**< GAP parameters w/o commissioning. */ +static ble_uuid_t m_adv_uuids[] = + { + {BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE} + }; /**< List of available service UUIDs in advertisement data. */ +#else // COMMISSIONING_ENABLED +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the active connection. */ +static bool m_connectable_mode_active = false; /**< Indicates if the node is in connectable mode. */ +static commissioning_id_mode_cb_t m_commissioning_id_mode_cb; +static commissioning_poweroff_cb_t m_commissioning_power_off_cb; +static bool m_adv_params_applied = false; /**< Indicates if advertising (and GAP) parameters have been applied. */ +#endif // COMMISSIONING_ENABLED + +static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */ +static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded advertising set. */ + +/**@brief Struct that contains pointers to the encoded advertising data. */ +static ble_gap_adv_data_t m_adv_data = +{ + .adv_data = + { + .p_data = m_enc_advdata, + .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX + }, + .scan_rsp_data = + { + .p_data = NULL, + .len = 0 + + } +}; + +#if IPV6_MEDIUM_CONFIG_LOG_ENABLED + +#define NRF_LOG_MODULE_NAME ipv6_medium + +#define NRF_LOG_LEVEL IPV6_MEDIUM_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR IPV6_MEDIUM_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR IPV6_MEDIUM_CONFIG_DEBUG_COLOR + +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +#define IPV6M_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */ +#define IPV6M_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */ +#define IPV6M_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */ + +#define IPV6M_ENTRY() IPV6M_TRC(">> %s", __func__) +#define IPV6M_EXIT() IPV6M_TRC("<< %s", __func__) + +#else // IPV6_MEDIUM_CONFIG_LOG_ENABLED + +#define IPV6M_TRC(...) /**< Disables traces. */ +#define IPV6M_DUMP(...) /**< Disables dumping of octet streams. */ +#define IPV6M_ERR(...) /**< Disables error logs. */ + +#define IPV6M_ENTRY(...) +#define IPV6M_EXIT(...) + +#endif // IPV6_MEDIUM_CONFIG_LOG_ENABLED + + +#ifndef COMMISSIONING_ENABLED + +/**@brief Function for setting advertisement parameters. + * + * @details These parameters are applied if the Commissioning module is + * not used or in Joining mode. + */ +static void adv_params_set(void) +{ + IPV6M_ENTRY(); + memset(&m_adv_params, 0x00, sizeof(m_adv_params)); + + m_adv_params.advdata.name_type = BLE_ADVDATA_FULL_NAME; + m_adv_params.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + m_adv_params.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); + m_adv_params.advdata.uuids_complete.p_uuids = m_adv_uuids; + + m_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; + m_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement. + m_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY; + m_adv_params.advparams.interval = APP_ADV_ADV_INTERVAL; + m_adv_params.advparams.duration = APP_ADV_DURATION; + + IPV6M_EXIT(); +} + +/**@brief Function for setting GAP parameters. + * + * @details These parameters are applied if the Commissioning module is + * not used or in Joining mode. + */ +static void gap_params_set(void) +{ + memset(&m_gap_params, 0x00, sizeof(m_gap_params)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_gap_params.sec_mode); + + m_gap_params.appearance = BLE_APPEARANCE_UNKNOWN; + + m_gap_params.p_dev_name = (const uint8_t *)DEVICE_NAME; + m_gap_params.dev_name_len = strlen(DEVICE_NAME); + + m_gap_params.gap_conn_params.min_conn_interval = (uint16_t)MIN_CONN_INTERVAL; + m_gap_params.gap_conn_params.max_conn_interval = (uint16_t)MAX_CONN_INTERVAL; + m_gap_params.gap_conn_params.slave_latency = SLAVE_LATENCY; + m_gap_params.gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; +} + +#endif // COMMISSIONING_ENABLED + + +/**@brief Function for applying the advertisement parameters. + * + * @details Encodes the required advertising data and passes it to the stack. + */ +static void adv_params_apply(void) +{ + uint32_t err_code; + + + err_code = ble_advdata_encode(&m_p_node_adv_params->advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len); + APP_ERROR_CHECK(err_code); +#ifndef COMMISSIONING_ENABLED + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params.advparams); + APP_ERROR_CHECK(err_code); +#else + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_p_node_adv_params->advparams); + APP_ERROR_CHECK(err_code); +#endif +} + + +/**@brief Function for applying the GAP configuration. + * + * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the + * device including the device name, appearance, and the preferred connection parameters. + */ +static void gap_params_apply(void) +{ + uint32_t err_code; + + err_code = sd_ble_gap_device_name_set(&m_p_node_gap_params->sec_mode, \ + m_p_node_gap_params->p_dev_name, \ + m_p_node_gap_params->dev_name_len); + APP_ERROR_CHECK(err_code); + + err_code = sd_ble_gap_appearance_set(m_p_node_gap_params->appearance); + APP_ERROR_CHECK(err_code); + + err_code = sd_ble_gap_ppcp_set(&m_p_node_gap_params->gap_conn_params); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for handling the application's BLE Stack events and + * passing them on to the applications as generic transport medium events. + * + * @param[in] p_ble_evt Bluetooth stack event. + */ +static void on_ble_evt(ble_evt_t const * p_ble_evt) +{ + ipv6_medium_evt_t ipv6_medium_evt; + + memset(&ipv6_medium_evt, 0x00, sizeof(ipv6_medium_evt)); + ipv6_medium_evt.ipv6_medium_instance_id.ipv6_medium_instance_id = m_module_instance_id; + ipv6_medium_evt.ipv6_medium_instance_id.ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE; + ipv6_medium_evt.medium_specific.ble.p_ble_evt = (ble_evt_t*)p_ble_evt; + + ipv6_medium_error_t ipv6_medium_error; + memset(&ipv6_medium_error, 0x00, sizeof(ipv6_medium_error)); + ipv6_medium_error.ipv6_medium_instance_id.ipv6_medium_instance_id = m_module_instance_id; + ipv6_medium_error.ipv6_medium_instance_id.ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE; + + bool do_notify_event = false; + bool do_notify_error = false; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + { +#ifdef COMMISSIONING_ENABLED + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +#endif // COMMISSIONING_ENABLED + ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONN_UP; + do_notify_event = true; + + break; + } + case BLE_GAP_EVT_DISCONNECTED: + { +#ifdef COMMISSIONING_ENABLED + m_conn_handle = BLE_CONN_HANDLE_INVALID; +#endif // COMMISSIONING_ENABLED + ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONN_DOWN; + do_notify_event = true; + + break; + } + case BLE_GAP_EVT_ADV_SET_TERMINATED: + { + if (p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT) + { + ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONNECTABLE_MODE_EXIT; + do_notify_event = true; + } + else + { + // This is not necessarily an error, only added here to show error handler usage. + ipv6_medium_error.medium_specific.ble.dummy_value = 0x13; + do_notify_error = true; + } + break; + } + default: + { + ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_PHY_SPECIFIC; + do_notify_event = true; + + break; + } + } + + ble_ipsp_evt_handler(p_ble_evt); + + if (do_notify_event == true) + { + m_ipv6_medium_evt_handler(&ipv6_medium_evt); + } + if (do_notify_error == true) + { + m_ipv6_medium_error_handler(&ipv6_medium_error); + } +} + +/* + * @brief Function for handling BLE events. + * + * @param[in] p_ble_evt Event received from the BLE stack. + * @param[in] p_context Context. + */ +static void ble_evt_handler(const ble_evt_t * p_ble_evt, void * p_context) +{ + UNUSED_PARAMETER(p_context); +#ifdef COMMISSIONING_ENABLED + commissioning_ble_evt_handler(p_ble_evt); + ble_ncfgs_ble_evt_handler(p_ble_evt); +#endif // COMMISSIONING_ENABLED + + on_ble_evt(p_ble_evt); +} + + + + +/**@brief Function for initializing the BLE stack. + * + * @details Initializes the SoftDevice and the BLE event interrupt. + */ +static uint32_t ble_stack_init(void) +{ + ret_code_t err_code; + uint32_t ram_start = 0; + ble_cfg_t ble_cfg; + + err_code = nrf_sdh_enable_request(); + + if (err_code == NRF_SUCCESS) + { + // Fetch the start address of the application RAM. + err_code = nrf_sdh_ble_app_ram_start_get(&ram_start); + } + + if (err_code == NRF_SUCCESS) + { + // Configure the maximum number of connections. + memset(&ble_cfg, 0, sizeof(ble_cfg)); + ble_cfg.gap_cfg.role_count_cfg.periph_role_count = BLE_IPSP_MAX_CHANNELS; + ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0; + ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0; + err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start); + } + + if (err_code == NRF_SUCCESS) + { + memset(&ble_cfg, 0, sizeof(ble_cfg)); + + // Configure total number of connections. + ble_cfg.conn_cfg.conn_cfg_tag = BLE_IPSP_TAG; + ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = BLE_IPSP_MAX_CHANNELS; + ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start); + + } + + if (err_code == NRF_SUCCESS) + { + memset(&ble_cfg, 0, sizeof(ble_cfg)); + + // Configure the number of custom UUIDS. +#ifdef COMMISSIONING_ENABLED + ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 1; +#else + ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 0; +#endif // COMMISSIONING_ENABLED + + err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, ram_start); + } + + if (err_code == NRF_SUCCESS) + { + memset(&ble_cfg, 0, sizeof(ble_cfg)); + + // Set L2CAP channel configuration + ble_cfg.conn_cfg.conn_cfg_tag = BLE_IPSP_TAG; + ble_cfg.conn_cfg.params.l2cap_conn_cfg.rx_mps = BLE_IPSP_RX_MPS; + ble_cfg.conn_cfg.params.l2cap_conn_cfg.rx_queue_size = BLE_IPSP_RX_BUFFER_COUNT; + ble_cfg.conn_cfg.params.l2cap_conn_cfg.tx_mps = BLE_IPSP_TX_MPS; + ble_cfg.conn_cfg.params.l2cap_conn_cfg.tx_queue_size = 1; + ble_cfg.conn_cfg.params.l2cap_conn_cfg.ch_count = 1; // One IPSP channel per link. + err_code = sd_ble_cfg_set(BLE_CONN_CFG_L2CAP, &ble_cfg, ram_start); + } + + if (err_code == NRF_SUCCESS) + { + memset(&ble_cfg, 0, sizeof(ble_cfg)); + + // Set the ATT table size. +#ifdef COMMISSIONING_ENABLED + ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 1024; +#else + ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 256; +#endif // COMMISSIONING_ENABLED + err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start); + } + + if (err_code == NRF_SUCCESS) + { + err_code = nrf_sdh_ble_enable(&ram_start); + } + + NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_IPV6_MEDIUM_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); + + return err_code; +} + + +uint32_t ipv6_medium_connectable_mode_enter(ipv6_medium_instance_id_t ipv6_medium_instance_id) +{ + IPV6M_ENTRY(); + + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + +#ifdef COMMISSIONING_ENABLED + if (m_adv_params_applied == false) + { + // Apply advertising (and GAP) parameters, if not applied when node mode changed. + commissioning_gap_params_get(&m_p_node_gap_params); + commissioning_adv_params_get(&m_p_node_adv_params); + gap_params_apply(); + adv_params_apply(); + } + m_adv_params_applied = false; +#endif // COMMISSIONING_ENABLED + + adv_params_apply(); + + uint32_t err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_IPSP_TAG); +#ifdef COMMISSIONING_ENABLED + if (err_code == NRF_SUCCESS) + { + m_connectable_mode_active = true; + } +#endif // COMMISSIONING_ENABLED + IPV6M_EXIT(); + return err_code; +} + + +uint32_t ipv6_medium_connectable_mode_exit(ipv6_medium_instance_id_t ipv6_medium_instance_id) +{ + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle); +#ifdef COMMISSIONING_ENABLED + if (err_code == NRF_SUCCESS) + { + m_connectable_mode_active = false; + } +#endif // COMMISSIONING_ENABLED + return err_code; +} + + +uint32_t ipv6_medium_eui48_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, \ + eui48_t * p_ipv6_medium_eui48) +{ + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + ble_gap_addr_t local_ble_addr; + uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr); + + memcpy(p_ipv6_medium_eui48->identifier, local_ble_addr.addr, EUI_48_SIZE); + + return err_code; +} + + +uint32_t ipv6_medium_eui48_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, \ + eui48_t * p_ipv6_medium_eui48) +{ + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + if (p_ipv6_medium_eui48->identifier[5] != 0x00) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_local_ble_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + memcpy(m_local_ble_addr.addr, p_ipv6_medium_eui48->identifier, EUI_48_SIZE); + + return sd_ble_gap_addr_set(&m_local_ble_addr); +} + + +uint32_t ipv6_medium_eui64_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, \ + eui64_t * p_ipv6_medium_eui64) +{ + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + ble_gap_addr_t local_ble_addr; + + uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr); + APP_ERROR_CHECK(err_code); + + IPV6_EUI64_CREATE_FROM_EUI48(p_ipv6_medium_eui64->identifier, + local_ble_addr.addr, + local_ble_addr.addr_type); + return NRF_SUCCESS; +} + + +uint32_t ipv6_medium_eui64_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, \ + eui64_t * p_ipv6_medium_eui64) +{ + if (ipv6_medium_instance_id != m_module_instance_id) + { + return NRF_ERROR_INVALID_PARAM; + } + if ((p_ipv6_medium_eui64->identifier[0] != 0x02) || + (p_ipv6_medium_eui64->identifier[3] != 0xFF) || + (p_ipv6_medium_eui64->identifier[4] != 0xFE)) + { + return NRF_ERROR_INVALID_PARAM; + } + + ble_gap_addr_t local_ble_addr; + + PUBLIC_BLE_GAP_ADDR_CREATE_FROM_EUI64(local_ble_addr.addr, \ + p_ipv6_medium_eui64->identifier, \ + local_ble_addr.addr_type); + + return sd_ble_gap_addr_set(&local_ble_addr); +} + + +#ifdef COMMISSIONING_ENABLED + +void commissioning_evt_handler(commissioning_evt_t * p_commissioning_evt) +{ + IPV6M_ENTRY(); + + switch (p_commissioning_evt->commissioning_evt_id) + { + case COMMISSIONING_EVT_CONFIG_MODE_ENTER: + // Fall-through. + case COMMISSIONING_EVT_JOINING_MODE_ENTER: + { + m_commissioning_power_off_cb(p_commissioning_evt->power_off_enable_requested); + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + // Making sure that advertising (and GAP) parameters are + // applied when entering connectable mode the next time. + m_adv_params_applied = false; + UNUSED_VARIABLE(sd_ble_gap_disconnect(m_conn_handle, \ + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION)); + } + else + { + bool do_return_to_connectable_mode = m_connectable_mode_active; + UNUSED_VARIABLE(ipv6_medium_connectable_mode_exit(m_module_instance_id)); + + commissioning_gap_params_get(&m_p_node_gap_params); + commissioning_adv_params_get(&m_p_node_adv_params); + gap_params_apply(); + adv_params_apply(); + // Advertising and GAP parameters applied, making sure that + // it is not repeated when entering connectable mode the next time. + m_adv_params_applied = true; + + if (do_return_to_connectable_mode == true) + { + // Restart connectable mode, if the node was in connectable mode applying + // the new parameters. + UNUSED_VARIABLE(ipv6_medium_connectable_mode_enter(m_module_instance_id)); + } + } + + break; + } + case COMMISSIONING_EVT_IDENTITY_MODE_ENTER: + { + m_commissioning_id_mode_cb(CMD_IDENTITY_MODE_ENTER); + + break; + } + case COMMISSIONING_EVT_IDENTITY_MODE_EXIT: + { + m_commissioning_id_mode_cb(CMD_IDENTITY_MODE_EXIT); + + break; + } + default: + { + // No implementation needed. + break; + } + } + + IPV6M_EXIT(); +} + +#endif // COMMISSIONING_ENABLED + + +uint32_t ipv6_medium_init(ipv6_medium_init_params_t * p_init_param, \ + ipv6_medium_type_t desired_medium_type, \ + ipv6_medium_instance_t * p_new_medium_instance) +{ + IPV6M_ENTRY(); + uint32_t err_code = NRF_SUCCESS; + NULL_PARAM_CHECK(p_init_param->ipv6_medium_evt_handler); + if (desired_medium_type != IPV6_MEDIUM_ID_BLE) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_ipv6_medium_evt_handler = p_init_param->ipv6_medium_evt_handler; + m_ipv6_medium_error_handler = p_init_param->ipv6_medium_error_handler; + + p_new_medium_instance->ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE; + p_new_medium_instance->ipv6_medium_instance_id = m_module_instance_id; + + err_code = ble_stack_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + +#ifndef COMMISSIONING_ENABLED + gap_params_set(); + adv_params_set(); + m_p_node_gap_params = &m_gap_params; + m_p_node_adv_params = &m_adv_params; + gap_params_apply(); +#else // COMMISSIONING_ENABLED + m_commissioning_id_mode_cb = p_init_param->commissioning_id_mode_cb; + m_commissioning_power_off_cb = p_init_param->commissioning_power_off_cb; + + commissioning_init_params_t init_param; + memset(&init_param, 0x00, sizeof(init_param)); + init_param.commissioning_evt_handler = commissioning_evt_handler; + uint8_t new_mode; + err_code = commissioning_init(&init_param, \ + &new_mode); + + commissioning_node_mode_change(new_mode); +#endif // COMMISSIONING_ENABLED + + IPV6M_EXIT(); + return err_code; +} diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h new file mode 100644 index 0000000..492afe4 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ipv6_medium_ble BLE IPv6 Medium Implementation + * @{ + * @ingroup iot_sdk_common + * @brief Bluetooth Low Energy implementation of the IPv6 medium interface. + * + * @details Type definitions for the BLE implementation of the IPv6 medium interface. + * This header also includes the header with BLE-specific configuration. + */ + +#ifndef IPV6_MEDIUM_BLE_H__ +#define IPV6_MEDIUM_BLE_H__ + +#include +#include "ble.h" +#include "ble_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Structure for storing all GAP parameters. */ +typedef struct +{ + uint16_t appearance; + uint8_t const * p_dev_name; + uint16_t dev_name_len; + ble_gap_conn_sec_mode_t sec_mode; + ble_gap_conn_params_t gap_conn_params; +} ipv6_medium_ble_gap_params_t; + +/**@brief Structure for storing all advertisement parameters. */ +typedef struct +{ + ble_advdata_t advdata; + ble_advdata_manuf_data_t adv_man_specific_data; + ble_advdata_t srdata; + ble_advdata_manuf_data_t sr_man_specific_data; + ble_gap_adv_params_t advparams; +} ipv6_medium_ble_adv_params_t; + +/**@brief Structure of BLE-specific parameters of events passed to the parent layer by the IPv6 medium. */ +typedef struct +{ + ble_evt_t * p_ble_evt; +} ipv6_medium_ble_cb_params_t; + +/**@brief Structure of BLE-specific parameters of errors passed to the parent layer by the IPv6 medium. */ +typedef struct +{ + uint8_t dummy_value; // Parameters to be added. +} ipv6_medium_ble_error_params_t; + +#ifdef __cplusplus +} +#endif + +#endif // IPV6_MEDIUM_BLE_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h new file mode 100644 index 0000000..341d326 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 IPV6_MEDIUM_PLATFORM_DUMMY_H__ +#define IPV6_MEDIUM_PLATFORM_DUMMY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int ipv6_medium_cb_params_union_t; +typedef int ipv6_medium_err_params_union_t; + +#ifdef __cplusplus +} +#endif + +#endif // IPV6_MEDIUM_PLATFORM_DUMMY_H__ -- cgit v1.2.3