Beispiel #1
0
void anps_send_ntf_status_update_ind(struct anps_idx_env_tag *idx_env, uint8_t alert_type)
{
    // Send the message to the application
    struct anps_ntf_status_update_ind *ind = KE_MSG_ALLOC(ANPS_NTF_STATUS_UPDATE_IND,
            idx_env->con_info.appid, idx_env->con_info.prf_id,
            anps_ntf_status_update_ind);

    ind->conhdl      = idx_env->con_info.conhdl;
    ind->alert_type  = alert_type;
    ind->ntf_ccc_cfg = ANPS_IS_ALERT_ENABLED(idx_env, alert_type) ? PRF_CLI_START_NTF : PRF_CLI_STOP_NTFIND;

    if (alert_type == ANP_NEW_ALERT)
    {
        ind->cat_ntf_cfg.cat_id_mask_0 = (uint8_t)(idx_env->ntf_new_alert_cfg & 0x00FF);
        ind->cat_ntf_cfg.cat_id_mask_1 = (uint8_t)((idx_env->ntf_new_alert_cfg & 0xFF00) >> 8);
    }
Beispiel #2
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_WRITE_CMD_IND 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 gattc_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                       struct gattc_write_cmd_ind const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint8_t conidx = KE_IDX_GET(src_id);
    // Get the address of the environment
    struct anps_idx_env_tag *anps_idx_env = PRF_CLIENT_GET_ENV(KE_BUILD_ID(dest_id, conidx), anps_idx);

    // Check if the connection exists
    if (anps_idx_env != NULL)
    {
        // Status
        uint8_t status = PRF_ERR_OK;

        /*
         * ---------------------------------------------------------------------------------------------
         * New Alert Client Characteristic Configuration Descriptor Value - Write
         * ---------------------------------------------------------------------------------------------
         */
        /*
         * ---------------------------------------------------------------------------------------------
         * Unread Status Alert Client Characteristic Configuration Descriptor Value - Write
         * ---------------------------------------------------------------------------------------------
         */
        if ((param->handle == (anps_env.ans_shdl + ANS_IDX_NEW_ALERT_CFG)) ||
            (param->handle == (anps_env.ans_shdl + ANS_IDX_UNREAD_ALERT_STATUS_CFG)))
        {
            // Received configuration value
            uint16_t ntf_cfg = co_read16p(&param->value[0]);

            if (ntf_cfg <= PRF_CLI_START_NTF)
            {
                // Alert type
                uint8_t alert_type = (param->handle == (anps_env.ans_shdl + ANS_IDX_NEW_ALERT_CFG))
                                     ? ANP_NEW_ALERT : ANP_UNREAD_ALERT;

                // Set the value of the Alert Status Client Characteristic Configuration Descriptor (Readable)
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&ntf_cfg);

                // Update the status in the environment
                if (ntf_cfg == PRF_CLI_START_NTF)
                {
                    ANPS_ENABLE_ALERT(anps_idx_env, alert_type);
                }
                else
                {
                    ANPS_DISABLE_ALERT(anps_idx_env, alert_type);
                }

                // Inform the HL that the notification configuration status has been written
                anps_send_ntf_status_update_ind(anps_idx_env, alert_type);
            }
            else
            {
                status = PRF_APP_ERROR;
            }
        }
        /*
         * ---------------------------------------------------------------------------------------------
         * Alert Notification Control Point Characteristic Value - Write
         * ---------------------------------------------------------------------------------------------
         */
        else if (param->handle == (anps_env.ans_shdl + ANS_IDX_ALERT_NTF_CTNL_PT_VAL))
        {
            do
            {
                // Check the command ID value
                if (param->value[0] >= CMD_ID_NB)
                {
                    status = ANP_CMD_NOT_SUPPORTED;
                    break;
                }

                // Check the category ID value
                if ((param->value[1] >= CAT_ID_NB) &&
                    (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT))
                {
                    status = ANP_CAT_NOT_SUPPORTED;
                    break;
                }

                if (param->value[1] < CAT_ID_NB)
                {
                    // New Alert
                    if ((param->value[0] % 2) == 0)
                    {
                        // Check if the category is supported
                        if (!ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(param->value[1]))
                        {
                            status = ANP_CAT_NOT_SUPPORTED;
                            break;
                        }
                    }
                    // Unread Alert Status
                    else
                    {
                        // Check if the category is supported
                        if (!ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(param->value[1]))
                        {
                            status = ANP_CAT_NOT_SUPPORTED;
                            break;
                        }
                    }
                }

                // React according to the received command id value
                switch (param->value[0])
                {
                    // Enable New Alert Notification
                    case (CMD_ID_EN_NEW_IN_ALERT_NTF):
                    {
                        if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT)
                        {
                            // Enable sending of new alert notification for the specified category
                            ANPS_ENABLE_NEW_ALERT_CATEGORY(param->value[1], anps_idx_env);
                        }
                        else
                        {
                            // Enable sending of new alert notification for all supported category
                            anps_idx_env->ntf_new_alert_cfg |= anps_env.supp_new_alert_cat;
                        }

                        anps_send_ntf_status_update_ind(anps_idx_env, ANP_NEW_ALERT);
                    } break;

                    // Enable Unread Alert Status Notification
                    case (CMD_ID_EN_UNREAD_CAT_STATUS_NTF):
                    {
                        if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT)
                        {
                            // Enable sending of unread alert notification for the specified category
                            ANPS_ENABLE_UNREAD_ALERT_CATEGORY(param->value[1], anps_idx_env);
                        }
                        else
                        {
                            // Enable sending of unread alert notification for all supported category
                            anps_idx_env->ntf_unread_alert_cfg |= anps_env.supp_unread_alert_cat;
                        }

                        anps_send_ntf_status_update_ind(anps_idx_env, ANP_UNREAD_ALERT);
                    } break;

                    // Disable New Alert Notification
                    case (CMD_ID_DIS_NEW_IN_ALERT_NTF):
                    {
                        if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT)
                        {
                            // Disable sending of new alert notification for the specified category
                            ANPS_DISABLE_NEW_ALERT_CATEGORY(param->value[1], anps_idx_env);
                        }
                        else
                        {
                            // Disable sending of new alert notification for all supported category
                            anps_idx_env->ntf_new_alert_cfg &= ~anps_env.supp_new_alert_cat;
                        }

                        anps_send_ntf_status_update_ind(anps_idx_env, ANP_NEW_ALERT);
                    } break;

                    // Disable Unread Alert Status Notification
                    case (CMD_ID_DIS_UNREAD_CAT_STATUS_NTF):
                    {
                        if (param->value[1] != CAT_ID_ALL_SUPPORTED_CAT)
                        {
                            // Disable sending of unread alert notification for the specified category
                            ANPS_DISABLE_UNREAD_ALERT_CATEGORY(param->value[1], anps_idx_env);
                        }
                        else
                        {
                            // Enable sending of unread alert notification for all supported category
                            anps_idx_env->ntf_unread_alert_cfg &= ~anps_env.supp_unread_alert_cat;
                        }

                        anps_send_ntf_status_update_ind(anps_idx_env, ANP_UNREAD_ALERT);
                    } break;

                    // Notify New Alert immediately
                    case (CMD_ID_NTF_NEW_IN_ALERT_IMM):
                    {
                        // Check if sending of notification is enabled
                        if (ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_NEW_ALERT))
                        {
                            if (param->value[1] == CAT_ID_ALL_SUPPORTED_CAT)
                            {
                                // Check if at least one category can be notified
                                if (anps_idx_env->ntf_new_alert_cfg != 0)
                                {
                                    anps_send_ntf_immediate_req_ind(anps_idx_env, ANP_NEW_ALERT,
                                                                    CAT_ID_ALL_SUPPORTED_CAT);
                                }
                            }
                            else
                            {
                                // Check if sending of notifications has been enabled for the specified category.
                                if (ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(param->value[1], anps_idx_env))
                                {
                                    anps_send_ntf_immediate_req_ind(anps_idx_env, ANP_NEW_ALERT,
                                                                    param->value[1]);
                                }
                            }
                        }
                    } break;

                    // Notify Unread Alert Status immediately
                    case (CMD_ID_NTF_UNREAD_CAT_STATUS_IMM):
                    {
                        if (ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_UNREAD_ALERT))
                        {
                            // Check if sending of notification is enabled
                            if (ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_UNREAD_ALERT))
                            {
                                if (param->value[1] == CAT_ID_ALL_SUPPORTED_CAT)
                                {
                                    // Check if at least one category can be notified
                                    if (anps_idx_env->ntf_unread_alert_cfg != 0)
                                    {
                                        anps_send_ntf_immediate_req_ind(anps_idx_env, ANP_UNREAD_ALERT,
                                                                        CAT_ID_ALL_SUPPORTED_CAT);
                                    }
                                }
                                else
                                {
                                    // Check if sending of notifications has been enabled for the specified category.
                                    if (ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(param->value[1], anps_idx_env))
                                    {
                                        anps_send_ntf_immediate_req_ind(anps_idx_env, ANP_UNREAD_ALERT,
                                                                        param->value[1]);
                                    }
                                }
                            }
                        }
                    } break;

                    default:
                    {
                        ASSERT_ERR(0);
                    } break;
                }
            } while (0);
        }
        else
        {
            ASSERT_ERR(0);
        }

        // Send write response
        atts_write_rsp_send(anps_idx_env->con_info.conidx, param->handle, status);
    }
    // else ignore the message

    return (KE_MSG_CONSUMED);
}
Beispiel #3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref ANPS_NTF_ALERT_CMD 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_ntf_alert_cmd_handler(ke_msg_id_t const msgid,
                                      struct anps_ntf_alert_cmd const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{

    // Message Status
    uint8_t msg_status = KE_MSG_CONSUMED;
    // Task environment
    struct anps_idx_env_tag *anps_idx_env = PRF_CLIENT_GET_ENV(dest_id, anps_idx);

    if (anps_idx_env != NULL)
    {
        // Status
        uint8_t status     = PRF_ERR_OK;
        // Category ID
        uint8_t cat_id;
        // Is the category supported ?
        bool cat_supported;
        // Handle
        uint16_t handle;

        do
        {
            // Check the provided connection handle value
            if (anps_idx_env->con_info.conidx != gapc_get_conidx(param->conhdl))
            {
                status = PRF_ERR_INVALID_PARAM;
                break;
            }

            if (ke_state_get(dest_id) == ANPS_BUSY)
            {
                // The message will be handled once the current operation is over
                msg_status = KE_MSG_NO_FREE;
                break;
            }

            ASSERT_ERR(ke_state_get(dest_id) == ANPS_CONNECTED);

            // Check the operation code, get the category ID.
            if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE)
            {
                // Check the length of the string info value
                if (param->value.new_alert.info_str_len > ANS_NEW_ALERT_STRING_INFO_MAX_LEN)
                {
                    status = PRF_ERR_INVALID_PARAM;
                    break;
                }

                // Get the category ID
                cat_id = param->value.new_alert.cat_id;
                // Check if the category is supported
                cat_supported = ANPS_IS_NEW_ALERT_CATEGORY_SUPPORTED(cat_id);
            }
            else if (param->operation == ANPS_UPD_UNREAD_ALERT_STATUS_OP_CODE)
            {
                // Get the category ID
                cat_id = param->value.unread_alert_status.cat_id;
                // Check if the category is supported
                cat_supported = ANPS_IS_UNREAD_ALERT_CATEGORY_SUPPORTED(cat_id);
            }
            else
            {
                status = PRF_ERR_INVALID_PARAM;
                break;
            }

            // Check the category ID
            if ((cat_id >= CAT_ID_NB) || (!cat_supported))
            {
                status = PRF_ERR_INVALID_PARAM;
                break;
            }

            if (param->operation == ANPS_UPD_NEW_ALERT_OP_CODE)
            {
                // Check if sending of notification is enabled for the provided category
                if (ANPS_IS_NEW_ALERT_CATEGORY_ENABLED(cat_id, anps_idx_env) &&
                    ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_NEW_ALERT))
                {
                    handle = anps_env.ans_shdl + ANS_IDX_NEW_ALERT_VAL;

                    // Notification can be sent, set the value in the database
                    attmdb_att_set_value(handle, 2 + param->value.new_alert.info_str_len,
                                         (uint8_t *)&param->value.new_alert.cat_id);
                }
                else
                {
                    status = PRF_ERR_NTF_DISABLED;
                    break;
                }
            }
            else
            {
                if (ANPS_IS_UNREAD_ALERT_CATEGORY_ENABLED(cat_id, anps_idx_env) &&
                    ANPS_IS_ALERT_ENABLED(anps_idx_env, ANP_UNREAD_ALERT))
                {
                    handle = anps_env.ans_shdl + ANS_IDX_UNREAD_ALERT_STATUS_VAL;

                    attmdb_att_set_value(handle, sizeof(struct anp_unread_alert),
                                         (uint8_t *)&param->value.unread_alert_status);
                }
                else
                {
                    status = PRF_ERR_NTF_DISABLED;
                    break;
                }
            }

            // Configure the environment
            anps_idx_env->operation = param->operation;

            // The notification can be sent, send the notification
            prf_server_send_event((prf_env_struct *)anps_idx_env, false, handle);

            // Go to Busy state
            ke_state_set(dest_id, ANPS_BUSY);
        } while (0);

        if (status != PRF_ERR_OK)
        {
            // Send response to application
            anps_send_cmp_evt(anps_idx_env->con_info.prf_id, anps_idx_env->con_info.appid,
                              gapc_get_conhdl(anps_idx_env->con_info.conidx),
                              param->operation, status);
        }
    }
    else
    {
        // Send response to application
        anps_send_cmp_evt(dest_id, src_id, param->conhdl, param->operation, PRF_ERR_REQ_DISALLOWED);
    }

    return (int)msg_status;
}