/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = 0; // Get the address of the environment struct streamdatah_env_tag *streamdatah_env = PRF_CLIENT_GET_ENV(dest_id, streamdatah); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { //Currently discovering Link Loss Service if (streamdatah_env->last_svc_req == STREAMDATAD_SERVICE_UUID) { if (streamdatah_env->last_uuid_req == STREAMDATAD_SERVICE_UUID) { if (streamdatah_env->streamdatad.svc.shdl == ATT_INVALID_HANDLE) { streamdatah_enable_cfm_send(streamdatah_env, &streamdatah_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(streamdatah_env->nb_streamdatrad_svc > 1) { // stop discovery procedure. streamdatah_enable_cfm_send(streamdatah_env, &streamdatah_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover StreamData Device characteristics prf_disc_char_all_send(&(streamdatah_env->con_info), &(streamdatah_env->streamdatad.svc)); // Keep last UUID requested and for which service in env streamdatah_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (streamdatah_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(STREAMDATAH_CHAR_MAX, streamdatah_env->streamdatad.chars, streamdatah_streamdata_char); if (status == PRF_ERR_OK) { streamdatah_env->nb_streamdatrad_svc = 0; } streamdatah_enable_cfm_send(streamdatah_env, &streamdatah_env->con_info, status); } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Get the address of the environment struct hogpbh_env_tag *hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { /*------------------------------------------------------------------------------------------------------------- * SERVICES DISCOVERY *-------------------------------------------------------------------------------------------------------------*/ if (hogpbh_env->last_uuid_req == ATT_SVC_HID) { // If no HIDS instance has been found if (hogpbh_env->hids_nb == 0) { // Stop discovery procedure. hogpbh_enable_cfm_send(hogpbh_env, &hogpbh_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } else { // Discover all HOGPBH characteristics for first service instance hogpbh_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; hogpbh_env->last_svc_inst_req = 0; prf_disc_char_all_send(&(hogpbh_env->con_info), &(hogpbh_env->hids[0].svc)); } } /*------------------------------------------------------------------------------------------------------------- * CHARACTERISTICS DISCOVERY *-------------------------------------------------------------------------------------------------------------*/ else if (hogpbh_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(HOGPBH_CHAR_MAX, hogpbh_env->hids[hogpbh_env->last_svc_inst_req].chars, hogpbh_hids_char); if (status == PRF_ERR_OK) { hogpbh_env->last_uuid_req = ATT_INVALID_HANDLE; // Check if Boot Keyboard Input Report Char has been found if (HOGPBH_FOUND_CHAR(hogpbh_env, HOGPBH_CHAR_BOOT_KB_IN_REPORT)) { hogpbh_env->last_char_code = HOGPBH_CHAR_BOOT_KB_IN_REPORT; } // Check if Boot Mouse Input Report Char has been found else if (HOGPBH_FOUND_CHAR(hogpbh_env, HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT)) { hogpbh_env->last_char_code = HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT; } // Error - At least one of these characteristic must be supported else { status = PRF_ERR_STOP_DISC_CHAR_MISSING; } } if (status != PRF_ERR_OK) { //If we are here, stop discovery hogpbh_enable_cfm_send(hogpbh_env, &hogpbh_env->con_info, status); } else { // Send discover descriptors request prf_disc_char_desc_send(&(hogpbh_env->con_info), &(hogpbh_env->hids[hogpbh_env->last_svc_inst_req].chars[hogpbh_env->last_char_code])); } } /*------------------------------------------------------------------------------------------------------------- * DESCRIPTORS DISCOVERY *-------------------------------------------------------------------------------------------------------------*/ else { if (hogpbh_env->last_char_code == HOGPBH_CHAR_BOOT_KB_IN_REPORT) { if (HOGPBH_FOUND_CHAR(hogpbh_env, HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT)) { hogpbh_env->last_char_code = HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT; // Discover Client Char. Cfg descriptor for Boot Mouse Input Report Char. prf_disc_char_desc_send(&(hogpbh_env->con_info), &(hogpbh_env->hids[hogpbh_env->last_svc_inst_req].chars[hogpbh_env->last_char_code])); } else { if (hogpbh_env->last_svc_inst_req < (hogpbh_env->hids_nb - 1)) { // Discover HIDS Characteristics for the next instance hogpbh_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; hogpbh_env->last_svc_inst_req++; prf_disc_char_all_send(&(hogpbh_env->con_info), &(hogpbh_env->hids[hogpbh_env->last_svc_inst_req].svc)); } else { // send app the details about the discovered BAPS DB to save hogpbh_enable_cfm_send(hogpbh_env, &hogpbh_env->con_info, PRF_ERR_OK); } } } else if (hogpbh_env->last_char_code == HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT) { if (hogpbh_env->last_svc_inst_req < (hogpbh_env->hids_nb - 1)) { // Discover HIDS Characteristics for the next instance hogpbh_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; hogpbh_env->last_svc_inst_req++; prf_disc_char_all_send(&(hogpbh_env->con_info), &(hogpbh_env->hids[hogpbh_env->last_svc_inst_req].svc)); } else { // send app the details about the discovered BAPS DB to save hogpbh_enable_cfm_send(hogpbh_env, &hogpbh_env->con_info, PRF_ERR_OK); } } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); // Get the address of the environment struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc); uint8_t status = PRF_ERR_OK; if(state == SCPPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { // Service start/end handles has been received if(scppc_env->last_uuid_req == ATT_SVC_SCAN_PARAMETERS) { // check if service handles are not ok if(scppc_env->scps.svc.shdl== ATT_INVALID_HANDLE) { // stop discovery procedure. scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(scppc_env->nb_svc > 1) { scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover all SCPS characteristics prf_disc_char_all_send(&(scppc_env->con_info), &(scppc_env->scps.svc)); scppc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(scppc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(SCPPC_CHAR_MAX, scppc_env->scps.chars, scppc_scps_char); if(status == PRF_ERR_OK) { //If Scan Refresh Char. is present, discover its descriptor if (scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].char_hdl != ATT_INVALID_HANDLE) { scppc_env->last_uuid_req = ATT_INVALID_HANDLE; scppc_env->last_char_code = scppc_scps_char_desc[SCPPC_DESC_SCAN_REFRESH_CFG].char_code; // Discover Scan Refresh Char. Descriptor - Mandatory prf_disc_char_desc_send(&(scppc_env->con_info), &(scppc_env->scps.chars[scppc_env->last_char_code])); } else { scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } } else { // Stop discovery procedure. scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } } else { status = prf_check_svc_char_desc_validity(SCPPC_DESC_MAX, scppc_env->scps.descs, scppc_scps_char_desc, scppc_env->scps.chars); scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } if (status == PRF_ERR_OK) { // Write Scan Interval Windows value struct scppc_scan_intv_wd_wr_req * req = KE_MSG_ALLOC(SCPPC_SCAN_INTV_WD_WR_REQ, dest_id, dest_id, scppc_scan_intv_wd_wr_req); req->conhdl = gapc_get_conhdl(scppc_env->con_info.conidx); co_write16p(&req->scan_intv_wd.le_scan_intv, scppc_env->scan_intv_wd.le_scan_intv); co_write16p(&req->scan_intv_wd.le_scan_window, scppc_env->scan_intv_wd.le_scan_window); ke_msg_send(req); } } } else if (state == SCPPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: { struct scppc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(SCPPC_WR_CHAR_RSP, scppc_env->con_info.appid, dest_id, scppc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(scppc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { // an error occurs while reading peer device attribute scppc_error_ind_send(scppc_env, param->status); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = 0; // Get the address of the environment struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(qppc_env->last_uuid_req == ATT_DECL_PRIMARY_SERVICE) { // check if service handles are not ok if(qppc_env->qpps.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. qppc_enable_cfm_send(qppc_env, &qppc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(qppc_env->nb_svc != 1) { // stop discovery procedure. qppc_enable_cfm_send(qppc_env, &qppc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all QPPS characteristics prf_disc_char_all_send(&(qppc_env->con_info), &(qppc_env->qpps.svc)); qppc_env->nb_char = 0; qppc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(qppc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_128_char_validity(2, qppc_env->qpps.chars, qppc_qpps_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { qppc_env->last_uuid_req = ATT_DESC_CHAR_USER_DESCRIPTION; qppc_env->last_char_code = qppc_qpps_char_desc[QPPC_QPPS_RX_CHAR_VALUE_USER_DESP].char_code; //Discover Quintic Private profile Configuration Descriptor - Mandatory prf_disc_char_desc_send(&(qppc_env->con_info), &(qppc_env->qpps.chars[qppc_env->last_char_code])); } else { // Stop discovery procedure. qppc_enable_cfm_send(qppc_env, &qppc_env->con_info, status); } } else if (qppc_env->last_uuid_req == ATT_DESC_CHAR_USER_DESCRIPTION) { qppc_env->last_uuid_req = ATT_DESC_CLIENT_CHAR_CFG; qppc_env->last_char_code = qppc_qpps_char_desc[QPPC_QPPS_FIRST_TX_VALUE_CLI_CFG].char_code; //Discover Quintic Private profile User Descriptor prf_disc_char_desc_send(&(qppc_env->con_info), &(qppc_env->qpps.chars[qppc_env->last_char_code])); } else if (qppc_env->last_uuid_req == ATT_DESC_CLIENT_CHAR_CFG) { if (qppc_env->last_char_code < qppc_env->nb_char) { prf_disc_char_desc_send(&(qppc_env->con_info), &(qppc_env->qpps.chars[++qppc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(2, qppc_env->qpps.descs, qppc_qpps_char_desc, qppc_env->qpps.chars); qppc_enable_cfm_send(qppc_env, &qppc_env->con_info, status); } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * @param[in] msgid Id of the message received. * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance. * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct cscpc_env_tag *cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc); if (cscpc_env != NULL) { // Status uint8_t status = PRF_ERR_STOP_DISC_CHAR_MISSING; ASSERT_ERR(cscpc_env->operation != NULL); ASSERT_ERR(((struct cscpc_cmd *)cscpc_env->operation)->operation == CSCPC_ENABLE_OP_CODE); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { /* ------------------------------------------------- * SERVICE DISCOVERY ------------------------------- * ------------------------------------------------- */ if (cscpc_env->last_req == ATT_SVC_CYCLING_SPEED_CADENCE) { if (cscpc_env->nb_svc > 0) { // Check if service handles are OK if ((cscpc_env->cscs.svc.shdl != ATT_INVALID_HANDLE) && (cscpc_env->cscs.svc.ehdl != ATT_INVALID_HANDLE) && (cscpc_env->cscs.svc.shdl < cscpc_env->cscs.svc.ehdl)) { // Status is OK status = PRF_ERR_OK; // Discover all CSCS characteristics cscpc_env->last_req = ATT_DECL_CHARACTERISTIC; prf_disc_char_all_send(&(cscpc_env->con_info), &(cscpc_env->cscs.svc)); } // Handles are not corrects, the Cycling Speed and Cadence Service has not been found, stop } // The Cycling Speed and Cadence Service has not been found, stop discovery } /* ------------------------------------------------- * CHARACTERISTICS DISCOVERY ----------------------- * ------------------------------------------------- */ else if (cscpc_env->last_req == ATT_DECL_CHARACTERISTIC) { // Check if mandatory properties have been found and if properties are correct status = prf_check_svc_char_validity(CSCP_CSCS_CHAR_MAX, cscpc_env->cscs.chars, cscpc_cscs_char); // Check for characteristic properties. if (status == PRF_ERR_OK) { cscpc_env->last_req = CSCP_CSCS_CSC_MEAS_CHAR; // Find the Client Characteristic Configuration Descriptor for the CSC Measurement characteristic prf_disc_char_desc_send(&(cscpc_env->con_info), &(cscpc_env->cscs.chars[CSCP_CSCS_CSC_MEAS_CHAR])); } } /* ------------------------------------------------- * DESCRIPTORS DISCOVERY --------------------------- * ------------------------------------------------- */ else { // Discovery over ? bool disc_over = true; if (cscpc_env->last_req == CSCP_CSCS_CSC_MEAS_CHAR) { // Check if the SC Control Point Characteristic has been found if (cscpc_env->cscs.chars[CSCP_CSCS_SC_CTNL_PT_CHAR].char_hdl != ATT_INVALID_SEARCH_HANDLE) { // Status is OK status = PRF_ERR_OK; // Find the Client Characteristic Configuration Descriptor for the SC Control Point characteristic cscpc_env->last_req = CSCP_CSCS_SC_CTNL_PT_CHAR; prf_disc_char_desc_send(&(cscpc_env->con_info), &(cscpc_env->cscs.chars[CSCP_CSCS_SC_CTNL_PT_CHAR])); // Discovery continues disc_over = false; } } else { // Discovery is over ASSERT_ERR(cscpc_env->last_req == CSCP_CSCS_SC_CTNL_PT_CHAR); } if (disc_over) { status = prf_check_svc_char_desc_validity(CSCPC_DESC_MAX, cscpc_env->cscs.descs, cscpc_cscs_char_desc, cscpc_env->cscs.chars); if (status == PRF_ERR_OK) { // Reset number of services cscpc_env->nb_svc = 0; // Register in GATT for notifications/indications prf_register_atthdl2gatt(&cscpc_env->con_info, &cscpc_env->cscs.svc); // Send the content of the service to the HL struct cscpc_cscs_content_ind *ind = KE_MSG_ALLOC(CSCPC_CSCS_CONTENT_IND, cscpc_env->con_info.appid, cscpc_env->con_info.prf_id, cscpc_cscs_content_ind); ind->conhdl = cscpc_env->con_info.conhdl; memcpy(&ind->cscs, &cscpc_env->cscs, sizeof(struct cscpc_cscs_content)); // Send the message ke_msg_send(ind); // Stop discovery procedure. cscpc_send_cmp_evt(cscpc_env, CSCPC_ENABLE_OP_CODE, status); } } } } else { status = param->status; } if (status != PRF_ERR_OK) { // Stop discovery procedure. cscpc_send_cmp_evt(cscpc_env, CSCPC_ENABLE_OP_CODE, status); } } // else ignore the message return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); uint8_t status = 0; // Get the address of the environment struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm); if(state == PROXM_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { //Currently discovering Link Loss Service if (proxm_env->last_svc_req == ATT_SVC_LINK_LOSS) { if (proxm_env->last_uuid_req == ATT_SVC_LINK_LOSS) { if (proxm_env->lls.svc.shdl == ATT_INVALID_HANDLE) { proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(proxm_env->nb_svc > 1) { // stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover LLS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->lls.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->lls.charact, &proxm_lls_char); if (status == PRF_ERR_OK) { proxm_env->nb_svc = 0; // Start discovering TXPS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_TX_POWER); proxm_env->last_uuid_req = ATT_SVC_TX_POWER; proxm_env->last_svc_req = ATT_SVC_TX_POWER; } else { // Stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } //Currently discovering TX Power Service else if (proxm_env->last_svc_req == ATT_SVC_TX_POWER) { if (proxm_env->last_uuid_req == ATT_SVC_TX_POWER) { // TXPS is optional if (proxm_env->txps.svc.shdl == ATT_INVALID_HANDLE) { proxm_env->nb_svc = 0; // Start discovering IAS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT); proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT; proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT; } else { // Discover TXPS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->txps.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->txps.charact, &proxm_txps_char); if (status == PRF_ERR_OK) { proxm_env->nb_svc = 0; // Start discovering IAS on peer prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT); proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT; proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT; } else { // Stop discovery procedure. proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } //Currently discovering Immediate Alert Service else if (proxm_env->last_svc_req == ATT_SVC_IMMEDIATE_ALERT) { if (proxm_env->last_uuid_req == ATT_SVC_IMMEDIATE_ALERT) { // IAS is optional if (proxm_env->ias.svc.shdl == ATT_INVALID_HANDLE) { proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_OK); } else { // Discover IAS characteristics prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->ias.svc)); // Keep last UUID requested and for which service in env proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(1, &proxm_env->txps.charact, &proxm_txps_char); proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status); } } } } else if (state == PROXM_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { proxm_write_char_rsp_send(proxm_env, param->status); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { // an error occurs while reading peer device attribute prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * @param[in] msgid Id of the message received. * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance. * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct anpc_env_tag *anpc_env = PRF_CLIENT_GET_ENV(dest_id, anpc); if (anpc_env != NULL) { switch (param->req_type) { case (GATTC_DISC_BY_UUID_SVC): case (GATTC_DISC_ALL_CHAR): case (GATTC_DISC_DESC_CHAR): { // Status uint8_t status = PRF_ERR_STOP_DISC_CHAR_MISSING; if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { ASSERT_ERR(((struct anpc_cmd *)anpc_env->operation)->operation == ANPC_ENABLE_OP_CODE); /* ------------------------------------------------- * SERVICE DISCOVERY ------------------------------- * ------------------------------------------------- */ if (anpc_env->last_req == ATT_SVC_ALERT_NTF) { if (anpc_env->nb_svc > 0) { // Check if service handles are OK if ((anpc_env->ans.svc.shdl != ATT_INVALID_HANDLE) && (anpc_env->ans.svc.ehdl != ATT_INVALID_HANDLE) && (anpc_env->ans.svc.shdl < anpc_env->ans.svc.ehdl)) { // Status is OK status = PRF_ERR_OK; // Discover all ANS characteristics prf_disc_char_all_send(&(anpc_env->con_info), &(anpc_env->ans.svc)); anpc_env->last_req = ATT_DECL_CHARACTERISTIC; } // Handles are not corrects, the Phone Alert Status Service has not been found, stop } // The Phone Alert Status Service has not been found, stop discovery } /* ------------------------------------------------- * CHARACTERISTICS DISCOVERY ----------------------- * ------------------------------------------------- */ else if (anpc_env->last_req == ATT_DECL_CHARACTERISTIC) { // Check if mandatory properties have been found and if properties are correct status = prf_check_svc_char_validity(ANPC_CHAR_MAX, anpc_env->ans.chars, anpc_ans_char); // Check for characteristic properties. if (status == PRF_ERR_OK) { anpc_env->last_req = ANPC_CHAR_NEW_ALERT; // Find the Client Characteristic Configuration Descriptor for the New Alert characteristic prf_disc_char_desc_send(&(anpc_env->con_info), &(anpc_env->ans.chars[ANPC_CHAR_NEW_ALERT])); } } /* ------------------------------------------------- * DESCRIPTORS DISCOVERY --------------------------- * ------------------------------------------------- */ else { if (anpc_env->last_req == ANPC_CHAR_NEW_ALERT) { status = PRF_ERR_OK; anpc_env->last_req = ANPC_CHAR_UNREAD_ALERT_STATUS; // Find the Client Characteristic Configuration Descriptor for the Unread Alert Status characteristic prf_disc_char_desc_send(&(anpc_env->con_info), &(anpc_env->ans.chars[ANPC_CHAR_UNREAD_ALERT_STATUS])); } else if (anpc_env->last_req == ANPC_CHAR_UNREAD_ALERT_STATUS) { status = prf_check_svc_char_desc_validity(ANPC_DESC_MAX, anpc_env->ans.descs, anpc_ans_char_desc, anpc_env->ans.chars); if (status == PRF_ERR_OK) { // Reset number of services anpc_env->nb_svc = 0; // Register in GATT for notifications/indications prf_register_atthdl2gatt(&anpc_env->con_info, &anpc_env->ans.svc); // Send the content of the service to the HL struct anpc_ans_content_ind *ind = KE_MSG_ALLOC(ANPC_ANS_CONTENT_IND, anpc_env->con_info.appid, anpc_env->con_info.prf_id, anpc_ans_content_ind); ind->conhdl = gapc_get_conhdl(anpc_env->con_info.conidx); memcpy(&ind->ans, &anpc_env->ans, sizeof(struct anpc_ans_content)); // Send the message ke_msg_send(ind); // Force the operation value ((struct anpc_enable_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_RD_NEW_ALERT_OP_CODE; // Check Supported New Alert Categories prf_read_char_send(&(anpc_env->con_info), anpc_env->ans.svc.shdl, anpc_env->ans.svc.ehdl, anpc_env->ans.chars[ANPC_CHAR_SUP_NEW_ALERT_CAT].val_hdl); } } else { ASSERT_ERR(0); } } } else { status = param->status; } if (status != PRF_ERR_OK) { // Stop discovery procedure. anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, status); } } break; case (GATTC_WRITE): { // Retrieve the operation currently performed uint8_t operation = ((struct anpc_cmd *)anpc_env->operation)->operation; switch (operation) { case (ANPC_WRITE_OP_CODE): { uint8_t wr_code = ((struct anpc_write_cmd *)anpc_env->operation)->write_code; if ((wr_code == ANPC_RD_WR_NEW_ALERT_CFG) || (wr_code == ANPC_RD_WR_UNREAD_ALERT_STATUS_CFG) || (wr_code == ANPC_WR_ALERT_NTF_CTNL_PT)) { anpc_send_cmp_evt(anpc_env, ANPC_WRITE_OP_CODE, param->status); } else { ASSERT_ERR(0); } } break; case (ANPC_ENABLE_WR_NEW_ALERT_OP_CODE): { // Look for the next category to enable if (anpc_found_next_alert_cat(anpc_env, ((struct anpc_enable_cmd *)anpc_env->operation)->new_alert_enable)) { // Enable sending of notifications for the found category ID anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_EN_NEW_IN_ALERT_NTF, anpc_env->last_req - 1); } else { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_WR_NTF_NEW_ALERT_OP_CODE; // Send a "Notify New Alert Immediately" command with the Category ID field set to 0xFF anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_NTF_NEW_IN_ALERT_IMM, CAT_ID_ALL_SUPPORTED_CAT); } } break; case (ANPC_ENABLE_WR_NTF_NEW_ALERT_OP_CODE): { // Reset the environment anpc_env->last_req = CAT_ID_SPL_ALERT; if (anpc_found_next_alert_cat(anpc_env, ((struct anpc_enable_cmd *)anpc_env->operation)->unread_alert_enable)) { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE; // Enable sending of notifications for the found category ID anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->last_req - 1); } else { anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, PRF_ERR_OK); } } break; case (ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE): { // Look for the next category to enable if (anpc_found_next_alert_cat(anpc_env, ((struct anpc_enable_cmd *)anpc_env->operation)->unread_alert_enable)) { // Enable sending of notifications for the found category ID anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->last_req - 1); } else { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_WR_NTF_UNREAD_ALERT_OP_CODE; // Send a "Notify New Alert Immediately" command with the Category ID field set to 0xFF anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_NTF_UNREAD_CAT_STATUS_IMM, CAT_ID_ALL_SUPPORTED_CAT); } } break; case (ANPC_ENABLE_WR_NTF_UNREAD_ALERT_OP_CODE): { // The discovery procedure is over anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, param->status); } break; default: { ASSERT_ERR(0); } break; } } break; case (GATTC_READ): { switch (((struct anpc_cmd *)anpc_env->operation)->operation) { // Read Supported New Alert Category Characteristic value case (ANPC_ENABLE_RD_NEW_ALERT_OP_CODE): { if (param->status == GATT_ERR_NO_ERROR) { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE; // Check Supported Unread Alert Category prf_read_char_send(&(anpc_env->con_info), anpc_env->ans.svc.shdl, anpc_env->ans.svc.ehdl, anpc_env->ans.chars[ANPC_CHAR_SUP_UNREAD_ALERT_CAT].val_hdl); } else { anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, param->status); } } break; case (ANPC_ENABLE_RD_UNREAD_ALERT_OP_CODE): { if (param->status == GATT_ERR_NO_ERROR) { // If peer device was unknown, stop the procedure if (((struct anpc_enable_cmd *)anpc_env->operation)->con_type == PRF_CON_DISCOVERY) { anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, PRF_ERR_OK); } // If peer device was already known (bonded), start Recovery from Connection Loss procedure else { // Reset the environment anpc_env->last_req = CAT_ID_SPL_ALERT; if (anpc_found_next_alert_cat(anpc_env, ((struct anpc_enable_cmd *)anpc_env->operation)->new_alert_enable)) { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_WR_NEW_ALERT_OP_CODE; // Enable sending of notifications for the found category ID anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_EN_NEW_IN_ALERT_NTF, anpc_env->last_req - 1); } else { // Reset the environment anpc_env->last_req = CAT_ID_SPL_ALERT; if (anpc_found_next_alert_cat(anpc_env, ((struct anpc_enable_cmd *)anpc_env->operation)->unread_alert_enable)) { // Force the operation value ((struct anpc_cmd *)anpc_env->operation)->operation = ANPC_ENABLE_WR_UNREAD_ALERT_OP_CODE; // Enable sending of notifications for the found category ID anpc_write_alert_ntf_ctnl_pt(anpc_env, CMD_ID_EN_UNREAD_CAT_STATUS_NTF, anpc_env->last_req - 1); } else { anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, PRF_ERR_OK); } } } } else { anpc_send_cmp_evt(anpc_env, ANPC_ENABLE_OP_CODE, param->status); } } break; case (ANPC_READ_OP_CODE): { // Inform the requester that the read procedure is over anpc_send_cmp_evt(anpc_env, ANPC_READ_OP_CODE, param->status); } break; default: { ASSERT_ERR(0); } } } break; case (GATTC_REGISTER): case (GATTC_UNREGISTER): { // Do nothing } break; default: { ASSERT_ERR(0); } break; } } // else ignore the message return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); uint8_t status; // Get the address of the environment struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc); if(state == GLPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(glpc_env->last_uuid_req == ATT_SVC_GLUCOSE) { // check if service handles are not ok if(glpc_env->gls.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(glpc_env->nb_svc != 1) { // stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all GLS characteristics prf_disc_char_all_send(&(glpc_env->con_info), &(glpc_env->gls.svc)); glpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(glpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(GLPC_CHAR_MAX, glpc_env->gls.chars, glpc_gls_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { glpc_env->last_uuid_req = ATT_INVALID_HANDLE; glpc_env->last_char_code = glpc_gls_char_desc[GLPC_DESC_MEAS_CLI_CFG].char_code; //Discover Glucose Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } else { // Stop discovery procedure. glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status); } } else { //If Glucose Measurement Context Char. found, discover its descriptor if ((glpc_env->gls.chars[GLPC_CHAR_MEAS_CTX].char_hdl != ATT_INVALID_HANDLE) && (glpc_env->last_char_code == GLPC_CHAR_MEAS)) { glpc_env->last_char_code = GLPC_CHAR_MEAS_CTX; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } // discover Record access control point descriptor else if (glpc_env->last_char_code != GLPC_CHAR_RACP) { glpc_env->last_char_code = GLPC_CHAR_RACP; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(glpc_env->con_info), &(glpc_env->gls.chars[glpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(GLPC_DESC_MAX, glpc_env->gls.descs, glpc_gls_char_desc, glpc_env->gls.chars); glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status); } } } } else if (state == GLPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { // RACP write done. if(glpc_env->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT) { // an error occurs while writing RACP command if(param->status != PRF_ERR_OK) { struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP, glpc_env->con_info.appid, dest_id, glpc_racp_rsp); // retrieve connection handle rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); // set error status rsp->status = param->status; // stop timer. ke_timer_clear(GLPC_RACP_REQ_TIMEOUT, dest_id); ke_msg_send(rsp); glpc_env->last_uuid_req = 0; } } else { bool finished = false; // Restore if measurement context notification should be register in from // unused variable bool meas_ctx_en = glpc_env->last_char_code; // Registration succeed if(param->status == PRF_ERR_OK) { // Glucose measurement notification registration done if(glpc_env->last_uuid_req == GLPC_DESC_MEAS_CLI_CFG) { // register to RACP indications prf_gatt_write_ntf_ind(&(glpc_env->con_info), glpc_env->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl, PRF_CLI_START_IND); glpc_env->last_uuid_req = GLPC_DESC_RACP_CLI_CFG; } // Record access control point indication registration done // Register to Glucose Measurement Context notifications if requested. else if((glpc_env->last_uuid_req == GLPC_DESC_RACP_CLI_CFG) && meas_ctx_en) { // register to Glucose Measurement Context notifications prf_gatt_write_ntf_ind(&(glpc_env->con_info), glpc_env->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl, PRF_CLI_START_NTF); glpc_env->last_uuid_req = GLPC_DESC_MEAS_CTX_CLI_CFG; } // All registration done else { // indication/notification registration finished finished = true; } } // send status if registration done or if an error occurs. if((param->status != PRF_ERR_OK) || (finished)) { struct glpc_register_cfm * cfm = KE_MSG_ALLOC(GLPC_REGISTER_CFM, glpc_env->con_info.appid, dest_id, glpc_register_cfm); // set error status cfm->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); cfm->status = param->status; ke_msg_send(cfm); } } } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP, glpc_env->con_info.appid, dest_id, glpc_read_features_rsp); // set connection handle rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx); // set error status rsp->status = param->status; ke_msg_send(rsp); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc); uint8_t status = PRF_ERR_OK; if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { // Service start/end handles has been received if(scppc_env->last_uuid_req == ATT_SVC_SCAN_PARAMETERS) { // check if service handles are not ok if(scppc_env->scps.svc.shdl== ATT_INVALID_HANDLE) { // stop discovery procedure. scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(scppc_env->nb_svc > 1) { scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover all SCPS characteristics prf_disc_char_all_send(&(scppc_env->con_info), &(scppc_env->scps.svc)); scppc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(scppc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(SCPPC_CHAR_MAX, scppc_env->scps.chars, scppc_scps_char); if(status == PRF_ERR_OK) { //If Scan Refresh Char. is present, discover its descriptor if (scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].char_hdl != ATT_INVALID_HANDLE) { scppc_env->last_uuid_req = ATT_INVALID_HANDLE; scppc_env->last_char_code = scppc_scps_char_desc[SCPPC_DESC_SCAN_REFRESH_CFG].char_code; // Discover Scan Refresh Char. Descriptor - Mandatory prf_disc_char_desc_send(&(scppc_env->con_info), &(scppc_env->scps.chars[scppc_env->last_char_code])); } else { scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } } else { // Stop discovery procedure. scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } } else { status = prf_check_svc_char_desc_validity(SCPPC_DESC_MAX, scppc_env->scps.descs, scppc_scps_char_desc, scppc_env->scps.chars); scppc_enable_cfm_send(scppc_env, &scppc_env->con_info, status); } if (status == PRF_ERR_OK) { // Write Scan Interval Windows value struct scppc_scan_intv_wd_wr_req * req = KE_MSG_ALLOC(SCPPC_SCAN_INTV_WD_WR_REQ, dest_id, dest_id, scppc_scan_intv_wd_wr_req); req->conhdl = scppc_env->con_info.conhdl; co_write16p(&req->scan_intv_wd.le_scan_intv, scppc_env->scan_intv_wd.le_scan_intv); co_write16p(&req->scan_intv_wd.le_scan_window, scppc_env->scan_intv_wd.le_scan_window); ke_msg_send(req); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); // Status uint8_t status; // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); if(state == HTPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // Service start/end handles has been received if(htpc_env->last_uuid_req == ATT_SVC_HEALTH_THERMOM) { // check if service handles are not ok if (htpc_env->hts.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(htpc_env->nb_svc > 1) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all HTS characteristics htpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; prf_disc_char_all_send(&(htpc_env->con_info), &(htpc_env->hts.svc)); } } else if(htpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(HTPC_CHAR_HTS_MAX, htpc_env->hts.chars, htpc_hts_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { htpc_env->last_uuid_req = ATT_INVALID_HANDLE; htpc_env->last_char_code = htpc_hts_char_desc[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].char_code; //Discover Temperature Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { // Stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } else //Descriptors { //Get code of next char. having descriptors htpc_env->last_char_code = htpc_get_next_desc_char_code(htpc_env, &htpc_hts_char_desc[0]); if (htpc_env->last_char_code != HTPC_DESC_HTS_MAX) { prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(HTPC_DESC_HTS_MAX, htpc_env->hts.descs, htpc_hts_char_desc, htpc_env->hts.chars); htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } } else { htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, param->status); } } else if(state == HTPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { // Get the address of the environment struct htpc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(HTPC_WR_CHAR_RSP, htpc_env->con_info.appid, dest_id, htpc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(htpc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { prf_client_att_info_rsp((prf_env_struct*) htpc_env, HTPC_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Get the address of the environment struct basc_env_tag *basc_env = PRF_CLIENT_GET_ENV(dest_id, basc); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND) || (param->status == ATT_ERR_NO_ERROR)) { // SERVICES if (basc_env->last_uuid_req == ATT_SVC_BATTERY_SERVICE) { // If no BAS instance has been found if (basc_env->bas_nb == 0) { // Stop discovery procedure. basc_enable_cfm_send(basc_env, &basc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } else { // Discover all BAS characteristics for first service instance basc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; basc_env->last_svc_inst_req = 0; prf_disc_char_all_send(&(basc_env->con_info), &(basc_env->bas[0].svc)); } } // CHARACTERISTICS else if (basc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(BAS_CHAR_MAX, basc_env->bas[basc_env->last_svc_inst_req].chars, basc_bas_char); if (status == PRF_ERR_OK) { basc_env->last_uuid_req = ATT_INVALID_HANDLE; basc_env->last_char_code = basc_bas_char_desc[BAS_DESC_BATT_LEVEL_CFG].char_code; // Request all service characteristic descriptor for BAS prf_disc_char_desc_send(&(basc_env->con_info), &(basc_env->bas[basc_env->last_svc_inst_req].chars[BAS_CHAR_BATT_LEVEL])); } else { // Stop discovery procedure. basc_enable_cfm_send(basc_env, &basc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } } // DESCRIPTORS else { //Check if Characteristic Presentation Format is present if (basc_env->bas_nb > 1) { // The Characteristic Presentation Format descriptor must be present if several BAS instances are present if (basc_env->bas[basc_env->last_svc_inst_req].descs[BAS_DESC_BATT_LEVEL_PRES_FORMAT].desc_hdl == ATT_INVALID_HANDLE) { // stop discovery procedure. basc_enable_cfm_send(basc_env, &basc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); return (KE_MSG_CONSUMED); } } //Check if Client Characteristic Configuration is present if ((basc_env->bas[basc_env->last_svc_inst_req].chars[BAS_CHAR_BATT_LEVEL].prop & ATT_CHAR_PROP_NTF) == ATT_CHAR_PROP_NTF) { // The Client Characteristic Configuration descriptor must be present if the characteristic supports NTFs if (basc_env->bas[basc_env->last_svc_inst_req].descs[BAS_DESC_BATT_LEVEL_CFG].desc_hdl == ATT_INVALID_HANDLE) { // Stop discovery procedure. basc_enable_cfm_send(basc_env, &basc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); return (KE_MSG_CONSUMED); } } if (basc_env->last_svc_inst_req < (basc_env->bas_nb-1)) { // Discover BAS Characteristics for the next instance basc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; basc_env->last_svc_inst_req++; prf_disc_char_all_send(&(basc_env->con_info), &(basc_env->bas[basc_env->last_svc_inst_req].svc)); } else { // send app the details about the discovered BAPS DB to save basc_enable_cfm_send(basc_env, &basc_env->con_info, PRF_ERR_OK); } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status; // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // Currently Discovering Current Time service characteristics. if(tipc_env->last_svc_req == ATT_SVC_CURRENT_TIME) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_CURRENT_TIME) { // check if service handles are not ok if (tipc_env->cts.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all CTS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->cts.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_CTS_MAX, tipc_env->cts.chars, tipc_cts_char); // check for characteristic properties. if(status == PRF_ERR_OK) { tipc_env->last_uuid_req = ATT_INVALID_HANDLE; tipc_env->last_char_code = TIPC_CHAR_CTS_CURR_TIME; //request all service characteristic description for CTS prf_disc_char_desc_send(&(tipc_env->con_info), &(tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME])); } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } else { status = prf_check_svc_char_desc_validity(TIPC_DESC_CTS_MAX, tipc_env->cts.descs, tipc_cts_char_desc, tipc_env->cts.chars); if(status == PRF_ERR_OK) { // reset number of services tipc_env->nb_svc = 0; //start discovering NDCS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_NEXT_DST_CHANGE); tipc_env->last_uuid_req = ATT_SVC_NEXT_DST_CHANGE; tipc_env->last_svc_req = ATT_SVC_NEXT_DST_CHANGE; } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } // Currently Next DST Change service characteristics. else if(tipc_env->last_svc_req == ATT_SVC_NEXT_DST_CHANGE) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_NEXT_DST_CHANGE) { if (tipc_env->ndcs.svc.shdl == ATT_INVALID_HANDLE) { // reset number of services tipc_env->nb_svc = 0; //start discovering RTUS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE); tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE; tipc_env->last_svc_req = ATT_SVC_REF_TIME_UPDATE; } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all NDCS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->ndcs.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_NDCS_MAX, tipc_env->ndcs.chars, tipc_ndcs_char); // check for characteristic properties. if(status == PRF_ERR_OK) { // reset number of services tipc_env->nb_svc = 0; //start discovering RTUS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE); tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE; tipc_env->last_svc_req = ATT_SVC_REF_TIME_UPDATE; } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } // Currently Reference Time Update service characteristics. else if(tipc_env->last_svc_req == ATT_SVC_REF_TIME_UPDATE) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_REF_TIME_UPDATE) { if (tipc_env->rtus.svc.shdl == ATT_INVALID_HANDLE) { // send app the details about the discovered TIPS DB to save tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK); } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all RTUS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->rtus.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_RTUS_MAX, tipc_env->rtus.chars, tipc_rtus_char); // check for characteristic properties. if(status == PRF_ERR_OK) { // send app the details about the discovered TIPS DB to save tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK); } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); uint8_t status; // Get the address of the environment struct blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc); if(state == BLPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(blpc_env->last_uuid_req == ATT_SVC_BLOOD_PRESSURE) { // check if service handles are not ok if(blpc_env->bps.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(blpc_env->nb_svc != 1) { // stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all BPS characteristics prf_disc_char_all_send(&(blpc_env->con_info), &(blpc_env->bps.svc)); blpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(blpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(BLPC_CHAR_MAX, blpc_env->bps.chars, blpc_bps_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { blpc_env->last_uuid_req = ATT_INVALID_HANDLE; blpc_env->last_char_code = blpc_bps_char_desc[BLPC_DESC_BP_MEAS_CLI_CFG].char_code; //Discover Blood Pressure Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(blpc_env->con_info), &(blpc_env->bps.chars[blpc_env->last_char_code])); } else { // Stop discovery procedure. blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, status); } } else { //If Intermediate Cuff Pressure Char. found, discover its descriptor if ((blpc_env->bps.chars[BLPC_CHAR_CP_MEAS].char_hdl != ATT_INVALID_HANDLE) && (blpc_env->last_char_code == BLPC_CHAR_BP_MEAS)) { blpc_env->last_char_code = BLPC_CHAR_CP_MEAS; //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory prf_disc_char_desc_send(&(blpc_env->con_info), &(blpc_env->bps.chars[blpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(BLPC_DESC_MAX, blpc_env->bps.descs, blpc_bps_char_desc, blpc_env->bps.chars); blpc_enable_cfm_send(blpc_env, &blpc_env->con_info, status); } } } } else if(state == BLPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { struct blpc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(BLPC_WR_CHAR_RSP, blpc_env->con_info.appid, dest_id, blpc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(blpc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { if(param->status != GATT_ERR_NO_ERROR) { prf_client_att_info_rsp((prf_env_struct*) blpc_env, BLPC_RD_CHAR_RSP, param->status, NULL); } } break; default: break; } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status; // Get the address of the environment struct hrpc_env_tag *hrpc_env = PRF_CLIENT_GET_ENV(dest_id, hrpc); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // service start/end handles has been received if(hrpc_env->last_uuid_req == ATT_SVC_HEART_RATE) { // check if service handles are not ok if(hrpc_env->hrs.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. hrpc_enable_cfm_send(hrpc_env, &hrpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(hrpc_env->nb_svc != 1) { // stop discovery procedure. hrpc_enable_cfm_send(hrpc_env, &hrpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { //discover all HRS characteristics prf_disc_char_all_send(&(hrpc_env->con_info), &(hrpc_env->hrs.svc)); hrpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(hrpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(HRPC_CHAR_MAX, hrpc_env->hrs.chars, hrpc_hrs_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { hrpc_env->last_uuid_req = ATT_INVALID_HANDLE; hrpc_env->last_char_code = hrpc_hrs_char_desc[HRPC_DESC_HR_MEAS_CLI_CFG].char_code; //Discover Heart Rate Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(hrpc_env->con_info), &(hrpc_env->hrs.chars[hrpc_env->last_char_code])); } else { // Stop discovery procedure. hrpc_enable_cfm_send(hrpc_env, &hrpc_env->con_info, status); } } else //Descriptors { status = prf_check_svc_char_desc_validity(HRPC_DESC_MAX, hrpc_env->hrs.descs, hrpc_hrs_char_desc, hrpc_env->hrs.chars); hrpc_enable_cfm_send(hrpc_env, &hrpc_env->con_info, status); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gatt_cmp_evt_handler(ke_msg_id_t const msgid, struct gatt_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // Service start/end handles has been received if(htpc_env->last_uuid_req == ATT_SVC_HEALTH_THERMOM) { // check if service handles are not ok if (htpc_env->hts.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(htpc_env->nb_svc > 1) { // stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all HTS characteristics htpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; prf_disc_char_all_send(&(htpc_env->con_info), &(htpc_env->hts.svc)); } } else if(htpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(HTPC_CHAR_HTS_MAX, htpc_env->hts.chars, htpc_hts_char); // Check for characteristic properties. if(status == PRF_ERR_OK) { htpc_env->last_uuid_req = ATT_INVALID_HANDLE; htpc_env->last_char_code = htpc_hts_char_desc[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].char_code; //Discover Temperature Measurement Char. Descriptor - Mandatory prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { // Stop discovery procedure. htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } else //Descriptors { //Get code of next char. having descriptors htpc_env->last_char_code = htpc_get_next_desc_char_code(htpc_env, &htpc_hts_char_desc[0]); if (htpc_env->last_char_code != HTPC_DESC_HTS_MAX) { prf_disc_char_desc_send(&(htpc_env->con_info), &(htpc_env->hts.chars[htpc_env->last_char_code])); } else { status = prf_check_svc_char_desc_validity(HTPC_DESC_HTS_MAX, htpc_env->hts.descs, htpc_hts_char_desc, htpc_env->hts.chars); htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, status); } } } else { htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, param->status); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_CMP_EVT message. * This generic event is received for different requests, so need to keep track. * @param[in] msgid Id of the message received (probably unused). * @param[in] param Pointer to the parameters of the message. * @param[in] dest_id ID of the receiving task instance (probably unused). * @param[in] src_id ID of the sending task instance. * @return If the message was consumed or not. **************************************************************************************** */ static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t state = ke_state_get(dest_id); uint8_t status; // Get the address of the environment struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); if(state == TIPC_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { // Currently Discovering Current Time service characteristics. if(tipc_env->last_svc_req == ATT_SVC_CURRENT_TIME) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_CURRENT_TIME) { // check if service handles are not ok if (tipc_env->cts.svc.shdl == ATT_INVALID_HANDLE) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all CTS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->cts.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_CTS_MAX, tipc_env->cts.chars, tipc_cts_char); // check for characteristic properties. if(status == PRF_ERR_OK) { tipc_env->last_uuid_req = ATT_INVALID_HANDLE; tipc_env->last_char_code = TIPC_CHAR_CTS_CURR_TIME; //request all service characteristic description for CTS prf_disc_char_desc_send(&(tipc_env->con_info), &(tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME])); } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } else { status = prf_check_svc_char_desc_validity(TIPC_DESC_CTS_MAX, tipc_env->cts.descs, tipc_cts_char_desc, tipc_env->cts.chars); if(status == PRF_ERR_OK) { // reset number of services tipc_env->nb_svc = 0; //start discovering NDCS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_NEXT_DST_CHANGE); tipc_env->last_uuid_req = ATT_SVC_NEXT_DST_CHANGE; tipc_env->last_svc_req = ATT_SVC_NEXT_DST_CHANGE; } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } // Currently Next DST Change service characteristics. else if(tipc_env->last_svc_req == ATT_SVC_NEXT_DST_CHANGE) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_NEXT_DST_CHANGE) { if (tipc_env->ndcs.svc.shdl == ATT_INVALID_HANDLE) { // reset number of services tipc_env->nb_svc = 0; //start discovering RTUS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE); tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE; tipc_env->last_svc_req = ATT_SVC_REF_TIME_UPDATE; } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all NDCS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->ndcs.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_NDCS_MAX, tipc_env->ndcs.chars, tipc_ndcs_char); // check for characteristic properties. if(status == PRF_ERR_OK) { // reset number of services tipc_env->nb_svc = 0; //start discovering RTUS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE); tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE; tipc_env->last_svc_req = ATT_SVC_REF_TIME_UPDATE; } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } // Currently Reference Time Update service characteristics. else if(tipc_env->last_svc_req == ATT_SVC_REF_TIME_UPDATE) { // service start/end handles has been received if(tipc_env->last_uuid_req == ATT_SVC_REF_TIME_UPDATE) { if (tipc_env->rtus.svc.shdl == ATT_INVALID_HANDLE) { // send app the details about the discovered TIPS DB to save tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK); } //too many services found only one such service should exist else if(tipc_env->nb_svc != 1) { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC); } // check if service handles are ok else { //discover all RTUS characteristics prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->rtus.svc)); tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity(TIPC_CHAR_RTUS_MAX, tipc_env->rtus.chars, tipc_rtus_char); // check for characteristic properties. if(status == PRF_ERR_OK) { // send app the details about the discovered TIPS DB to save tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK); } else { // stop discovery procedure. tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status); } } } } } else if(state == TIPC_CONNECTED) { switch(param->req_type) { case GATTC_WRITE: case GATTC_WRITE_NO_RESPONSE: { struct tipc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(TIPC_WR_CHAR_RSP, tipc_env->con_info.appid, dest_id, tipc_wr_char_rsp); wr_cfm->conhdl = gapc_get_conhdl(tipc_env->con_info.conidx); //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); } break; case GATTC_READ: { // an error occurs while reading peer attribute, inform app if(param->status != GATT_ERR_NO_ERROR) { tipc_error_ind_send(tipc_env, param->status); } } break; default: break; } } return (KE_MSG_CONSUMED); }
static int gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = 0; uint8_t state = ke_state_get(dest_id); // Get the address of the environment struct sps_client_env_tag *sps_client_env = PRF_CLIENT_GET_ENV(dest_id, sps_client); if(state == SPS_CLIENT_DISCOVERING) { if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)|| (param->status == ATT_ERR_NO_ERROR)) { //Currently discovering sps_server Service uint8_t stream_data_service_uuid[]=SPS_SERVICE_UUID; if (!memcmp(sps_client_env->last_svc_req, stream_data_service_uuid, ATT_UUID_128_LEN)) { if (sps_client_env->last_uuid_req == ATT_DECL_PRIMARY_SERVICE) { if (sps_client_env->sps_server.svc.shdl == ATT_INVALID_HANDLE) { sps_client_enable_cfm_send(sps_client_env, &sps_client_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING); } // Too many services found only one such service should exist else if(sps_client_env->nb_streamdatrad_svc > 1) { // stop discovery procedure. sps_client_enable_cfm_send(sps_client_env, &sps_client_env->con_info, PRF_ERR_MULTIPLE_SVC); } else { // Discover StreamData Device characteristics prf_disc_char_all_send(&(sps_client_env->con_info), &(sps_client_env->sps_server.svc)); // Keep last UUID requested and for which service in env sps_client_env->last_uuid_req = ATT_DECL_CHARACTERISTIC; } } else if (sps_client_env->last_uuid_req == ATT_DECL_CHARACTERISTIC) { status = prf_check_svc_char_validity_128(SPS_CLIENT_MAX, sps_client_env->sps_server.chars, sps_client_sps_char); if (status == PRF_ERR_OK) { sps_client_env->nb_streamdatrad_svc = 0; sps_client_enable_cfm_send(sps_client_env, &sps_client_env->con_info, status); } else { sps_client_enable_cfm_send(sps_client_env, &sps_client_env->con_info, status); } } } } } else if (state == SPS_CLIENT_CONNECTED) { if(param->req_type == GATTC_WRITE_NO_RESPONSE) { complete_event_counter_sending_packages++; } } return (KE_MSG_CONSUMED); }