/** **************************************************************************************** * @brief Request to update Measurement Interval Value * @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 htpt_meas_intv_upd_req_handler(ke_msg_id_t const msgid, struct htpt_meas_intv_upd_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t handle; //Check if Measurement Interval is supported if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00) { //Check Connection Handle if(param->conhdl == gapc_get_conhdl(htpt_env.con_info.conidx)) { handle = htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1; //Update saved value in database attmdb_att_set_value(handle, sizeof(param->meas_intv), (uint8_t *)¶m->meas_intv); //Must be indicated if enabled if((htpt_env.features & HTPT_MASK_MEAS_INTV_CFG) == HTPT_MASK_MEAS_INTV_CFG) { prf_server_send_event((prf_env_struct *)&htpt_env, true, handle); } } else { //Wrong Connection Handle prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_INVALID_PARAM, HTPT_ERROR_IND, HTPT_MEAS_INTV_UPD_REQ); } } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the Sample128 role, used after connection. * @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 sample128_enable_req_handler(ke_msg_id_t const msgid, struct sample128_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Keep source of message, to respond to it further on sample128_env.con_info.appid = src_id; // Store the connection handle for which this profile is enabled sample128_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (sample128_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&sample128_env, PRF_ERR_REQ_DISALLOWED, SAMPLE128_ERROR_IND, SAMPLE128_ENABLE_REQ); } else { // Sample128 1 attmdb_svc_set_permission(sample128_env.sample128_1_shdl, param->sec_lvl); //Set LLS Alert Level to specified value attmdb_att_set_value(sample128_env.sample128_1_shdl + SAMPLE128_1_IDX_VAL, sizeof(uint8_t), (uint8_t *)¶m->sample128_1_val); // Go to Connected state ke_state_set(TASK_SAMPLE128, SAMPLE128_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref FINDT_ENABLE_REQ message. * The handler enables the Find Me profile - target 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 findt_enable_req_handler(ke_msg_id_t const msgid, struct findt_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Save the application task id findt_env.con_info.appid = src_id; // Save the connection index associated to the profile findt_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (findt_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&findt_env, PRF_ERR_REQ_DISALLOWED, FINDT_ERROR_IND, FINDT_ENABLE_REQ); } else { // Enable Service + Set Security Level attmdb_svc_set_permission(findt_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_FINDT, FINDT_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HRPS_ENABLE_REQ message. * The handler enables the Heart Rate Sensor Profile. * @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 hrps_enable_req_handler(ke_msg_id_t const msgid, struct hrps_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0; // Save the application task id hrps_env.con_info.appid = src_id; // Save the connection handle associated to the profile hrps_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (hrps_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&hrps_env, PRF_ERR_REQ_DISALLOWED, HRPS_ERROR_IND, HRPS_ENABLE_REQ); } else { // If this connection is a not configuration one, apply config saved by app if(param->con_type == PRF_CON_NORMAL) { value = param->hr_meas_ntf_en; if (param->hr_meas_ntf_en == PRF_CLI_START_NTF) { hrps_env.features |= HRPS_HR_MEAS_NTF_CFG; } } //Set HR Meas. Char. NTF Configuration in DB attmdb_att_set_value(hrps_env.shdl + HRS_IDX_HR_MEAS_NTF_CFG, sizeof(uint16_t), (uint8_t *)&value); if (HRPS_IS_SUPPORTED(HRPS_BODY_SENSOR_LOC_CHAR_SUP)) { //Set Body Sensor Location Char Value in DB - Not supposed to change during connection attmdb_att_set_value(hrps_env.shdl + HRS_IDX_BOBY_SENSOR_LOC_VAL, sizeof(uint8_t), (uint8_t *)¶m->body_sensor_loc); } // Enable Service + Set Security Level attmdb_svc_set_permission(hrps_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_HRPS, HRPS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref UDSS_SET_CHAR_VAL_REQ 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 udss_set_char_val_req_handler(ke_msg_id_t const msgid, struct udss_set_char_val_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Request status uint8_t status; // Characteristic Declaration attribute handle uint16_t handle; //Save the application task id udss_env.con_info.appid = src_id; // Check Characteristic Code if (param->char_code <= 0)//UDS_PNP_ID_CHAR) { // Get Characteristic Declaration attribute handle handle = udss_env.shdl + udss_env.att_tbl[param->char_code]; // Check if the Characteristic exists in the database if (handle != PRF_ERR_INEXISTENT_HDL) { // Check the value length // status = udss_check_val_len(param->char_code, param->val_len); if (status == PRF_ERR_OK) { // Set value in the database attmdb_att_set_value(handle + 1, param->val_len, (uint8_t *)¶m->val[0]); } } else { status = PRF_ERR_INEXISTENT_HDL; } } else { status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { // Status is PRF_ERR_INVALID_PARAM or PRF_ERR_UNEXPECTED_LEN or PRF_ERR_INEXISTENT_HDL prf_server_error_ind_send((prf_env_struct *)&udss_env, status, UDSS_ERROR_IND, UDSS_SET_CHAR_VAL_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the ADC Notify role, used after connection. * @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 adc_notify_enable_req_handler(ke_msg_id_t const msgid, struct adc_notify_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t temp = 1; // Keep source of message, to respond to it further on adc_notify_env.con_info.appid = src_id; // Store the connection handle for which this profile is enabled adc_notify_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (adc_notify_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&adc_notify_env, PRF_ERR_REQ_DISALLOWED, ADC_NOTIFY_ERROR_IND, ADC_NOTIFY_ENABLE_REQ); } else { attmdb_svc_set_permission(adc_notify_env.adc_notify_shdl, param->sec_lvl); attmdb_att_set_value(adc_notify_env.adc_notify_shdl + ADC_NOTIFY_IDX_VAL, sizeof(uint16_t), (uint8_t *)¶m->adc_notify_val); adc_notify_env.feature = param->feature; if (!adc_notify_env.feature) { temp = 0; } attmdb_att_set_value(adc_notify_env.adc_notify_shdl + ADC_NOTIFY_IDX_CFG, sizeof(uint16_t), (uint8_t *)&temp); // Go to Connected state ke_state_set(TASK_ADC_NOTIFY, ADC_NOTIFY_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref UDSS_ENABLE_REQ 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 udss_enable_req_handler(ke_msg_id_t const msgid, struct udss_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Save the connection handle associated to the profile udss_env.con_info.conidx = gapc_get_conidx(param->conhdl); //Save the application id udss_env.con_info.appid = src_id; // Check if the provided connection exist if (udss_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&udss_env, PRF_ERR_REQ_DISALLOWED, UDSS_ERROR_IND, UDSS_ENABLE_REQ); } else { //Enable Attributes + Set Security Level attmdb_svc_set_permission(udss_env.shdl, param->sec_lvl); //Set User Height to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_height); //Set User Age to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_AGE_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_age); //Set User Date of Birth to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DATE_OF_BIRTH_VAL, sizeof(struct date), (uint8_t *)¶m->user_date_of_birth); //Set User DB Change Increment to specified value attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_DB_CHANGE_INCR_VAL, sizeof(uint8_t), (uint8_t *)¶m->user_db_change_incr); // Go to connected state ke_state_set(TASK_UDSS, UDSS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HTPT_TEMP_TYPE_UPD_REQ message. * The handler compares the new values with current ones and notifies them if they changed. * @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 htpt_temp_type_upd_req_handler(ke_msg_id_t const msgid, struct htpt_temp_type_upd_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { if (htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] != 0x00) { //Update value in database attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] + 1, sizeof(param->value), (uint8_t *)&(param->value)); } else { prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_FEATURE_NOT_SUPPORTED, HTPT_ERROR_IND, HTPT_TEMP_TYPE_UPD_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Enable the HPS Server role, used after connection. * @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 hpss_enable_req_handler(ke_msg_id_t const msgid, struct hpss_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0; // Keep source of message, to respond to it further on hpss_env.con_info.appid = src_id; // Store the connection handle for which this profile is enabled hpss_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (hpss_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&hpss_env, PRF_ERR_REQ_DISALLOWED, HPSS_ERROR_IND, HPSS_ENABLE_REQ); } else { // Enable HPS + Set Security Level attmdb_svc_set_permission(hpss_env.hps_shdl, param->sec_lvl); //Set HR Meas. Char. NTF Configuration in DB attmdb_att_set_value(hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_CFG, sizeof(uint16_t), (uint8_t *)&value); //fix me? //Set LLS Alert Level to specified value // attmdb_att_set_value(hpss_env.hps_shdl + LLS_IDX_ALERT_LVL_VAL, // sizeof(uint8_t), (uint8_t *)¶m->lls_alert_lvl); // Go to Connected state ke_state_set(TASK_HPSS, HPSS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BAPS_ENABLE_REQ message. * The handler enables the Battery 'Profile' Server 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 beacon_enable_req_handler(ke_msg_id_t const msgid, struct beacon_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Save the application task id beacon_env.con_info.appid = src_id; // Save the connection handle associated to the profile beacon_env.conhdl = param->conhdl; // Check if the provided connection exist if (gap_get_rec_idx(param->conhdl) == GAP_INVALID_CONIDX) { // ?????????????????? // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&beacon_env, PRF_ERR_REQ_DISALLOWED, BEACON_ERROR_IND, BEACON_ENABLE_REQ); } else { attsdb_att_set_value(beacon_env.shdl + BEACON_IDX_LVL_VAL, sizeof(uint8_t), (uint8_t *)¶m->measured_power_val); attsdb_svc_set_permission(beacon_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_BEACON, BEACON_CONNECTED); } // // Attribute offset - Used to retrieve Char. Pres. Format Descriptor handle // uint8_t offset; // // Packed Char. Presentation Format value // uint8_t packed_char_pres[PRF_CHAR_PRES_FMT_SIZE]; // // Counter // uint8_t i; // // Notification Configuration // uint16_t ntf_cfg = 0; // // Save the application task id // bass_env.con_info.appid = src_id; // // Save the connection handle associated to the profile // bass_env.con_info.conhdl = param->conhdl; // // Check if the provided connection exist // if (gap_get_rec_idx(param->conhdl) == GAP_INVALID_CONIDX) // { // // The connection doesn't exist, request disallowed // prf_server_error_ind_send((prf_env_struct *)&bass_env, PRF_ERR_REQ_DISALLOWED, // BASS_ERROR_IND, BASS_ENABLE_REQ); // } // else // { // // For each BAS instance // for (i = 0; i < bass_env.bas_nb; i++) // { // // Reset Offset value // offset = BAS_IDX_BATT_LVL_NTF_CFG; // // Update Battery Level value in DB // attsdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, sizeof(uint8_t), // (uint8_t *)¶m->current_batt_lvl[i]); // // Check if BAS supports notifications // if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP) // { // // Increment offset (Client Char. Cfg is placed before Char. Pres Fmt. in DB) // offset++; // // If client is a bonded client // if (param->con_type == PRF_CON_NORMAL) // { // ntf_cfg = param->batt_level_ntf_cfg[i]; // /* // * The server shall send a notification if value of the Battery Level characteristic // * has changed while the service has been disconnected from a bonded client. // */ // if (param->batt_level_ntf_cfg[i] == PRF_CLI_START_NTF) // { // // Conserve information in environment // bass_env.features[i] |= BASS_FLAG_NTF_CFG_BIT; // // Check if old and previous battery level values are different // if (param->old_batt_lvl[i] != param->current_batt_lvl[i]) // { // //Notify current battery level value // struct gatt_notify_req *ntf = KE_MSG_ALLOC(GATT_NOTIFY_REQ, TASK_GATT, // TASK_BASS, gatt_notify_req); // ntf->conhdl = bass_env.con_info.conhdl; // ntf->charhdl = bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL; // ke_msg_send(ntf); // } // } // } // // Set NTF Cfg value in the DB // attsdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_NTF_CFG, sizeof(uint16_t), // (uint8_t *)&ntf_cfg); // } // // Check if Characteristic Presentation Format descriptor has been added // if (bass_env.bas_nb > 1) // { // prf_pack_char_pres_fmt(&packed_char_pres[0], ¶m->batt_level_pres_format[i]); // /* // * Set Characteristic Presentation Format descriptor value // * Not supposed to change during connection // */ // attsdb_att_set_value(bass_env.shdl[i] + offset, // PRF_CHAR_PRES_FMT_SIZE, // &packed_char_pres[0]); // } // // Enable Service + Set Security Level // attsdb_svc_set_permission(bass_env.shdl[i], param->sec_lvl); // } // // Go to connected state // ke_state_set(TASK_BASS, BASS_CONNECTED); // } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPS_RACP_RSP_REQ message. * Send by TASK_APP when a RACP requests is finished * * @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 glps_racp_rsp_req_handler(ke_msg_id_t const msgid, struct glps_racp_rsp_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { struct glp_racp_rsp racp_rsp; // Status uint8_t status = PRF_ERR_OK; // check connection handle if(param->conhdl == glps_env.con_info.conhdl) { // check if op code valid if((param->op_code < GLP_REQ_REP_STRD_RECS) || (param->op_code > GLP_REQ_REP_NUM_OF_STRD_RECS)) { //Wrong op code status = PRF_ERR_INVALID_PARAM; } // check if RACP on going else if((param->op_code != GLP_REQ_ABORT_OP) && !(GLPS_IS(RACP_ON_GOING))) { //Cannot send response since no RACP on going status = PRF_ERR_REQ_DISALLOWED; } else { // Number of stored record calculation succeed. if((param->op_code == GLP_REQ_REP_NUM_OF_STRD_RECS) && ( param->status == GLP_RSP_SUCCESS)) { racp_rsp.op_code = GLP_REQ_NUM_OF_STRD_RECS_RSP; racp_rsp.operand.num_of_record = param->num_of_record; } // Send back status information else { racp_rsp.op_code = GLP_REQ_RSP_CODE; racp_rsp.operand.rsp.op_code_req = param->op_code; racp_rsp.operand.rsp.status = param->status; } // There is no more RACP on going GLPS_CLEAR(RACP_ON_GOING); // send RACP indication glps_send_racp_rsp(&(racp_rsp), glps_env.con_info.appid); } } else { //Wrong Connection Handle status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { prf_server_error_ind_send((prf_env_struct *)&glps_env, status, GLPS_ERROR_IND, GLPS_RACP_RSP_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref HTPT_ENABLE_REQ message. * The handler enables the Health Thermometer Profile Thermometer 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 htpt_enable_req_handler(ke_msg_id_t const msgid, struct htpt_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t value = 0; //Save the application task id htpt_env.con_info.appid = src_id; //Save the connection handle associated to the profile htpt_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (htpt_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&htpt_env, PRF_ERR_REQ_DISALLOWED, HTPT_ERROR_IND, HTPT_ENABLE_REQ); } else { //Configure Intermediate Temp Ntf Cfg in DB if (htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] != 0x00) { //Written value is 0 is discovery connection, given value if normal if(param->con_type == PRF_CON_NORMAL) { memcpy(&value, ¶m->interm_temp_ntf_en, sizeof(uint16_t)); if (param->interm_temp_ntf_en == PRF_CLI_START_NTF) { htpt_env.features |= HTPT_MASK_INTM_MEAS_CFG; } } attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 2, sizeof(uint16_t), (uint8_t *)&value); //Reset value value = 0; } //Configure Meas. Interval value and IND Cfg in DB if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00) { //----------- Meas. Intv. Value ---------------------------------------------- //Written value is 0 is discovery connection, given value if normal if(param->con_type == PRF_CON_NORMAL) { memcpy(&value, ¶m->meas_intv, sizeof(uint16_t)); } attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1, sizeof(uint16_t), (uint8_t *)&value); //Reset value value = 0; //----------- IND Cfg ---------------------------------------------- if ((htpt_env.features & HTPT_MEAS_INTV_IND_SUP) == HTPT_MEAS_INTV_IND_SUP) { //Written value is 0 is discovery connection, given value if normal if(param->con_type == PRF_CON_NORMAL) { memcpy(&value, ¶m->meas_intv_ind_en, sizeof(uint16_t)); if (param->meas_intv_ind_en == PRF_CLI_START_IND) { htpt_env.features |= HTPT_MASK_MEAS_INTV_CFG; } } attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 2, sizeof(uint16_t), (uint8_t *)&value); //Reset value value = 0; } } //Configure Temp Meas value IND Cfg in DB if(param->con_type == PRF_CON_NORMAL) { memcpy(&value, ¶m->temp_meas_ind_en, sizeof(uint16_t)); if (param->temp_meas_ind_en == PRF_CLI_START_IND) { htpt_env.features |= HTPT_MASK_TEMP_MEAS_CFG; } } attmdb_att_set_value(htpt_env.shdl + HTS_IDX_TEMP_MEAS_IND_CFG, sizeof(uint16_t), (uint8_t *)&value); //Reset value value = 1; //Initialize Temp Type value in DB if (htpt_env.att_tbl[HTPT_TEMP_TYPE_CHAR] != 0x00) { attmdb_att_set_value(htpt_env.shdl + HTS_IDX_TEMP_TYPE_VAL, sizeof(uint8_t), (uint8_t *)&value); } //Enable Attributes + Set Security Level attmdb_svc_set_permission(htpt_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_HTPT, HTPT_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref GLPS_RACP_RSP_REQ message. * Send when a RACP requests is finished * * @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 udss_ucp_rsp_req_handler(ke_msg_id_t const msgid, struct udss_ucp_rsp_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { struct uds_ucp_rsp ucp_rsp; // Status volatile uint8_t status = PRF_ERR_OK; volatile int x = sizeof(struct udss_ucp_rsp_req); volatile int xx = param->ucp_rsp.op_code; // check connection handle if(param->conhdl == gapc_get_conhdl(udss_env.con_info.conidx)) { // check if op code valid if(param->ucp_rsp.op_code != UDS_REQ_RSP_CODE) { //Wrong op code status = PRF_ERR_INVALID_PARAM; } // check if UCP on going // else if((param->op_code != GLP_REQ_ABORT_OP) && !(GLPS_IS(RACP_ON_GOING))) // { // //Cannot send response since no RACP on going // status = PRF_ERR_REQ_DISALLOWED; // } else { /// Fill-in response code op code ucp_rsp.op_code = param->ucp_rsp.op_code; /// Fill-in request op code ucp_rsp.req_op_code = param->ucp_rsp.req_op_code; // Check if request op code is supported if((param->ucp_rsp.req_op_code < UDS_REQ_REG_NEW_USER) && ( param->ucp_rsp.req_op_code > UDS_REQ_DEL_USER_DATA)) { /// Fill-in response value for not supported op code ucp_rsp.rsp_val = UDS_RSP_OP_CODE_NOT_SUP; } else { // Fill-in response value from application ucp_rsp.rsp_val = param->ucp_rsp.rsp_val; if((ucp_rsp.req_op_code == UDS_REQ_REG_NEW_USER) &&(ucp_rsp.rsp_val == UDS_RSP_SUCCESS)) { ucp_rsp.parameter.reg_new_user.user_idx = param->ucp_rsp.parameter.reg_new_user.user_idx; } // There is no more UCP on going // UDSS_CLEAR(UCP_ON_GOING); // send UCP indication udss_send_ucp_rsp(&(ucp_rsp), udss_env.con_info.appid); } } } else { //Wrong Connection Handle status = PRF_ERR_INVALID_PARAM; } if (status != PRF_ERR_OK) { prf_server_error_ind_send((prf_env_struct *)&udss_env, status, UDSS_ERROR_IND, UDSS_UCP_RSP_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BLPS_ENABLE_REQ message. * The handler enables the Blood Pressure Sensor Profile and initialize readable values. * @param[in] msgid Id of the message received (probably unused).off * @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 blps_enable_req_handler(ke_msg_id_t const msgid, struct blps_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Value used to initialize all readable value in DB uint16_t indntf_cfg = 0; // Save the application task id blps_env.con_info.appid = src_id; // Save the connection handle associated to the profile blps_env.con_info.conhdl = param->conhdl; // Check if the provided connection exist if (gap_get_rec_idx(param->conhdl) == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&blps_env, PRF_ERR_REQ_DISALLOWED, BLPS_ERROR_IND, BLPS_ENABLE_REQ); } else { // Set Blood Pressure Feature Value in database - Not supposed to change during connection attsdb_att_set_value(blps_env.shdl + BPS_IDX_BP_FEATURE_VAL, sizeof(uint16_t), (uint8_t *)¶m->bp_feature); // Configure Blood Pressure Measuremment IND Cfg in DB if(param->con_type == PRF_CON_NORMAL) { memcpy(&indntf_cfg, ¶m->bp_meas_ind_en, sizeof(uint16_t)); if (param->bp_meas_ind_en == PRF_CLI_START_IND) { blps_env.evt_cfg |= BLPS_BP_MEAS_IND_CFG; } } //Set BP Meas. Char. IND Configuration in DB - 0 if not normal connection attsdb_att_set_value(blps_env.shdl + BPS_IDX_BP_MEAS_IND_CFG, sizeof(uint16_t), (uint8_t *)&indntf_cfg); // Configure Intermediate Cuff Pressure NTF Cfg in DB if (BLPS_IS_SUPPORTED(BLPS_INTM_CUFF_PRESS_SUP)) { if(param->con_type == PRF_CON_NORMAL) { memcpy(&indntf_cfg, ¶m->interm_cp_ntf_en, sizeof(uint16_t)); if (param->interm_cp_ntf_en == PRF_CLI_START_NTF) { blps_env.evt_cfg |= BLPS_INTM_CUFF_PRESS_NTF_CFG; } } //Set Intm. Cuff Pressure NTF Configuration in DB - 0 if not normal connection attsdb_att_set_value(blps_env.shdl + BPS_IDX_INTM_CUFF_PRESS_NTF_CFG, sizeof(uint16_t), (uint8_t *)&indntf_cfg); } // Enable Service + Set Security Level attsdb_svc_set_permission(blps_env.shdl, param->sec_lvl); // Go to connected state ke_state_set(TASK_BLPS, BLPS_CONNECTED); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref BAPS_ENABLE_REQ message. * The handler enables the Battery 'Profile' Server 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 bass_enable_req_handler(ke_msg_id_t const msgid, struct bass_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Attribute offset - Used to retrieve Char. Pres. Format Descriptor handle uint8_t offset; // Packed Char. Presentation Format value uint8_t packed_char_pres[PRF_CHAR_PRES_FMT_SIZE]; // Counter uint8_t i; // Notification Configuration uint16_t ntf_cfg = 0; // Save the application task id bass_env.con_info.appid = src_id; // Save the connection handle associated to the profile bass_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Check if the provided connection exist if (bass_env.con_info.conidx == GAP_INVALID_CONIDX) { // The connection doesn't exist, request disallowed prf_server_error_ind_send((prf_env_struct *)&bass_env, PRF_ERR_REQ_DISALLOWED, BASS_ERROR_IND, BASS_ENABLE_REQ); } else { // For each BAS instance for (i = 0; i < bass_env.bas_nb; i++) { // Reset Offset value offset = BAS_IDX_BATT_LVL_NTF_CFG; // Update Battery Level value in DB attmdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, sizeof(uint8_t), (uint8_t *)¶m->current_batt_lvl[i]); // Check if BAS supports notifications if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP) { // Increment offset (Client Char. Cfg is placed before Char. Pres Fmt. in DB) offset++; // If client is a bonded client if (param->con_type == PRF_CON_NORMAL) { ntf_cfg = param->batt_level_ntf_cfg[i]; /* * The server shall send a notification if value of the Battery Level characteristic * has changed while the service has been disconnected from a bonded client. */ if (param->batt_level_ntf_cfg[i] == PRF_CLI_START_NTF) { // Conserve information in environment bass_env.features[i] |= BASS_FLAG_NTF_CFG_BIT; // Check if old and previous battery level values are different if (param->old_batt_lvl[i] != param->current_batt_lvl[i]) { //Notify current battery level value prf_server_send_event((prf_env_struct *)&bass_env, false, bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL); } } } // Set NTF Cfg value in the DB attmdb_att_set_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_NTF_CFG, sizeof(uint16_t), (uint8_t *)&ntf_cfg); } // Check if Characteristic Presentation Format descriptor has been added if (bass_env.bas_nb > 1) { prf_pack_char_pres_fmt(&packed_char_pres[0], ¶m->batt_level_pres_format[i]); /* * Set Characteristic Presentation Format descriptor value * Not supposed to change during connection */ attmdb_att_set_value(bass_env.shdl[i] + offset, PRF_CHAR_PRES_FMT_SIZE, &packed_char_pres[0]); } // Enable Service + Set Security Level attmdb_svc_set_permission(bass_env.shdl[i], param->sec_lvl); } // Go to connected state ke_state_set(TASK_BASS, BASS_CONNECTED); } return (KE_MSG_CONSUMED); }