From 79f47c65ba3e979977489e2a77753d352c8e5a1b Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Mon, 18 Jan 2016 14:04:08 +0200 Subject: [PATCH] Bluetooth: nble: Add RPC Serialization IPC Port RPC Serialization to Zephyr upstream Signed-off-by: Andrei Emeltchenko Change-Id: I315d52dc6576254a6928520d1353856d41a25c69 --- drivers/nble/Makefile | 2 +- drivers/nble/gap.c | 1 + drivers/nble/gap_internal.h | 960 +++++++++++++++++++++++ drivers/nble/gatt_internal.h | 522 ++++++++++++ drivers/nble/rpc.h | 162 ++++ drivers/nble/rpc_functions_to_ble_core.h | 102 +++ drivers/nble/rpc_functions_to_quark.h | 143 ++++ drivers/nble/rpc_serialize.c | 371 +++++++++ drivers/nble/version.h | 95 +++ 9 files changed, 2357 insertions(+), 1 deletion(-) create mode 100644 drivers/nble/gap_internal.h create mode 100644 drivers/nble/gatt_internal.h create mode 100644 drivers/nble/rpc.h create mode 100644 drivers/nble/rpc_functions_to_ble_core.h create mode 100644 drivers/nble/rpc_functions_to_quark.h create mode 100644 drivers/nble/rpc_serialize.c create mode 100644 drivers/nble/version.h diff --git a/drivers/nble/Makefile b/drivers/nble/Makefile index 2e94f487c70..a9d8829a3ab 100644 --- a/drivers/nble/Makefile +++ b/drivers/nble/Makefile @@ -1 +1 @@ -obj-$(CONFIG_NBLE) += gap.o conn.o gatt.o uart.o +obj-$(CONFIG_NBLE) += gap.o conn.o gatt.o uart.o rpc_serialize.o diff --git a/drivers/nble/gap.c b/drivers/nble/gap.c index 5193a231d34..d219af52174 100644 --- a/drivers/nble/gap.c +++ b/drivers/nble/gap.c @@ -25,6 +25,7 @@ #include #include "uart.h" +#include "rpc.h" #define NBLE_SWDIO_PIN 6 #define NBLE_RESET_PIN NBLE_SWDIO_PIN diff --git a/drivers/nble/gap_internal.h b/drivers/nble/gap_internal.h new file mode 100644 index 00000000000..5a49d88bfba --- /dev/null +++ b/drivers/nble/gap_internal.h @@ -0,0 +1,960 @@ +/** @file + * @brief Internal API for Generic Access Profile. + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +/* For bt_addr_le_t */ +#include "bluetooth/hci.h" +#include "version.h" + +/* Must be the same with ble_service_gap_api.h ! */ + +/**< Maximum security key len (LTK, CSRK) */ +#define BLE_GAP_SEC_MAX_KEY_LEN 16 +#define BLE_PASSKEY_LEN 6 + +/* Must be the same with BLE_GAP_SM_OPTIONS ! */ + +/** + * GAP security manager options for bonding/authentication procedures, + * see Vol 3: Part H, 3.5. + */ +enum BLE_CORE_GAP_SM_OPTIONS { + BLE_CORE_GAP_BONDING = 0x01, /**< SMP supports bonding */ + /**< SMP requires Man In The Middle protection */ + BLE_CORE_GAP_MITM = 0x04, + BLE_CORE_GAP_OOB = 0x08 /**< SMP supports Out Of Band data */ +}; + +/* Must be the same with BLE_CORE_GAP_SM_PASSKEY_TYPE ! */ +/** + * Security manager passkey type. + */ +enum BLE_CORE_GAP_SM_PASSKEY_TYPE { + BLE_CORE_GAP_SM_PK_NONE = 0, /**< No key (may be used to reject). */ + BLE_CORE_GAP_SM_PK_PASSKEY, /**< Sec data is a 6-digit passkey. */ + BLE_CORE_GAP_SM_PK_OOB, /**< Sec data is 16 bytes of OOB data */ +}; + +/* Must be the same with BLE_GAP_SM_STATUS ! */ +/** + * GAP security manager status codes. + */ +enum BLE_CORE_GAP_SM_STATUS { + BLE_CORE_GAP_SM_ST_START_PAIRING, /*< Pairing has started */ + BLE_CORE_GAP_SM_ST_BONDING_COMPLETE, /*< Bonding has completed */ + BLE_CORE_GAP_SM_ST_LINK_ENCRYPTED, /*< Link is encrypted */ + BLE_CORE_GAP_SM_ST_SECURITY_UPDATE, /*< Link keys updated */ +}; + +/* Must be the same with BLE_GAP_RSSI_OPS ! */ +/** + * RSSI operation definition. + */ +enum BLE_CORE_GAP_RSSI_OPS { + BLE_CORE_GAP_RSSI_DISABLE_REPORT = 0, + BLE_CORE_GAP_RSSI_ENABLE_REPORT +}; + +/** Test Mode opcodes. The same with ble_service_gap_api.h */ +enum BLE_CORE_TEST_OPCODE { + /**< Put BLE controller in HCI UART DTM test mode */ + BLE_CORE_TEST_INIT_DTM = 0x01, + BLE_CORE_TEST_START_DTM_RX = 0x1d, /**< LE rcv test HCI op */ + BLE_CORE_TEST_START_DTM_TX = 0x1e, /**< LE trans test HCI op */ + BLE_CORE_TEST_END_DTM = 0x1f, /**< End LE DTM TEST */ + /** vendor specific commands start at 0x80 + * Set Tx power. To be called before start of tx test + */ + BLE_CORE_TEST_SET_TXPOWER = 0x80, + BLE_CORE_TEST_START_TX_CARRIER, /**< Start Tx Carrier Test */ +}; + +struct ble_core_response { + int status; /**< Status of the operation */ + void *user_data; +}; + +struct ble_gap_device_name { + /**< Security mode for writing device name, @ref BLE_GAP_SEC_MODES */ + uint8_t sec_mode; + /**< 0: no authorization, 1: authorization required */ + uint8_t authorization; + uint8_t len; /**< Device name length (0-248) */ + uint8_t name_array[20]; /**< Device */ +}; + +struct ble_gap_connection_values { + uint16_t interval; /**< Conn interval (unit 1.25 ms) */ + uint16_t latency; /**< Conn latency (unit interval) */ + uint16_t supervision_to; /**< Conn supervision timeout (10ms) */ +}; + + +enum BLE_GAP_SVC_ATTR_TYPE { + GAP_SVC_ATTR_NAME = 0, /**< Device Name, UUID 0x2a00 */ + GAP_SVC_ATTR_APPEARANCE, /**< Appearance, UUID 0x2a01 */ + /**< Peripheral Preferred Connection Parameters (PPCP), UUID 0x2a04 */ + GAP_SVC_ATTR_PPCP = 4, + /**< Central Address Resolution (CAR), UUID 0x2aa6, BT 4.2 */ + GAP_SVC_ATTR_CAR = 0xa6, +}; + +/** + * Connection requested parameters. + */ +struct ble_core_gap_connection_params { + /**< minimal conne interval: range 0x0006 to 0x0c80 (unit 1.25ms) */ + uint16_t interval_min; + /**< max conn interv: range 0x0006 to 0x0c80 must be bigger then min */ + uint16_t interval_max; + /**< maximum connection slave latency: 0x0000 to 0x01f3 */ + uint16_t slave_latency; + /**< link supervision timeout: 0x000a to 0x0c80 (unit 10ms) */ + uint16_t link_sup_to; +}; + +/** + * Connection scan requested parameters. + */ +struct ble_core_gap_scan_params { + uint8_t active; /**< If 1, perform active scan (scan req) */ + uint8_t selective; /**< If 1, ignore unknown dev (non whitelist) */ + /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units + * (2.5ms to 10.24s). + */ + uint16_t interval; + /**< Scan window between 0x0004 and 0x4000 in 0.625ms units + * (2.5ms to 10.24s). + */ + uint16_t window; + /**< Scan timeout between 0x0001 and 0xFFFF in seconds, + * 0x0000 disables timeout. + */ + uint16_t timeout; +}; + +struct ble_gap_service_write_params { + /**< GAP Characteristics attribute type @ref BLE_GAP_SVC_ATTR_TYPE */ + uint16_t attr_type; + union { + struct ble_gap_device_name name; + uint16_t appearance; /**< Appearance UUID */ + /**< Preferred Peripheral Connection Parameters */ + struct ble_core_gap_connection_params conn_params; + /**< Central Address Resolution support 0: no, 1: yes */ + uint8_t car; + }; +}; + +struct ble_service_read_bda_response { + int status; /**< Status of the operation */ + bt_addr_le_t bd; /**< If @ref status ok */ + void *user_data; +}; + +struct ble_service_write_response { + int status; /**< Status of the operation */ + /**< GAP Characteristics attribute type @ref BLE_GAP_SVC_ATTR_TYPE */ + uint16_t attr_type; + void *user_data; /**< Pointer to the user data of the request */ +}; + +struct ble_gap_service_read_params { + /**< Type of GAP data charact to read @ref BLE_GAP_SVC_ATTR_TYPE */ + uint16_t attr_type; +}; + +struct debug_params { + uint32_t u0; /** user parameter */ + uint32_t u1; /** user parameter */ +}; + +struct debug_response { + int status; /**< Status of the operation */ + uint32_t u0; /** user parameter */ + uint32_t u1; /** user parameter */ + void *user_data; /**< Pointer to the user data of the request */ +}; + +struct ble_wr_config_params { + bt_addr_le_t bda; + uint8_t bda_present; + int8_t tx_power; + struct ble_core_gap_connection_params central_conn_params; +}; + +/** + * Advertisement parameters. + */ + +/* Complete encoded eir data structure */ +struct bt_eir_data { + uint8_t len; + uint8_t data[31]; +}; + +struct ble_gap_adv_params { + uint16_t timeout; + uint16_t interval_min; /**< min interval 0xffff: use default 0x0800 */ + uint16_t interval_max; /**< max interval 0xffff: use default 0x0800 */ + uint8_t type; /**< advertisement types @ref GAP_ADV_TYPES */ + uint8_t filter_policy; /**< filter policy to apply with white list */ + /**< bd address of peer device in case of directed advertisement */ + bt_addr_le_t peer_bda; + struct bt_eir_data ad; /**< Advertisement data, maybe 0 (length) */ + struct bt_eir_data sd; /**< Scan response data, maybe 0 (length) */ +}; + +struct ble_log_s { + uint8_t param0; + uint8_t param1; + uint8_t param2; + uint8_t param3; +}; + +void ble_log(const struct ble_log_s *p_param, char *p_buf, uint8_t buflen); + +void ble_core_delete_conn_params_timer(void); + +void on_nble_up(void); + +/** + * Write GAP Service Attribute Characteristics. + * + * The response to this request is received through + * @ref on_ble_gap_service_write_rsp + * + * @param par data of the characteristic to write + * @param user_data User data + */ +void ble_gap_service_write_req(const struct ble_gap_service_write_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_read_bda_req. + * + * @param par Response + */ +void on_ble_gap_read_bda_rsp(const struct ble_service_read_bda_response *par); + +/** + * Response to @ref ble_gap_service_write_req. + * + * @param par Response + */ +void on_ble_gap_service_write_rsp(const struct ble_service_write_response *par); + +/** + * Send generic debug command + * + * The response to this request is received through @ref on_ble_gap_dbg_rsp + * + * @param par debug parameters + * @param user_data User data + */ +void ble_gap_dbg_req(const struct debug_params *par, void *user_data); + +/** + * Response to @ref ble_gap_dbg_req. + * + * @param par Response + */ +void on_ble_gap_dbg_rsp(const struct debug_response *par); + +/** + * Set Enable configuration parameters (BD address, etc). + * + * The response to this request is received through + * @ref on_ble_set_enable_config_rsp + * + * This shall put the controller stack into a usable (enabled) state. + * Hence this should be called first! + * + * @param config BLE write configuration + * @param user_data User data + * + */ +void ble_set_enable_config_req(const struct ble_wr_config_params *config, + void *user_data); + +/** + * Start advertising. + * + * The response to this request is received through + * @ref on_ble_gap_start_advertise_rsp + * + * @param par advertisement + * @param p_adv_data Pointer to advertisement and scan response data + */ +void ble_gap_start_advertise_req(struct ble_gap_adv_params *par); + +/** + * Response to @ref ble_gap_start_advertise_req. + * + * @param par Response + */ +void on_ble_gap_start_advertise_rsp(const struct ble_core_response *par); + +/** + * Request to stop advertisement + * + * @param user_data pointer to private data + */ +void ble_gap_stop_advertise_req(void *user_data); + +/** + * Response to @ref ble_gap_stop_advertise_req. + * + * @param par Response + */ +void on_ble_gap_stop_advertise_rsp(const struct ble_core_response *par); + +/** + * Read BD address from Controller. + * + * The response to this request is received through @ref on_ble_gap_read_bda_rsp + * + * @param priv Pointer to private data + */ +void ble_gap_read_bda_req(void *priv); + +struct ble_gap_irk_info { + uint8_t irk[BLE_GAP_SEC_MAX_KEY_LEN]; +}; + +/** + * Write white list to the BLE controller. + * + * The response to this request is received through + * @ref on_ble_gap_wr_white_list_rsp + * + * Store white in BLE controller. It needs to be done BEFORE starting + * advertisement or start scanning + * + * @param bd_array array of bd addresses + * @param bd_array_size size of bd addresses array + * @param irk_array array of irk keys (for address resolution offload) + * @param irk_array_size size of irk keys array + * @param priv pointer to private data + */ +void ble_gap_wr_white_list_req(bt_addr_le_t *bd_array, uint8_t bd_array_size, + struct ble_gap_irk_info *irk_array, + uint8_t irk_array_size, void *priv); + +/** + * Response to @ref ble_gap_wr_white_list_req. + * + * @param par Response + */ +void on_ble_gap_wr_white_list_rsp(const struct ble_core_response *par); + +/** + * Clear previously stored white list. + * + * The response to this request is received through + * @ref on_ble_gap_clr_white_list_rsp + * + * @param priv Pointer to private data + */ +void ble_gap_clr_white_list_req(void *priv); + +/** + * Response to @ref ble_gap_clr_white_list_req. + * + * @param par Response + */ +void on_ble_gap_clr_white_list_rsp(const struct ble_core_response *par); + +struct ble_gap_connect_update_params { + uint16_t conn_handle; + struct ble_core_gap_connection_params params; +}; + +/** + * Update connection. + * + * The response to this request is received through + * @ref on_ble_gap_conn_update_rsp + * + * This function's behavior depends on the role of the connection: + * - in peripheral mode, it sends an L2CAP signaling connection parameter + * update request based the values in p_conn_param argument, + * and the action can be taken by the central at link layer + * - in central mode, it will send a link layer command to change the + * connection values based on the values in p_conn_param argument + * where the connection interval is interval_min. + * + * When the connection is updated, function event on_ble_gap_conn_update_evt + * is called. + * + * @param par Connection parameters + * @param user_data User data + */ +void ble_gap_conn_update_req(const struct ble_gap_connect_update_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_conn_update_req. + * + * @param par Response + */ +void on_ble_gap_conn_update_rsp(const struct ble_core_response *par); + +struct ble_gap_connect_req_params { + bt_addr_le_t bda; + struct ble_core_gap_connection_params conn_params; + struct ble_core_gap_scan_params scan_params; +}; + +struct ble_gap_disconnect_req_params { + uint16_t conn_handle; /**< Connection handle */ + uint8_t reason; /**< Reason of the disconnect */ +}; + +/** + * Disconnect connection (peripheral or central role). + * + * The response to this request is received through + * @ref on_ble_gap_disconnect_rsp + * + * @param par Connection to terminate + * @param user_data User data + */ +void ble_gap_disconnect_req(const struct ble_gap_disconnect_req_params *par, + void *user_data); +/** + * Response to @ref ble_gap_disconnect_req. + * + * @param par Response + */ +void on_ble_gap_disconnect_rsp(const struct ble_core_response *par); + +/** + * Read GAP Service Characteristics. + * + * The response to this request is received through + * @ref on_ble_gap_service_read_rsp + * + * @param ble_gap_service_read GAP service characteristic to read + * @param user_data Pointer to private data + */ +void ble_gap_service_read_req(const struct ble_gap_service_read_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_service_read_req. + * + * @param par Response + */ +void on_ble_gap_service_read_rsp(const struct ble_core_response *par); + +/** + * Security manager configuration parameters. + * + * options and io_caps will define there will be a passkey request or not. + * It is assumed that io_caps and options are compatible. + */ +struct ble_core_gap_sm_config_params { + uint8_t options; /**< Sec options (@ref BLE_GAP_SM_OPTIONS) */ + /**< I/O Capabilities to allow passkey exchange + * (@ref BLE_GAP_IO_CAPABILITIES) + */ + uint8_t io_caps; + uint8_t key_size; /**< Maximum encryption key size (7-16) */ +}; + +/** + * Configuring the security manager. + * + * The response to this request is received through + * @ref on_ble_gap_sm_config_rsp + * + * @param par local authentication/bonding parameters + * @param user_data User data + */ +void ble_gap_sm_config_req(const struct ble_core_gap_sm_config_params *par, + void *user_data); + +struct ble_gap_sm_config_rsp { + void *user_data; /**< Pointer to user data structure */ + int status; /**< Result of sec manager initialization */ + uint32_t state; /**< State of bond DB */ +}; + +/** + * Response to @ref ble_gap_sm_config_req. + * + * @param par Response + */ +void on_ble_gap_sm_config_rsp(struct ble_gap_sm_config_rsp *par); + +/** + * Security manager pairing parameters. + */ +struct ble_core_gap_sm_pairing_params { + /**< authentication level see @ref BLE_GAP_SM_OPTIONS */ + uint8_t auth_level; +}; + +struct ble_core_gap_sm_pairing_req_params { + /**< Connection on which bonding procedure is executed */ + uint16_t conn_handle; + /**< Local authentication/bonding parameters */ + struct ble_core_gap_sm_pairing_params params; +}; + +/** + * Initiate the bonding procedure (central). + * + * The response to this request is received through + * @ref on_ble_gap_sm_pairing_rsp + * + * @param par Connection to initiate with its parameters + * @param user_data Pointer to private data + */ +void ble_gap_sm_pairing_req(const struct ble_core_gap_sm_pairing_req_params *p, + void *user_data); + +/** + * Response to @ref ble_gap_sm_pairing_req. + * + * @param par Response + */ +void on_ble_gap_sm_pairing_rsp(const struct ble_core_response *par); + +/** + * Security reply to incoming security request. + */ +struct ble_core_gap_sm_passkey { + /**< Security data type in this reply @ref BLE_GAP_SM_PASSKEY_TYPE */ + uint8_t type; + union { + uint8_t passkey[6]; /**< 6 digits (string) */ + uint8_t oob[16]; /**< 16 bytes of OOB security data */ + }; +}; + +struct ble_gap_sm_key_reply_req_params { + /**< Connection on which bonding is going on */ + uint16_t conn_handle; + struct ble_core_gap_sm_passkey params; /**< Bonding security reply */ +}; + +/** + * Reply to an incoming passkey request event. + * + * The response to this request is received through + * @ref on_ble_gap_sm_passkey_reply_rsp + * + * @param par connection on which bonding is going on and bonding security + * reply + * @param user_data User data + */ +void ble_gap_sm_passkey_reply_req(const struct ble_gap_sm_key_reply_req_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_sm_passkey_reply_req. + * + * @param par Response + */ +void on_ble_gap_sm_passkey_reply_rsp(const struct ble_core_response *par); + +/** + * Clear bonds + * + * The response to this request is received through + * @ref on_ble_gap_sm_clear_bonds_rsp + * + * @param user_data User data + */ +void ble_gap_sm_clear_bonds_req(void *user_data); + +/** + * Response to @ref ble_gap_sm_clear_bonds_req. + * + * @param par Response + */ +void on_ble_gap_sm_clear_bonds_rsp(const struct ble_core_response *par); + +/** + * RSSI report parameters + */ +struct ble_core_rssi_report_params { + uint16_t conn_handle; /**< Connection handle */ + uint8_t op; /**< RSSI operation @ref BLE_GAP_RSSI_OPS */ + uint8_t delta_dBm; /**< minimum RSSI dBm change to report a new RSSI value */ + uint8_t min_count; /**< number of delta_dBm changes before sending a new RSSI report */ +}; + +/** + * Enable or disable the reporting of the RSSI value. + * + * The response to this request is received through @ref on_ble_gap_set_rssi_report_rsp + * + * @param params RSSI report parameters + * @param user_data pointer to user data + */ +void ble_gap_set_rssi_report_req(const struct ble_core_rssi_report_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_set_rssi_report_req. + * + * @param par Response + */ +void on_ble_gap_set_rssi_report_rsp(const struct ble_core_response *par); + +enum BLE_GAP_SCAN_OPTIONS { + BLE_GAP_SCAN_DEFAULT = 0, + BLE_GAP_SCAN_ACTIVE = 0x01, + BLE_GAP_SCAN_WHITE_LISTED = 0x02, +}; + +struct ble_gap_scan_params { + uint16_t timeout; /**< scan timeout in s, 0 never */ + /**< interval: 0x4 - 0x4000 (unit: 0.625ms), default: 0xffff (0x0010) */ + uint16_t interval; + /**< Window: 0x4 - 0x4000 (unit: 0.625ms), default 0xffff (= 0x0010) */ + uint16_t window; + /**< scan options, ORed options from @ref BLE_GAP_SCAN_OPTIONS */ + uint8_t options; +}; + +/** + * Start scanning for BLE devices doing advertisement. + * + * The response to this request is received through + * @ref on_ble_gap_start_scan_rsp + * + * @param par scan parameters + * @param user_data Pointer to user data + */ +void ble_gap_start_scan_req(const struct ble_gap_scan_params *par, void *priv); + +/** + * Response to @ref ble_gap_start_scan_req. + * + * @param par Response + */ +void on_ble_gap_start_scan_rsp(const struct ble_core_response *par); + +/** + * Stop scanning. + * + * The response to this request is received through @ref on_ble_gap_stop_scan_rsp + * + * @param user_data Pointer to user data + */ +void ble_gap_stop_scan_req(void *priv); + +/** + * Response to @ref ble_gap_stop_scan_req. + * + * @param par Response + */ +void on_ble_gap_stop_scan_rsp(const struct ble_core_response *par); + +/** + * Connect to a Remote Device. + * + * The response to this request is received through @ref on_ble_gap_connect_rsp + * + * @param par connection parameters @ref ble_gap_connect_req_params + * @param priv Pointer to private data + */ +void ble_gap_connect_req(const struct ble_gap_connect_req_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_connect_req. + * + * @param par Response + */ +void on_ble_gap_connect_rsp(const struct ble_core_response *par); + +struct ble_gap_cancel_connect_params { + const bt_addr_le_t bd; +}; + +/** + * Cancel an ongoing connection attempt. + * + * The response to this request is received through + * @ref on_ble_gap_cancel_connect_rsp + * + * @param par contains address of device for which the connection shall + * be canceled + * @param user_data Pointer to user data + */ +void ble_gap_cancel_connect_req(const struct ble_gap_cancel_connect_params *par, + void *priv); + +/** + * Response to @ref ble_gap_cancel_connect_req. + * + * @param par Response + */ +void on_ble_gap_cancel_connect_rsp(const struct ble_core_response *par); + +enum BLE_GAP_SET_OPTIONS { + BLE_GAP_SET_CH_MAP = 0, /**< Set channel map */ +}; + +struct ble_gap_channel_map { + uint16_t conn_handle; /**< conn on which to change channel map */ + uint8_t map[5]; /**< 37 bits are used of the 40 bits (LSB) */ +}; + + +struct ble_gap_set_option_params { + uint8_t op; /**< Option to set @ref BLE_GAP_SET_OPTIONS */ + union { + struct ble_gap_channel_map ch_map; + }; +}; + +/** + * Set a gap option (channel map etc) on a connection. + * + * The response to this request is received through + * @ref on_ble_gap_set_option_rsp + * + * @param par contains gap options parameters + * @param user_data Pointer to user data + */ +void ble_gap_set_option_req(const struct ble_gap_set_option_params *par, + void *user_data); + +/** + * Response to @ref ble_gap_set_option_req. + * + * @param par Response + */ +void on_ble_gap_set_option_rsp(const struct ble_core_response *par); + +/** Generic request op codes. + * This allows to access some non connection related commands like DTM. + */ +enum BLE_GAP_GEN_OPS { + DUMMY_VALUE = 0, /**< Not used now. */ +}; + +/** Generic command parameters. */ +struct ble_gap_gen_cmd_params { + uint8_t op_code; /**< @ref BLE_GAP_GEN_OPS */ +}; + +/** + * Generic command + * + * The response to this request is received through + * @ref on_ble_gap_generic_cmd_rsp + * + * @param par contains Generic command parameters. + * @param user_data Pointer to user data + */ +void ble_gap_generic_cmd_req(const struct ble_gap_gen_cmd_params *par, + void *priv); + +/** + * Response to @ref ble_gap_generic_cmd_req. + * + * @param par Response + */ +void on_ble_gap_generic_cmd_rsp(const struct ble_core_response *par); + +/** + * Get ble_core version. + * + * The response to this request is received through @ref on_ble_get_version_rsp + * + * @param rsp Pointer to response data structure + */ +void ble_get_version_req(void *user_data); + +struct ble_version_response { + struct version_header version; + void *user_data; /**< Pointer to response data structure */ +}; + +/** + * Response to @ref ble_get_version_req. + * + * @param par Response + */ +void on_ble_get_version_rsp(const struct ble_version_response *par); + +/** + * Init DTM mode. + * + * The response to this request is received through @ref on_ble_gap_dtm_init_rsp + * + * @param user_data Pointer to response data structure + */ +void ble_gap_dtm_init_req(void *user_data); + +/** + * Response to @ref ble_gap_dtm_init_req. + * + * @param user_data Pointer to user data structure + */ +void on_ble_gap_dtm_init_rsp(void *user_data); + +struct ble_gap_connect_evt { + uint16_t conn_handle; + struct ble_gap_connection_values conn_values; + uint8_t role; + bt_addr_le_t peer_bda; +}; + +/** + * Function invoked by the BLE service when a new connection is established. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_connect_evt(const struct ble_gap_connect_evt *ev); + +struct ble_gap_disconnect_evt { + uint16_t conn_handle; /**< Connection handle */ + uint8_t hci_reason; /**< HCI disconnect reason */ +}; + +/** + * Function invoked by the BLE service when a connection is lost. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_disconnect_evt(const struct ble_gap_disconnect_evt *ev); + + +/** + * Updated connection event. + */ +struct ble_gap_conn_update_evt { + uint16_t conn_handle; + struct ble_gap_connection_values conn_values; +}; + +/** + * Function invoked by the BLE service when a connection is updated. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_conn_update_evt(const struct ble_gap_conn_update_evt *ev); + +struct ble_gap_rssi_evt { + uint16_t conn_handle; /**< Connection handle */ + int8_t rssi_lvl; /**< RSSI level (compared to 0 dBm) */ +}; + +/** + * Function invoked by the BLE service upon RSSI event. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_rssi_evt(const struct ble_gap_rssi_evt *ev); + +struct ble_gap_timout_evt { + uint16_t conn_handle; /**< Connection handle */ + /**< reason for timeout @ref BLE_SVC_GAP_TIMEOUT_REASON */ + int reason; +}; + +/** + * Function invoked by the BLE service upon timeout event. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_to_evt(const struct ble_gap_timout_evt *ev); + +struct ble_gap_sm_passkey_req_evt { + uint16_t conn_handle; /**< Connection handle */ + /**< Passkey or OBB data see @ref BLE_GAP_SM_PASSKEY_TYPE */ + uint8_t key_type; +}; + +/** + * Function invoked by the BLE service upon security manager passkey + * request event. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_sm_passkey_req_evt(const struct ble_gap_sm_passkey_req_evt *ev); + +struct ble_gap_sm_passkey_disp_evt { + uint16_t conn_handle; /**< Connection handle */ + uint8_t passkey[BLE_PASSKEY_LEN]; /**< Passkey to be displayed */ +}; + +/** + * Function invoked by the BLE service upon security manager display event. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_sm_passkey_display_evt(const struct ble_gap_sm_passkey_disp_evt *ev); + +struct ble_gap_sm_status_evt { + uint16_t conn_handle; /**< Connection handle */ + /**< Security manager status @ref BLE_GAP_SM_STATUS */ + uint8_t status; + /**< Result of SM procedure, non-null indicates failure */ + uint8_t gap_status; +}; + +/** + * Function invoked by the BLE service upon a security manager event. + * + * @param ev Pointer to the event structure. + */ +void on_ble_gap_sm_status_evt(const struct ble_gap_sm_status_evt *ev); + +/** + * Response to @ref ble_set_enable_config_req. + * + * @param par Response + */ +void on_ble_set_enable_config_rsp(const struct ble_core_response *par); + +/** + * Get the list of bonded devices + * + * @param user_data User Data + */ +void ble_get_bonded_device_list_req(void *user_data); + +/**@brief Structure containing list of bonded devices. */ +struct ble_core_bonded_devices { +#ifdef CONFIG_TCMD_BLE_DEBUG + /**< Pointer to an array of device address pointers, pointing to + * addresses to be used in whitelist. NULL if none are given. + */ + bt_addr_le_t addrs[8]; +#endif + uint8_t addr_count; /**< Count of device addr in array. */ +}; + +struct ble_get_bonded_device_list_rsp { + int status; /**< Status of the operation */ + struct ble_core_bonded_devices bonded_dev; + struct cfw_message *priv; +}; + +void on_ble_get_bonded_device_list_rsp(const struct ble_get_bonded_device_list_rsp *par); diff --git a/drivers/nble/gatt_internal.h b/drivers/nble/gatt_internal.h new file mode 100644 index 00000000000..acf8a19c7d9 --- /dev/null +++ b/drivers/nble/gatt_internal.h @@ -0,0 +1,522 @@ +/** @file + * @brief Internal API for Generic Attribute Profile handling. + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +/* Forward declarations */ +struct ble_core_response; + +/* Max number of service supported, if changed update BLE core needs to be + * updated too! + */ +#define BLE_GATTS_MAX_SERVICES (CONFIG_BT_GATT_BLE_MAX_SERVICES) + +/* + * Internal APIs used between host and BLE controller + * Typically they are required if gatt.h APIs can not be mapped 1:1 onto + * controller API + */ + +/** + * GATT indication types. + */ +enum BLE_GATT_IND_TYPES { + BLE_GATT_IND_TYPE_NONE = 0, + BLE_GATT_IND_TYPE_NOTIFICATION, + BLE_GATT_IND_TYPE_INDICATION, +}; + +/** GATT Register structure for one service */ +struct ble_gatt_register { + /**< Index of service data base, used in response to match request */ + uint8_t service_idx; + uint8_t attr_count; /**< Number of of attributes in this service */ +}; + +/** Service index and Attribute index mapping structure. + * + * Mapping index into attribute tables as registered with bt_gatt_register/ + * ble_gatt_register. + */ +struct ble_gatt_attr_handle_mapping { + uint8_t svc_idx; /**< Service index */ + uint8_t attr_idx; /**< Attribute index into service attribute table */ +}; + +enum BLE_GATTS_WR_OPS { + BLE_GATTS_OP_NONE = 0, + /**< 3.4.5.1 Write Request (Attribute), expects write response */ + BLE_GATTS_OP_WR, + /**< 3.4.5.3 Write Command (Attribute) NO response sent */ + BLE_GATTS_OP_WR_CMD, + /**< 3.4.5.4 Write Command Signed (Attribute), NO response sent */ + BLE_GATTS_OP_WR_CMD_SIGNED, + /**< 3.4.6.1 Write Prepare Request, expects a prepare write request + * response + */ + BLE_GATTS_OP_WR_PREP_REQ, + /**< 3.4.6.3 Cancel Executed Write Request, cancel and clear queue + * (flags = 0) + */ + BLE_GATTS_OP_WR_EXE_REQ_CANCEL, + /**< 3.4.6.3 Immediately Execute Write Request */ + BLE_GATTS_OP_WR_EXE_REQ_IMM +}; + +/** + * Write event context data structure. + */ +struct ble_gatt_wr_evt { + /**< Attribute mapping indexes */ + struct ble_gatt_attr_handle_mapping attr; + uint16_t conn_handle; /**< Connection handle */ + uint16_t attr_handle; /**< handle of attribute to write */ + uint16_t offset; /**< offset in attribute buffer */ + uint8_t op; /**< @ref BLE_GATTS_WR_OPS */ +}; + +/** + * Notification/Indication parameters + */ +struct ble_gatt_notif_ind_params { + uint16_t val_handle; + uint16_t offset; +}; + +/** + * Indication or notification. + */ + +struct ble_gatt_send_notif_ind_params { + uint16_t conn_handle; + struct ble_gatt_notif_ind_params params; +}; + +enum ble_gatts_notif_ind_type { + MSG_ID_BLE_GATTS_SEND_NOTIF_RSP, /**< Notification type */ + MSG_ID_BLE_GATTS_SEND_IND_RSP, /**< Indication type */ +}; + +struct ble_gatt_notif_ind_rsp { + int status; /**< Status of the operation. */ + /**< Connection handle, can be 0xFFFF if value change broadcast */ + uint16_t conn_handle; + uint16_t handle; /**< Characteristic value handle */ + /**< MSG_ID_BLE_GATTS_SEND_NOTIF_RSP for notification or + * MSG_ID_BLE_GATTS_SEND_IND_RSP for indication + */ + uint8_t msg_type; +}; + +/** + * Attribute handle range definition. + */ +struct ble_core_gatt_handle_range { + uint16_t start_handle; + uint16_t end_handle; +}; + +struct ble_gattc_svc { + /**< range of characteristic handles within a service */ + struct ble_core_gatt_handle_range handle_range; + struct bt_uuid uuid; /**< service uuid */ +}; + +/** + * Primary service + */ +struct ble_gattc_prim_svc { + struct bt_uuid uuid; /**< Attribute's UUID */ + uint16_t handle; /**< Attribute handle */ + struct ble_core_gatt_handle_range handle_range; /**< handle range */ +}; + +/** + * Generic GATTC response message. + */ +struct ble_gattc_rsp { + int status; + uint16_t conn_handle; /**< GAP connection handle */ +}; + +struct ble_gattc_evt { + uint16_t conn_handle; + int status; +}; + +/** + * Included service. + */ +struct ble_gattc_incl_svc { + uint16_t incl_handle; /**< Handle of included service */ + struct ble_gattc_svc svc; /**< Included service */ + struct ble_core_gatt_handle_range handle_range; /**< handle range */ +}; + +/* GATTC characteristic */ +struct ble_gattc_characteristic { + uint8_t prop; /**< Charact property */ + uint16_t decl_handle; /**< Charact declaration handle */ + uint16_t value_handle; /**< Charact value handle */ + struct bt_uuid uuid; /**< Charact UUID */ +}; + +/** + * GATTC descriptor. + */ +struct ble_gattc_descriptor { + uint16_t handle; /**< descriptor handle */ + struct bt_uuid uuid; /**< uuid of the descriptor */ +}; + +struct ble_gattc_attr { + uint8_t type; /**< @ref BLE_GATT_DISC_TYPES */ + union { + struct ble_gattc_prim_svc prim; + struct ble_gattc_incl_svc incls; + struct ble_gattc_characteristic chars; + struct ble_gattc_descriptor desc; + }; +}; + +struct ble_gatts_set_attribute_params { + uint16_t value_handle; /* mandatory */ + uint16_t offset; /* by default 0 */ +}; + +struct ble_gatts_get_attribute_params { + uint16_t value_handle; /* mandatory */ +}; + +struct ble_gatts_attribute_response { + int status; /**< Status of the operation. */ + uint16_t value_handle; /* mandatory */ + void *p_priv; +}; + +/** + * Set an attribute value. + * + * The response to this request is received through @ref + * on_ble_gatts_send_svc_changed_rsp + * + * @param par attribute parameters + * @param data attribute value data to write + * @param len length of attribute value to write + * @param priv pointer to private data + */ +void ble_gatts_set_attribute_value_req(const struct ble_gatts_set_attribute_params *par, + uint8_t *data, uint8_t len, + void *priv); + +/** + * Response to @ref ble_gatts_send_svc_changed_req. + * + * @param par Response + */ +void on_ble_gatts_set_attribute_value_rsp(const struct ble_gatts_attribute_response *par); + +/** + * Get an attribute value. + * + * The response to this request is received through @ref + * on_ble_gatts_get_attribute_value_rsp + * + * @param par getting attribute parameters + * @param priv pointer to private data + */ +void ble_gatts_get_attribute_value_req(const struct ble_gatts_get_attribute_params *par, + void *priv); + +/** + * Response to @ref ble_gatts_get_attribute_value_req. + * + * @param par response + * @param data attribute value + * @param length length of attribute value + */ +void on_ble_gatts_get_attribute_value_rsp(const struct ble_gatts_attribute_response *par, + uint8_t *data, uint8_t length); + +struct ble_gatts_svc_changed_params { + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +}; + +/** + * Send a service change indication. + * + * The response to this request is received through @ref + * on_ble_gatts_send_svc_changed_rsp + * + * @note Not yet supported + * + * @param par service parameters + * @param priv pointer to private data + */ +void ble_gatts_send_svc_changed_req(const struct ble_gatts_svc_changed_params *par, + void *priv); + +/** + * Response to @ref ble_gatts_send_svc_changed_req. + * + * @param par Response + */ +void on_ble_gatts_send_svc_changed_rsp(const struct ble_core_response *par); + +/** Register a BLE GATT Service. + * + * @param par Parameters of attribute data base + * @param attr Serialized attribute buffer + * @param attr_len length of buffer + */ +void ble_gatt_register_req(const struct ble_gatt_register *par, + uint8_t *buf, uint16_t len); + +/** + * Conversion table entry ble_core to host attr index + * + * This is returned as a table on registering. + */ +struct ble_gatt_attr_idx_entry { + uint16_t handle; /* handle from ble contr should be sufficient */ +}; + +/** Response to registering a BLE GATT Service. + * + * The returned buffer contains an array (@ref ble_gatt_attr_idx_entry)with the + * corresponding handles. + * + * @param par Parameters of attribute data base + * @param attr Returned attributes index list + * @param attr_len length of buffer + */ +void on_ble_gatt_register_rsp(const struct ble_gatt_register *par, + const struct ble_gatt_attr_idx_entry *attr, + uint8_t len); + +/** + * Function invoked by the BLE core when a write occurs. + * + * @param ev Pointer to the event structure + * @param buf Pointer to data buffer + * @param buflen Buffer length + */ +void on_ble_gatts_write_evt(const struct ble_gatt_wr_evt *ev, + const uint8_t *buf, uint8_t buflen); + +/** + * Retrieves handle based on attribute array and index of attribute + * + * @param attrs attribute array + * @param index index of attribute + * + * @return Handle of attribute or 0 if not found + */ +uint16_t ble_attr_idx_to_handle(const struct bt_gatt_attr *attrs, + uint8_t index); + +/** + * Send notification. + * + * The response to this request is received through @ref + * on_ble_gatts_send_notif_ind_rsp + * + * @param par notification parameters + * @param data indication data to write + * @param length length of indication - may be 0, in this case already + * stored data is sent + */ +void ble_gatt_send_notif_req(const struct ble_gatt_send_notif_ind_params *par, + uint8_t *data, uint16_t length); + +/** + * Send indication. + * + * The response to this request is received through @ref + * on_ble_gatts_send_notif_ind_rsp + * + * @param par indication parameters + * @param data indication data to write + * @param length length of indication - may be 0, in this case already + * stored data is sent + */ +void ble_gatt_send_ind_req(const struct ble_gatt_send_notif_ind_params *par, + uint8_t *data, uint8_t length); + +/** + * Response to @ref ble_gatts_send_ind_req and @ref ble_gatts_send_notif_req + * + * @param par Response + */ +void on_ble_gatts_send_notif_ind_rsp(const struct ble_gatt_notif_ind_rsp *par); + +/** Discover parameters. */ +struct ble_core_discover_params { + struct bt_uuid uuid; /**< Attribute UUID */ + struct ble_core_gatt_handle_range handle_range; /**< Discover range */ + uint16_t conn_handle; /**< Connection handle */ + uint8_t type; /**< Discover type @ref BLE_GATT_DISC_TYPES */ +}; + +/** + * Discover service. + * + * @param req Request structure. + * @param priv Pointer to private data. + */ +void ble_gattc_discover_req(const struct ble_core_discover_params *req, + void *priv); + +/** + * Response to @ref ble_gattc_discover_req. + * + * @param ev Pointer to the event structure + * @param data Pointer to the data + * @param data_len Length of the data + */ +void on_ble_gattc_discover_rsp(const struct ble_gattc_evt *ev, + const struct ble_gattc_attr *data, uint8_t data_len); + +/** GATT Attribute stream structure. + * + * This structure is a "compressed" copy of @ref bt_gatt_attr. + * UUID pointer and user_data pointer are used as offset into buffer itself. + * The offset is from the beginning of the buffer. therefore a value of 0 + * means that UUID or user_data is not present. + */ +struct ble_gatt_attr { + /** Attribute UUID offset */ + uint16_t uuid_offset; + /** Attribute user data offset */ + uint16_t user_data_offset; + /**< User data max length */ + uint16_t max_len; + /** Attribute permissions */ + uint16_t perm; +}; + +struct ble_gattc_read_params { + uint16_t conn_handle; /**< Connection handle*/ + uint16_t char_handle; /**< Handle of the attribute to be read */ + uint16_t offset; /**< Offset into the attr value to be read */ +}; + +struct ble_gattc_read_rsp { + uint16_t conn_handle; + int status; + uint16_t handle; /**< handle of char attr read */ + uint16_t offset; /**< offset of data returned */ +}; + +struct ble_gattc_write_params { + uint16_t conn_handle; /**< Connection handle*/ + uint16_t char_handle; /**< Handle of the attribute to be read */ + uint16_t offset; /**< Offset into the attr value to be write */ + bool with_resp; /**< Equal to true is response is needed */ +}; + +struct ble_gattc_write_rsp { + uint16_t conn_handle; + int status; + uint16_t char_handle; + uint16_t len; +}; + + +/** + * Read characteristic on remote server. + * + * @param params Request structure. + * @param priv Pointer to private data. + */ +void ble_gattc_read_req(const struct ble_gattc_read_params *params, + void *priv); + +/** + * Response to @ref ble_gattc_read_req. + * + * @param ev Pointer to the event structure + * @param data Pointer to the data byte stream + * @param data_len Length of the data byte stream + * @param priv Pointer to private data. + */ +void on_ble_gattc_read_rsp(const struct ble_gattc_read_rsp *ev, + uint8_t *data, uint8_t data_len, void *priv); + +/** + * Write characteristic on server. + * + * @param params Write parameters + * @param buf Characteristic value to write. + * @param buflen Characteristic value length. If length is bigger then ATT MTU + * size, the controller fragment buffer itself. + * @param priv Pointer to private data. + */ +void ble_gattc_write_req(const struct ble_gattc_write_params *params, + const uint8_t *buf, uint8_t buflen, void *priv); + +/** + * Response to @ref ble_gattc_write_req. + * + * @param ev Pointer to the event structure + * @param priv Pointer to private data. + */ +void on_ble_gattc_write_rsp(const struct ble_gattc_write_rsp *ev, + void *priv); + +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) +void bt_gatt_connected(struct bt_conn *conn); +void bt_gatt_disconnected(struct bt_conn *conn); +#endif + +struct ble_gattc_value_evt { + uint16_t conn_handle; + int status; + /**< handle of characteristic being notified/indicated */ + uint16_t handle; + /**< notification versus indication, @ref BLE_GATT_IND_TYPES */ + uint8_t type; +}; + +/** + * Function invoked by BLE service for value event + * + * @param ev Pointer to the event structure + * @param buf Pointer to the data byte stream + * @param buflen Length of the data byte stream + */ +void on_ble_gattc_value_evt(const struct ble_gattc_value_evt *ev, + uint8_t *buf, uint8_t buflen); + +struct ble_gattc_to_evt { + uint16_t conn_handle; + uint16_t reason; /**< GATT timeout reason */ +}; + +/** + * Function invoked by BLE service for gattc timeout protocol error + * + * @param ev Pointer to the event structure + */ +void on_ble_gattc_to_evt(const struct ble_gattc_to_evt *ev); diff --git a/drivers/nble/rpc.h b/drivers/nble/rpc.h new file mode 100644 index 00000000000..fdf4c692326 --- /dev/null +++ b/drivers/nble/rpc.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +/** Identifiers of the signature supported by the RPC */ +enum { + SIG_TYPE_NONE = 1, + SIG_TYPE_S, + SIG_TYPE_P, + SIG_TYPE_S_B, + SIG_TYPE_B_B_P, + SIG_TYPE_S_P, + SIG_TYPE_S_B_P, + SIG_TYPE_S_B_B_P +}; + +/** + * RPC memory allocation function, must be implemented by the user of the RPC. + * + * This function is called by the RPC mechanism to allocate a buffer for + * transmission of a serialized function. The function should not fail. + * + * @param length Length of the buffer to allocate + * + * @return Pointer to the allocated buffer, the allocation shall not fail, + * error must be handled internally + */ +uint8_t *rpc_alloc_cb(uint16_t length); + +/** + * RPC transmission function, must be implemented by the user of the RPC. + * + * @param p_buf Pointer to the buffer allocated for transmission + * by @ref rpc_alloc_cb + * @param length Length of the buffer to transmit + */ +void rpc_transmit_cb(uint8_t *p_buf, uint16_t length); + +/** + * RPC serialization function to serialize a function that does not require any + * parameter. + * + * @param fn_index Index of the function + */ +void rpc_serialize_none(uint8_t fn_index); + +/** + * RPC serialization function to serialize a function that expects a structure + * as parameter. + * + * @param fn_index Index of the function + * @param struct_data Pointer to the structure to serialize + * @param struct_length Length of the structure to serialize + */ +void rpc_serialize_s(uint8_t fn_index, const void *struct_data, + uint8_t struct_length); + +/** + * RPC serialization function to serialize a function that expects a structure + * as parameter. + * + * @param fn_index Index of the function + * @param struct_data Pointer to the structure to serialize + * @param struct_length Length of the structure to serialize + * @param p_priv Pointer to serialize + */ +void rpc_serialize_s_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, void *p_priv); + +/** + * RPC serialization function to serialize a function that expects a pointer as + * parameter. + * + * @param fn_index Index of the function + * @param p_priv Pointer to serialize + */ +void rpc_serialize_p(uint8_t fn_index, void *p_priv); + +/** + * RPC serialization function to serialize a function that expects a structure + * and a buffer as parameters. + * + * @param fn_index Index of the function + * @param struct_data Pointer to the structure to serialize + * @param struct_length Length of the structure to serialize + * @param vbuf Pointer to the buffer to serialize + * @param vbuf_length Length of the buffer to serialize + */ +void rpc_serialize_s_b(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf, + uint16_t vbuf_length); + +/** + * RPC serialization function to serialize a function that expects a structure + * and a buffer as parameters. + * + * @param fn_index Index of the function + * @param vbuf1 Pointer to the buffer1 to serialize + * @param vbuf1_length Length of the buffer1 to serialize + * @param vbuf2 Pointer to the buffer2 to serialize + * @param vbuf2_length Length of the buffer2 to serialize + * @param p_priv Pointer to serialize + */ +void rpc_serialize_b_b_p(uint8_t fn_index, const void *vbuf1, + uint16_t vbuf1_length, const void *vbuf2, + uint16_t vbuf2_length, void *p_priv); + +/** + * RPC serialization function to serialize a function that expects a structure + * and a buffer as parameters. + * + * @param fn_index Index of the function + * @param struct_data Pointer to the structure to serialize + * @param struct_length Length of the structure to serialize + * @param vbuf Pointer to the buffer to serialize + * @param vbuf_length Length of the buffer to serialize + * @param p_priv Pointer to serialize + */ +void rpc_serialize_s_b_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf, + uint16_t vbuf_length, void *p_priv); + +/** + * RPC serialization function to serialize a function that expects a structure + * and a buffer as parameters. + * + * @param fn_index Index of the function + * @param struct_data Pointer to the structure to serialize + * @param struct_length Length of the structure to serialize + * @param vbuf1 Pointer to the buffer1 to serialize + * @param vbuf1_length Length of the buffer1 to serialize + * @param vbuf2 Pointer to the buffer2 to serialize + * @param vbuf2_length2 Length of the buffer2 to serialize + * @param p_priv Pointer to serialize + */ +void rpc_serialize_s_b_b_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf1, + uint16_t vbuf1_length, const void *vbuf2, + uint16_t vbuf2_length, void *p_priv); + +/** + * RPC deserialization function, shall be invoked when a buffer is received + * over the transport interface. + * + * @param p_buf Pointer to the received buffer + * @param length Length of the received buffer + */ +void rpc_deserialize(const uint8_t *p_buf, uint16_t length); diff --git a/drivers/nble/rpc_functions_to_ble_core.h b/drivers/nble/rpc_functions_to_ble_core.h new file mode 100644 index 00000000000..d6bef43b4af --- /dev/null +++ b/drivers/nble/rpc_functions_to_ble_core.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gap_internal.h" +#include "gatt_internal.h" + +/* declare the list of functions sorted by signature */ +#define LIST_FN_SIG_NONE + +#define LIST_FN_SIG_S \ + FN_SIG_S(ble_gap_start_advertise_req, struct ble_gap_adv_params *) + +#define LIST_FN_SIG_P \ + FN_SIG_P(ble_get_version_req, void *) \ + FN_SIG_P(ble_gap_dtm_init_req, void *) \ + FN_SIG_P(ble_gap_read_bda_req, void *) \ + FN_SIG_P(ble_gap_stop_advertise_req, void *) \ + FN_SIG_P(ble_gap_clr_white_list_req, void *) \ + FN_SIG_P(ble_gap_stop_scan_req, void *) \ + FN_SIG_P(ble_gap_sm_clear_bonds_req, void *) \ + FN_SIG_P(ble_get_bonded_device_list_req, void *) + +#define LIST_FN_SIG_S_B \ + FN_SIG_S_B(ble_gatt_register_req, \ + const struct ble_gatt_register *, \ + uint8_t *, uint16_t) \ + FN_SIG_S_B(ble_gatt_send_notif_req, \ + const struct ble_gatt_send_notif_ind_params *, \ + uint8_t *, uint16_t) \ + FN_SIG_S_B(ble_gatt_send_ind_req, \ + const struct ble_gatt_send_notif_ind_params *, \ + uint8_t *, uint8_t) + +#define LIST_FN_SIG_B_B_P \ + FN_SIG_B_B_P(ble_gap_wr_white_list_req, bt_addr_le_t *, \ + uint8_t, struct ble_gap_irk_info *, \ + uint8_t, void *) + +#define LIST_FN_SIG_S_P \ + FN_SIG_S_P(ble_gap_disconnect_req, \ + const struct ble_gap_disconnect_req_params *, void *)\ + FN_SIG_S_P(ble_gap_sm_pairing_req, \ + const struct ble_core_gap_sm_pairing_req_params *, \ + void *) \ + FN_SIG_S_P(ble_gap_sm_config_req, \ + const struct ble_core_gap_sm_config_params *, void *)\ + FN_SIG_S_P(ble_gap_sm_passkey_reply_req, \ + const struct ble_gap_sm_key_reply_req_params *, \ + void *) \ + FN_SIG_S_P(ble_gap_connect_req, \ + const struct ble_gap_connect_req_params *, void *) \ + FN_SIG_S_P(ble_gap_start_scan_req, \ + const struct ble_gap_scan_params *, void *) \ + FN_SIG_S_P(ble_gap_cancel_connect_req, \ + const struct ble_gap_cancel_connect_params *, void *)\ + FN_SIG_S_P(ble_gap_generic_cmd_req, \ + const struct ble_gap_gen_cmd_params *, void *) \ + FN_SIG_S_P(ble_gap_set_option_req, \ + const struct ble_gap_set_option_params *, void *) \ + FN_SIG_S_P(ble_gap_conn_update_req, \ + const struct ble_gap_connect_update_params *, void *)\ + FN_SIG_S_P(ble_gap_service_read_req, \ + const struct ble_gap_service_read_params *, void *) \ + FN_SIG_S_P(ble_set_enable_config_req, \ + const struct ble_wr_config_params *, void *) \ + FN_SIG_S_P(ble_gap_set_rssi_report_req, \ + const struct ble_core_rssi_report_params *, void *) \ + FN_SIG_S_P(ble_gap_service_write_req, \ + const struct ble_gap_service_write_params *, void *) \ + FN_SIG_S_P(ble_gap_dbg_req, const struct debug_params *, void *)\ + FN_SIG_S_P(ble_gattc_discover_req, \ + const struct ble_core_discover_params *, void *) \ + FN_SIG_S_P(ble_gattc_read_req, \ + const struct ble_gattc_read_params *, void *) \ + FN_SIG_S_P(ble_gatts_send_svc_changed_req, \ + const struct ble_gatts_svc_changed_params *, void *) \ + FN_SIG_S_P(ble_gatts_get_attribute_value_req, \ + const struct ble_gatts_get_attribute_params *, \ + void *) + +#define LIST_FN_SIG_S_B_P \ + FN_SIG_S_B_P(ble_gatts_set_attribute_value_req, \ + const struct ble_gatts_set_attribute_params *, \ + uint8_t *, uint8_t, void *) \ + FN_SIG_S_B_P(ble_gattc_write_req, \ + const struct ble_gattc_write_params *, \ + const uint8_t *, uint8_t, void *) + +#define LIST_FN_SIG_S_B_B_P diff --git a/drivers/nble/rpc_functions_to_quark.h b/drivers/nble/rpc_functions_to_quark.h new file mode 100644 index 00000000000..9371c6abafb --- /dev/null +++ b/drivers/nble/rpc_functions_to_quark.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gap_internal.h" +#include "gatt_internal.h" + +/* declare the list of functions sorted by signature */ +#define LIST_FN_SIG_NONE \ + FN_SIG_NONE(on_nble_up) + +#define LIST_FN_SIG_S \ + FN_SIG_S(on_ble_get_version_rsp, \ + const struct ble_version_response *) + +#define LIST_FN_SIG_P +#define LIST_FN_SIG_S_B +#define LIST_FN_SIG_B_B_P +#define LIST_FN_SIG_S_B_P +#define LIST_FN_SIG_S_P +#define LIST_FN_SIG_S_B_B_P + +#if 0 +#define LIST_FN_SIG_S \ + FN_SIG_S(on_ble_get_version_rsp, \ + const struct ble_version_response *) \ + FN_SIG_S(on_ble_gap_connect_evt, \ + const struct ble_gap_connect_evt *) \ + FN_SIG_S(on_ble_gap_disconnect_evt, \ + const struct ble_gap_disconnect_evt *) \ + FN_SIG_S(on_ble_gap_conn_update_evt, \ + const struct ble_gap_conn_update_evt *) \ + FN_SIG_S(on_ble_gap_sm_status_evt, \ + const struct ble_gap_sm_status_evt *) \ + FN_SIG_S(on_ble_gap_sm_passkey_display_evt, \ + const struct ble_gap_sm_passkey_disp_evt *) \ + FN_SIG_S(on_ble_gap_sm_passkey_req_evt, \ + const struct ble_gap_sm_passkey_req_evt *) \ + FN_SIG_S(on_ble_gap_to_evt, \ + const struct ble_gap_timout_evt *) \ + FN_SIG_S(on_ble_gap_rssi_evt, \ + const struct ble_gap_rssi_evt *) \ + FN_SIG_S(on_ble_gap_service_read_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_read_bda_rsp, \ + const struct ble_service_read_bda_response *) \ + FN_SIG_S(on_ble_gap_disconnect_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_sm_pairing_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_sm_config_rsp, \ + struct ble_gap_sm_config_rsp *) \ + FN_SIG_S(on_ble_gap_clr_white_list_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_sm_passkey_reply_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_connect_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_start_scan_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_stop_scan_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_cancel_connect_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_set_option_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_generic_cmd_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_conn_update_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_sm_clear_bonds_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_service_write_rsp, \ + const struct ble_service_write_response *) \ + FN_SIG_S(on_ble_set_enable_config_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_set_rssi_report_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_wr_white_list_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_dbg_rsp, \ + const struct debug_response *) \ + FN_SIG_S(on_ble_gatts_send_svc_changed_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gatts_set_attribute_value_rsp, \ + const struct ble_gatts_attribute_response *) \ + FN_SIG_S(on_ble_gatts_send_notif_ind_rsp, \ + const struct ble_gatt_notif_ind_rsp *) \ + FN_SIG_S(on_ble_get_bonded_device_list_rsp, \ + const struct ble_get_bonded_device_list_rsp*) \ + FN_SIG_S(on_ble_gap_start_advertise_rsp, \ + const struct ble_core_response *) \ + FN_SIG_S(on_ble_gap_stop_advertise_rsp, \ + const struct ble_core_response *) + +#define LIST_FN_SIG_P \ + FN_SIG_P(on_ble_gap_dtm_init_rsp, void *) + +#define LIST_FN_SIG_S_B \ + FN_SIG_S_B(ble_log, const struct ble_log_s *, \ + char *, uint8_t) \ + FN_SIG_S_B(on_ble_gattc_value_evt, \ + const struct ble_gattc_value_evt *, \ + uint8_t *, uint8_t) \ + FN_SIG_S_B(on_ble_gatts_write_evt, \ + const struct ble_gatt_wr_evt *, \ + const uint8_t *, uint8_t) \ + FN_SIG_S_B(on_ble_gatts_get_attribute_value_rsp, \ + const struct ble_gatts_attribute_response *, \ + uint8_t *, uint8_t) \ + FN_SIG_S_B(on_ble_gatt_register_rsp, \ + const struct ble_gatt_register *, \ + const struct ble_gatt_attr_idx_entry *, \ + uint8_t) \ + FN_SIG_S_B(on_ble_gattc_discover_rsp, \ + const struct ble_gattc_evt *, \ + const struct ble_gattc_attr *, uint8_t) + +#define LIST_FN_SIG_B_B_P + +#define LIST_FN_SIG_S_P \ + FN_SIG_S_P(on_ble_gattc_write_rsp, \ + const struct ble_gattc_write_rsp *, void*) + +#define LIST_FN_SIG_S_B_P \ + FN_SIG_S_B_P(on_ble_gattc_read_rsp, \ + const struct ble_gattc_read_rsp *, \ + uint8_t *, uint8_t, void*) + +#define LIST_FN_SIG_S_B_B_P +#endif diff --git a/drivers/nble/rpc_serialize.c b/drivers/nble/rpc_serialize.c new file mode 100644 index 00000000000..33d2e6ec440 --- /dev/null +++ b/drivers/nble/rpc_serialize.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "rpc.h" + +#include "rpc_functions_to_ble_core.h" + +/* Build the functions exposed */ +/* Define the functions identifiers per signature */ +#define FN_SIG_NONE(__fn) fn_index_##__fn, +#define FN_SIG_S(__fn, __s) FN_SIG_NONE(__fn) +#define FN_SIG_P(__fn, __type) FN_SIG_NONE(__fn) +#define FN_SIG_S_B(__fn, __s, __type, __length) FN_SIG_NONE(__fn) +#define FN_SIG_B_B_P(__fn, __type1, __length1, __type2, __length2, __type3) \ + FN_SIG_NONE(__fn) +#define FN_SIG_S_P(__fn, __s, __type) FN_SIG_NONE(__fn) +#define FN_SIG_S_B_P(__fn, __s, __type, __length, __type_ptr) \ + FN_SIG_NONE(__fn) +#define FN_SIG_S_B_B_P(__fn, __s, __type1, __length1, __type2, __length2, \ + __type3) FN_SIG_NONE(__fn) + +/* Build the list of function indexes -> this should match the array at + * deserialization + */ +enum { LIST_FN_SIG_NONE fn_none_index_max }; +enum { LIST_FN_SIG_S fn_s_index_max }; +enum { LIST_FN_SIG_P fn_p_index_max }; +enum { LIST_FN_SIG_S_B fn_s_b_index_max }; +enum { LIST_FN_SIG_B_B_P fn_b_b_p_index_max }; +enum { LIST_FN_SIG_S_P fn_s_p_index_max }; +enum { LIST_FN_SIG_S_B_P fn_s_b_p_index_max }; +enum { LIST_FN_SIG_S_B_B_P fn_s_b_b_p_index_max }; + +/* Implement the functions using serialization API */ +#undef FN_SIG_NONE +#undef FN_SIG_S +#undef FN_SIG_P +#undef FN_SIG_S_B +#undef FN_SIG_B_B_P +#undef FN_SIG_S_P +#undef FN_SIG_S_B_P +#undef FN_SIG_S_B_B_P + +#define FN_SIG_NONE(__fn) \ + void __fn(void) \ + { \ + rpc_serialize_none(fn_index_##__fn); \ + } + +#define FN_SIG_S(__fn, __s) \ + void __fn(__s p_s) \ + { \ + rpc_serialize_s(fn_index_##__fn, p_s, sizeof(*p_s)); \ + } + +#define FN_SIG_P(__fn, __type) \ + void __fn(__type p_priv) \ + { \ + rpc_serialize_p(fn_index_##__fn, p_priv); \ + } + +#define FN_SIG_S_B(__fn, __s, __type, __length) \ + void __fn(__s p_s, __type p_buf, __length length) \ + { \ + rpc_serialize_s_b(fn_index_##__fn, p_s, sizeof(*p_s), \ + p_buf, length); \ + } + +#define FN_SIG_B_B_P(__fn, __type1, __length1, __type2, __length2, \ + __type3) \ + void __fn(__type1 p_buf1, __length1 length1, __type2 p_buf2, \ + __length2 length2, __type3 p_priv) \ + { \ + rpc_serialize_b_b_p(fn_index_##__fn, p_buf1, length1, \ + p_buf2, length2, p_priv); \ + } + +#define FN_SIG_S_P(__fn, __s, __type) \ + void __fn(__s p_s, __type p_priv) \ + { \ + rpc_serialize_s_p(fn_index_##__fn, p_s, sizeof(*p_s), \ + p_priv); \ + } + +#define FN_SIG_S_B_P(__fn, __s, __type, __length, __type_ptr) \ + void __fn(__s p_s, __type p_buf, __length length, \ + __type_ptr p_priv) \ + { \ + rpc_serialize_s_b_p(fn_index_##__fn, p_s, sizeof(*p_s), \ + p_buf, length, p_priv); \ + } + +#define FN_SIG_S_B_B_P(__fn, __s, __type1, __length1, __type2, \ + __length2, __type3) \ + void __fn(__s p_s, __type1 p_buf1, __length1 length1, \ + __type2 p_buf2, __length2 length2, __type3 p_priv) \ + { \ + rpc_serialize_s_b_b_p(fn_index_##__fn, p_s, \ + sizeof(*p_s), p_buf1, length1, \ + p_buf2, length2, p_priv); \ + } + + +/* Build the functions */ +LIST_FN_SIG_NONE +LIST_FN_SIG_S +LIST_FN_SIG_P +LIST_FN_SIG_S_B +LIST_FN_SIG_B_B_P +LIST_FN_SIG_S_P +LIST_FN_SIG_S_B_P +LIST_FN_SIG_S_B_B_P + +#define SIG_TYPE_SIZE 1 +#define FN_INDEX_SIZE 1 +#define POINTER_SIZE 4 + +static void _send(uint8_t *buf, uint16_t length) +{ + rpc_transmit_cb(buf, length); +} + +static uint16_t encoded_structlen(uint8_t structlen) +{ + return 1 + structlen; +} + +static uint8_t *serialize_struct(uint8_t *p, const uint8_t *struct_data, + uint8_t struct_length) +{ + *p++ = struct_length; + memcpy(p, struct_data, struct_length); + p += struct_length; + + return p; +} + +static uint16_t encoded_buflen(const uint8_t *buf, uint16_t buflen) +{ + if (!buf) { + return 1; + } + + if (buflen < (1 << 7)) { + return 1 + buflen; + } else { + return 2 + buflen; + } +} + +static uint8_t *serialize_buf(uint8_t *p, const uint8_t *buf, uint16_t buflen) +{ + uint16_t varint; + + if (!buf) { + buflen = 0; + } + + varint = buflen; + + *p = varint & 0x7F; + if (varint >= (1 << 7)) { + *p |= 0x80; + p++; + *p = varint >> 7; + } + + p++; + memcpy(p, buf, buflen); + p += buflen; + + return p; +} + +static uint8_t *serialize_p(uint8_t *p, uintptr_t priv) +{ + *p++ = priv; + *p++ = (priv >> 8); + *p++ = (priv >> 16); + *p++ = (priv >> 24); + + return p; +} + +void rpc_serialize_none(uint8_t fn_index) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_NONE; + *p = fn_index; + + _send(buf, length); +} + +void rpc_serialize_s(uint8_t fn_index, const void *struct_data, + uint8_t struct_length) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + + encoded_structlen(struct_length); + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_S; + *p++ = fn_index; + p = serialize_struct(p, struct_data, struct_length); + + _send(buf, length); +} + + +void rpc_serialize_p(uint8_t fn_index, void *p_priv) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + uintptr_t priv = (uintptr_t) p_priv; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + POINTER_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_P; + *p++ = fn_index; + p = serialize_p(p, priv); + + _send(buf, length); +} + +void rpc_serialize_s_b(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf, + uint16_t vbuf_length) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + + encoded_structlen(struct_length) + + encoded_buflen(vbuf, vbuf_length); + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_S_B; + *p++ = fn_index; + p = serialize_struct(p, struct_data, struct_length); + p = serialize_buf(p, vbuf, vbuf_length); + + _send(buf, length); +} + +void rpc_serialize_b_b_p(uint8_t fn_index, const void *vbuf1, + uint16_t vbuf1_length, const void *vbuf2, + uint16_t vbuf2_length, void *p_priv) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + uintptr_t priv = (uintptr_t) p_priv; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + + encoded_buflen(vbuf1, vbuf1_length) + + encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_B_B_P; + *p++ = fn_index; + p = serialize_buf(p, vbuf1, vbuf1_length); + p = serialize_buf(p, vbuf2, vbuf2_length); + p = serialize_p(p, priv); + + _send(buf, length); +} + +void rpc_serialize_s_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, void *p_priv) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + uintptr_t priv = (uintptr_t) p_priv; + + length = SIG_TYPE_SIZE + + FN_INDEX_SIZE + encoded_structlen(struct_length) + + POINTER_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_S_P; + *p++ = fn_index; + p = serialize_struct(p, struct_data, struct_length); + p = serialize_p(p, priv); + + _send(buf, length); +} + +void rpc_serialize_s_b_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf, + uint16_t vbuf_length, void *p_priv) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + uintptr_t priv = (uintptr_t) p_priv; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + + encoded_structlen(struct_length) + + encoded_buflen(vbuf, vbuf_length) + POINTER_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_S_B_P; + *p++ = fn_index; + p = serialize_struct(p, struct_data, struct_length); + p = serialize_buf(p, vbuf, vbuf_length); + p = serialize_p(p, priv); + + _send(buf, length); +} + +void rpc_serialize_s_b_b_p(uint8_t fn_index, const void *struct_data, + uint8_t struct_length, const void *vbuf1, + uint16_t vbuf1_length, const void *vbuf2, + uint16_t vbuf2_length, void *p_priv) +{ + uint16_t length; + uint8_t *buf; + uint8_t *p; + uintptr_t priv = (uintptr_t) p_priv; + + length = SIG_TYPE_SIZE + FN_INDEX_SIZE + + encoded_structlen(struct_length) + + encoded_buflen(vbuf1, vbuf1_length) + + encoded_buflen(vbuf2, vbuf2_length) + POINTER_SIZE; + + p = buf = rpc_alloc_cb(length); + + *p++ = SIG_TYPE_S_B_B_P; + *p++ = fn_index; + p = serialize_struct(p, struct_data, struct_length); + p = serialize_buf(p, vbuf1, vbuf1_length); + p = serialize_buf(p, vbuf2, vbuf2_length); + p = serialize_p(p, priv); + + _send(buf, length); +} diff --git a/drivers/nble/version.h b/drivers/nble/version.h new file mode 100644 index 00000000000..7f53f89a87a --- /dev/null +++ b/drivers/nble/version.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +/** + * @defgroup infra_version Binary Version Header + * Define the content of binary version header + * @ingroup infra + * @{ + */ + +/** + * Define the content of a 48-bytes binary version header. + * + * The binary version header allows to uniquely identify the binary used. Note: + * - a device may include more than one binary, each having its own binary + * version header. + * - the position of this struct is usually defined in the linker script and + * its content is overwritten after the build (in a special post-build script). + * It therefore doesn't need to be initialized at compile-time (excepted magic + * and version), yet can be used in the code at runtime. + * + * The binary version header is usually localized at the beginning of + * the payload, but in the case of e.g. a bootloader, it can also be stored + * at the end of the payload, or even anywhere within the payload. + * + * Major, Minor, Patch are the following the usual definition, e.g. 1.0.0 + */ +struct version_header { + /** Always equal to $B!N */ + uint8_t magic[4]; + + /** Header format version */ + uint8_t version; + uint8_t major; + uint8_t minor; + uint8_t patch; + + /** + * Human-friendly version string, free format (not NULL terminated) + * Advised format is: PPPPXXXXXX-YYWWTBBBB + * - PPPP : product code, e.g ATP1 + * - XXXXXX: binary info. Usually contains information such as the + * binary type (bootloader, application), build variant (unit tests, + * debug, release), release/branch name + * - YY : year last 2 digits + * - WW : work week number + * - T : build type, e.g. [W]eekly, [L]atest, [R]elease, [P]rod, + * [F]actory, [C]ustom + * - BBBB : build number, left padded with zeros + * Examples: + * - ATP1BOOT01-1503W0234 + * - CLRKAPP123-1502R0013 + */ + char version_string[20]; + + /** + * Micro-SHA1 (first 4 bytes of the SHA1) of the binary payload excl + * this header. It allows to uniquely identify the exact binary used. + * In the case the header is located in the middle of the payload, the + * SHA1 has to be computed from two disjoint buffers. + */ + uint8_t hash[4]; + + /** Position of the payload start relative to the address of struct */ + int32_t offset; + + /** Filled with zeros, can be eventually used for 64 bits support */ + uint8_t reserved_1[4]; + + /** Size of the payload in bytes, including this header */ + uint32_t size; + + /** Filled with zeros, can be eventually used for 64 bits support */ + uint8_t reserved_2[4]; +} __packed; + +/** The global version header struct */ +extern const struct version_header version_header; + +/** @} */