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 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); }