static int udss_create_db_req_handler(ke_msg_id_t const msgid, struct udss_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //DB Creation Statis uint8_t status = ATT_ERR_NO_ERROR; //Save profile id udss_env.con_info.prf_id = TASK_UDSS; status = attm_svc_create_db(&udss_env.shdl, NULL, UDS_IDX_NB, &udss_env.att_tbl[0], dest_id, &udss_att_db[0]); if (status == ATT_ERR_NO_ERROR) { //Disable service status = attmdb_svc_set_permission(udss_env.shdl, PERM(SVC, DISABLE)); //If we are here, database has been fulfilled with success, go to idle test ke_state_set(TASK_UDSS, UDSS_IDLE); } //Send response to application struct udss_create_db_cfm * cfm = KE_MSG_ALLOC(UDSS_CREATE_DB_CFM, src_id, TASK_UDSS, udss_create_db_cfm); cfm->status = status; ke_msg_send(cfm); 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 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); }
void pasps_disable(struct pasps_idx_env_tag *idx_env, uint16_t conhdl) { // Disable PAS service attmdb_svc_set_permission(pasps_env.pass_shdl, PERM(SVC, DISABLE)); struct pasps_disable_ind *ind = KE_MSG_ALLOC(PASPS_DISABLE_IND, idx_env->con_info.appid, idx_env->con_info.prf_id, pasps_disable_ind); memset(ind, 0x00, sizeof(struct pasps_disable_ind)); ind->conhdl = conhdl; if (PASPS_IS_NTF_ENABLED(idx_env, PASPS_FLAG_ALERT_STATUS_CFG)) { ind->alert_status_ntf_cfg = PRF_CLI_START_NTF; } if (PASPS_IS_NTF_ENABLED(idx_env, PASPS_FLAG_RINGER_SETTING_CFG)) { ind->ringer_setting_ntf_cfg = PRF_CLI_START_NTF; } ke_msg_send(ind); // Go to idle state ke_state_set(idx_env->con_info.prf_id, PASPS_IDLE); // Free the environment allocated for this connection PRF_CLIENT_DISABLE(pasps_idx_envs, KE_IDX_GET(idx_env->con_info.prf_id), PASPS); }
void wechat_disable(void) { att_size_t length; uint8_t *alert_lvl; // Disable service in database attmdb_svc_set_permission(wechat_env.wechat_shdl, PERM_RIGHT_DISABLE); struct wechat_disable_ind *ind = KE_MSG_ALLOC(WECHAT_DISABLE_IND, wechat_env.con_info.appid, TASK_WECHAT, wechat_disable_ind); //Get value stored in DB attmdb_att_get_value(wechat_env.wechat_shdl + WECHAT_1_IDX_VAL, &length, &alert_lvl); // Fill in the parameter structure ind->conhdl = gapc_get_conhdl(wechat_env.con_info.conidx); // Send the message ke_msg_send(ind); // Go to idle state ke_state_set(TASK_WECHAT, WECHAT_IDLE); }
void htpt_disable(uint16_t conhdl) { att_size_t att_length; uint8_t *att_value; //Disable HTS in database attmdb_svc_set_permission(htpt_env.shdl, PERM_RIGHT_DISABLE); //Send current configuration to APP struct htpt_disable_ind* ind = KE_MSG_ALLOC(HTPT_DISABLE_IND, htpt_env.con_info.appid, TASK_HTPT, htpt_disable_ind); ind->conhdl = conhdl; //Temperature Measurement Char. - Indications Configuration if (HTPT_IS_INDNTF_ENABLED(HTPT_MASK_TEMP_MEAS_CFG)) { ind->temp_meas_ind_en = PRF_CLI_START_IND; } //Intermediate Measurement Char. - Indications Configuration if (HTPT_IS_CHAR_SUPPORTED(HTPT_INTERM_TEMP_CHAR)) { if (HTPT_IS_INDNTF_ENABLED(HTPT_MASK_INTM_MEAS_CFG)) { ind->interm_temp_ntf_en = PRF_CLI_START_NTF; } } //Measurement Interval Char. - Value if (HTPT_IS_CHAR_SUPPORTED(HTPT_MEAS_INTV_CHAR)) { //Measurement Interval Char. - Indications Configuration if (HTPT_IS_FEATURE_SUPPORTED(HTPT_MEAS_INTV_IND_SUP)) { if (HTPT_IS_INDNTF_ENABLED(HTPT_MASK_MEAS_INTV_CFG)) { ind->meas_intv_ind_en = PRF_CLI_START_IND; } } attmdb_att_get_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1, &att_length, &att_value); memcpy(&(ind->meas_intv), att_value, sizeof(uint16_t)); } ke_msg_send(ind); //Reset indications/notifications bit field htpt_env.features &= ~HTPT_CFG_NTFIND_MASK; //Go to idle state ke_state_set(TASK_HTPT, HTPT_IDLE); }
/** **************************************************************************************** * @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 GLPS_CREATE_DB_REQ message. * The handler adds GLS 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 glps_create_db_req_handler(ke_msg_id_t const msgid, struct glps_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Service Configuration Flag uint16_t cfg_flag = GLPS_MANDATORY_MASK; //Database Creation Status uint8_t status; //Save Profile ID glps_env.con_info.prf_id = TASK_GLPS; //Save Database Configuration if(param->meas_ctx_supported) { GLPS_SET(MEAS_CTX_SUPPORTED); } // set start handle or automatically set it when creating database (start_hdl = 0) glps_env.shdl=param->start_hdl; /*---------------------------------------------------* * Glucose Service Creation *---------------------------------------------------*/ //Set Configuration Flag Value if (GLPS_IS(MEAS_CTX_SUPPORTED)) { cfg_flag |= GLPS_MEAS_CTX_PRES_MASK; } //Add Service Into Database status = attm_svc_create_db(&glps_env.shdl, (uint8_t *)&cfg_flag, GLS_IDX_NB, NULL, dest_id, &glps_att_db[0]); //Disable GLS attmdb_svc_set_permission(glps_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_GLPS, GLPS_IDLE); } //Send response to application struct glps_create_db_cfm * cfm = KE_MSG_ALLOC(GLPS_CREATE_DB_CFM, src_id, TASK_GLPS, glps_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
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 Handles reception of the @ref HRPS_CREATE_DB_REQ message. * The handler adds HRS 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 hrps_create_db_req_handler(ke_msg_id_t const msgid, struct hrps_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 = HRPS_MANDATORY_MASK; //Database Creation Status uint8_t status; //Save Profile ID hrps_env.con_info.prf_id = TASK_HRPS; //Save Database Configuration hrps_env.features = param->features; /*---------------------------------------------------* * Heart Rate Service Creation *---------------------------------------------------*/ //Set Configuration Flag Value if (HRPS_IS_SUPPORTED(HRPS_BODY_SENSOR_LOC_CHAR_SUP)) { cfg_flag |= HRPS_BODY_SENSOR_LOC_MASK; } if (HRPS_IS_SUPPORTED(HRPS_ENGY_EXP_FEAT_SUP)) { cfg_flag |= HRPS_HR_CTNL_PT_MASK; } //Add Service Into Database status = attm_svc_create_db(&hrps_env.shdl, (uint8_t *)&cfg_flag, HRS_IDX_NB, NULL, dest_id, &hrps_att_db[0]); //Disable HRS attmdb_svc_set_permission(hrps_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_HRPS, HRPS_IDLE); } //Send response to application struct hrps_create_db_cfm * cfm = KE_MSG_ALLOC(HRPS_CREATE_DB_CFM, src_id, TASK_HRPS, hrps_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref STREAMDATAD_ENABLE_REQ message. * The handler enables the StreamData Device 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 streamdatad_enable_req_handler(ke_msg_id_t const msgid, struct streamdatad_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t disable_val = 0x00; //Save Application ID //streamdatad_env.con_info.appid = src_id; streamdatad_env.con_info.prf_id = dest_id; streamdatad_env.con_info.appid = src_id; streamdatad_env.appid = src_id; //streamdatad_env.con_info.prf_id = dest_id; // Save the connection handle associated to the profile streamdatad_env.con_info.conidx = gapc_get_conidx(param->conhdl); // Save the connection handle associated to the profile streamdatad_env.conhdl = param->conhdl; streamdatad_env.next_attribute_idx = 0; streamdatad_env.nr_enabled_attributes = 0; streamdatad_env.stream_enabled = 0; // get tx buffers available nb_buf_av = l2cm_get_nb_buffer_available() - 6; attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_ENABLE_VAL), sizeof(uint16_t), (uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D0_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D1_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D2_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D3_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D4_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D5_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D6_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D7_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D8_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(STREAMDATAD_HANDLE(STREAMDATAD_IDX_STREAMDATAD_D9_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); //Enable Service attmdb_svc_set_permission(streamdatad_env.shdl, PERM(SVC, ENABLE)); // Go to active state ke_state_set(TASK_STREAMDATAD, STREAMDATAD_ACTIVE); 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); }
void findt_disable(uint16_t conhdl) { // Inform the application about the disconnection struct findt_disable_ind *ind = KE_MSG_ALLOC(FINDT_DISABLE_IND, findt_env.con_info.appid, TASK_FINDT, findt_disable_ind); ind->conhdl = conhdl; ke_msg_send(ind); //Disable IAS in database attmdb_svc_set_permission(findt_env.shdl, PERM_RIGHT_DISABLE); //Go to idle state ke_state_set(TASK_FINDT, FINDT_IDLE); }
/** **************************************************************************************** * @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); }
void cpps_disable(uint16_t conhdl) { // Disable CPS in database attmdb_svc_set_permission(cpps_env.shdl, PERM_RIGHT_DISABLE); //Send current configuration to APP struct cpps_disable_ind* ind = KE_MSG_ALLOC(CPPS_DISABLE_IND, cpps_env.con_info.appid, cpps_env.con_info.prf_id, cpps_disable_ind); ind->conhdl = conhdl; // CP Measurement Char. - Client Characteristic Configuration Descriptor ind->prfl_ntf_ind_cfg = CPPS_IS_NTF_IND_BCST_ENABLED(CPP_PRF_CFG_FLAG_CP_MEAS_NTF); if (CPPS_IS_FEATURE_SUPPORTED(cpps_env.prfl_cfg, CPPS_MEAS_BCST_MASK)) { // CP Measurement Char. - Server Characteristic Configuration Descriptor ind->prfl_ntf_ind_cfg |= CPPS_IS_NTF_IND_BCST_ENABLED(CPP_PRF_CFG_FLAG_SP_MEAS_NTF); } if (CPPS_IS_FEATURE_SUPPORTED(cpps_env.prfl_cfg, CPPS_VECTOR_MASK)) { // CP Vector. - Client Characteristic Configuration Descriptor ind->prfl_ntf_ind_cfg |= CPPS_IS_NTF_IND_BCST_ENABLED(CPP_PRF_CFG_FLAG_VECTOR_NTF); } if (CPPS_IS_FEATURE_SUPPORTED(cpps_env.prfl_cfg, CPPS_CTNL_PT_MASK)) { // Control Point Char. - Client Characteristic Configuration Descriptor ind->prfl_ntf_ind_cfg |= CPPS_IS_NTF_IND_BCST_ENABLED(CPP_PRF_CFG_FLAG_CTNL_PT_IND); } // Instantaneous Power ind->instantaneous_power = cpps_env.inst_power; ke_msg_send(ind); // Reset the notification/indication status cpps_env.prfl_cfg &= CPP_FEAT_ALL_SUPP; // Go to idle state ke_state_set(TASK_CPPS, CPPS_IDLE); }
/** **************************************************************************************** * @brief Handles reception of the @ref ACCEL_ENABLE_REQ message. * The handler enables the accelerometer 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 accel_enable_req_handler(ke_msg_id_t const msgid, struct accel_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { uint16_t disable_val = 0x00; //Save Application ID accel_env.con_info.appid = src_id; accel_env.con_info.prf_id = dest_id; // Save the connection index associated to the profile accel_env.con_info.conidx = gapc_get_conidx(param->conhdl); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_RANGE_VAL), sizeof(uint8_t), (uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_X_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Y_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_Z_EN), sizeof(uint16_t),(uint8_t*) &(disable_val)); { uint8_t tb; // tb = battery_get_lvl(BATT_CR2032); tb = battery_get_lvl(BATT_JPLUS);//gsx,jplus battery type. // Update the value in the attribute database attmdb_att_set_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), sizeof(uint8_t), (uint8_t*) &(tb)); } //Enable Service attmdb_svc_set_permission(accel_env.shdl, PERM(SVC, ENABLE)); // Go to active state ke_state_set(TASK_ACCEL, ACCEL_ACTIVE); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @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); }
/** **************************************************************************************** * @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); }
static int diss_create_db_req_handler(ke_msg_id_t const msgid, struct diss_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Service content flag uint32_t cfg_flag; //DB Creation Statis uint8_t status = ATT_ERR_NO_ERROR; //Save profile id diss_env.con_info.prf_id = TASK_DISS; //Compute Attribute Table and save it in environment cfg_flag = diss_compute_cfg_flag(param->features); status = attm_svc_create_db(&diss_env.shdl, (uint8_t *)&cfg_flag, DIS_IDX_NB, &diss_env.att_tbl[0], dest_id, &diss_att_db[0]); if (status == ATT_ERR_NO_ERROR) { //Disable service status = attmdb_svc_set_permission(diss_env.shdl, PERM(SVC, DISABLE)); //If we are here, database has been fulfilled with success, go to idle test ke_state_set(TASK_DISS, DISS_IDLE); } //Send response to application struct diss_create_db_cfm * cfm = KE_MSG_ALLOC(DISS_CREATE_DB_CFM, src_id, TASK_DISS, diss_create_db_cfm); cfm->status = status; ke_msg_send(cfm); 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 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); }
/** **************************************************************************************** * @brief Handles reception of the @ref SAMPLE128_CREATE_DB_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 sample128_create_db_req_handler(ke_msg_id_t const msgid, struct sample128_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; uint8_t nb_att_16; uint8_t nb_att_128; uint8_t nb_att_32; uint16_t att_decl_svc = ATT_DECL_PRIMARY_SERVICE; uint16_t att_decl_char = ATT_DECL_CHARACTERISTIC; uint16_t att_decl_cfg = ATT_DESC_CLIENT_CHAR_CFG; uint16_t val_hdl; uint16_t char_hdl; //Save Profile ID sample128_env.con_info.prf_id = TASK_SAMPLE128; /*---------------------------------------------------* * Link Loss Service Creation *---------------------------------------------------*/ //Add Service Into Database nb_att_16 = 4; // 2 UUID16 atts nb_att_32 = 0;// No UUID32 att nb_att_128 = 2; //1 UUID128 att status = attmdb_add_service(&(sample128_env.sample128_shdl), TASK_SAMPLE128, nb_att_16, nb_att_32, nb_att_128, 58); //total attributte size = 36, 16 (svc) + 19 (desc_char) + 1 (att) if (status == ATT_ERR_NO_ERROR) { //add svc attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN, //Data size = 16 (ATT_UUID_128_LEN) ATT_UUID_16_LEN, (uint8_t*)&att_decl_svc, PERM(RD, ENABLE), &(sample128_env.sample128_shdl)); status = attmdb_att_set_value(sample128_env.sample128_shdl, ATT_UUID_128_LEN, (uint8_t *)sample128_svc.uuid); //char 1 //add char attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3) ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE), &(char_hdl)); //add val attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1 ATT_UUID_128_LEN, (uint8_t*)&sample128_1_val.uuid, PERM(RD, ENABLE) | PERM(WR, ENABLE), &(val_hdl)); memcpy(sample128_1_char.attr_hdl, &val_hdl, sizeof(uint16_t)); status = attmdb_att_set_value(char_hdl, sizeof(sample128_1_char), (uint8_t *)&sample128_1_char); //////char 2 //add char attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, ATT_UUID_128_LEN + 3, //Data size = 19 (ATT_UUID_128_LEN + 3) ATT_UUID_16_LEN, (uint8_t*) &att_decl_char, PERM(RD, ENABLE), &(char_hdl)); //add val attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint8_t), //Data size = 1 ATT_UUID_128_LEN, (uint8_t*)&sample128_2_val.uuid, PERM(RD, ENABLE) | PERM(NTF, ENABLE), &(val_hdl)); memcpy(sample128_2_char.attr_hdl, &val_hdl, sizeof(uint16_t)); status = attmdb_att_set_value(char_hdl, sizeof(sample128_2_char), (uint8_t *)&sample128_2_char); //add cfg attribute status = attmdb_add_attribute(sample128_env.sample128_shdl, sizeof(uint16_t), ATT_UUID_16_LEN, (uint8_t*) &att_decl_cfg, PERM(RD, ENABLE) | PERM(WR, ENABLE), &(val_hdl)); //Disable sample128 service attmdb_svc_set_permission(sample128_env.sample128_shdl, PERM(SVC, DISABLE)); //Go to Idle State //If we are here, database has been fulfilled with success, go to idle state ke_state_set(TASK_SAMPLE128, SAMPLE128_IDLE); } //Send CFM to application struct sample128_create_db_cfm * cfm = KE_MSG_ALLOC(SAMPLE128_CREATE_DB_CFM, src_id, TASK_SAMPLE128, sample128_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
static int htpt_create_db_req_handler(ke_msg_id_t const msgid, struct htpt_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Valid Range value uint32_t valid_range; //Service content flag uint16_t cfg_flag; uint16_t total_size = 0; uint8_t nb_att = 0; uint8_t status = ATT_ERR_NO_ERROR; uint8_t i; // Save profile ID htpt_env.con_info.prf_id = TASK_HTPT; //Save database configuration htpt_env.features = param->features; //Compute Attribute Table and save it in environment cfg_flag = htpt_compute_att_table(param->features); status = attm_svc_create_db(&htpt_env.shdl, (uint8_t *)&cfg_flag, HTS_IDX_NB, &htpt_env.att_tbl[0], dest_id, &htpt_att_db[0]); //Disable the service and set optional features if (status == ATT_ERR_NO_ERROR) { //Disable service status = attmdb_svc_set_permission(htpt_env.shdl, PERM(SVC, DISABLE)); //Set optional properties and permissions if (htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] != 0x00) { nb_att = ATT_CHAR_PROP_RD; total_size = PERM(RD, ENABLE); i = 1; if ((param->features & HTPT_MEAS_INTV_IND_SUP) == HTPT_MEAS_INTV_IND_SUP) { nb_att |= ATT_CHAR_PROP_IND; total_size |= PERM(IND, ENABLE); i++; } if ((param->features & HTPT_MEAS_INTV_WR_SUP) == HTPT_MEAS_INTV_WR_SUP) { nb_att |= ATT_CHAR_PROP_WR; total_size |= PERM(WR, UNAUTH); i++; //Set Measurement Interval Char. - Valid Range value if ((param->valid_range_min) < (param->valid_range_max)) { valid_range = param->valid_range_min | (param->valid_range_max << 16); } else { //If minimal and maximal values are the same or if maximal value is upper than minimal value valid_range = HTPT_MEAS_INTV_DFLT_MIN | (HTPT_MEAS_INTV_DFLT_MAX << 16); } status = attmdb_att_set_value(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + i, sizeof(uint32_t), (uint8_t *)&valid_range); } attmdb_att_partial_value_update(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR], 0, 1, &nb_att); attmdb_att_set_permission(htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1, total_size); } //If we are here, database has been fulfilled with success, go to idle test ke_state_set(TASK_HTPT, HTPT_IDLE); } //Send response to application struct htpt_create_db_cfm * cfm = KE_MSG_ALLOC(HTPT_CREATE_DB_CFM, src_id, TASK_HTPT, htpt_create_db_cfm); cfm->status = status; ke_msg_send(cfm); 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 PASPS_CREATE_DB_REQ 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 pasps_create_db_req_handler(ke_msg_id_t const msgid, struct pasps_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Service Configuration Flag - All attributes have to be added in the database uint16_t cfg_flag = PASPS_DB_CFG_FLAG; // Database Creation Status uint8_t status; // Counter uint8_t counter; // Check if a PAS has already been added in the database if (ke_state_get(TASK_PASPS) == PASPS_DISABLED) { // Check the provided values if ((param->alert_status <= PASP_ALERT_STATUS_VAL_MAX) && (param->ringer_setting <= PASP_RINGER_NORMAL)) { // Add service in the database status = attm_svc_create_db(&pasps_env.pass_shdl, (uint8_t *)&cfg_flag, PASS_IDX_NB, NULL, dest_id, &pasps_att_db[0]); // Go to Idle State if (status == ATT_ERR_NO_ERROR) { // Set the value of the Alert Status characteristic attmdb_att_set_value(pasps_env.pass_shdl + PASS_IDX_ALERT_STATUS_VAL, sizeof(uint8_t), (uint8_t *)¶m->alert_status); // Set the value of the Ringer Setting characteristic attmdb_att_set_value(pasps_env.pass_shdl + PASS_IDX_RINGER_SETTING_VAL, sizeof(uint8_t), (uint8_t *)¶m->ringer_setting); // Update the ringer state in the environment pasps_env.ringer_state = param->ringer_setting; // Disable PAS attmdb_svc_set_permission(pasps_env.pass_shdl, PERM(SVC, DISABLE)); for (counter = 0; counter < PASPS_IDX_MAX; counter++) { // If we are here, database has been fulfilled with success, go to idle state ke_state_set(KE_BUILD_ID(TASK_PASPS, counter), PASPS_IDLE); } } } else { // One of the provided value in not within the defined range status = PRF_ERR_INVALID_PARAM; } } else { // Request is disallowed, a PAS has already been added status = PRF_ERR_REQ_DISALLOWED; } // Send response to application pasps_send_cmp_evt(TASK_PASPS, src_id, GAP_INVALID_CONHDL, PASPS_CREATE_DB_OP_CODE, status); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref PASPS_ENABLE_REQ 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 pasps_enable_req_handler(ke_msg_id_t const msgid, struct pasps_enable_req *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Phone Alert Status Profile Server Role Task Index Environment struct pasps_idx_env_tag *pasps_idx_env = NULL; // Connection Information structure struct prf_con_info con_info; // Status uint8_t status = PRF_ERR_OK; // Message status uint8_t msg_status = KE_MSG_CONSUMED; // Check if the provided connection handle is valid if (gapc_get_conidx(param->conhdl) != GAP_INVALID_CONIDX) { // 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, pasps_idx); } else { status = PRF_ERR_REQ_DISALLOWED; } if (status == PRF_ERR_OK) { pasps_idx_env = PRF_CLIENT_GET_ENV(dest_id, pasps_idx); // Keep the Connection Information structure content memcpy(&pasps_idx_env->con_info, &con_info, sizeof(struct prf_con_info)); if (param->con_type == PRF_CON_DISCOVERY) { // Force the configuration to 0 param->alert_status_ntf_cfg = PRF_CLI_STOP_NTFIND; param->ringer_setting_ntf_cfg = PRF_CLI_STOP_NTFIND; } else { if (param->alert_status_ntf_cfg != PRF_CLI_STOP_NTFIND) { // Force to PRF_CLI_START_NTF param->alert_status_ntf_cfg = PRF_CLI_START_NTF; PASPS_ENABLE_NTF(pasps_idx_env, PASPS_FLAG_ALERT_STATUS_CFG); } if (param->ringer_setting_ntf_cfg != PRF_CLI_STOP_NTFIND) { // Force to PRF_CLI_START_NTF param->ringer_setting_ntf_cfg = PRF_CLI_START_NTF; PASPS_ENABLE_NTF(pasps_idx_env, PASPS_FLAG_RINGER_SETTING_CFG); } } // Set the value of the Alert Status Client Characteristic Configuration Descriptor attmdb_att_set_value(pasps_env.pass_shdl + PASS_IDX_ALERT_STATUS_CFG, sizeof(uint16_t), (uint8_t *)¶m->alert_status_ntf_cfg); // Set the value of the Ringer Setting Client Characteristic Configuration Descriptor attmdb_att_set_value(pasps_env.pass_shdl + PASS_IDX_RINGER_SETTING_CFG, sizeof(uint16_t), (uint8_t *)¶m->ringer_setting_ntf_cfg); // Enable PAS attmdb_svc_set_permission(pasps_env.pass_shdl, param->sec_lvl); // Go to Connected State ke_state_set(dest_id, PASPS_CONNECTED); // Send response to application pasps_send_cmp_evt(dest_id, src_id, param->conhdl, PASPS_ENABLE_OP_CODE, PRF_ERR_OK); } else if (status == PRF_ERR_FEATURE_NOT_SUPPORTED) { // The message has been forwarded to another task id. msg_status = KE_MSG_NO_FREE; } else { // Send response to application pasps_send_cmp_evt(dest_id, src_id, param->conhdl, PASPS_ENABLE_OP_CODE, PRF_ERR_REQ_DISALLOWED); } return (int)msg_status; }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_CREATE_DB_REQ message. * The handler adds CTS, NDCS and RTUS 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 tips_create_db_req_handler(ke_msg_id_t const msgid, struct tips_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { //Service Configuration Flag - For CTS, Current Time Char. is mandatory uint8_t cfg_flag = TIPS_CTS_CURRENT_TIME_MASK; //Database Creation Status uint8_t status = ATT_ERR_NO_ERROR; //Save Database Configuration tips_env.features = param->features; /*---------------------------------------------------* * Current Time Service Creation *---------------------------------------------------*/ //Set Configuration Flag Value if (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP)) { cfg_flag |= TIPS_CTS_LOC_TIME_INFO_MASK; } if (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP)) { cfg_flag |= TIPS_CTS_REF_TIME_INFO_MASK; } //Add Service Into Database status = attm_svc_create_db(&tips_env.cts_shdl, (uint8_t *)&cfg_flag, CTS_IDX_NB, &tips_env.cts_att_tbl[0], dest_id, &cts_att_db[0]); //Disable CTS attmdb_svc_set_permission(tips_env.cts_shdl, PERM(SVC, DISABLE)); //All attributes are mandatory for NDCS and RTUS cfg_flag = 0xFF; /*---------------------------------------------------* * Next DST Change Service Creation *---------------------------------------------------*/ if ((status == ATT_ERR_NO_ERROR) && (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP))) { status = attm_svc_create_db(&tips_env.ndcs_shdl, (uint8_t *)&cfg_flag, NDCS_IDX_NB, &tips_env.ndcs_att_tbl[0], dest_id, &ndcs_att_db[0]); //Disable NDCS attmdb_svc_set_permission(tips_env.ndcs_shdl, PERM(SVC, DISABLE)); } /*---------------------------------------------------* * Reference Time Update Service Creation *---------------------------------------------------*/ if ((status == ATT_ERR_NO_ERROR) && (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP))) { status = attm_svc_create_db(&tips_env.rtus_shdl, (uint8_t *)&cfg_flag, RTUS_IDX_NB, &tips_env.rtus_att_tbl[0], dest_id, &rtus_att_db[0]); //Disable RTUS attmdb_svc_set_permission(tips_env.rtus_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_TIPS, TIPS_IDLE); } //Send response to application struct tips_create_db_cfm * cfm = KE_MSG_ALLOC(TIPS_CREATE_DB_CFM, src_id, TASK_TIPS, tips_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_ENABLE_REQ message. * The handler enables the Time Server 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 tips_enable_req_handler(ke_msg_id_t const msgid, struct tips_enable_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status; // Time Profile Server Role Task Index Environment struct tips_idx_env_tag *tips_idx_env; // Connection Information struct prf_con_info con_info; // Value used to initialize readable value in DB uint16_t value = 0; // Value used to initialize readable value whose size is upper than 2 bytes struct attm_elmt *att = NULL; // 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, tips_idx); 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) { //If this connection is a not configuration one, apply configuration saved by APP if(param->con_type == PRF_CON_NORMAL) { memcpy(&value, ¶m->current_time_ntf_en, sizeof(uint16_t)); if (param->current_time_ntf_en == PRF_CLI_START_NTF) { // Get the environment for the device tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); tips_idx_env->ntf_state |= TIPS_CTS_CURRENT_TIME_CFG; } } //Set Current Time Char. NTF Configuration in database attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_CFG, sizeof(uint16_t), (uint8_t *)&value); //Reset value value = 0; // Initialize Local Time Info Char. Value - (UTC+0.00 / Standard Time) if (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP)) { //sizeof(struct tip_ref_time_info) = sizeof(uint16_t) attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_LOCAL_TIME_INFO_VAL, sizeof(struct tip_loc_time_info), (uint8_t *)&value); } // Initialize Reference Time Info Char. Value if (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP)) { att = attmdb_get_attribute(tips_env.cts_shdl + tips_env.cts_att_tbl[CTS_REF_TIME_INFO_CHAR] + 1); att->length = sizeof(struct tip_ref_time_info); memset(att->value, 0, sizeof(struct tip_ref_time_info)); } //Enable CTS + Set Security Level attmdb_svc_set_permission(tips_env.cts_shdl, param->sec_lvl); if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP)) { att = attmdb_get_attribute(tips_env.ndcs_shdl + NDCS_IDX_TIME_DST_VAL); // Initialize Time With DST Char. Value - (Idle / Successful) att->length = NDCS_TIME_DST_VAL_LEN; memset(att->value, 0, NDCS_TIME_DST_VAL_LEN); attmdb_svc_set_permission(tips_env.ndcs_shdl, param->sec_lvl); } if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP)) { // Initialize Time Update State Char. Value - (Idle / Successful) attmdb_att_set_value(tips_env.rtus_shdl + RTUS_IDX_TIME_UPD_STATE_VAL, sizeof(struct tip_time_upd_state), (uint8_t *)&value); attmdb_svc_set_permission(tips_env.rtus_shdl, param->sec_lvl); } // Go to Connected State ke_state_set(dest_id, TIPS_CONNECTED); //send APP confirmation that can start normal connection tips_enable_cfm_send(&con_info, PRF_ERR_OK); } else { // Send confirmation that can start normal connection tips_enable_cfm_send(&con_info, status); } 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); }
/** **************************************************************************************** * @brief Handles reception of the @ref BASS_CREATE_DB_REQ message. * The handler adds BAS into the database using value of the features 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 bass_create_db_req_handler(ke_msg_id_t const msgid, struct bass_create_db_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Service content flag uint8_t cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK; // Status uint8_t status = PRF_ERR_OK; // Counter uint8_t i; // Battery Level characteristic value permissions uint16_t perm; // Battery Level characteristic value properties uint8_t prop; // Save profile id bass_env.con_info.prf_id = TASK_BASS; // Check number of BAS instances if (param->bas_nb <= BASS_NB_BAS_INSTANCES_MAX) { // Save number of BAS bass_env.bas_nb = param->bas_nb; for (i = 0; ((i < param->bas_nb) && (status == PRF_ERR_OK)); i++) { // Save database configuration bass_env.features[i] = param->features[i]; // Check if notifications are supported if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP) { cfg_flag |= BAS_CFG_FLAG_NTF_SUP_MASK; } // Check if multiple instances if (bass_env.bas_nb > 1) { cfg_flag |= BAS_CFG_FLAG_MTP_BAS_MASK; } //Create BAS in the DB status = attm_svc_create_db(&bass_env.shdl[i], (uint8_t *)&cfg_flag, BAS_IDX_NB, NULL, dest_id, &bas_att_db[0]); //Disable the service and set optional features if (status == PRF_ERR_OK) { //Disable service status = attmdb_svc_set_permission(bass_env.shdl[i], PERM(SVC, DISABLE)); //Set optional properties and permissions if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP) { prop = ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF; perm = PERM(RD, ENABLE) | PERM(NTF, ENABLE); attmdb_att_partial_value_update(bass_env.shdl[i] + BAS_IDX_BATT_LVL_CHAR, 0, 1, &prop); attmdb_att_set_permission(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, perm); } } // Reset configuration flag cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK; } if (status == PRF_ERR_OK) { //If we are here, database has been fulfilled with success, go to idle state ke_state_set(TASK_BASS, BASS_IDLE); } } else { status = PRF_ERR_INVALID_PARAM; } // Send confirmation to application struct bass_create_db_cfm * cfm = KE_MSG_ALLOC(BASS_CREATE_DB_CFM, src_id, TASK_BASS, bass_create_db_cfm); cfm->status = status; ke_msg_send(cfm); return (KE_MSG_CONSUMED); }