123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- #include "sdk_common.h"
- #if NRF_MODULE_ENABLED(BLE_DIS_C)
- #include <stdlib.h>
- #include "ble.h"
- #include "ble_dis_c.h"
- #include "ble_gattc.h"
- #include "nrf_bitmask.h"
- #include "app_error.h"
- #define NRF_LOG_MODULE_NAME ble_dis
- #include "nrf_log.h"
- NRF_LOG_MODULE_REGISTER();
- #define BLE_DIS_C_MANUF_ID_LEN 5
- #define BLE_DIS_C_OU_ID_LEN 3
- #define BLE_DIS_C_VENDOR_ID_SRC_LEN 1
- #define BLE_DIS_C_VENDOR_ID_LEN 2
- #define BLE_DIS_C_PRODUCT_ID_LEN 2
- #define BLE_DIS_C_PRODUCT_VER_LEN 2
- #define BLE_DIS_C_ALL_CHARS_DISABLED_MASK 0x0000
- #define BLE_DIS_C_ALL_CHARS_ENABLED_MASK 0xFFFF
- static void gatt_error_handler(uint32_t nrf_error, void * p_contex, uint16_t conn_handle)
- {
- UNUSED_PARAMETER(conn_handle);
- ble_dis_c_t const * const p_ble_disc_c = (ble_dis_c_t *)p_contex;
- if (p_ble_disc_c != NULL)
- {
- p_ble_disc_c->error_handler(nrf_error);
- }
- }
- static ret_code_t system_id_decode(uint8_t const * p_data,
- uint16_t len,
- ble_dis_sys_id_t * const p_sys_id)
- {
- uint16_t const expected_len = (BLE_DIS_C_MANUF_ID_LEN + BLE_DIS_C_OU_ID_LEN);
-
- if (expected_len != len)
- {
- NRF_LOG_ERROR("System ID characteristic data cannot be decoded.");
- NRF_LOG_ERROR("Expected data length != Received data length: %d != %d", expected_len, len);
- return NRF_ERROR_INVALID_LENGTH;
- }
-
- p_sys_id->manufacturer_id = uint40_decode(p_data);
- p_data += BLE_DIS_C_MANUF_ID_LEN;
-
- p_sys_id->organizationally_unique_id = uint24_decode(p_data);
- return NRF_SUCCESS;
- }
- static ret_code_t pnp_id_decode(uint8_t const * p_data,
- uint16_t len,
- ble_dis_pnp_id_t * const p_pnp_id)
- {
- uint16_t const expected_len = (BLE_DIS_C_VENDOR_ID_SRC_LEN + BLE_DIS_C_VENDOR_ID_LEN +
- BLE_DIS_C_PRODUCT_ID_LEN + BLE_DIS_C_PRODUCT_VER_LEN);
-
- if (expected_len != len)
- {
- NRF_LOG_ERROR("PnP ID characteristic data cannot be decoded.");
- NRF_LOG_ERROR("Expected data length != Received data length: %d != %d", expected_len, len);
- return NRF_ERROR_INVALID_LENGTH;
- }
-
- p_pnp_id->vendor_id_source = p_data[0];
- p_data += BLE_DIS_C_VENDOR_ID_SRC_LEN;
-
- p_pnp_id->vendor_id = uint16_decode(p_data);
- p_data += BLE_DIS_C_VENDOR_ID_LEN;
-
- p_pnp_id->product_id = uint16_decode(p_data);
- p_data += BLE_DIS_C_PRODUCT_ID_LEN;
-
- p_pnp_id->product_version = uint16_decode(p_data);
- return NRF_SUCCESS;
- }
- static ble_dis_c_char_type_t char_type_get(ble_dis_c_t * p_ble_dis_c, uint16_t response_handle)
- {
- for (ble_dis_c_char_type_t char_type = (ble_dis_c_char_type_t) 0;
- char_type < BLE_DIS_C_CHAR_TYPES_NUM;
- char_type++)
- {
- if (response_handle == p_ble_dis_c->handles[char_type])
- {
- return char_type;
- }
- }
- return BLE_DIS_C_CHAR_TYPES_NUM;
- }
- static void on_read_rsp(ble_dis_c_t * p_ble_dis_c, ble_evt_t const * p_ble_evt)
- {
- ret_code_t err_code;
- ble_gattc_evt_read_rsp_t const * p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
- ble_dis_c_evt_t ble_dis_c_evt;
- ble_dis_c_char_type_t char_type;
-
- if ((p_ble_dis_c->evt_handler == NULL) ||
- (p_ble_dis_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle))
- {
- return;
- }
- char_type = char_type_get(p_ble_dis_c, p_response->handle);
- if (char_type < BLE_DIS_C_CHAR_TYPES_NUM)
- {
- memset(&ble_dis_c_evt, 0, sizeof(ble_dis_c_evt_t));
- ble_dis_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
- if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS)
- {
- ble_dis_c_evt_read_rsp_t * const p_dis_rsp = &ble_dis_c_evt.params.read_rsp;
- ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DIS_C_READ_RSP;
- p_dis_rsp->char_type = char_type;
- p_dis_rsp->handle = p_response->handle;
-
- switch (char_type)
- {
- case BLE_DIS_C_MANUF_NAME:
- case BLE_DIS_C_MODEL_NUM:
- case BLE_DIS_C_SERIAL_NUM:
- case BLE_DIS_C_HW_REV:
- case BLE_DIS_C_FW_REV:
- case BLE_DIS_C_SW_REV:
- p_dis_rsp->content.string.p_data = (uint8_t *) p_response->data;
- p_dis_rsp->content.string.len = p_response->len;
- break;
- case BLE_DIS_C_SYS_ID:
- err_code = system_id_decode(p_response->data,
- p_response->len,
- &p_dis_rsp->content.sys_id);
- if ((p_ble_dis_c->error_handler != NULL) && (err_code != NRF_SUCCESS))
- {
- p_ble_dis_c->error_handler(err_code);
- }
- break;
- case BLE_DIS_C_CERT_LIST:
- p_dis_rsp->content.cert_list.p_list = (uint8_t *) p_response->data;
- p_dis_rsp->content.cert_list.list_len = p_response->len;
- break;
- case BLE_DIS_C_PNP_ID:
- err_code = pnp_id_decode(p_response->data,
- p_response->len,
- &p_dis_rsp->content.pnp_id);
- if ((p_ble_dis_c->error_handler != NULL) && (err_code != NRF_SUCCESS))
- {
- p_ble_dis_c->error_handler(err_code);
- }
- break;
- default:
- break;
- }
- p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
- NRF_LOG_DEBUG("Received correct read response.");
- }
- else
- {
- ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR;
- ble_dis_c_evt.params.read_rsp_err.char_type = char_type;
- ble_dis_c_evt.params.read_rsp_err.err_handle = p_ble_evt->evt.gattc_evt.error_handle;
- ble_dis_c_evt.params.read_rsp_err.gatt_status = p_ble_evt->evt.gattc_evt.gatt_status;
- p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
- NRF_LOG_ERROR("Read request failed: 0x%04X.", p_ble_evt->evt.gattc_evt.gatt_status);
- }
- }
- }
- static void on_disconnected(ble_dis_c_t * p_ble_dis_c, const ble_evt_t * p_ble_evt)
- {
- if (p_ble_dis_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
- {
- p_ble_dis_c->conn_handle = BLE_CONN_HANDLE_INVALID;
- if (p_ble_dis_c->evt_handler != NULL)
- {
- ble_dis_c_evt_t dis_c_evt =
- {
- .evt_type = BLE_DIS_C_EVT_DISCONNECTED,
- .conn_handle = p_ble_evt->evt.gap_evt.conn_handle
- };
- p_ble_dis_c->evt_handler(p_ble_dis_c, &dis_c_evt);
- }
- }
- }
- ret_code_t ble_dis_c_init(ble_dis_c_t * p_ble_dis_c, ble_dis_c_init_t * p_ble_dis_c_init)
- {
- ble_uuid_t dis_uuid;
- VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
- VERIFY_PARAM_NOT_NULL(p_ble_dis_c_init);
- dis_uuid.type = BLE_UUID_TYPE_BLE;
- dis_uuid.uuid = BLE_UUID_DEVICE_INFORMATION_SERVICE;
- p_ble_dis_c->conn_handle = BLE_CONN_HANDLE_INVALID;
- p_ble_dis_c->p_gatt_queue = p_ble_dis_c_init->p_gatt_queue;
- p_ble_dis_c->evt_handler = p_ble_dis_c_init->evt_handler;
- p_ble_dis_c->error_handler = p_ble_dis_c_init->error_handler;
- memset(p_ble_dis_c->handles, BLE_GATT_HANDLE_INVALID, sizeof(p_ble_dis_c->handles));
-
- if (p_ble_dis_c_init->char_group.p_char_type != NULL)
- {
- p_ble_dis_c->char_mask = BLE_DIS_C_ALL_CHARS_DISABLED_MASK;
- for (uint8_t i = 0; i < p_ble_dis_c_init->char_group.size; i++)
- {
- nrf_bitmask_bit_set(p_ble_dis_c_init->char_group.p_char_type[i],
- &p_ble_dis_c->char_mask);
- }
- }
- else
- {
- p_ble_dis_c->char_mask = BLE_DIS_C_ALL_CHARS_ENABLED_MASK;
- }
- return ble_db_discovery_evt_register(&dis_uuid);
- }
- void ble_dis_c_on_db_disc_evt(ble_dis_c_t * p_ble_dis_c, ble_db_discovery_evt_t * p_evt)
- {
- ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
- ble_dis_c_evt_t ble_dis_c_evt;
-
- if ((p_ble_dis_c->evt_handler == NULL) ||
- (p_ble_dis_c->conn_handle == p_evt->conn_handle))
- {
- return;
- }
-
- if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
- (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_DEVICE_INFORMATION_SERVICE) &&
- (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
- {
- memset(&ble_dis_c_evt, 0, sizeof(ble_dis_c_evt_t));
- ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DISCOVERY_COMPLETE;
- ble_dis_c_evt.conn_handle = p_evt->conn_handle;
- for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
- {
- switch (p_chars[i].characteristic.uuid.uuid)
- {
- case BLE_UUID_MANUFACTURER_NAME_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_MANUF_NAME] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_MODEL_NUMBER_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_MODEL_NUM] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_SERIAL_NUMBER_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SERIAL_NUM] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_HARDWARE_REVISION_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_HW_REV] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_FIRMWARE_REVISION_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_FW_REV] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_SOFTWARE_REVISION_STRING_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SW_REV] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_SYSTEM_ID_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SYS_ID] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_CERT_LIST] =
- p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_PNP_ID_CHAR:
- ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_PNP_ID] =
- p_chars[i].characteristic.handle_value;
- break;
- default:
- break;
- }
- }
-
- for (ble_dis_c_char_type_t char_type = (ble_dis_c_char_type_t) 0;
- char_type < BLE_DIS_C_CHAR_TYPES_NUM;
- char_type++)
- {
- if (!nrf_bitmask_bit_is_set(char_type, &p_ble_dis_c->char_mask))
- {
- ble_dis_c_evt.params.disc_complete.handles[char_type] = BLE_GATT_HANDLE_INVALID;
- }
- }
- p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
- }
- }
- void ble_dis_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
- {
- ble_dis_c_t * p_ble_dis_c = (ble_dis_c_t *) p_context;
- if ((p_ble_dis_c == NULL) || (p_ble_evt == NULL))
- {
- return;
- }
- if (p_ble_dis_c->conn_handle == BLE_CONN_HANDLE_INVALID)
- {
- return;
- }
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GATTC_EVT_READ_RSP:
- on_read_rsp(p_ble_dis_c, p_ble_evt);
- break;
- case BLE_GAP_EVT_DISCONNECTED:
- on_disconnected(p_ble_dis_c, p_ble_evt);
- break;
- default:
-
- break;
- }
- }
- ret_code_t ble_dis_c_read(ble_dis_c_t * p_ble_dis_c, ble_dis_c_char_type_t char_type)
- {
- ret_code_t err_code;
- nrf_ble_gq_req_t dis_c_req;
- VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
- VERIFY_TRUE(char_type < BLE_DIS_C_CHAR_TYPES_NUM, NRF_ERROR_INVALID_PARAM);
- if ((p_ble_dis_c->conn_handle == BLE_CONN_HANDLE_INVALID) ||
- (p_ble_dis_c->handles[char_type] == BLE_GATT_HANDLE_INVALID))
- {
- return NRF_ERROR_INVALID_STATE;
- }
- memset(&dis_c_req, 0, sizeof(dis_c_req));
- dis_c_req.type = NRF_BLE_GQ_REQ_GATTC_READ;
- dis_c_req.error_handler.cb = gatt_error_handler;
- dis_c_req.error_handler.p_ctx = p_ble_dis_c;
- dis_c_req.params.gattc_read.handle = p_ble_dis_c->handles[char_type];
- err_code = nrf_ble_gq_item_add(p_ble_dis_c->p_gatt_queue, &dis_c_req, p_ble_dis_c->conn_handle);
- return err_code;
- }
- ret_code_t ble_dis_c_handles_assign(ble_dis_c_t * p_ble_dis_c,
- uint16_t conn_handle,
- ble_dis_c_handle_t const * p_peer_handles)
- {
- VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
- p_ble_dis_c->conn_handle = conn_handle;
- if (p_peer_handles != NULL)
- {
- memcpy(p_ble_dis_c->handles, p_peer_handles, sizeof(p_ble_dis_c->handles));
- }
- else
- {
- memset(p_ble_dis_c->handles, BLE_GATT_HANDLE_INVALID, sizeof(p_ble_dis_c->handles));
- }
- return nrf_ble_gq_conn_handle_register(p_ble_dis_c->p_gatt_queue, conn_handle);
- }
- #endif
|