/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_TIME_UPD_STATE_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 tips_upd_time_upd_state_req_handler(ke_msg_id_t const msgid, struct tips_upd_time_upd_state_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the provided Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Reference Time Update Service is supported if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP)) { status = attmdb_att_set_value(tips_env.rtus_shdl + RTUS_IDX_TIME_UPD_STATE_VAL, sizeof(struct tip_time_upd_state), (uint8_t *)&(param->time_upd_state)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_TIME_UPD_STATE_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_REF_TIME_INFO_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 tips_upd_ref_time_info_req_handler(ke_msg_id_t const msgid, struct tips_upd_ref_time_info_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Reference Time Info Char. has been added in the database if (TIPS_IS_SUPPORTED(TIPS_CTS_REF_TIME_INFO_SUP)) { status = attmdb_att_set_value(tips_env.cts_shdl + tips_env.cts_att_tbl[CTS_REF_TIME_INFO_CHAR] + 1, sizeof(struct tip_ref_time_info), (uint8_t *)&(param->ref_time_info)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_REF_TIME_INFO_REQ); } 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 TIPS_UPD_TIME_DST_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 tips_upd_time_dst_req_handler(ke_msg_id_t const msgid, struct tips_upd_time_dst_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Packed Time With DST value uint8_t pckd_time_dst[NDCS_TIME_DST_VAL_LEN]; // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the provided Connection Handle if (param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Next DST Change Service is supported if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP)) { //Pack the Time with DST value and Save it into the DB tips_pack_time_dst_value(&pckd_time_dst[0], ¶m->time_with_dst); // Set the value in the database status = attmdb_att_set_value(tips_env.ndcs_shdl + NDCS_IDX_TIME_DST_VAL, NDCS_TIME_DST_VAL_LEN, (uint8_t *)&pckd_time_dst[0]); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_TIME_DST_REQ); } return (KE_MSG_CONSUMED); }
/** **************************************************************************************** * @brief Handles reception of the @ref TIPS_UPD_LOCAL_TIME_INFO_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 tips_upd_local_time_info_req_handler(ke_msg_id_t const msgid, struct tips_upd_local_time_info_req const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) { // Status uint8_t status = PRF_ERR_INVALID_PARAM; // Get the address of the environment struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx); // Check the Connection Handle if(param->conhdl == gapc_get_conhdl(tips_idx_env->con_info.conidx)) { // Check if the Local Time Info Char. has been added in the database if (TIPS_IS_SUPPORTED(TIPS_CTS_LOC_TIME_INFO_SUP)) { // Set the value in the database status = attmdb_att_set_value(tips_env.cts_shdl + CTS_IDX_LOCAL_TIME_INFO_VAL, sizeof(struct tip_loc_time_info), (uint8_t *)&(param->loc_time_info)); } else { status = PRF_ERR_FEATURE_NOT_SUPPORTED; } } // Send a message to the application if an error has been raised. if (status != PRF_ERR_OK) { //Wrong Connection Handle tips_error_ind_send(&(tips_idx_env->con_info), status, TIPS_UPD_LOCAL_TIME_INFO_REQ); } 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 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); }