475 lines
19 KiB
C
475 lines
19 KiB
C
/**
|
|
* Copyright (c) 2017 - 2020, 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_ots Object Transfer Service
|
|
* @{
|
|
* @ingroup ble_sdk_srv
|
|
* @brief Object Transfer Service module
|
|
*
|
|
* @details This is the main module of the OTS service.
|
|
*/
|
|
|
|
#ifndef BLE_OTS_H__
|
|
#define BLE_OTS_H__
|
|
|
|
#include <stdint.h>
|
|
#include "ble_srv_common.h"
|
|
#include "ble_date_time.h"
|
|
#include "nrf_ble_gq.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**@brief Macro for defining a ble_ots instance.
|
|
*
|
|
* @param _name Name of the instance.
|
|
* @hideinitializer
|
|
*/
|
|
#define BLE_OTS_DEF(_name) \
|
|
static ble_ots_t _name; \
|
|
NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
|
|
BLE_OTS_BLE_OBSERVER_PRIO, \
|
|
ble_ots_on_ble_evt, &_name) \
|
|
|
|
|
|
#define NRF_BLE_OTS_SIZE_CHAR_LEN (2*sizeof(uint32_t))
|
|
#define BLE_OTS_FEATURE_LEN (2*sizeof(uint32_t))
|
|
#define BLE_OTS_NAME_MAX_SIZE 128
|
|
#define BLE_OTS_MAX_OBJ_SIZE 1028
|
|
#define BLE_OTS_INVALID_CID 0x0000 /**< Invalid connection ID. */
|
|
#define BLE_OTS_PSM 0x0025
|
|
#define BLE_OTS_MAX_OACP_SIZE 21
|
|
#define BLE_OTS_WRITE_MODE_TRUNCATE (1 << 1)
|
|
#define BLE_OTS_WRITE_MODE_NO_TRUNCATE 0
|
|
|
|
// Forward declarations.
|
|
typedef struct ble_ots_s ble_ots_t;
|
|
typedef struct ble_ots_oacp_s ble_ots_oacp_t;
|
|
typedef struct ble_ots_l2cap_s ble_ots_l2cap_t;
|
|
|
|
|
|
/*------------------------------------------ BLE OTS OBJECT --------------------------------------*/
|
|
|
|
/**@brief Properties of an Object Transfer Service object. */
|
|
typedef union
|
|
{
|
|
struct
|
|
{
|
|
bool is_delete_permitted :1;
|
|
bool is_execute_permitted :1;
|
|
bool is_read_permitted :1;
|
|
bool is_write_permitted :1;
|
|
bool is_append_permitted :1;
|
|
bool is_truncate_permitted:1; /**< When writing using truncate mode, and the written length is shorter than the object, the object size is decreased. */
|
|
bool is_patch_permitted :1; /**< When patching, a part of the object is replaced. */
|
|
bool is_marked :1;
|
|
} decoded;
|
|
uint32_t raw;
|
|
} ble_ots_obj_properties_t;
|
|
|
|
/**@brief A structure representing the object type. */
|
|
typedef struct
|
|
{
|
|
uint8_t len; /**< The length of the object type in bytes. 2 and 16 are the only valid type lengths. */
|
|
union
|
|
{
|
|
uint16_t type16;
|
|
uint8_t type128[16];
|
|
} param;
|
|
} ble_ots_obj_type_t;
|
|
|
|
/**@brief The structure representing one Object Transfer Service object. */
|
|
typedef struct
|
|
{
|
|
uint8_t name[BLE_OTS_NAME_MAX_SIZE]; /**< The name of the object. If the name is "", the object will be invalidated on disconnect. */
|
|
uint8_t data[BLE_OTS_MAX_OBJ_SIZE];
|
|
uint32_t current_size;
|
|
ble_ots_obj_type_t type;
|
|
ble_ots_obj_properties_t properties;
|
|
uint32_t alloc_len;
|
|
bool is_valid; /**< States if the object will be shown in a list. */
|
|
bool is_locked; /**< When an object is written or read, the object will be locked. */
|
|
} ble_ots_object_t;
|
|
|
|
/**@brief The definition of an event from the object characteristics. */
|
|
typedef struct
|
|
{
|
|
enum
|
|
{
|
|
BLE_OTS_OBJECT_EVT_NAME_CHANGED,
|
|
BLE_OTS_OBJECT_EVT_PROPERTIES_CHANGED,
|
|
} type;
|
|
union
|
|
{
|
|
ble_ots_object_t * p_object;
|
|
} evt;
|
|
} ble_ots_object_evt_t;
|
|
|
|
/**@brief Initialization properties of the Object Transfer Service Object characteristics. */
|
|
typedef struct
|
|
{
|
|
ble_ots_t * p_ots;
|
|
security_req_t name_read_access;
|
|
security_req_t name_write_access;
|
|
security_req_t type_read_access;
|
|
security_req_t size_read_access;
|
|
security_req_t properties_read_access;
|
|
security_req_t properties_write_access;
|
|
} ble_ots_object_chars_init_t;
|
|
|
|
/**@brief The structure holding the state of the OTS object characteristics. */
|
|
typedef struct
|
|
{
|
|
ble_ots_t * p_ots;
|
|
ble_gatts_char_handles_t obj_name_handles;
|
|
ble_gatts_char_handles_t obj_type_handles;
|
|
ble_gatts_char_handles_t obj_size_handles;
|
|
ble_gatts_char_handles_t obj_properties_handles;
|
|
} ble_ots_object_chars_t;
|
|
|
|
|
|
/*------------------------------------------ BLE OTS L2CAP ---------------------------------------*/
|
|
|
|
/**@brief L2cap event types. */
|
|
typedef enum
|
|
{
|
|
BLE_OTS_L2CAP_EVT_CH_CONNECTED,
|
|
BLE_OTS_L2CAP_EVT_CH_DISCONNECTED,
|
|
BLE_OTS_L2CAP_EVT_SEND_COMPLETE,
|
|
BLE_OTS_L2CAP_EVT_RECV_COMPLETE,
|
|
} ble_ots_l2cap_evt_type_t;
|
|
|
|
/**@brief l2cap event. */
|
|
typedef struct
|
|
{
|
|
ble_ots_l2cap_evt_type_t type;
|
|
struct
|
|
{
|
|
uint8_t * p_data;
|
|
uint16_t len;
|
|
} param;
|
|
} ble_ots_l2cap_evt_t;
|
|
|
|
/**@brief L2CAP event handler. */
|
|
typedef void (*ble_ots_l2cap_evt_handler_t)(ble_ots_l2cap_t * p_ots_l2cap,
|
|
ble_ots_l2cap_evt_t * p_evt);
|
|
|
|
/**@brief The structure holding the l2cap connection oriented channels state. */
|
|
struct ble_ots_l2cap_s
|
|
{
|
|
ble_ots_l2cap_evt_handler_t evt_handler;
|
|
ble_ots_oacp_t * p_ots_oacp;
|
|
enum
|
|
{
|
|
NOT_CONNECTED,
|
|
CONNECTED,
|
|
SENDING,
|
|
RECEIVING
|
|
} state;
|
|
ble_data_t tx_transfer_buffer;
|
|
ble_l2cap_ch_rx_params_t rx_params;
|
|
ble_l2cap_ch_tx_params_t tx_params;
|
|
uint16_t remaining_bytes; /**< The number of remaining bytes in the current transfer. */
|
|
uint16_t transmitted_bytes;
|
|
uint16_t received_bytes;
|
|
uint16_t transfer_len; /**< The total number of bytes in the current transfer. */
|
|
uint16_t local_cid; /**< Connection ID of the current connection. */
|
|
uint16_t conn_mtu; /**< The maximum transmission unit, that is the number of packets that can be sent or received. */
|
|
uint16_t conn_mps; /**< MPS defines the maximum payload size in bytes. */
|
|
};
|
|
|
|
/**@brief The initialization structure of the l2cap module. */
|
|
typedef struct
|
|
{
|
|
ble_ots_oacp_t * p_ots_oacp;
|
|
ble_ots_l2cap_evt_handler_t evt_handler;
|
|
uint8_t * p_transfer_buffer; /**< The user must provide buffer for transfers. */
|
|
uint16_t buffer_len; /**< Length of the transfer buffer. */
|
|
} ble_ots_l2cap_init_t;
|
|
|
|
|
|
/*------------------------------------------ BLE OTS OCAP ----------------------------------------*/
|
|
|
|
/**< Types of Object Action Control Point Procedures. */
|
|
typedef enum
|
|
{
|
|
BLE_OTS_OACP_PROC_CREATE = 0x01, //!< Create object.
|
|
BLE_OTS_OACP_PROC_DELETE = 0x02, //!< Delete object.
|
|
BLE_OTS_OACP_PROC_CALC_CHKSUM = 0x03, //!< Calculate Checksum.
|
|
BLE_OTS_OACP_PROC_EXECUTE = 0x04, //!< Execute Object.
|
|
BLE_OTS_OACP_PROC_READ = 0x05, //!< Read object.
|
|
BLE_OTS_OACP_PROC_WRITE = 0x06, //!< Write object.
|
|
BLE_OTS_OACP_PROC_ABORT = 0x07, //!< Abort object.
|
|
BLE_OTS_OACP_PROC_RESP = 0x60 //!< Procedure response.
|
|
} ble_ots_oacp_proc_type_t;
|
|
|
|
/**< Object Action Control Point return codes. */
|
|
typedef enum
|
|
{
|
|
BLE_OTS_OACP_RES_SUCCESS = 0x01, //!< Success.
|
|
BLE_OTS_OACP_RES_OPCODE_NOT_SUP = 0x02, //!< Not supported
|
|
BLE_OTS_OACP_RES_INV_PARAM = 0x03, //!< Invalid parameter
|
|
BLE_OTS_OACP_RES_INSUFF_RES = 0x04, //!< Insufficient resources.
|
|
BLE_OTS_OACP_RES_INV_OBJ = 0x05, //!< Invalid object.
|
|
BLE_OTS_OACP_RES_CHAN_UNAVAIL = 0x06, //!< Channel unavailable.
|
|
BLE_OTS_OACP_RES_UNSUP_TYPE = 0x07, //!< Unsupported procedure.
|
|
BLE_OTS_OACP_RES_NOT_PERMITTED = 0x08, //!< Procedure not permitted.
|
|
BLE_OTS_OACP_RES_OBJ_LOCKED = 0x09, //!< Object locked.
|
|
BLE_OTS_OACP_RES_OPER_FAILED = 0x0A //!< Operation Failed.
|
|
} ble_ots_oacp_res_code_t;
|
|
|
|
/**< Object Action Control Point procedure definition. */
|
|
typedef struct
|
|
{
|
|
ble_ots_oacp_proc_type_t type;
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t size;
|
|
ble_ots_obj_type_t * p_obj_type;
|
|
} create_params;
|
|
struct
|
|
{
|
|
uint32_t offset;
|
|
uint32_t length;
|
|
} checksum_params;
|
|
struct
|
|
{
|
|
uint8_t cmd_data_len;
|
|
uint8_t * p_cmd_data;
|
|
} execute_params;
|
|
struct
|
|
{
|
|
uint32_t offset;
|
|
uint32_t length;
|
|
} read_params;
|
|
struct
|
|
{
|
|
uint32_t offset;
|
|
uint32_t length;
|
|
uint8_t write_mode;
|
|
} write_params;
|
|
} params;
|
|
} ble_ots_oacp_proc_t;
|
|
|
|
/**@brief Definition of an OACP event. */
|
|
typedef struct
|
|
{
|
|
enum
|
|
{
|
|
BLE_OTS_OACP_EVT_EXECUTE,
|
|
BLE_OTS_OACP_EVT_REQ_READ,
|
|
BLE_OTS_OACP_EVT_INCREASE_ALLOC_LEN,
|
|
BLE_OTS_OACP_EVT_REQ_WRITE,
|
|
BLE_OTS_OACP_EVT_ABORT,
|
|
} type;
|
|
union
|
|
{
|
|
ble_ots_object_t * p_object;
|
|
struct
|
|
{
|
|
uint8_t cmd_data_len;
|
|
uint8_t * p_cmd_data;
|
|
} execute_params;
|
|
} evt;
|
|
} ble_ots_oacp_evt_t;
|
|
|
|
/**@brief OACP initialization properties. */
|
|
typedef struct
|
|
{
|
|
ble_ots_t * p_ots;
|
|
uint32_t on_create_obj_properties_raw; /**< The encoded properties of a newly created object.*/
|
|
security_req_t write_access; /**< The write security level for the OACP. */
|
|
security_req_t cccd_write_access; /**< The write security level for the OACP CCCD. */
|
|
uint8_t * p_l2cap_buffer;
|
|
uint16_t l2cap_buffer_len;
|
|
} ble_ots_oacp_init_t;
|
|
|
|
struct ble_ots_oacp_s
|
|
{
|
|
ble_ots_t * p_ots;
|
|
uint32_t on_create_obj_properties_raw; /**< The encoded properties of a newly created object.*/
|
|
ble_ots_l2cap_t ots_l2cap; /**< L2CAP connection oriented channel module. */
|
|
ble_gatts_char_handles_t oacp_handles; /**< The characteristic handles of the OACP. */
|
|
};
|
|
|
|
|
|
/*------------------------------------------ BLE OTS ---------------------------------------------*/
|
|
|
|
/**@brief The event type indicates which module the event is connected to.*/
|
|
typedef enum
|
|
{
|
|
BLE_OTS_EVT_OACP,
|
|
BLE_OTS_EVT_OBJECT,
|
|
BLE_OTS_EVT_INDICATION_ENABLED,
|
|
BLE_OTS_EVT_INDICATION_DISABLED,
|
|
BLE_OTS_EVT_OBJECT_RECEIVED /**< If this event is received, data is now available in the current object.*/
|
|
} ble_ots_evt_type_t;
|
|
|
|
/**@brief This structure represents the state of the Object Transfer Service. */
|
|
typedef struct
|
|
{
|
|
ble_ots_evt_type_t type;
|
|
union
|
|
{
|
|
ble_ots_oacp_evt_t oacp_evt;
|
|
ble_ots_object_evt_t object_evt;
|
|
|
|
} evt; /**< Event data. */
|
|
} ble_ots_evt_t;
|
|
|
|
/**@brief OTS event handler. */
|
|
typedef void (*ble_ots_evt_handler_t) (ble_ots_t * p_ots, ble_ots_evt_t * p_evt);
|
|
|
|
/**@brief Structure for initializing the OTS. */
|
|
typedef struct
|
|
{
|
|
ble_ots_evt_handler_t evt_handler;
|
|
ble_srv_error_handler_t error_handler;
|
|
ble_ots_object_t * p_object; /**< Pointer to the object. */
|
|
security_req_t feature_char_read_access; /**< Read security level for the feature characteristic value. */
|
|
ble_ots_object_chars_init_t object_chars_init; /**< The initialization structure of the object characteristics. */
|
|
ble_ots_oacp_init_t oacp_init; /**< The initialization structure of the object action control point. */
|
|
uint16_t rx_mps; /**< Size of L2CAP Rx MPS (must be at least BLE_L2CAP_MPS_MIN).*/
|
|
uint16_t rx_mtu; /**< Size of L2CAP Rx MTU (must be at least BLE_L2CAP_MTU_MIN).*/
|
|
nrf_ble_gq_t * p_gatt_queue; /**< Pointer to BLE GATT queue instance. */
|
|
} ble_ots_init_t;
|
|
|
|
struct ble_ots_s
|
|
{
|
|
uint16_t conn_handle; /**< Connection handle of service. */
|
|
uint16_t service_handle; /**< THe service handle of OTS. */
|
|
ble_ots_evt_handler_t evt_handler;
|
|
ble_srv_error_handler_t error_handler;
|
|
ble_gatts_char_handles_t feature_handles;
|
|
ble_ots_object_chars_t object_chars; /**< The structure holding the object characteristics representation. */
|
|
ble_ots_oacp_t oacp_chars; /**< The structure holding the object action control point characteristics representation. */
|
|
ble_ots_object_t * p_current_object; /**< Pointer to the currently selected object. */
|
|
nrf_ble_gq_t * p_gatt_queue; /**< Pointer to BLE GATT queue instance. */
|
|
};
|
|
|
|
|
|
/**@brief Function for initializing the Object Transfer Service.
|
|
*
|
|
* @param[out] p_ots Object Transfer Service structure. This structure will have to be supplied by
|
|
* the application. It will be initialized by this function, and will later
|
|
* be used to identify this particular service instance.
|
|
* @param[in] p_ots_init Information needed to initialize the service.
|
|
*
|
|
* @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
|
|
*/
|
|
uint32_t ble_ots_init(ble_ots_t * p_ots, ble_ots_init_t * p_ots_init);
|
|
|
|
/**@brief Function for handling the Application's BLE Stack events.
|
|
*
|
|
* @details Handles all events from the BLE stack of interest to the Object Transfer Service.
|
|
*
|
|
* @param[in] p_ble_evt Event received from the BLE stack.
|
|
* @param[in] p_context Object Transfer Service structure.
|
|
*/
|
|
void ble_ots_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
|
|
|
|
/**@brief Function for setting the name of an object.
|
|
*
|
|
* @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
|
|
* @note If the name of the object is "" on disconnection, the object will be invalidated.
|
|
*
|
|
* @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
|
|
* @param[in] p_object Pointer to the object where the name will be changed.
|
|
* @param[in] new_name The new name of the object.
|
|
*
|
|
* @return NRF_SUCCESS On success, otherwise an error code.
|
|
*/
|
|
uint32_t ble_ots_object_set_name(ble_ots_object_chars_t * p_ots_object_chars,
|
|
ble_ots_object_t * p_object,
|
|
char const * new_name);
|
|
|
|
/**@brief Function for setting the type of an object.
|
|
*
|
|
* @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
|
|
* @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
|
|
* @param[in] p_object Pointer to the object where the type will be changed.
|
|
* @param[in] p_new_type Pointer to the new type of the object.
|
|
*
|
|
* @return NRF_SUCCESS On success, otherwise an error code.
|
|
*/
|
|
uint32_t ble_ots_object_set_type(ble_ots_object_chars_t * p_ots_object_chars,
|
|
ble_ots_object_t * p_object,
|
|
ble_ots_obj_type_t * p_new_type);
|
|
|
|
/**@brief Function for setting the current size of an object.
|
|
*
|
|
* @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
|
|
* @note If the new current size is smaller than the current size, the object will be truncated.
|
|
*
|
|
* @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
|
|
* @param[in] p_object Pointer to the object where the current size will be changed.
|
|
* @param[in] new_current_size The new current size of the object.
|
|
*
|
|
* @return NRF_SUCCESS On success, otherwise an error code.
|
|
*/
|
|
uint32_t ble_ots_object_set_current_size(ble_ots_object_chars_t * p_ots_object_chars,
|
|
ble_ots_object_t * p_object,
|
|
uint32_t new_current_size);
|
|
|
|
/**@brief Function for setting the properties of an object.
|
|
*
|
|
* @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
|
|
*
|
|
* @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
|
|
* @param[in] p_object Pointer to the object where the properties will be changed.
|
|
* @param[in] p_new_properties The properties of the object.
|
|
*
|
|
* @return NRF_SUCCESS On success, otherwise an error code.
|
|
*/
|
|
uint32_t ble_ots_object_set_properties(ble_ots_object_chars_t * p_ots_object_chars,
|
|
ble_ots_object_t * p_object,
|
|
ble_ots_obj_properties_t * p_new_properties);
|
|
|
|
|
|
|
|
#endif // BLE_OTS_H__
|
|
|
|
/** @} */
|