/** **************************************************************************************** * @brief Handles @ref GATT_HANDLE_VALUE_CFM message meaning that Measurement indication * has been correctly sent to peer device. * * Convey this information to appli task using @ref GLPS_MEAS_SEND_CFM * * @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_handle_value_cfm_handler(ke_msg_id_t const msgid, struct gatt_handle_value_cfm const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // verify if indication should be conveyed to application task if(glps_env.racp_ind_src == glps_env.con_info.appid) { // send completed information to APP task struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid, TASK_GLPS, glps_req_cmp_evt); cmp_evt->conhdl = glps_env.con_info.conhdl; cmp_evt->request = GLPS_SEND_RACP_RSP_IND_CMP; cmp_evt->status = param->status; ke_msg_send(cmp_evt); } return (KE_MSG_CONSUMED); }
void pasps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, uint16_t conhdl, uint8_t operation, uint8_t status) { // Come back to the Connected state if the state was busy. if (ke_state_get(src_id) == PASPS_BUSY) { ke_state_set(src_id, PASPS_CONNECTED); } // Send the message to the application struct pasps_cmp_evt *evt = KE_MSG_ALLOC(PASPS_CMP_EVT, dest_id, src_id, pasps_cmp_evt); evt->conhdl = conhdl; evt->operation = operation; evt->status = status; ke_msg_send(evt); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_WRITE_CHAR_RESP message. * Generic event received after every simple write command sent to peer server. * @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_write_char_rsp_handler(ke_msg_id_t const msgid, struct gatt_write_char_resp const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc); 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 = htpc_env->con_info.conhdl; //it will be a GATT status code wr_cfm->status = param->status; // send the message ke_msg_send(wr_cfm); return (KE_MSG_CONSUMED); }
void app_proxr_enable(void) { // Allocate the message struct proxr_enable_req * req = KE_MSG_ALLOC(PROXR_ENABLE_REQ, TASK_PROXR, TASK_APP, proxr_enable_req); // init application alert state app_proxr_alert_stop(); // Fill in the parameter structure req->conhdl = app_env.conhdl; req->sec_lvl = PERM(SVC, ENABLE); req->lls_alert_lvl = (uint8_t) alert_state.ll_alert_lvl; req->txp_lvl = alert_state.txp_lvl; // Send the message ke_msg_send(req); }
void app_adc_notify_enable(void) { // Allocate the message struct adc_notify_enable_req* req = KE_MSG_ALLOC(ADC_NOTIFY_ENABLE_REQ, TASK_ADC_NOTIFY, TASK_APP, adc_notify_enable_req); req->conhdl = app_env.conhdl; req->sec_lvl = PERM(SVC, ENABLE); adc_init(GP_ADC_SE, ADC_POLARITY_UNSIGNED); // Single ended mode adc_enable_channel(ADC_CHANNEL_P01); // req->adc_notify_val = SWAP(adc_get_sample());//dummy value req->feature = 0x00; //client CFG notif/ind disable // Send the message ke_msg_send(req); }
/** **************************************************************************************** * @brief Handles ready indication from the GAP. - Reset the stack * * @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 (TASK_GAP). * @param[in] src_id ID of the sending task instance. * * @return If the message was consumed or not. **************************************************************************************** */ int gapm_device_ready_ind_handler(ke_msg_id_t const msgid, void const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { if (ke_state_get(dest_id) == APP_DISABLED) { // reset the lower layers. struct gapm_reset_cmd* cmd = KE_MSG_ALLOC(GAPM_RESET_CMD, TASK_GAPM, TASK_APP, gapm_reset_cmd); cmd->operation = GAPM_RESET; ke_msg_send(cmd); } else { // APP_DISABLED state is used to wait the GAP_READY_EVT message ASSERT_ERR(0); } return (KE_MSG_CONSUMED); }
void bass_disable(void) { // Counter uint8_t i; // Information get in the DB atts_size_t att_length; uint8_t *att_value; // Send current configuration to the application struct bass_disable_ind *ind = KE_MSG_ALLOC(BASS_DISABLE_IND, bass_env.con_info.appid, TASK_BASS, bass_disable_ind); ind->conhdl = bass_env.con_info.conhdl; for (i = 0; i < bass_env.bas_nb; i++) { if((bass_env.features[i] & BASS_FLAG_NTF_CFG_BIT) == BASS_FLAG_NTF_CFG_BIT) { ind->batt_level_ntf_cfg[i] = PRF_CLI_START_NTF; // Reset ntf cfg bit in features bass_env.features[i] &= ~BASS_FLAG_NTF_CFG_BIT; } else { ind->batt_level_ntf_cfg[i] = PRF_CLI_STOP_NTFIND; } // Get Battery Level value attsdb_att_get_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, &att_length, &att_value); ind->batt_lvl[i] = *att_value; } ke_msg_send(ind); // Go to idle state ke_state_set(TASK_BASS, BASS_IDLE); }
void app_send_ltk_exch_func(struct gapc_bond_req_ind *param) { struct gapc_bond_cfm* cfm = KE_MSG_ALLOC(GAPC_BOND_CFM, TASK_GAPC, TASK_APP, gapc_bond_cfm); // generate ltk app_sec_gen_ltk(param->data.key_size); cfm->request = GAPC_LTK_EXCH; cfm->accept = true; cfm->data.ltk.key_size = app_sec_env.key_size; cfm->data.ltk.ediv = app_sec_env.ediv; memcpy(&(cfm->data.ltk.randnb), &(app_sec_env.rand_nb) , RAND_NB_LEN); memcpy(&(cfm->data.ltk.ltk), &(app_sec_env.ltk) , KEY_LEN); ke_msg_send(cfm); }
/** **************************************************************************************** * @brief Handles start indication from the SPOTAR profile. * * @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 (TASK_GAP). * @param[in] src_id ID of the sending task instance. * * @return If the message was consumed or not. **************************************************************************************** */ int spotar_create_db_cfm_handler(ke_msg_id_t const msgid, struct spotar_create_db_cfm const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // If state is not idle, ignore the message if (ke_state_get(dest_id) == APP_DB_INIT) { // Inform the Application Manager struct app_module_init_cmp_evt *cfm = KE_MSG_ALLOC(APP_MODULE_INIT_CMP_EVT, TASK_APP, TASK_APP, app_module_init_cmp_evt); cfm->status = param->status; ke_msg_send(cfm); } return (KE_MSG_CONSUMED); }
/* **************************************************************************************** * @brief Start the Heart Rate Collector profile - at connection. *//** * @param[in] hrs Heart Rate Service Content Structure. * @param[in] conhdl Connection handle for which the profile Heart Rate Collector role is enabled. * @response HRPC_ENABLE_CFM * @description * * This API is used for enabling the Collector role of the Heart Rate profile. This function contains * BLE connection handle, the connection type and the previously saved discovered HRS details on peer. * The connection type may be 0 = Connection for discovery/initial configuration or 1 = Normal connection. This * parameter is used by Application to discover peer device services once at first connection. Application shall save those * information to reuse them for other connections. During normal connection, previously discovered device * information can be reused. * * This is useful since most use cases allow Heart Rate Sensor to disconnect the link once all measurements have been * sent to Collector. * * If it is a discovery /configuration type of connection, the HRS parameters are useless, they will be filled with 0's. * Otherwise they will contain pertinent data which will be kept in the Collector environment while enabled. It allows for * the Application to not be aware of attribute details. * * For a normal connection, the response to this request is sent right away after saving the HRS content in the * environment and registering HRPC in GATT to receive the indications and notifications for the known attribute * handles in HRS that would be notified/indicated. For a discovery connection, discovery of the peer HRS is started and * the response will be sent at the end of the discovery with the discovered attribute details. * **************************************************************************************** */ void app_hrpc_enable_req(struct hrs_content *hrs, uint16_t conhdl) { struct hrpc_enable_req * msg = KE_MSG_ALLOC(HRPC_ENABLE_REQ, KE_BUILD_ID(TASK_HRPC, conhdl), TASK_APP, hrpc_enable_req); ///Connection handle msg->conhdl = conhdl; ///Connection type if (hrs == NULL) { msg->con_type = PRF_CON_DISCOVERY; } else { msg->con_type = PRF_CON_NORMAL; memcpy(&msg->hrs, hrs, sizeof(struct hrs_content)); } // Send the message ke_msg_send(msg); }
void app_neb_msg_rx_resp_flow(struct app_neb_msg_resp_flow* msg) { uint8_t status = NEB_ERR_SUCCESS; if(ke_state_get(TASK_APP_NEB) == APP_NEB_CONNECTED) { ASSERT_INFO(app_neb_env.resp_flow_sample_nb < NEB_RESP_FLOW_PCK_NB, app_neb_env.resp_flow_sample_nb, NEB_RESP_FLOW_PCK_NB); // Store sample app_neb_env.resp_flow_sample_buf[app_neb_env.resp_flow_sample_nb++] = msg->flow; // Check the buffer size if(app_neb_env.resp_flow_sample_nb == NEB_RESP_FLOW_PCK_NB) { // Allocate message to profile struct nbps_neb_record_send_req *req = KE_MSG_ALLOC(NBPS_NEB_RECORD_SEND_REQ, TASK_NBPS, TASK_APP_NEB, nbps_neb_record_send_req); req->conhdl = app_neb_env.conhdl; req->neb_rec.neb_id = app_neb_env.curr_neb_id; req->neb_rec.rec_id = app_neb_env.next_rec_id; req->neb_rec.flags = NEB_REC_RESP_RATE_FLAG; // Parameters req->neb_rec.nb_resp_rate = NEB_RESP_FLOW_PCK_NB; memcpy(&req->neb_rec.resp_rate[0], &app_neb_env.resp_flow_sample_buf[0], NEB_RESP_FLOW_PCK_NB * sizeof(uint16_t)); ke_msg_send(req); // Clear number of samples app_neb_env.resp_flow_sample_nb = 0; // Increment record ID app_neb_env.next_rec_id++; } } // Confirm the message app_neb_msg_tx_confirm_basic(NEB_MSG_ID_RESP_FLOW, status); }
void app_smpc_start_enc_req(uint8_t idx, uint8_t auth_req, uint16_t ediv, struct rand_nb *rand_nb, struct smp_key *ltk) { struct smpc_start_enc_req *msg = KE_MSG_ALLOC(SMPC_START_ENC_REQ, TASK_SMPC, TASK_APP, smpc_start_enc_req); ///Connection index msg->idx = idx; ///Authentication Requirements - needed if slave msg->auth_req = auth_req; ///EDIV msg->ediv = ediv; ///Random number msg->randnb = *rand_nb; ///LTK msg->ltk = *ltk; ke_msg_send(msg); }
/** **************************************************************************************** * @brief Clears both the normal and the virtual White Lists. * * @param void * * @return void **************************************************************************************** */ void clear_white_list(void) { int i; if (con_fsm_params.has_white_list) { struct gapm_white_list_mgt_cmd * req = KE_MSG_ALLOC(GAPM_WHITE_LIST_MGT_CMD, TASK_GAPM, TASK_APP, gapm_white_list_mgt_cmd); // Fill in the parameter structure req->operation = GAPM_CLEAR_WLIST; req->nb = 0; ke_msg_send(req); } else if (con_fsm_params.has_virtual_white_list) { for (i = 0; i < MAX_BOND_PEER; i++) { virtual_white_list[i].status = UNUSED; } virtual_wlist_policy = ADV_ALLOW_SCAN_ANY_CON_ANY; } white_list_written = 0; }
/** **************************************************************************************** * @brief Handles reception of the @ref STREAMDATAD_CREATE_DB_REQ message. * The handler adds STREAMDATAD Service into the database using the database * configuration value given in param. * @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 streamdatad_create_db_req_handler(ke_msg_id_t const msgid, struct streamdatad_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Service Configuration Flag uint32_t cfg_flag = 0xFFFFFFFF; //Database Creation Status uint8_t status; //Save Application ID streamdatad_env.appid = src_id; // set start handle or automatically set it when creating database (start_hdl = 0) streamdatad_env.shdl=param->start_hdl; //Add Service Into Database status = attm_svc_create_db(&streamdatad_env.shdl, (uint8_t *)&cfg_flag, STREAMDATAD_IDX_NB, NULL, dest_id, &streamdatad_att_db[0]); //Disable GLS attmdb_svc_set_permission(streamdatad_env.shdl, PERM(SVC, DISABLE)); //Go to Idle State if (status == ATT_ERR_NO_ERROR) { //If we are here, database has been fulfilled with success, go to idle test ke_state_set(TASK_STREAMDATAD, STREAMDATAD_IDLE); } //Send response to application struct streamdatad_create_db_cfm * cfm = KE_MSG_ALLOC(STREAMDATAD_CREATE_DB_CFM, streamdatad_env.appid, TASK_STREAMDATAD, streamdatad_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
void app_smpc_chk_bd_addr_req_rsp(uint8_t idx, uint8_t found_flag, uint8_t sec_status, uint8_t type, struct bd_addr *addr) { struct smpc_chk_bd_addr_rsp *msg = KE_MSG_ALLOC(SMPC_CHK_BD_ADDR_REQ_RSP, TASK_SMPC, TASK_APP, smpc_chk_bd_addr_rsp); ///Connection index -may be a free task index msg->idx = idx; ///Status - found or not msg->found_flag = found_flag; ///Saved link security status from higher layer msg->lk_sec_status = sec_status; ///Type of address to check msg->type = type; ///Random address to resolve or Public address to check in APP msg->addr = *addr; ke_msg_send(msg); }
void tips_disable(struct tips_idx_env_tag *tips_idx_env, uint16_t conhdl) { // Disable CTS attmdb_svc_set_permission(tips_env.cts_shdl, PERM(SVC, DISABLE)); if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP)) { // Disable NDCS attmdb_svc_set_permission(tips_env.ndcs_shdl, PERM(SVC, DISABLE)); } if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP)) { // Disable RTUS attmdb_svc_set_permission(tips_env.rtus_shdl, PERM(SVC, DISABLE)); } // Send APP cfg every time, C may have changed it struct tips_disable_ind *ind = KE_MSG_ALLOC(TIPS_DISABLE_IND, tips_idx_env->con_info.appid, tips_idx_env->con_info.prf_id, tips_disable_ind); ind->conhdl = conhdl; if ((tips_idx_env->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) == TIPS_CTS_CURRENT_TIME_CFG) { ind->current_time_ntf_en = PRF_CLI_START_NTF; //Reset notifications bit field tips_idx_env->ntf_state &= ~TIPS_CTS_CURRENT_TIME_CFG; } ke_msg_send(ind); //Go to idle state ke_state_set(tips_idx_env->con_info.prf_id, TIPS_IDLE); PRF_CLIENT_DISABLE(tips_idx_envs, KE_IDX_GET(tips_idx_env->con_info.prf_id), TIPS); }
/* **************************************************************************************** * @brief Start the Phone Alert Status Profile Client role - at connection. *//** * @param[in] pass Service structure previously discovered in the database of the peer device. * @param[in] conhdl Connection handle for which the Alert Notification Status Client role is enabled. * @response PASPC_PASS_CONTENT_IND and PASPC_CMP_EVT * @description * * This API is used by Application to send message to TASK_PASPC for enabling the Collector role * of the Phone Alert Status profile, and it contains the connection handle for the connection * this profile is activated, the connection type and the previously saved discovered PASS details on peer. * * The connection type may be PRF_CON_DISCOVERY (0x00) for discovery/initial configuration or * PRF_CON_NORMAL (0x01) for a normal connection with a bonded device. Application shall save * those information to reuse them for other connections. During normal connection, previously * discovered device information can be reused. * * For a normal connection, the response to this request is sent right away after saving the * PASS content in the environment and registering PASPC in GATT to receive the notifications * for the known attribute handles in PASS that would be notified. * * For a discovery connection, discovery of the peer PASS is started and the response will be * sent at the end of the discovery with the discovered attribute details. * **************************************************************************************** */ void app_paspc_enable_req(struct paspc_pass_content *pass, uint16_t conhdl) { struct paspc_enable_cmd * msg = KE_MSG_ALLOC(PASPC_ENABLE_CMD, KE_BUILD_ID(TASK_PASPC, conhdl), TASK_APP, paspc_enable_cmd); ///Connection handle msg->conhdl = conhdl; ///Connection type if (pass == NULL) { msg->con_type = PRF_CON_DISCOVERY; } else { msg->con_type = PRF_CON_NORMAL; memcpy(&msg->pass, pass, sizeof(struct paspc_pass_content)); } // Send the message ke_msg_send(msg); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATT_HANDLE_VALUE_NTF message. * @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_handle_value_ntf_handler(ke_msg_id_t const msgid, struct gatt_handle_value_notif const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // BAS Instance uint8_t bas_nb; // Attribute found uint8_t found = PRF_APP_ERROR; // Get the address of the environment struct basc_env_tag *basc_env = PRF_CLIENT_GET_ENV(dest_id, basc); if (param->conhdl == basc_env->con_info.conhdl) { //Battery Level - BAS instance is unknown. for (bas_nb = 0; ((bas_nb < basc_env->bas_nb) && (found != PRF_ERR_OK)); bas_nb++) { if (param->charhdl == basc_env->bas[bas_nb].chars[BAS_CHAR_BATT_LEVEL].val_hdl) { found = PRF_ERR_OK; struct basc_batt_level_ind * ind = KE_MSG_ALLOC(BASC_BATT_LEVEL_IND, basc_env->con_info.appid, dest_id, basc_batt_level_ind); ind->conhdl = param->conhdl; ind->ind_type = BASC_BATT_LEVEL_NTF; ind->batt_level = param->value[0]; ind->bas_nb = bas_nb; //Send Battery Level value to APP ke_msg_send(ind); } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref FINDT_CREATE_DB_REQ message. * The handler adds IAS into the database using the database * configuration value given in param. * @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 findt_create_db_req_handler(ke_msg_id_t const msgid, struct findt_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Service Configuration Flag uint8_t cfg_flag = FINDT_MANDATORY_MASK; //Database Creation Status uint8_t status; //Save Profile ID findt_env.con_info.prf_id = TASK_FINDT; /*---------------------------------------------------* * Immediate Alert Service Creation *---------------------------------------------------*/ //Add Service Into Database status = attm_svc_create_db(&findt_env.shdl, (uint8_t *)&cfg_flag, FINDT_IAS_IDX_NB, NULL, dest_id, &findt_att_db[0]); //Disable IAS attmdb_svc_set_permission(findt_env.shdl, PERM(SVC, DISABLE)); //Go to Idle State if (status == ATT_ERR_NO_ERROR) { //If we are here, database has been fulfilled with success, go to idle state ke_state_set(TASK_FINDT, FINDT_IDLE); } //Send CFM to application struct findt_create_db_cfm * cfm = KE_MSG_ALLOC(FINDT_CREATE_DB_CFM, src_id, TASK_FINDT, findt_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
void cscps_send_cmp_evt(uint8_t src_id, uint8_t dest_id, uint16_t conhdl, uint8_t operation, uint8_t status) { // Go back to the Connected state if the state is busy if (ke_state_get(src_id) == CSCPS_BUSY) { ke_state_set(src_id, CSCPS_CONNECTED); } // Set the operation code cscps_env.operation = CSCPS_RESERVED_OP_CODE; // Send the message struct cscps_cmp_evt *evt = KE_MSG_ALLOC(CSCPS_CMP_EVT, dest_id, src_id, cscps_cmp_evt); evt->conhdl = conhdl; evt->operation = operation; evt->status = status; ke_msg_send(evt); }
/* **************************************************************************************** * @brief Start the HID Over GATT profile - at connection. *//** * * @param[in] hids_nb Number of instances of the HID Service that have been found during the last discovery * @param[in] hids Information about HID Services that have been found during the last discovery * @param[in] conhdl Connection handle * @response HOGPBH_ENABLE_CFM * @description * * This API is used for enabling the Boot Host role of the HOGP. This function contains * BLE connection handle, the connection type and the previously saved discovered HIDS details on peer. * * The connection type may be PRF_CON_DISCOVERY (0x00) for discovery/initial configuration or PRF_CON_NORMAL * (0x01) for a normal connection with a bonded device. Application shall save those information to reuse them for * other connections. During normal connection, previously discovered device information can be reused. * * If it is a discovery/configuration type of connection, it is useless to fill the HIDS parameters (hids_nb and hids) are * useless. Otherwise they will contain pertinent data which will be kept in the Boot Host environment while enabled. * * For a normal connection, the response to this request is sent right away after saving the HIDS content in the * environment and registering HOGPBH in GATT to receive the notifications for the known attribute handles in HIDS that * would be notified (Boot Keyboard Input Report and Boot Mouse Input Report). For a discovery connection, discovery * of the peer HIDS is started and the response will be sent at the end of the discovery with the discovered attribute * details. * **************************************************************************************** */ void app_hogpbh_enable_req(uint8_t hids_nb, struct hids_content *hids, uint16_t conhdl) { struct hogpbh_enable_req * msg = KE_MSG_ALLOC(HOGPBH_ENABLE_REQ, KE_BUILD_ID(TASK_HOGPBH, conhdl), TASK_APP, hogpbh_enable_req); ///Connection handle msg->conhdl = conhdl; ///Number of HIDS instances msg->hids_nb = hids_nb; ///Connection type if (hids == NULL || hids_nb == 0) { msg->con_type = PRF_CON_DISCOVERY; } else { msg->con_type = PRF_CON_NORMAL; memcpy(&msg->hids[0], hids, hids_nb*sizeof(struct hids_content)); } // Send the message ke_msg_send(msg); }
/** **************************************************************************************** * @brief Handles reception of the @ref GATTC_READ_IND message. * Generic event received after every simple read command sent to peer server. * @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_read_ind_handler(ke_msg_id_t const msgid, struct gattc_read_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Get the address of the environment struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc); 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 = ATT_ERR_NO_ERROR; // unpack feature information rsp->features = co_read16p(param->value); ke_msg_send(rsp); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message. * The message is redirected from TASK_SVC because at profile enable, the ATT handle is * register for TASK_FINDT. In the handler, an ATT Write Response/Error Response should * be sent for ATT protocol, but Alert Level Characteristic only supports WNR so no * response PDU is needed. * @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_write_cmd_ind_handler(ke_msg_id_t const msgid, struct gattc_write_cmd_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t alert_lvl = 0x0000; if (KE_IDX_GET(src_id) == findt_env.con_info.conidx) { if(param->handle == findt_env.shdl + FINDT_IAS_IDX_ALERT_LVL_VAL) { alert_lvl = param->value[0]; //Check if Alert Level is valid if ((param->value[0] <= FINDT_ALERT_HIGH)) { //Update the attribute value attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&alert_lvl); if(param->last) { // Allocate the alert value change indication struct findt_alert_ind *ind = KE_MSG_ALLOC(FINDT_ALERT_IND, findt_env.con_info.appid, TASK_FINDT, findt_alert_ind); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(findt_env.con_info.conidx); ind->alert_lvl = alert_lvl; // Send the message ke_msg_send(ind); } // It was a Write Without Response so no RSP needed. } } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of encrypt request command * * @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 (TASK_GAP). * @param[in] src_id ID of the sending task instance. * * @return If the message was consumed or not. **************************************************************************************** */ int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid, struct gapc_encrypt_req_ind *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { struct gapc_encrypt_cfm* cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM, src_id, dest_id, gapc_encrypt_cfm); if (!app_validate_encrypt_req_func(param)) { cfm->found = false; } else { if(((app_sec_env.auth & GAP_AUTH_BOND) != 0) && (memcmp(&(app_sec_env.rand_nb), &(param->rand_nb), RAND_NB_LEN) == 0) && (app_sec_env.ediv == param->ediv)) { cfm->found = true; cfm->key_size = app_sec_env.key_size; memcpy(&(cfm->ltk), &(app_sec_env.ltk), KEY_LEN); // update connection auth app_connect_confirm(app_sec_env.auth); app_sec_encrypt_complete_func(); } else { cfm->found = false; } } ke_msg_send(cfm); if (cfm->found == false) app_disconnect(); return (KE_MSG_CONSUMED); }
void prf_disc_char_desc_send(struct prf_con_info* con_info, struct prf_char_inf * charact) { // Check if there is at least one descriptor to find if ((charact->val_hdl + 1) <= (charact->char_hdl + charact->char_ehdl_off - 1)) { // Ask for handles of a certain uuid struct gattc_disc_cmd * dsc_req = KE_MSG_ALLOC_DYN(GATTC_DISC_CMD, KE_BUILD_ID(TASK_GATTC, con_info->conidx), con_info->prf_id, gattc_disc_cmd, ATT_UUID_16_LEN); dsc_req->req_type = GATTC_DISC_DESC_CHAR; dsc_req->start_hdl = charact->val_hdl + 1; dsc_req->end_hdl = charact->char_hdl + charact->char_ehdl_off - 1; // UUID info - Don't care dsc_req->uuid_len = ATT_UUID_16_LEN; //set the first two bytes to the value array, LSB to MSB:Health Thermometer Service UUID first co_write16p(&(dsc_req->uuid[0]), ATT_INVALID_UUID); //send the message to GATT;there should be only one handle response every time ke_msg_send(dsc_req); } else { // TODO [FBE] to be changed if SDP task implemented // Send a GATT complete event message struct gattc_cmp_evt *evt = KE_MSG_ALLOC(GATTC_CMP_EVT, con_info->prf_id, KE_BUILD_ID(TASK_GATTC , con_info->conidx), gattc_cmp_evt); evt->status = PRF_ERR_OK; // Send the message ke_msg_send(evt); } }
/** **************************************************************************************** * @brief Handles read command characteristic event indication from device_config profile * * @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 (TASK_GAP). * @param[in] src_id ID of the sending task instance. * * @return If the message was consumed or not. **************************************************************************************** */ int app_device_read_request_ind_handler(ke_msg_id_t const msgid, struct device_config_read_request_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint8_t status = 0; // Allocate message struct device_config_read_response_cmd *cmd = KE_MSG_ALLOC(DEVICE_READ_RESPONSE_CMD, TASK_DEVICE_CONFIG, TASK_APP, device_config_read_response_cmd); if (param->param_id >= app_device_config_env.params_num) { status = 1; } if (!status) { cmd->size = app_device_config_env.params[param->param_id].size; memcpy(cmd->val, app_device_config_env.params[param->param_id].p_data, cmd->size ); } else { cmd->size = 0; } cmd->param_id = param->param_id; cmd->conhdl = app_env.conhdl; cmd->status = status; ke_msg_send(cmd); return (KE_MSG_CONSUMED); }
/* **************************************************************************************** * @brief Gatt Read Characteristic request. *//** * * @param[in] req_type GATT request type: * - GATT_READ_CHAR * - GATT_READ_BY_UUID_CHAR * - GATT_READ_LONG_CHAR * - GATT_READ_MULT_LONG_CHAR * - GATT_READ_DESC * - GATT_READ_LONG_DESC * @param[in] conhdl Connection handle. * @param[in] valhdl Value handle. * @response GATT_READ_CHAR_RESP or GATT_READ_CHAR_MULTI_RESP * @description * * This API is used by the application to send a GATT_READ_CHAR_REQ mssage. * Upon reception of this message, GATT will checks whether the parameters are correct, * if not correct then the GATT_CMP_EVT message with error code GATT_INVALID_PARAM_ERR * will be generically built and sent to Application directly. If parameter is correct, * the GATT_READ_CHAR_RESP message will be received. * **************************************************************************************** */ void app_gatt_read_char_req(uint8_t req_type, uint16_t conhdl, uint16_t valhdl) { struct gatt_read_char_req *msg = KE_MSG_ALLOC(GATT_READ_CHAR_REQ, TASK_GATT, TASK_APP, gatt_read_char_req); //Connection handle msg->conhdl = conhdl; //GATT request type msg->req_type = req_type; //Read offset msg->offset = 0; //Start handle range msg->start_hdl = 0x0001; //End handle range msg->end_hdl = GATT_MAX_ATTR_HDL; //Number of UUID msg->nb_uuid = 0x01; //Handle of char value msg->uuid[0].expect_resp_size = ATT_UUID_16_LEN; msg->uuid[0].value_size = ATT_UUID_16_LEN; co_write16p(&msg->uuid[0].value[0], valhdl); ke_msg_send(msg); }
/** **************************************************************************************** * @brief Handles reception of the @ref HPSS_CREATE_DB_REQ message. * The handler adds HPS into the database. * @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 hpss_create_db_req_handler(ke_msg_id_t const msgid, struct hpss_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Database Creation Status uint8_t status; //Save Profile ID hpss_env.con_info.prf_id = TASK_HPSS; /*---------------------------------------------------* * HTTP Proxy Service Creation *---------------------------------------------------*/ //Add Service Into Database status = attm_svc_create_db(&hpss_env.hps_shdl, NULL, HPS_IDX_NB, NULL, dest_id, &hpss_att_db[0]); //Disable HPS attmdb_svc_set_permission(hpss_env.hps_shdl, PERM(SVC, DISABLE)); //Go to Idle State if (status == ATT_ERR_NO_ERROR) { //If we are here, database has been fulfilled with success, go to idle state ke_state_set(TASK_HPSS, HPSS_IDLE); } //Send CFM to application struct hpss_create_db_cfm * cfm = KE_MSG_ALLOC(HPSS_CREATE_DB_CFM, src_id, TASK_HPSS, hpss_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
void app_hrps_enable(void) { // Allocate the message struct hrps_enable_req * req = KE_MSG_ALLOC(HRPS_ENABLE_REQ, TASK_HRPS, TASK_APP, hrps_enable_req); //结构体填充部分需要后续改善 // Fill in the parameter structure ///Connection handle req->conhdl = app_env.conhdl; /// security level: b0= nothing, b1=unauthenticated, b2=authenticated, b3=authorized; /// b1 or b2 and b3 can go together req->sec_lvl = PERM(SVC, ENABLE); ///Type of connection - will someday depend on button press length; can be CFG or DISCOVERY req->con_type = PRF_CON_NORMAL;// PRF_CON_DISCOVERY; /// Heart Rate Notification configuration req->hr_meas_ntf_en = 1;//PRF_CLI_START_NTF;//PRF_CLI_STOP_NTFIND ///Body Sensor Location req->body_sensor_loc = 1; // Send the message ke_msg_send(req); }
void app_custom_connection(struct gapc_connection_req_ind const *param) { #if BLE_ACCEL int temp=4; uint8_t *temp_v; app_accel_adv_stopped(); if (!param->con_latency) { // Not completely verified, but this improves the stability of the connection. struct gapc_param_update_req_ind * req = KE_MSG_ALLOC(GAPC_PARAM_UPDATE_REQ_IND, TASK_GAPC, TASK_APP, gapc_param_update_req_ind); // Fill in the parameter structure //req->conhdl = param->conn_info.conhdl; //GZ req->conn_par.intv_min = param->conn_info.con_interval; //GZ req->conn_par.intv_max = param->conn_info.con_interval; attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_X_EN), &(temp), &(temp_v)); if(temp_v[1] > 1) accel_con_interval = temp_v[1]; req->params.intv_min = (accel_con_interval-1)*10/1.25; req->params.intv_max = (accel_con_interval)*10/1.25; req->params.latency = param->con_latency; if(param->sup_to * 8 / 1.25 <= 3200) req->params.time_out = param->sup_to * 8 / 1.25; else req->params.time_out = 3200/1.25; #if BLE_HID_DEVICE puts("Send GAP_PARAM_UPDATE_REQ"); #endif ke_msg_send(req); } #endif }