/** **************************************************************************************** * @brief Handles reception of the @ref TIPC_ENABLE_REQ message. * The handler enables the Time Profile Client Role. * @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 tipc_enable_req_handler(ke_msg_id_t const msgid, struct tipc_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Battery Service Client Role Task Environment struct tipc_env_tag *tipc_env; // Connection Information struct prf_con_info con_info; // Fill the Connection Information structure con_info.conidx = gapc_get_conidx(param->conhdl); con_info.prf_id = dest_id; con_info.appid = src_id; // Add an environment for the provided device status = PRF_CLIENT_ENABLE(con_info, param, tipc); if (status == PRF_ERR_FEATURE_NOT_SUPPORTED) { // The message has been forwarded to another task id. return (KE_MSG_NO_FREE); } else if (status == PRF_ERR_OK) { tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc); //config connection, start discovering if(param->con_type == PRF_CON_DISCOVERY) { //start discovering CTS on peer prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_CURRENT_TIME); tipc_env->last_uuid_req = ATT_SVC_CURRENT_TIME; tipc_env->last_svc_req = ATT_SVC_CURRENT_TIME; // Go to DISCOVERING state ke_state_set(dest_id, TIPC_DISCOVERING); } //normal connection, get saved att details else { tipc_env->cts = param->cts; tipc_env->ndcs = param->ndcs; tipc_env->rtus = param->rtus; //send APP confirmation that can start normal connection tipc_enable_cfm_send(tipc_env, &con_info, PRF_ERR_OK); } } else { // Send confirmation that can start normal connection tipc_enable_cfm_send(NULL, &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 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); }
/** **************************************************************************************** * @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); }