/** **************************************************************************************** * @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 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); }
/** **************************************************************************************** * @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 ANPS_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 anps_create_db_req_handler(ke_msg_id_t const msgid, struct anps_create_db_req *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 = ANPS_DB_CONFIG_MASK; // Database Creation Status uint8_t status; // Counter uint8_t counter; // Check if an ANS has already been added in the database if (ke_state_get(TASK_ANPS) == ANPS_DISABLED) { // Check the provided values (Supported New Alert Category Char value - shall not be 0) if ((param->supp_new_alert_cat.cat_id_mask_0 != 0) || (param->supp_new_alert_cat.cat_id_mask_1 != 0)) { // Add service in the database status = attm_svc_create_db(&anps_env.ans_shdl, (uint8_t *)&cfg_flag, ANS_IDX_NB, NULL, dest_id, &ans_att_db[0]); // Go to Idle State if (status == ATT_ERR_NO_ERROR) { uint8_t length = sizeof(uint8_t); // Mask the Category ID Bit Mask 1 values to have a good value param->supp_new_alert_cat.cat_id_mask_1 &= ANP_CAT_ID_1_MASK; param->supp_unread_alert_cat.cat_id_mask_1 &= ANP_CAT_ID_1_MASK; // The second part of a supported category value is optional is set to 0, remove it if (param->supp_new_alert_cat.cat_id_mask_1 != 0x00) { length *= 2; } // Set the value of the Supported New Alert Category characteristic attmdb_att_set_value(anps_env.ans_shdl + ANS_IDX_SUPP_NEW_ALERT_CAT_VAL, length, (uint8_t *)¶m->supp_new_alert_cat); length = sizeof(uint8_t); // The second part of a supported category value is optional is set to 0, remove it if (param->supp_unread_alert_cat.cat_id_mask_1 != 0x00) { length *= 2; } // Set the value of the Supported Unread Alert Category characteristic attmdb_att_set_value(anps_env.ans_shdl + ANS_IDX_SUPP_UNREAD_ALERT_CAT_VAL, length, (uint8_t *)¶m->supp_unread_alert_cat); // Keep the supported categories in the environment anps_env.supp_new_alert_cat = ((param->supp_new_alert_cat.cat_id_mask_0) | (param->supp_new_alert_cat.cat_id_mask_1 << 8)); anps_env.supp_unread_alert_cat = ((param->supp_unread_alert_cat.cat_id_mask_0) | (param->supp_unread_alert_cat.cat_id_mask_1 << 8)); // Disable ANS attmdb_svc_set_permission(anps_env.ans_shdl, PERM(SVC, DISABLE)); for (counter = 0; counter < ANPS_IDX_MAX; counter++) { // If we are here, database has been fulfilled with success, go to idle state ke_state_set(KE_BUILD_ID(TASK_ANPS, counter), ANPS_IDLE); } } } else { // One of the provided value in not within the defined range status = PRF_ERR_INVALID_PARAM; } } else { // Request is disallowed, an ANS has already been added status = PRF_ERR_REQ_DISALLOWED; } // Send response to application anps_send_cmp_evt(TASK_ANPS, src_id, GAP_INVALID_CONHDL, ANPS_CREATE_DB_OP_CODE, status); return (KE_MSG_CONSUMED); }