es_gatts_read.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include "es_gatts_read.h"
  41. #include "es_adv.h"
  42. #include "es_gatts.h"
  43. #include "es_security.h"
  44. #include "es_slot.h"
  45. static ret_code_t send_read_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply)
  46. {
  47. VERIFY_PARAM_NOT_NULL(p_escs);
  48. VERIFY_PARAM_NOT_NULL(p_reply);
  49. p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_READ;
  50. p_reply->params.read.update = 1;
  51. p_reply->params.read.offset = 0;
  52. return es_gatts_send_reply(p_escs, p_reply);
  53. }
  54. static ret_code_t read_value(nrf_ble_escs_t * p_escs, uint8_t length, const void * p_value)
  55. {
  56. VERIFY_PARAM_NOT_NULL(p_escs);
  57. VERIFY_PARAM_NOT_NULL(p_value);
  58. ble_gatts_rw_authorize_reply_params_t reply = {0};
  59. reply.params.read.len = length;
  60. reply.params.read.p_data = p_value;
  61. reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
  62. return send_read_reply(p_escs, &reply);
  63. }
  64. static ret_code_t read_from_gattdb(nrf_ble_escs_t * p_escs, uint16_t val_handle)
  65. {
  66. VERIFY_PARAM_NOT_NULL(p_escs);
  67. ret_code_t err_code;
  68. // Go straight to the characteristic
  69. uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0};
  70. ble_gatts_value_t value = {.len = sizeof(value_buffer),
  71. .offset = 0,
  72. .p_value = &(value_buffer[0])};
  73. err_code = sd_ble_gatts_value_get(p_escs->conn_handle, val_handle, &value);
  74. RETURN_IF_ERROR(err_code);
  75. return read_value(p_escs, value.len, value.p_value);
  76. }
  77. static ret_code_t read_adv_slot(nrf_ble_escs_t * p_escs, uint8_t active_slot, const es_slot_reg_t * p_reg)
  78. {
  79. VERIFY_PARAM_NOT_NULL(p_escs);
  80. ble_gatts_rw_authorize_reply_params_t reply = {0};
  81. uint8_t eid_buf[14];
  82. // If an EID slot is read, load scaler, clock value and ephemeral ID.
  83. if (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID)
  84. {
  85. /*lint -save -e666 */
  86. uint32_t clock_value = es_security_clock_get(active_slot);
  87. clock_value = BYTES_REVERSE_32BIT(clock_value);
  88. /*lint -restore */
  89. reply.params.read.len = ES_EID_GATTS_READ_LENGTH;
  90. // Fill EID buffer with data
  91. eid_buf[ES_EID_GATTS_READ_FRAME_TYPE_IDX] = ES_FRAME_TYPE_EID;
  92. eid_buf[ES_EID_GATTS_READ_EXPONENT_IDX] = es_security_scaler_get(active_slot);
  93. memcpy(&eid_buf[ES_EID_GATTS_READ_CLCK_VALUE_IDX], &clock_value, sizeof(clock_value));
  94. /*lint -save -e545 */
  95. memcpy(&eid_buf[ES_EID_GATTS_READ_EID_IDX],
  96. &p_reg->slots[active_slot].adv_frame.frame.eid.eid,
  97. ES_EID_ID_LENGTH);
  98. /*lint -restore */
  99. reply.params.read.p_data = eid_buf;
  100. }
  101. // Otherwise, simply load the contents of the frame.
  102. else
  103. {
  104. // Check if slot being read is an eTLM slot.
  105. if ((p_reg->num_configured_eid_slots > 0) && p_reg->tlm_configured && (p_reg->tlm_slot == active_slot))
  106. {
  107. // Fill eTLM slot using EID key from first EID slot.
  108. es_slot_etlm_update(p_reg->eid_slots_configured[0]);
  109. }
  110. reply.params.read.len = p_reg->slots[active_slot].adv_frame.length;
  111. reply.params.read.p_data = (uint8_t *)&p_reg->slots[active_slot].adv_frame.frame;
  112. }
  113. reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
  114. return send_read_reply(p_escs, &reply);
  115. }
  116. ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, uint16_t uuid)
  117. {
  118. VERIFY_PARAM_NOT_NULL(p_escs);
  119. if (uuid == BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR)
  120. {
  121. uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED;
  122. return read_value(p_escs, sizeof(retval), &retval);
  123. }
  124. else if (uuid == BLE_UUID_ESCS_LOCK_STATE_CHAR)
  125. {
  126. return read_value(p_escs, ESCS_LOCK_STATE_READ_LENGTH, &p_escs->lock_state);
  127. }
  128. else
  129. {
  130. return es_gatts_send_op_not_permitted(p_escs, true);
  131. }
  132. }
  133. ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs)
  134. {
  135. VERIFY_PARAM_NOT_NULL(p_escs);
  136. ret_code_t err_code;
  137. uint8_t key_buff[ESCS_AES_KEY_SIZE];
  138. err_code = es_security_random_challenge_generate(key_buff);
  139. RETURN_IF_ERROR(err_code);
  140. es_security_unlock_prepare(key_buff);
  141. return read_value(p_escs, ESCS_AES_KEY_SIZE, key_buff);
  142. }
  143. ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs,
  144. uint16_t uuid,
  145. uint16_t val_handle,
  146. uint8_t active_slot)
  147. {
  148. VERIFY_PARAM_NOT_NULL(p_escs);
  149. const es_slot_reg_t * p_reg = es_slot_get_registry();
  150. switch (uuid)
  151. {
  152. case BLE_UUID_ESCS_BROADCAST_CAP_CHAR:
  153. case BLE_UUID_ESCS_UNLOCK_CHAR:
  154. case BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR:
  155. case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR:
  156. return read_from_gattdb(p_escs, val_handle);
  157. case BLE_UUID_ESCS_LOCK_STATE_CHAR:
  158. return read_value(p_escs, ESCS_LOCK_STATE_READ_LENGTH, &p_escs->lock_state);
  159. case BLE_UUID_ESCS_ADV_INTERVAL_CHAR:
  160. {
  161. nrf_ble_escs_adv_interval_t adv_interval = es_adv_interval_get();
  162. adv_interval = BYTES_SWAP_16BIT(adv_interval);
  163. return read_value(p_escs, sizeof(adv_interval), &adv_interval);
  164. }
  165. case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR:
  166. return read_value(p_escs,
  167. sizeof(nrf_ble_escs_radio_tx_pwr_t),
  168. &p_reg->slots[active_slot].radio_tx_pwr);
  169. case BLE_UUID_ESCS_ADV_TX_PWR_CHAR:
  170. return read_value(p_escs,
  171. sizeof(nrf_ble_escs_radio_tx_pwr_t),
  172. p_reg->slots[active_slot].adv_custom_tx_power
  173. ? (uint8_t *)(&p_reg->slots[active_slot].custom_tx_power)
  174. : (uint8_t *)(&p_reg->slots[active_slot].radio_tx_pwr));
  175. case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR:
  176. {
  177. uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED;
  178. return read_value(p_escs, sizeof(retval), &retval);
  179. }
  180. case BLE_UUID_ESCS_EID_ID_KEY_CHAR:
  181. if (p_reg->slots[active_slot].configured &&
  182. (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID))
  183. {
  184. return read_value(p_escs,
  185. sizeof(nrf_ble_escs_eid_id_key_t),
  186. &p_reg->slots[active_slot].encrypted_eid_id_key);
  187. }
  188. else
  189. {
  190. return es_gatts_send_op_not_permitted(p_escs, true);
  191. }
  192. case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR:
  193. return read_adv_slot(p_escs, active_slot, p_reg);
  194. default:
  195. return NRF_ERROR_INVALID_PARAM;
  196. }
  197. }