123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691 |
- /**
- * 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.
- *
- */
- #include "ble_ots_oacp.h"
- #include <string.h>
- #include "fds.h"
- #include "crc32.h"
- #include "ble_ots.h"
- #include "ble_ots_l2cap.h"
- #include "ble_ots_object.h"
- #define NRF_LOG_MODULE_NAME ble_ots_oacp
- #include "nrf_log.h"
- NRF_LOG_MODULE_REGISTER();
- #define OTS_FILE_ID 1234
- #define OTS_FDS_KEY 4321
- #define OACP_INDICATION_LEN 3 /**< Indication data length. */
- /**@brief Function for interception of GATT errors and @ref nrf_ble_gq errors.
- *
- * @param[in] nrf_error Error code.
- * @param[in] p_ctx Parameter from the event handler.
- * @param[in] conn_handle Connection handle.
- */
- static void gatt_error_handler(uint32_t nrf_error,
- void * p_ctx,
- uint16_t conn_handle)
- {
- ble_ots_t * p_ots = (ble_ots_t *)p_ctx;
- if (p_ots->error_handler != NULL)
- {
- p_ots->error_handler(nrf_error);
- }
- }
- /**@brief Checks if the cccd handle is configured for indication
- *
- * @param[in] cccd_handle The CCCD handle.
- */
- static bool is_cccd_configured(ble_ots_oacp_t * const p_ots_oacp)
- {
- uint32_t err_code;
- uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
- bool is_oacp_indic_enabled = false;
- ble_gatts_value_t gatts_value;
- uint16_t cccd_handle = p_ots_oacp->oacp_handles.cccd_handle;
- uint16_t conn_handle = p_ots_oacp->p_ots->conn_handle;
- // Initialize value struct.
- memset(&gatts_value, 0, sizeof(gatts_value));
- gatts_value.len = BLE_CCCD_VALUE_LEN;
- gatts_value.offset = 0;
- gatts_value.p_value = cccd_value_buf;
- err_code = sd_ble_gatts_value_get(conn_handle,
- cccd_handle,
- &gatts_value);
- if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING)
- {
- is_oacp_indic_enabled = false;
- }
- else if (err_code != NRF_SUCCESS)
- {
- // Report error to application
- if (p_ots_oacp->p_ots->error_handler != NULL)
- {
- p_ots_oacp->p_ots->error_handler(err_code);
- }
- }
- else
- {
- is_oacp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
- }
- return is_oacp_indic_enabled;
- }
- /** @brief This is the l2cap connection oriented channel event handler.
- *
- * @param[in] p_ots_l2cap Pointer to the l2cap module
- * @param[in] p_evt The pointer to the event.
- */
- static void ots_l2cap_evt_handler(ble_ots_l2cap_t * p_ots_l2cap, ble_ots_l2cap_evt_t * p_evt)
- {
- uint32_t err_code;
- switch (p_evt->type)
- {
- case BLE_OTS_L2CAP_EVT_CH_CONNECTED:
- NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_CH_CONNECTED.");
- break;
- case BLE_OTS_L2CAP_EVT_CH_DISCONNECTED:
- NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_CH_DISCONNECTED.");
- break;
- case BLE_OTS_L2CAP_EVT_SEND_COMPLETE:
- NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_SEND_COMPLETE.");
- p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->is_locked = false;
- break;
- case BLE_OTS_L2CAP_EVT_RECV_COMPLETE:
- NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_RECV_COMPLETE.");
- memcpy(p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->data,
- p_ots_l2cap->rx_params.sdu_buf.p_data,
- p_ots_l2cap->rx_params.sdu_buf.len);
- err_code = ble_ots_object_set_current_size(&p_ots_l2cap->p_ots_oacp->p_ots->object_chars,
- p_ots_l2cap->p_ots_oacp->p_ots->p_current_object,
- p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->current_size);
- if (err_code != NRF_SUCCESS)
- {
- NRF_LOG_ERROR("ble_ots_object_set_current_size returned error 0x%x", err_code);
- }
- ble_ots_evt_t evt;
- evt.type = BLE_OTS_EVT_OBJECT_RECEIVED;
- p_ots_l2cap->p_ots_oacp->p_ots->evt_handler(p_ots_l2cap->p_ots_oacp->p_ots, &evt);
- break;
- }
- }
- /**@brief Adds the OACP characteristic
- *
- * @param[in] p_ots_oacp Pointer to the OACP structure.
- * @param[in] service_handle The service handle to attach the characteristic to.
- * @param[in] write_access The write security level for the OACP value handle.
- * @param[in] cccd_write_access The write security level for the OACP cccd handle.
- *
- * @return NRF_SUCCESS When added successfully, else an error code from characteristic_add().
- */
- static uint32_t oacp_char_add(ble_ots_oacp_t * const p_ots_oacp,
- uint16_t service_handle,
- security_req_t write_access,
- security_req_t cccd_write_access)
- {
- ble_add_char_params_t add_char_params;
- memset(&add_char_params, 0, sizeof(add_char_params));
- add_char_params.uuid = BLE_UUID_OTS_OACP;
- add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
- add_char_params.max_len = BLE_OTS_MAX_OACP_SIZE;
- add_char_params.init_len = 0;
- add_char_params.is_var_len = 1;
- add_char_params.char_props.indicate = true;
- add_char_params.char_props.write = true;
- add_char_params.cccd_write_access = cccd_write_access;
- add_char_params.is_defered_write = true;
- add_char_params.write_access = write_access;
- return characteristic_add(service_handle,
- &add_char_params,
- &p_ots_oacp->oacp_handles);
- }
- /**@brief Handling the OACP write procedure.
- *
- * @details The object is opened, and a l2cap transfer is started.
- *
- * @param[in] p_ots_oacp Pointer to the OACP structure.
- * @param[in] offset The offset for where the read should start.
- * @param[in] length The length of the read.
- */
- static inline ble_ots_oacp_res_code_t oacp_write_proc(ble_ots_oacp_t * p_ots_oacp,
- uint32_t offset,
- uint32_t length,
- uint8_t mode)
- {
- uint32_t err_code;
- if (p_ots_oacp->p_ots->p_current_object == NULL)
- {
- return BLE_OTS_OACP_RES_INV_OBJ;
- }
- if (p_ots_oacp->p_ots->p_current_object->is_valid == false)
- {
- return BLE_OTS_OACP_RES_INV_OBJ;
- }
- if (p_ots_oacp->p_ots->p_current_object->properties.decoded.is_write_permitted == false)
- {
- return BLE_OTS_OACP_RES_NOT_PERMITTED;
- }
- if (ble_ots_l2cap_is_channel_available(&p_ots_oacp->ots_l2cap) == false)
- {
- return BLE_OTS_OACP_RES_CHAN_UNAVAIL;
- }
- if (length + offset > p_ots_oacp->p_ots->p_current_object->alloc_len)
- {
- return BLE_OTS_OACP_RES_INV_PARAM;
- }
- if (p_ots_oacp->p_ots->p_current_object->is_locked)
- {
- return BLE_OTS_OACP_RES_OBJ_LOCKED;
- }
- err_code = ble_ots_l2cap_start_recv(&p_ots_oacp->ots_l2cap, length);
- if (err_code != NRF_SUCCESS)
- {
- return BLE_OTS_OACP_RES_OPER_FAILED;
- }
- ble_ots_evt_t ble_ots_evt;
- ble_ots_evt.type = BLE_OTS_EVT_OACP;
- ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_REQ_WRITE;
- ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
- p_ots_oacp->p_ots->p_current_object->current_size = length;
- p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
- return BLE_OTS_OACP_RES_SUCCESS;
- }
- /**@brief Handling the OACP read procedure.
- *
- * @details The object is opened, and a l2cap transfer is started.
- *
- * @param[in] p_ots_oacp Pointer to the OACP structure.
- * @param[in] offset The offset for where the read should start.
- * @param[in] length The length of the read.
- */
- static inline ble_ots_oacp_res_code_t oacp_read_proc(ble_ots_oacp_t * p_ots_oacp,
- uint32_t offset,
- uint32_t length)
- {
- if (p_ots_oacp->p_ots->p_current_object == NULL)
- {
- return BLE_OTS_OACP_RES_INV_OBJ;
- }
- if (p_ots_oacp->p_ots->p_current_object->is_valid == false)
- {
- return BLE_OTS_OACP_RES_INV_OBJ;
- }
- if (p_ots_oacp->p_ots->p_current_object->properties.decoded.is_read_permitted == false)
- {
- return BLE_OTS_OACP_RES_NOT_PERMITTED;
- }
- if (ble_ots_l2cap_is_channel_available(&p_ots_oacp->ots_l2cap) == false)
- {
- return BLE_OTS_OACP_RES_CHAN_UNAVAIL;
- }
- if (length + offset > p_ots_oacp->p_ots->p_current_object->current_size)
- {
- return BLE_OTS_OACP_RES_INV_PARAM;
- }
- if (p_ots_oacp->p_ots->p_current_object->is_locked)
- {
- return BLE_OTS_OACP_RES_OBJ_LOCKED;
- }
- ble_ots_evt_t ble_ots_evt;
- ble_ots_evt.type = BLE_OTS_EVT_OACP;
- ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_REQ_READ;
- ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
- p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
-
- ret_code_t err_code = ble_ots_l2cap_obj_send(&p_ots_oacp->ots_l2cap,
- p_ots_oacp->p_ots->p_current_object->data,
- p_ots_oacp->p_ots->p_current_object->current_size);
- if (err_code != NRF_SUCCESS)
- {
- NRF_LOG_ERROR("ble_ots_l2cap_obj_send returned error 0x%x", err_code);
- }
- return BLE_OTS_OACP_RES_SUCCESS;
- }
- /**@brief Handling the OACP abort procedure.
- *
- * @details The transmission is aborted.
- *
- * @param[in] p_ots_oacp Pointer to the OACP structure.
- */
- static inline ble_ots_oacp_res_code_t oacp_abort_proc(ble_ots_oacp_t * p_ots_oacp)
- {
- uint32_t err_code;
- err_code = ble_ots_l2cap_abort_transmission(&p_ots_oacp->ots_l2cap);
- if (err_code != NRF_SUCCESS)
- {
- return BLE_OTS_OACP_RES_OPER_FAILED;
- }
- p_ots_oacp->p_ots->p_current_object->is_locked = false;
- ble_ots_evt_t ble_ots_evt;
- ble_ots_evt.type = BLE_OTS_EVT_OACP;
- ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_ABORT;
- ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
- p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
- return BLE_OTS_OACP_RES_SUCCESS;
- }
- /**@brief Sending the oacp procedure response back to the client.
- *
- * @details Encodes and sends the response.
- *
- * @param[in] p_ots_oacp Pointer to the OACP structure.
- * @param[in] req_op_code The operation code of the procedure.
- * @param[in] result_code The result of the procedure.
- * @param[in] conn_handle The connection handle to send the result to.
- */
- static uint32_t ble_ots_oacp_response_send(ble_ots_oacp_t * p_ots_oacp,
- ble_ots_oacp_proc_type_t req_op_code,
- ble_ots_oacp_res_code_t result_code,
- uint16_t conn_handle)
- {
- uint16_t index = 0;
- uint8_t data[OACP_INDICATION_LEN];
- nrf_ble_gq_req_t ots_req;
- data[index++] = BLE_OTS_OACP_PROC_RESP;
- // Encode the Request Op code
- data[index++] = (uint8_t)req_op_code;
- // Encode the Result code.
- data[index++] = (uint8_t)result_code;
- memset(&ots_req, 0, sizeof(nrf_ble_gq_req_t));
- ots_req.type = NRF_BLE_GQ_REQ_GATTS_HVX;
- ots_req.error_handler.cb = gatt_error_handler;
- ots_req.error_handler.p_ctx = p_ots_oacp->p_ots;
- ots_req.params.gatts_hvx.type = BLE_GATT_HVX_INDICATION;
- ots_req.params.gatts_hvx.handle = p_ots_oacp->oacp_handles.value_handle;
- ots_req.params.gatts_hvx.offset = 0;
- ots_req.params.gatts_hvx.p_data = data;
- ots_req.params.gatts_hvx.p_len = &index;
- return nrf_ble_gq_item_add(p_ots_oacp->p_ots->p_gatt_queue,
- &ots_req,
- conn_handle);
- }
- /**@brief Decode an OACP command, and extract its data.
- *
- * @param[in] p_ble_write_evt The write event from BLE stack.
- * @param[out] p_proc The decoded OACP procedure is sent out.
- *
- * @return BLE_OTS_WRITE_SUCCESS If the filter was decoded correctly, else an error code.
- */
- static inline ble_ots_oacp_res_code_t decode_oacp_command(ble_gatts_evt_write_t const * p_ble_write_evt,
- ble_ots_oacp_proc_t * p_proc)
- {
- uint32_t index = 0;
- p_proc->type = (ble_ots_oacp_proc_type_t)p_ble_write_evt->data[index++];
- switch (p_proc->type)
- {
- case BLE_OTS_OACP_PROC_READ:
- if (p_ble_write_evt->len !=
- sizeof(p_proc->params.read_params.offset)
- + sizeof(p_proc->params.read_params.length)
- + index)
- {
- return BLE_OTS_OACP_RES_INV_PARAM;
- }
- /*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
- p_proc->params.read_params.offset = uint32_decode(&(p_ble_write_evt->data[index]));
- index += 4;
- p_proc->params.read_params.length = uint32_decode(&(p_ble_write_evt->data[index]));
- /*lint -restore*/
- break;
- //return BLE_OTS_OACP_RES_SUCCESS;
- case BLE_OTS_OACP_PROC_WRITE:
- p_proc->params.write_params.offset = uint32_decode(&(p_ble_write_evt->data[index]));
- index += sizeof(uint32_t);
- p_proc->params.write_params.length = uint32_decode(&(p_ble_write_evt->data[index]));
- index += sizeof(uint32_t);
- p_proc->params.write_params.write_mode = p_ble_write_evt->data[index];
- break;
- default:
- // No implementation needed
- break;
- }
- return BLE_OTS_OACP_RES_SUCCESS;
- }
- /**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event.
- *
- * @param[in] p_ots_oacp OTS OACP Structure.
- * @param[in] p_ble_evt Pointer to the event received from BLE stack.
- */
- static inline void on_disconnect(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
- {
- uint32_t err_code;
- err_code = fds_gc();
- if (err_code != NRF_SUCCESS)
- {
- p_ots_oacp->p_ots->error_handler(err_code);
- }
- }
- /**@brief Function for handling the write events to the Blood Pressure Measurement characteristic.
- *
- * @param[in] p_bps Blood Pressure Service structure.
- * @param[in] p_evt_write Write event received from the BLE stack.
- */
- static void on_cccd_write(ble_ots_oacp_t * p_ots_oacp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if (p_evt_write->len == 2)
- {
- // CCCD written, update indication state
- if (p_ots_oacp->p_ots->evt_handler != NULL)
- {
- ble_ots_evt_t evt;
- if (ble_srv_is_indication_enabled(p_evt_write->data))
- {
- evt.type = BLE_OTS_EVT_INDICATION_ENABLED;
- }
- else
- {
- evt.type = BLE_OTS_EVT_INDICATION_DISABLED;
- }
- p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &evt);
- }
- }
- }
- static void on_oacp_write(ble_ots_oacp_t * p_ots_oacp, ble_gatts_evt_write_t const * p_ble_evt_write)
- {
- ret_code_t err_code;
- ble_ots_oacp_res_code_t oacp_status;
- ble_ots_oacp_proc_t oacp_proc;
- ble_gatts_rw_authorize_reply_params_t auth_reply;
- memset(&auth_reply, 0, sizeof(auth_reply));
- auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
- auth_reply.params.write.offset = 0;
- auth_reply.params.write.len = 0;
- auth_reply.params.write.p_data = NULL;
- auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
- auth_reply.params.write.update = 1;
- if(is_cccd_configured(p_ots_oacp))
- {
- auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
- err_code = sd_ble_gatts_rw_authorize_reply(p_ots_oacp->p_ots->conn_handle, &auth_reply);
- if (err_code != NRF_SUCCESS && p_ots_oacp->p_ots->error_handler != NULL)
- {
- p_ots_oacp->p_ots->error_handler(err_code);
- }
- }
- else
- {
- NRF_LOG_DEBUG("OACD indications not enabled.");
- auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
- err_code = sd_ble_gatts_rw_authorize_reply(p_ots_oacp->p_ots->conn_handle, &auth_reply);
-
- if (err_code != NRF_SUCCESS && p_ots_oacp->p_ots->error_handler != NULL)
- {
- p_ots_oacp->p_ots->error_handler(err_code);
- }
- return;
- }
- memset(&oacp_proc, 0, sizeof(oacp_proc));
- oacp_status = decode_oacp_command(p_ble_evt_write, &oacp_proc);
- if (oacp_status == BLE_OTS_OACP_RES_SUCCESS)
- {
- oacp_status = ble_ots_oacp_do_proc(p_ots_oacp, &oacp_proc);
- }
- err_code = ble_ots_oacp_response_send(p_ots_oacp,
- oacp_proc.type,
- oacp_status,
- p_ots_oacp->p_ots->conn_handle);
- if (err_code != NRF_SUCCESS)
- {
- p_ots_oacp->p_ots->error_handler(err_code);
- }
- }
- /**@brief Function for handling the Write event.
- *
- * @param[in] p_bps Blood Pressure Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_write(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
- {
- ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
- if (p_evt_write->handle == p_ots_oacp->p_ots->oacp_chars.oacp_handles.cccd_handle)
- {
- on_cccd_write(p_ots_oacp, p_evt_write);
- }
- }
- static void on_rw_authorize_request(ble_ots_oacp_t * p_ots_oacp, ble_gatts_evt_t const * p_gatts_evt)
- {
- ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
- &p_gatts_evt->params.authorize_request;
- if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
- {
- if ( (p_gatts_evt->params.authorize_request.request.write.op
- != BLE_GATTS_OP_PREP_WRITE_REQ)
- && (p_gatts_evt->params.authorize_request.request.write.op
- != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
- && (p_gatts_evt->params.authorize_request.request.write.op
- != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
- )
- {
- if (p_auth_req->request.write.handle == p_ots_oacp->p_ots->oacp_chars.oacp_handles.value_handle)
- {
- on_oacp_write(p_ots_oacp, &p_auth_req->request.write);
- }
- }
- }
- }
- void ble_ots_oacp_on_ble_evt(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
- {
- if ((p_ots_oacp == NULL) || (p_ble_evt == NULL))
- {
- return;
- }
- ble_ots_l2cap_on_ble_evt(&p_ots_oacp->ots_l2cap, p_ble_evt);
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_DISCONNECTED:
- on_disconnect(p_ots_oacp, p_ble_evt);
- break;
- case BLE_GATTS_EVT_WRITE:
- on_write(p_ots_oacp, p_ble_evt);
- break;
- case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
- on_rw_authorize_request(p_ots_oacp, &p_ble_evt->evt.gatts_evt);
- break;
- default:
- // No implementation needed.
- break;
- }
- }
- uint32_t ble_ots_oacp_init(ble_ots_oacp_t * p_ots_oacp, ble_ots_oacp_init_t * p_ots_oacp_init)
- {
- uint32_t err_code;
- if (p_ots_oacp == NULL || p_ots_oacp_init == NULL)
- {
- return NRF_ERROR_NULL;
- }
- p_ots_oacp->p_ots = p_ots_oacp_init->p_ots;
- p_ots_oacp->on_create_obj_properties_raw = p_ots_oacp_init->on_create_obj_properties_raw;
- ble_ots_l2cap_init_t l2cap_init;
- l2cap_init.p_ots_oacp = p_ots_oacp;
- l2cap_init.evt_handler = ots_l2cap_evt_handler;
- l2cap_init.p_transfer_buffer = p_ots_oacp_init->p_l2cap_buffer;
- l2cap_init.buffer_len = p_ots_oacp_init->l2cap_buffer_len;
- err_code = ble_ots_l2cap_init(&p_ots_oacp->ots_l2cap, &l2cap_init);
- if (err_code != NRF_SUCCESS)
- {
- return err_code;
- }
- return oacp_char_add(p_ots_oacp,
- p_ots_oacp->p_ots->service_handle,
- p_ots_oacp_init->write_access,
- p_ots_oacp_init->cccd_write_access);
- }
- ble_ots_oacp_res_code_t ble_ots_oacp_do_proc(ble_ots_oacp_t * p_ots_oacp,
- ble_ots_oacp_proc_t * p_oacp_proc)
- {
- if (p_ots_oacp == NULL || p_oacp_proc == NULL)
- {
- return BLE_OTS_OACP_RES_INV_PARAM;
- }
- ble_ots_oacp_res_code_t oacp_status;
- switch (p_oacp_proc->type)
- {
- case BLE_OTS_OACP_PROC_WRITE:
- oacp_status = oacp_write_proc(p_ots_oacp,
- p_oacp_proc->params.write_params.offset,
- p_oacp_proc->params.write_params.length,
- p_oacp_proc->params.write_params.write_mode);
- break;
- case BLE_OTS_OACP_PROC_READ:
- oacp_status = oacp_read_proc(p_ots_oacp,
- p_oacp_proc->params.read_params.offset,
- p_oacp_proc->params.read_params.length);
- break;
- case BLE_OTS_OACP_PROC_ABORT:
- oacp_status = oacp_abort_proc(p_ots_oacp);
- break;
- default:
- // Unsupported op code.
- oacp_status = BLE_OTS_OACP_RES_OPCODE_NOT_SUP;
- }
- return oacp_status;
- }
|