123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806 |
- /**
- * Copyright (c) 2015 - 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_ln_cp.h"
- #include "ble_ln_db.h"
- #include "ble_ln_common.h"
- #include "sdk_common.h"
- #define NRF_LOG_MODULE_NAME ble_ln_cp
- #include "nrf_log.h"
- NRF_LOG_MODULE_REGISTER();
- // Feature Mask bits
- #define FEATURE_MASK_INSTANTANEOUS_SPEED (0x01 << 0) /**< Instantaneous Speed mask bit. */
- #define FEATURE_MASK_TOTAL_DISTANCE (0x01 << 1) /**< Total Distance mask bit. */
- #define FEATURE_MASK_LOCATION (0x01 << 2) /**< Location mask bit. */
- #define FEATURE_MASK_ELEVATION (0x01 << 3) /**< Elevation mask bit. */
- #define FEATURE_MASK_HEADING (0x01 << 4) /**< Heading mask bit. */
- #define FEATURE_MASK_ROLLING_TIME (0x01 << 5) /**< Rolling Time mask bit. */
- #define FEATURE_MASK_UTC_TIME (0x01 << 6) /**< UTC Time mask bit. */
- // Data Control point parameter type lengths.
- #define INT8_LEN 1
- #define INT16_LEN 2
- #define INT24_LEN 3
- #define INT32_LEN 4
- #define OPCODE_LENGTH 1 /**< Length of opcode inside Location and Navigation Measurement packet. */
- #define HANDLE_LENGTH 2 /**< Length of handle inside Location and Navigation Measurement packet. */
- /**@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_lncp_t * p_lncp = (ble_lncp_t *)p_ctx;
- if (p_lncp->error_handler != NULL)
- {
- p_lncp->error_handler(nrf_error);
- }
- }
- static ble_lncp_rsp_code_t notify_app(ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt)
- {
- ble_lncp_rsp_code_t rsp = LNCP_RSP_SUCCESS;
- if (p_lncp->evt_handler != NULL)
- {
- rsp = p_lncp->evt_handler(p_lncp, p_evt);
- }
- return rsp;
- }
- static void resp_send(ble_lncp_t * p_lncp)
- {
- // Send indication
- uint16_t hvx_len;
- uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN];
- uint32_t err_code;
- nrf_ble_gq_req_t lncp_req;
- memset(&lncp_req, 0, sizeof(nrf_ble_gq_req_t));
- hvx_len = 3 + p_lncp->pending_rsp.rsp_param_len;
- hvx_data[0] = LNCP_OP_RESPONSE_CODE;
- hvx_data[1] = p_lncp->pending_rsp.op_code;
- hvx_data[2] = p_lncp->pending_rsp.rsp_code;
- memcpy(&hvx_data[3], &p_lncp->pending_rsp.rsp_param[0], p_lncp->pending_rsp.rsp_param_len);
- lncp_req.type = NRF_BLE_GQ_REQ_GATTS_HVX;
- lncp_req.error_handler.cb = gatt_error_handler;
- lncp_req.error_handler.p_ctx = p_lncp;
- lncp_req.params.gatts_hvx.handle = p_lncp->ctrlpt_handles.value_handle;
- lncp_req.params.gatts_hvx.offset = 0;
- lncp_req.params.gatts_hvx.p_data = hvx_data;
- lncp_req.params.gatts_hvx.p_len = &hvx_len;
- lncp_req.params.gatts_hvx.type = BLE_GATT_HVX_INDICATION;
- p_lncp->is_indication_pending = true;
- err_code = nrf_ble_gq_item_add(p_lncp->p_gatt_queue, &lncp_req, p_lncp->conn_handle);
- if ((p_lncp->error_handler != NULL) &&
- (err_code != NRF_SUCCESS))
- {
- p_lncp->error_handler(err_code);
- }
- }
- static void on_connect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t));
- p_lncp->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
- }
- static void on_disconnect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- UNUSED_PARAMETER(p_ble_evt);
- p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID;
- }
- static void on_hvc_confirm(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_lncp->ctrlpt_handles.value_handle)
- {
- if (p_lncp->is_indication_pending)
- {
- p_lncp->is_indication_pending = false;
- }
- else
- {
- if (p_lncp->error_handler != NULL)
- {
- p_lncp->error_handler(NRF_ERROR_INVALID_STATE);
- }
- }
- }
- }
- /**@brief Handle write events to the control point cccd.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_evt_write Write event received from the BLE stack.
- */
- static void on_lncp_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
- {
- // CCCD written, update indications state
- p_lncp->is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data);
- }
- }
- /**@brief Handle write events to the navigation cccd.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_evt_write Write event received from the BLE stack.
- */
- static void on_nav_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
- {
- // CCCD written, update notification state
- p_lncp->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data);
- }
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_set_cumulative_value(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if ( !(p_lncp->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const uint32_t total_distance = uint24_decode(&p_evt_write->data[1]);
- const ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_TOTAL_DISTANCE_SET,
- .params.total_distance = total_distance
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
- {
- p_lncp->total_distance = total_distance;
- }
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_mask_loc_speed_content(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if ( !(p_lncp->available_features & BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- uint16_t rcvd_mask = uint16_decode(&p_evt_write->data[1]);
- if (rcvd_mask > 0x7F)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_MASK_SET,
- .params.mask.flags = rcvd_mask
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
- {
- p_lncp->mask.flags = rcvd_mask;
- }
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_nav_control(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if ( !(p_lncp->is_navigation_present) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != LNCP_NAV_CMD_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
- const uint8_t data_buf = p_evt_write->data[1];
- /*lint -restore*/
- if (data_buf > LNCP_NAV_CMD_MAX)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const ble_lncp_nav_cmd_t cmd = (ble_lncp_nav_cmd_t) data_buf;
- if (cmd == LNCP_CMD_NAV_START || cmd == LNCP_CMD_NAV_CONTINUE || cmd == LNCP_CMD_NAV_NEAREST)
- {
- p_lncp->is_navigation_running = true;
- }
- else if (cmd == LNCP_CMD_NAV_STOP || cmd == LNCP_CMD_NAV_PAUSE)
- {
- p_lncp->is_navigation_running = false;
- }
- const ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_NAV_COMMAND,
- .params.nav_cmd = cmd
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_req_num_routes(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
- if ( !(p_lncp->is_navigation_present) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const uint8_t num_records = ble_ln_db_num_records_get();
- p_lncp->pending_rsp.rsp_param_len = uint16_encode(num_records, &p_lncp->pending_rsp.rsp_param[0]);
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_req_name_of_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- uint8_t * p_name;
- uint32_t err_code;
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
- if ( !(p_lncp->is_navigation_present) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
- const uint16_t route_num = uint16_decode(&p_evt_write->data[1]);
- /*lint -restore*/
- err_code = ble_ln_db_record_name_get(route_num, &p_name);
- if (err_code != NRF_SUCCESS)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OPERATION_FAILED;
- return;
- }
- memcpy(&p_lncp->pending_rsp.rsp_param[0], p_name, BLE_LNS_MAX_ROUTE_NAME_LEN);
- p_lncp->pending_rsp.rsp_param_len = BLE_LNS_MAX_ROUTE_NAME_LEN;
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_select_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- if ( !(p_lncp->is_navigation_present))
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const uint16_t route_num = uint16_decode(&p_evt_write->data[1]);
- const uint16_t stored_num = ble_ln_db_num_records_get();
- if (route_num >= stored_num)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_ROUTE_SELECTED,
- .params.selected_route = route_num
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
- {
- p_lncp->selected_route = route_num;
- }
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_set_fix_rate(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
- if ( !(p_lncp->available_features & BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT8_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
- const uint8_t fix_rate = p_evt_write->data[1];
- /*lint -restore*/
- const ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_FIX_RATE_SET,
- .params.fix_rate = fix_rate
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
- {
- p_lncp->fix_rate = fix_rate;
- }
- }
- /**@brief Event handler for control point write.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_set_elevation(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
- if ( !(p_lncp->available_features & BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) )
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- return;
- }
- if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN)
- {
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
- return;
- }
- const uint32_t elevation = uint24_decode(&p_evt_write->data[1]);
- ble_lncp_evt_t evt = {
- .evt_type = LNCP_EVT_ELEVATION_SET,
- .params.elevation = elevation
- };
- p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
- if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
- {
- p_lncp->elevation = elevation;
- }
- }
- /**@brief Handle write events to the Location and Navigation Service Control Point characteristic.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_evt_write Write event received from the BLE stack.
- */
- static void on_ctrlpt_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
- {
- uint32_t err_code;
- p_lncp->pending_rsp.rsp_param_len = 0;
- ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
- memset(&write_authorize_reply, 0, sizeof(write_authorize_reply));
- write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
- if (p_lncp->is_ctrlpt_indication_enabled)
- {
- if (!p_lncp->is_indication_pending)
- {
- write_authorize_reply.params.write.update = 1;
- write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
- // if the op code is navigation control, its cccd must be checked
- if (p_evt_write->len > 0 && p_lncp->is_navigation_present)
- {
- if ( p_evt_write->data[0] == LNCP_OP_NAV_CONTROL
- || p_evt_write->data[0] == LNCP_OP_REQ_NAME_OF_ROUTE
- || p_evt_write->data[0] == LNCP_OP_REQ_NUM_ROUTES)
- {
- if (!p_lncp->is_nav_notification_enabled)
- {
- write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
- }
- }
- }
- }
- else
- {
- write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG;
- }
- }
- else
- {
- write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
- }
- // reply to the write authorization
- do {
- err_code = sd_ble_gatts_rw_authorize_reply(p_lncp->conn_handle, &write_authorize_reply);
- if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY)
- {
- if (p_lncp->error_handler != NULL)
- {
- p_lncp->error_handler(err_code);
- }
- }
- } while (err_code == NRF_ERROR_BUSY);
- if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
- {
- return;
- }
- // Start executing the control point write action
- if (p_evt_write->len > 0)
- {
- p_lncp->pending_rsp.op_code = (ble_lncp_op_code_t) p_evt_write->data[0];
- switch (p_lncp->pending_rsp.op_code)
- {
- case LNCP_OP_SET_CUMULATIVE_VALUE:
- on_set_cumulative_value(p_lncp, p_evt_write);
- break;
- case LNCP_OP_MASK_LOC_SPEED_CONTENT:
- on_mask_loc_speed_content(p_lncp, p_evt_write);
- break;
- case LNCP_OP_NAV_CONTROL:
- on_nav_control(p_lncp, p_evt_write);
- break;
- case LNCP_OP_REQ_NUM_ROUTES:
- on_req_num_routes(p_lncp, p_evt_write);
- break;
- case LNCP_OP_REQ_NAME_OF_ROUTE:
- on_req_name_of_route(p_lncp, p_evt_write);
- break;
- case LNCP_OP_SELECT_ROUTE:
- on_select_route(p_lncp, p_evt_write);
- break;
- case LNCP_OP_SET_FIX_RATE:
- on_set_fix_rate(p_lncp, p_evt_write);
- break;
- case LNCP_OP_SET_ELEVATION:
- on_set_elevation(p_lncp, p_evt_write);
- break;
- // Unrecognized Op Code
- default:
- p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
- break;
- }
- resp_send(p_lncp);
- }
- }
- /**@brief Write authorization request event handler.
- *
- * @details The write authorization request event handler is only called when writing to the control point.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_rw_authorize_req(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- const ble_gatts_evt_rw_authorize_request_t * p_auth_req =
- &p_ble_evt->evt.gatts_evt.params.authorize_request;
- if (
- (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
- &&
- (p_auth_req->request.write.handle == p_lncp->ctrlpt_handles.value_handle)
- &&
- (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)
- &&
- (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
- &&
- (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
- )
- {
- on_ctrlpt_write(p_lncp, &p_auth_req->request.write);
- }
- }
- /**@brief Write event handler.
- *
- * @param[in] p_lncp Location and Navigation Service structure.
- * @param[in] p_ble_evt Event received from the BLE stack.
- */
- static void on_write(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
- if (p_evt_write->handle == p_lncp->ctrlpt_handles.cccd_handle)
- {
- on_lncp_cccd_write(p_lncp, p_evt_write);
- }
- else if (p_evt_write->handle == p_lncp->navigation_handles.cccd_handle)
- {
- on_nav_cccd_write(p_lncp, p_evt_write);
- }
- }
- void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
- {
- VERIFY_PARAM_NOT_NULL_VOID(p_lncp);
- VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_CONNECTED:
- on_connect(p_lncp, p_ble_evt);
- break;
- case BLE_GAP_EVT_DISCONNECTED:
- if (p_ble_evt->evt.gap_evt.conn_handle == p_lncp->conn_handle)
- {
- on_disconnect(p_lncp, p_ble_evt);
- }
- break;
- case BLE_GATTS_EVT_WRITE:
- if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
- {
- on_write(p_lncp, p_ble_evt);
- }
- break;
- case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
- if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
- {
- on_rw_authorize_req(p_lncp, p_ble_evt);
- }
- break;
- case BLE_GATTS_EVT_HVC:
- if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
- {
- on_hvc_confirm(p_lncp, p_ble_evt);
- }
- break;
- default:
- // no implementation
- break;
- }
- }
- uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp)
- {
- if (p_lncp == NULL)
- {
- return 0;
- }
- return p_lncp->total_distance;
- }
- uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp)
- {
- if (p_lncp == NULL)
- {
- return 0;
- }
- return p_lncp->elevation;
- }
- ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp)
- {
- if (p_lncp == NULL)
- {
- const ble_lncp_mask_t empty_mask = {0};
- return empty_mask;
- }
- return p_lncp->mask;
- }
- bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp)
- {
- if (p_lncp == NULL)
- {
- return false;
- }
- return p_lncp->is_navigation_running;
- }
- ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init)
- {
- VERIFY_PARAM_NOT_NULL(p_lncp);
- VERIFY_PARAM_NOT_NULL(p_lncp_init);
- VERIFY_PARAM_NOT_NULL(p_lncp_init->p_gatt_queue);
- ble_add_char_params_t add_char_params;
- memset(&add_char_params, 0, sizeof(add_char_params));
- p_lncp->service_handle = p_lncp_init->service_handle;
- p_lncp->evt_handler = p_lncp_init->evt_handler;
- p_lncp->error_handler = p_lncp_init->error_handler;
- p_lncp->p_gatt_queue = p_lncp_init->p_gatt_queue;
- p_lncp->available_features = p_lncp_init->available_features;
- p_lncp->is_position_quality_present = p_lncp_init->is_position_quality_present;
- p_lncp->is_navigation_present = p_lncp_init->is_navigation_present;
- p_lncp->total_distance = p_lncp_init->total_distance;
- p_lncp->elevation = p_lncp_init->elevation;
- p_lncp->navigation_handles = p_lncp_init->navigation_handles;
- p_lncp->fix_rate = BLE_LNS_NO_FIX;
- p_lncp->selected_route = BLE_LNS_INVALID_ROUTE;
- p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID;
- p_lncp->is_navigation_running = false;
- p_lncp->is_nav_notification_enabled = false;
- p_lncp->is_ctrlpt_indication_enabled = false;
- memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t));
- add_char_params.uuid = BLE_UUID_LN_CONTROL_POINT_CHAR;
- add_char_params.max_len = 0;
- add_char_params.char_props.indicate = true;
- add_char_params.char_props.write = true;
- add_char_params.is_defered_write = true;
- add_char_params.is_var_len = true;
- add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT;
- add_char_params.write_access = p_lncp_init->write_perm;
- add_char_params.cccd_write_access = p_lncp_init->cccd_write_perm;
- NRF_LOG_DEBUG("Initialized");
- return characteristic_add(p_lncp->service_handle,
- &add_char_params,
- &p_lncp->ctrlpt_handles);
- }
|