コード例 #1
0
ファイル: streamdatad_task.c プロジェクト: FuangCao/jwaoo-toy
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * The handler checks if the stream needs to be turned on.
 * @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)
{
    // Update the attribute value
    attmdb_att_update_value(param->handle, param->length, param->offset,
            (uint8_t*)&(param->value[0]));

    switch (STREAMDATAD_IDX(param->handle))
    {
        case STREAMDATAD_IDX_ENABLE_VAL:
			streamdatad_streamonoff();
			atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK);
			break;

        case STREAMDATAD_IDX_STREAMDATAD_D0_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D1_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D2_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D3_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D4_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D5_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D6_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D7_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D8_EN:
        case STREAMDATAD_IDX_STREAMDATAD_D9_EN:
			atts_write_rsp_send(streamdatad_env.conhdl, param->handle, PRF_ERR_OK);
            break;
        
        case STREAMDATAD_IDX_STREAMDATAD_D0_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D1_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D2_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D3_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D4_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D5_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D6_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D7_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D8_VAL:
        case STREAMDATAD_IDX_STREAMDATAD_D9_VAL:
        {
            struct streamdatad_rcv_data_packet_ind * ind = KE_MSG_ALLOC(STREAMDATAD_RCV_DATA_PACKET_IND,
														streamdatad_env.con_info.appid, dest_id,
														streamdatad_rcv_data_packet_ind);

            ind->conhdl     = gapc_get_conhdl(streamdatad_env.con_info.conidx);
            ind->handle     = param->handle;
            ind->seq        = param->value[0]; // is already incrementing (with the dummy data of the test)
            ind->size       = param->length;
            memcpy(&(ind->value[0]), &(param->value[0]), param->length);

            // Forward Received packet data to APP with the sequence number to indicate lost packets
            ke_msg_send(ind);
        }
        break;
        
    }

    return (KE_MSG_CONSUMED);
}
コード例 #2
0
ファイル: beacon_task.c プロジェクト: haby77/tqb6
static int gatt_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                      struct gatt_write_cmd_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    //uint8_t char_code = PROXR_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;
    
    if (param->conhdl == beacon_env.con_info.conhdl)
    {
        if (param->handle == beacon_env.shdl + BEACON_IDX_LVL_VAL)
        {

            //Save value in DB
            attsdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);
                
#if QN_NVDS_WRITE
            if (NVDS_OK == nvds_put(NVDS_TAG_MEASURED_POWER, sizeof(param->value[0]), (uint8_t *)&param->value[0]))
            {
                status = PRF_ERR_OK;
            }
#else
            status = PRF_ERR_OK;
#endif
            //Response
            atts_write_rsp_send(beacon_env.con_info.conhdl, param->handle, status);
        }
    }

    return (KE_MSG_CONSUMED);
}
コード例 #3
0
ファイル: adc_notify_task.c プロジェクト: FuangCao/jwaoo-toy
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_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 char_code = ADC_NOTIFY_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == adc_notify_env.con_info.conidx)
    {
                
        if (param->handle == adc_notify_env.adc_notify_shdl + ADC_NOTIFY_IDX_CFG)
        {
            char_code = ADC_NOTIFY_CFG;
        }
        
        if (char_code == ADC_NOTIFY_CFG)
        {
            
            // Written value
            uint16_t ntf_cfg;

            // Extract value before check
            ntf_cfg = co_read16p(&param->value[0]);
        
            // Only update configuration if value for stop or notification enable
            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
            {
                //Save value in DB
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&param->value[0]);
                
                // Conserve information in environment
                if (ntf_cfg == PRF_CLI_START_NTF)
                {
                    // Ntf cfg bit set to 1
                    adc_notify_env.feature |= PRF_CLI_START_NTF;
                }
                else
                {
                    // Ntf cfg bit set to 0
                    adc_notify_env.feature &= ~PRF_CLI_START_NTF;
                }                
                
                adc_notify_send_cfg(ntf_cfg);
                
                status = PRF_ERR_OK; 
                
            }
        }
    }

    // Send Write Response
    atts_write_rsp_send(adc_notify_env.con_info.conidx, param->handle, status);
    
    return (KE_MSG_CONSUMED);
}
コード例 #4
0
ファイル: sample128_task.c プロジェクト: yangchengxcy/da14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_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 char_code = SAMPLE128_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx)
    {
        if (param->handle == sample128_env.sample128_1_shdl + SAMPLE128_1_IDX_VAL)
        {
            char_code = SAMPLE128_1_CHAR;
        }

        if (char_code != SAMPLE128_ERR_CHAR)
        {
            
            //Save value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);
            
            if(param->last)
            {
                sample128_send_val(param->value[0]);
            }

            status = PRF_ERR_OK;
            
            // Send Write Response
            atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status);
            
        }
    }

    return (KE_MSG_CONSUMED);
}
コード例 #5
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_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 char_code = SAMPLE128_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx)
    {
        if (param->handle == sample128_env.sample128_shdl + SAMPLE128_1_IDX_VAL)
        {
            char_code = SAMPLE128_1_CHAR;
        }
        
        if (param->handle == sample128_env.sample128_shdl + SAMPLE128_2_IDX_CFG)
        {
            char_code = SAMPLE128_2_CFG;
        }
        
        if (char_code == SAMPLE128_1_CHAR)
        {
            
            //Save value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);
            
            if(param->last)
            {
                sample128_send_val(param->value[0]);
							  leds_state.flag = param->value[0];
							  //app_sample128_start_leds();
            }

            status = PRF_ERR_OK;
               
        }
        else if (char_code == SAMPLE128_2_CFG)
        {
            
            // Written value
            uint16_t ntf_cfg;

            // Extract value before check
            ntf_cfg = co_read16p(&param->value[0]);
        
            // Only update configuration if value for stop or notification enable
            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
            {
                //Save value in DB
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&param->value[0]);
                
                // Conserve information in environment
                if (ntf_cfg == PRF_CLI_START_NTF)
                {
                    // Ntf cfg bit set to 1
                    sample128_env.feature |= PRF_CLI_START_NTF;
                }
                else
                {
                    // Ntf cfg bit set to 0
                    sample128_env.feature &= ~PRF_CLI_START_NTF;
                }                
                
                status = PRF_ERR_OK; 
                
            }
        }
    }

    // Send Write Response
    atts_write_rsp_send(sample128_env.con_info.conidx, param->handle, status);
    
    return (KE_MSG_CONSUMED);
}
コード例 #6
0
ファイル: htpt_task.c プロジェクト: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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 *meas_intv_range;
    uint16_t meas_intv_rge[2];

    uint16_t value = 0x0000;
    uint8_t status = PRF_ERR_OK;
    uint8_t char_code = 0;

    if (KE_IDX_GET(src_id) == htpt_env.con_info.conidx)
    {
        //Extract value before check
        memcpy(&value, &(param->value), sizeof(uint16_t));

        //Measurement Interval Char. - Value
        if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 1))
        {
            /*
             * Get Measurement Interval range in database
             * Valid Range descriptor exists because measurement interval is writable
             */
            attmdb_att_get_value(param->handle + htpt_get_valid_rge_offset(), &meas_intv_rge[0], &meas_intv_range);

            memcpy(&meas_intv_rge[0], meas_intv_range, sizeof(uint16_t));
            memcpy(&meas_intv_rge[1], meas_intv_range + 2, sizeof(uint16_t));

            //Check if value to write is in allowed range
            if (((value >= meas_intv_rge[0]) && (value <= meas_intv_rge[1])) || (value == 0))
            {
                //Send APP the indication with the new value
                struct htpt_meas_intv_chg_ind * ind = KE_MSG_ALLOC(HTPT_MEAS_INTV_CHG_IND,
                                                                   htpt_env.con_info.appid, TASK_HTPT,
                                                                   htpt_meas_intv_chg_ind);

                memcpy(&ind->intv, &value, sizeof(uint16_t));

                ke_msg_send(ind);
            }
            else
            {
                status = HTPT_OUT_OF_RANGE_ERR_CODE;
            }
        }
        else
        {
            //Temperature Measurement Char. - Client Char. Configuration
            if (param->handle == (htpt_env.shdl + HTS_IDX_TEMP_MEAS_IND_CFG))
            {
                char_code = HTPT_TEMP_MEAS_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_TEMP_MEAS_CFG;
                }
                else if (value == PRF_CLI_START_IND)
                {
                    htpt_env.features |= HTPT_MASK_TEMP_MEAS_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }
            //Measurement Interval Char. - Client Char. Configuration
            else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_MEAS_INTV_CHAR] + 2))
            {
                char_code = HTPT_MEAS_INTV_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_MEAS_INTV_CFG;
                }
                else if (value == PRF_CLI_START_IND)
                {
                    htpt_env.features |= HTPT_MASK_MEAS_INTV_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }
            //Intermediate Measurement Char. - Client Char. Configuration
            else if (param->handle == (htpt_env.shdl + htpt_env.att_tbl[HTPT_INTERM_TEMP_CHAR] + 2))
            {
                char_code = HTPT_INTERM_TEMP_CHAR;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    htpt_env.features &= ~HTPT_MASK_INTM_MEAS_CFG;
                }
                else if (value == PRF_CLI_START_NTF)
                {
                    htpt_env.features |= HTPT_MASK_INTM_MEAS_CFG;
                }
                else
                {
                    //Invalid value
                    status = HTPT_OUT_OF_RANGE_ERR_CODE;
                }
            }

            if (status == PRF_ERR_OK)
            {
                if(param->last)
                {
                    //Inform APP of configuration change
                    struct htpt_cfg_indntf_ind * ind = KE_MSG_ALLOC(HTPT_CFG_INDNTF_IND,
                                                                    htpt_env.con_info.appid, TASK_HTPT,
                                                                    htpt_cfg_indntf_ind);

                    ind->conhdl = gapc_get_conhdl(htpt_env.con_info.conidx);
                    ind->char_code = char_code;
                    memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                    ke_msg_send(ind);
                }
            }
        }

        if (status == PRF_ERR_OK)
        {
            //Update the attribute value
            attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);
        }

        //Send write response
        atts_write_rsp_send(htpt_env.con_info.conidx, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #7
0
ファイル: pasps_task.c プロジェクト: GumpYangchh/wuzhuangbo
/**
 ****************************************************************************************
 * @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)
{
    // Get the conidx
    uint8_t conidx = KE_IDX_GET(src_id);
    // Get the address of the environment
    struct pasps_idx_env_tag *pasps_idx_env = PRF_CLIENT_GET_ENV(KE_BUILD_ID(dest_id, conidx), pasps_idx);

    // Check if the connection exists
    if (pasps_idx_env != NULL)
    {
        /*
         * ---------------------------------------------------------------------------------------------
         * Alert Status Client Characteristic Configuration Descriptor Value - Write
         * ---------------------------------------------------------------------------------------------
         */
        /*
         * ---------------------------------------------------------------------------------------------
         * Ringer Setting Client Characteristic Configuration Descriptor Value - Write
         * ---------------------------------------------------------------------------------------------
         */
        if ((param->handle == (pasps_env.pass_shdl + PASS_IDX_ALERT_STATUS_CFG)) ||
            (param->handle == (pasps_env.pass_shdl + PASS_IDX_RINGER_SETTING_CFG)))
        {
            // Status
            uint8_t status = PRF_ERR_OK;
            // Received configuration value
            uint16_t ntf_cfg = co_read16p(&param->value[0]);

            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
            {
                // Set the value of the Alert Status Client Characteristic Configuration Descriptor
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&ntf_cfg);

                struct pasps_written_char_val_ind *ind = KE_MSG_ALLOC(PASPS_WRITTEN_CHAR_VAL_IND,
                                                                      pasps_idx_env->con_info.appid, dest_id,
                                                                      pasps_written_char_val_ind);

                ind->conhdl   = gapc_get_conhdl(pasps_idx_env->con_info.conidx);

                if (param->handle == pasps_env.pass_shdl + PASS_IDX_ALERT_STATUS_CFG)
                {
                    ind->value.alert_status_ntf_cfg = ntf_cfg;
                    ind->att_code = PASPS_ALERT_STATUS_NTF_CFG;

                    if (ntf_cfg == PRF_CLI_STOP_NTFIND)
                    {
                        PASPS_DISABLE_NTF(pasps_idx_env, PASPS_FLAG_ALERT_STATUS_CFG);
                    }
                    else
                    {
                        PASPS_ENABLE_NTF(pasps_idx_env, PASPS_FLAG_ALERT_STATUS_CFG);
                    }
                }
                else
                {
                    ind->value.ringer_setting_ntf_cfg = ntf_cfg;
                    ind->att_code = PASPS_RINGER_SETTING_NTF_CFG;

                    if (ntf_cfg == PRF_CLI_STOP_NTFIND)
                    {
                        PASPS_DISABLE_NTF(pasps_idx_env, PASPS_FLAG_RINGER_SETTING_CFG);
                    }
                    else
                    {
                        PASPS_ENABLE_NTF(pasps_idx_env, PASPS_FLAG_RINGER_SETTING_CFG);
                    }
                }

                ke_msg_send(ind);
            }
            else
            {
                status = PRF_APP_ERROR;
            }

            // Send write response
            atts_write_rsp_send(pasps_idx_env->con_info.conidx, param->handle, status);
        }
        /*
         * ---------------------------------------------------------------------------------------------
         * Ringer Control Point Characteristic Value - Write Without Response
         * ---------------------------------------------------------------------------------------------
         */
        else if (param->handle == (pasps_env.pass_shdl + PASS_IDX_RINGER_CTNL_PT_VAL))
        {
            // Inform the HL ?
            bool inform_hl = false;

            // Check the received value
            switch (param->value[0])
            {
                case (PASP_SILENT_MODE):
                {
                    // Ignore if ringer is already silent
                    if (pasps_env.ringer_state == PASP_RINGER_NORMAL)
                    {
                        inform_hl = true;
                    }
                } break;

                case (PASP_CANCEL_SILENT_MODE):
                {
                    // Ignore if ringer is not silent
                    if (pasps_env.ringer_state == PASP_RINGER_SILENT)
                    {
                        inform_hl = true;
                    }
                } break;

                case (PASP_MUTE_ONCE):
                {
                    inform_hl = true;
                } break;

                // No need to respond with an error (Write Without Response)
                default: break;
            }

            if (inform_hl)
            {
                struct pasps_written_char_val_ind *ind = KE_MSG_ALLOC(PASPS_WRITTEN_CHAR_VAL_IND,
                                                                      pasps_idx_env->con_info.appid, TASK_PASPS,
                                                                      pasps_written_char_val_ind);

                ind->conhdl   = gapc_get_conhdl(pasps_idx_env->con_info.conidx);;
                ind->att_code = PASPS_RINGER_CTNL_PT_CHAR_VAL;
                ind->value.ringer_ctnl_pt = param->value[0];

                ke_msg_send(ind);
            }
        }
        else
        {
            ASSERT_ERR(0);
        }
    }
    // else ignore the message

    return (KE_MSG_CONSUMED);
}
コード例 #8
0
ファイル: tips_task.c プロジェクト: yangchengxcy/da14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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)
{
    uint16_t cfg_value           = 0x0000;
    uint8_t time_upd_ctnl_pt     = 0x00;
    uint8_t status               = CO_ERROR_NO_ERROR;

    // Get the address of the environment
    struct tips_idx_env_tag *tips_idx_env = PRF_CLIENT_GET_ENV(dest_id, tips_idx);

        //CTS : Current Time Char. - Notification Configuration
    if (param->handle == tips_env.cts_shdl + CTS_IDX_CURRENT_TIME_CFG)
    {
        //Extract value before check
        memcpy(&cfg_value, &param->value[0], sizeof(uint16_t));

        //only update configuration if value for stop or notification enable
        if ((cfg_value == PRF_CLI_STOP_NTFIND) || (cfg_value == PRF_CLI_START_NTF))
        {
            //Update value in DB
            attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&cfg_value);

            if (cfg_value == PRF_CLI_STOP_NTFIND)
            {
                tips_idx_env->ntf_state &= ~TIPS_CTS_CURRENT_TIME_CFG;
            }
            else //PRF_CLI_START_NTF
            {
                tips_idx_env->ntf_state |= TIPS_CTS_CURRENT_TIME_CFG;
            }
            if (param->last)
            {
                //Inform APP of configuration change
                struct tips_current_time_ccc_ind * msg = KE_MSG_ALLOC(TIPS_CURRENT_TIME_CCC_IND,
                                                                      tips_idx_env->con_info.appid, dest_id,
                                                                      tips_current_time_ccc_ind);

                msg->conhdl  = gapc_get_conhdl(tips_idx_env->con_info.conidx);
                msg->cfg_val = cfg_value;

                ke_msg_send(msg);
            }
        }
        else
        {
            //Invalid value => send Error Response with Error Code set to App Error
            status = PRF_APP_ERROR;
        }
    }
    //RTUS : Time Update Control Point Char. - Val
    else if (param->handle == tips_env.rtus_shdl + RTUS_IDX_TIME_UPD_CTNL_PT_VAL)
    {
        time_upd_ctnl_pt = param->value[0];

        //Check if value to write is in allowed range
        if ((time_upd_ctnl_pt == TIPS_TIME_UPD_CTNL_PT_GET) ||
            (time_upd_ctnl_pt == TIPS_TIME_UPD_CTNL_PT_CANCEL))
        {
            //Update value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&time_upd_ctnl_pt);

            if(param->last)
            {
                //Send APP the indication with the new value
                struct tips_time_upd_ctnl_pt_ind * msg = KE_MSG_ALLOC(TIPS_TIME_UPD_CTNL_PT_IND,
                                                                      tips_idx_env->con_info.appid, dest_id,
                                                                      tips_time_upd_ctnl_pt_ind);

                msg->conhdl  = gapc_get_conhdl(tips_idx_env->con_info.conidx);
                /*
                 * Time Update Control Point Characteristic Value
                 * 0x01 - Get Reference Update
                 * 0x02 - Cancel Reference Update
                 */
                msg->value = time_upd_ctnl_pt;

                ke_msg_send(msg);
            }
        }
    }

    //Send Write Response
    if (param->response == 0x01)
    {
        atts_write_rsp_send(tips_idx_env->con_info.conidx, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #9
0
ファイル: udss_task.c プロジェクト: FuangCao/jwaoo-toy
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler will analyse what has been set and decide alert level
 * @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 char_code = UDSS_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == udss_env.con_info.conidx)
    {
//        uint8_t att_idx = GLPS_IDX(param->handle);
        status = PRF_ERR_OK;

        if (param->handle == udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL)
        {
            char_code = UDSS_USER_HEIGHT_CHAR;
            //Set User Height to specified value
            attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_HEIGHT_VAL,
                             sizeof(uint8_t), (uint8_t *)&param->value[0]);
        }
        else if (param->handle == udss_env.shdl + UDS_IDX_USER_AGE_VAL)
        {
            char_code = UDSS_USER_AGE_CHAR;
            //Set User Age to specified value
            attmdb_att_set_value(udss_env.shdl + UDS_IDX_USER_AGE_VAL,
                                 sizeof(uint8_t), (uint8_t *)&param->value[0]);
        }
        else if (param->handle == udss_env.shdl + UDS_IDX_USER_DATE_OF_BIRTH_VAL)
        {
            char_code = UDSS_USER_DATE_OF_BIRTH_CHAR;
            //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 *)&param->value[0]);
        }
        else if (param->handle == udss_env.shdl + UDS_IDX_USER_DB_CHANGE_INCR_VAL)
        {
            char_code = UDSS_USER_DB_CHANGE_INCR_CHAR;
            //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 *)&param->value[0]);
        }
        else if (param->handle == udss_env.shdl + UDS_IDX_USER_CTRL_POINT_VAL)
        {
            uint8_t reqstatus;
            uint8_t* value;
            uint16_t length;
            struct uds_ucp_req ucp_req;

            // Update the attribute value (note several write could be required since
            // attribute length > (ATT_MTU-3)
            attmdb_att_update_value(param->handle, param->length, param->offset,
                    (uint8_t*)&(param->value[0]));

            // retrieve full data.
            attmdb_att_get_value(param->handle, &length, &value);

            // unpack user control point value
            reqstatus = udss_unpack_ucp_req(value, length, &ucp_req);

            // check unpacked status
            switch(reqstatus)
            {
                case PRF_APP_ERROR:
                {
                    /* Do nothing, ignore request since it's not complete and maybe
                     * requires several peer write to be performed.
                     */
                }
                break;
                case PRF_ERR_OK:
                {
                    // check wich request shall be send to api task
                    switch(ucp_req.op_code)
                    {
                        case UDS_REQ_REG_NEW_USER:
                        case UDS_REQ_CONSENT:
                        case UDS_REQ_DEL_USER_DATA:
                        {
                            //forward request operation to application
                            struct udss_ucp_req_ind * req = KE_MSG_ALLOC(UDSS_UCP_REQ_IND,
                                    udss_env.con_info.appid, TASK_UDSS,
                                    udss_ucp_req_ind);

                            // UCP on going.
//                            UDSS_SET(UCP_ON_GOING);

                            req->conhdl = gapc_get_conhdl(udss_env.con_info.conidx);
                            req->ucp_req = ucp_req;

                            ke_msg_send(req);
                        }
                        break;
//                        case UDS_REQ_ABORT_OP:
//                        {
//                            // nothing to abort, send an error message.
//                            struct uds_ucp_rsp ucp_rsp;

//                            ucp_rsp.op_code = UDS_REQ_RSP_CODE;
//                            ucp_rsp.operand.rsp.op_code_req =
//                                    ucp_req.op_code;
//                            ucp_rsp.operand.rsp.status = UDS_RSP_ABORT_UNSUCCESSFUL;

//                            // send user control response indication
//                            udss_send_ucp_rsp(&(ucp_rsp),
//                                    TASK_UDSS);
//                        }
//                        break;
                        default:
                        {
                            // nothing to do since it's handled during unpack
                        }
                        break;
                    }
                }
                break;
                default:
                {
                    /* There is an error in user control request, inform peer
                     * device that request is incorrect. */
                    struct uds_ucp_rsp ucp_rsp;

                    ucp_rsp.op_code = UDS_REQ_RSP_CODE;
                    ucp_rsp.req_op_code = ucp_req.op_code;
                    ucp_rsp.rsp_val = reqstatus;

                    // send user control response indication
                    udss_send_ucp_rsp(&(ucp_rsp),
                            TASK_UDSS);
                }
                break;
            }
            
        }
        // not expected request
        else
        {
            status = ATT_ERR_WRITE_NOT_PERMITTED;
        }
    }
    
    if(param->response)
    {
        // Send Write Response
        atts_write_rsp_send(udss_env.con_info.conidx, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #10
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler will
 * @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)
{
    uint16_t value = 0x0000;
    uint8_t char_code = HPS_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

    if (KE_IDX_GET(src_id) == hpss_env.con_info.conidx)
    {
        if (param->handle == hpss_env.hps_shdl + HPS_IDX_URI_VAL)
        {
            char_code = HPS_URI_CHAR;
        }
        else if (param->handle == hpss_env.hps_shdl + HPS_IDX_HEADER_VAL)
        {
            char_code = HPS_HEADER_CHAR;
        }
        else if (param->handle == hpss_env.hps_shdl + HPS_IDX_BODY_VAL)
        {
            char_code = HPS_BODY_CHAR;
        }
        else if (param->handle == hpss_env.hps_shdl + HPS_IDX_CNTL_PT_VAL)
        {
            char_code = HPS_CNTL_PT_CHAR;
        }
        //this case is processed seperately
        else if (param->handle == hpss_env.hps_shdl + HPS_IDX_STATUS_CODE_CFG)
        {
            //Extract value before check
            memcpy(&value, &(param->value), sizeof(uint16_t));

            if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF))
            {
                status = PRF_ERR_OK;
                if (value == PRF_CLI_STOP_NTFIND)
                {
                    hpss_env.features &= ~HPSS_STATUS_CODE_NTF_CFG;
                }
                else //PRF_CLI_START_NTF
                {
                    hpss_env.features |= HPSS_STATUS_CODE_NTF_CFG;
                }
            }
            else
            {
                status = PRF_APP_ERROR;
            }

            if (status == PRF_ERR_OK)
            {
                //Update the attribute value
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);
                if(param->last)
                {
                    //Inform APP of configuration change
                    struct hpss_cfg_indntf_ind * ind = KE_MSG_ALLOC(HPSS_CFG_INDNTF_IND,
                                                       hpss_env.con_info.appid, TASK_HPSS,
                                                       hpss_cfg_indntf_ind);

                    ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx);
                    memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                    ke_msg_send(ind);
                }
            }
            //If HPS, send write response
            if (param->response != 0x00)
            {
                // Send Write Response
                atts_write_rsp_send(hpss_env.con_info.conidx, param->handle, status);
            }
            return  (KE_MSG_CONSUMED);
        }
        if (char_code != HPS_ERR_CHAR)
        {
            //Save value in DB
            attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&param->value[0]);

            status = PRF_ERR_OK;

            switch(char_code)
            {
            case  HPS_URI_CHAR:
                if ((param->length + param->offset) <= HPS_URI_MAX_LEN)
                {
                    // First part of the uri value
                    if (param->offset == 0)
                    {
                        // Set value in the database
                        attmdb_att_set_value(param->handle, param->length, (uint8_t *)&param->value[0]);
                    }
                    else
                    {
                        // Complete the value stored in the database
                        attmdb_att_update_value(param->handle, param->length, param->offset,
                                                (uint8_t *)&param->value[0]);
                    }
                    if(param->last)
                    {
                        uint16_t len = 0;
                        uint8_t *data = NULL;
                        // Get complete uri value and length
                        attmdb_att_get_value(param->handle, &len, &data);
                        // Inform APP. Allocate the URI value change indication
                        struct hpss_uri_ind *ind = KE_MSG_ALLOC(HPSS_URI_IND,
                                                                hpss_env.con_info.appid, TASK_HPSS,
                                                                hpss_uri_ind);


                        // Fill in the parameter structure
                        ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx);
                        ind->char_code = HPS_URI_CHAR;
                        ind->len = len;

                        memcpy(&ind->uri, data, len);

                        ke_msg_send(ind);
                    }
                }
                break;
            case  HPS_HEADER_CHAR:
                if ((param->length + param->offset) <= HPS_HEADER_MAX_LEN)
                {
                    // First part of the uri value
                    if (param->offset == 0)
                    {
                        // Set value in the database
                        attmdb_att_set_value(param->handle, param->length, (uint8_t *)&param->value[0]);
                    }
                    else
                    {
                        // Complete the value stored in the database
                        attmdb_att_update_value(param->handle, param->length, param->offset,
                                                (uint8_t *)&param->value[0]);
                    }
                    if(param->last)
                    {
                        uint16_t len = 0;
                        uint8_t *data = NULL;
                        // Get complete uri value and length
                        attmdb_att_get_value(param->handle, &len, &data);
                        // Inform APP. Allocate the URI value change indication
                        struct hpss_header_ind *ind = KE_MSG_ALLOC(HPSS_HEADER_IND,
                                                      hpss_env.con_info.appid, TASK_HPSS,
                                                      hpss_header_ind);


                        // Fill in the parameter structure
                        ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx);
                        ind->char_code = HPS_HEADER_CHAR;
                        ind->len = len;

                        memcpy(&ind->header, data, len);

                        ke_msg_send(ind);
                    }
                }
                break;
            case  HPS_BODY_CHAR:
                if ((param->length + param->offset) <= HPS_BODY_MAX_LEN)
                {
                    // First part of the uri value
                    if (param->offset == 0)
                    {
                        // Set value in the database
                        attmdb_att_set_value(param->handle, param->length, (uint8_t *)&param->value[0]);
                    }
                    else
                    {
                        // Complete the value stored in the database
                        attmdb_att_update_value(param->handle, param->length, param->offset,
                                                (uint8_t *)&param->value[0]);
                    }
                    if(param->last)
                    {
                        uint16_t len = 0;
                        uint8_t *data = NULL;
                        // Get complete uri value and length
                        attmdb_att_get_value(param->handle, &len, &data);
                        // Inform APP. Allocate the URI value change indication
                        struct hpss_body_ind *ind = KE_MSG_ALLOC(HPSS_BODY_IND,
                                                    hpss_env.con_info.appid, TASK_HPSS,
                                                    hpss_body_ind);


                        // Fill in the parameter structure
                        ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx);
                        ind->char_code = HPS_BODY_CHAR;
                        ind->len = len;

                        memcpy(&ind->body, data, len);

                        ke_msg_send(ind);
                    }
                }
                break;
            case  HPS_CNTL_PT_CHAR:
                if ((param->length + param->offset) <= HPS_CNTL_PT_MAX_LEN)
                {
                    // First part of the uri value
                    if (param->offset == 0)
                    {
                        // Set value in the database
                        attmdb_att_set_value(param->handle, param->length, (uint8_t *)&param->value[0]);
                    }
                    else
                    {
                        // Complete the value stored in the database
                        attmdb_att_update_value(param->handle, param->length, param->offset,
                                                (uint8_t *)&param->value[0]);
                    }
                    if(param->last)
                    {
                        uint16_t len = 0;
                        uint8_t *data = NULL;
                        // Get complete uri value and length
                        attmdb_att_get_value(param->handle, &len, &data);
                        // Inform APP. Allocate the URI value change indication
                        struct hpss_cntl_pt_ind *ind = KE_MSG_ALLOC(HPSS_CNTL_PT_IND,
                                                       hpss_env.con_info.appid, TASK_HPSS,
                                                       hpss_cntl_pt_ind);


                        // Fill in the parameter structure
                        ind->conhdl = gapc_get_conhdl(hpss_env.con_info.conidx);
                        ind->char_code = HPS_CNTL_PT_CHAR;
                        ind->len = len;

                        memcpy(&ind->cntl_pt, data, len);

                        ke_msg_send(ind);
                    }
                }
                break;
            default:
                break;
            }
            //If HPS, send write response
            if (param->response != 0x00)
            {
                // Send Write Response
                atts_write_rsp_send(hpss_env.con_info.conidx, param->handle, status);
            }
        }
    }
    return (KE_MSG_CONSUMED);
}
コード例 #11
0
ファイル: accel_task.c プロジェクト: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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)
{
    // Update the attribute value
    attmdb_att_update_value(param->handle, param->length, param->offset,
            (uint8_t*)&(param->value[0]));

    switch (ACCEL_IDX(param->handle))
    {
        case ACCEL_IDX_ENABLE_VAL:
        {
            uint16_t len;
            uint8_t* accel_en;
            uint8_t* axis_en;
            uint8_t* range;

            if(*(uint8_t*)&(param->value[0]) > 1)
                accel_threshold = *(uint8_t*)&(param->value[0]) - 2;
//            set_accel_thr();
                        
            attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_ENABLE_VAL), &(len), &(accel_en));

            // Indicate to the application the state of the profile
            if (accel_en)
            {
                // Allocate the start indication message
                struct accel_start_ind *ind = KE_MSG_ALLOC(ACCEL_START_IND,
                                                           accel_env.con_info.appid, dest_id,
                                                           accel_start_ind);

                // Fill in the parameter structure
                for (int i = 0; i < ACCEL_MAX; i++)
                {
                    attmdb_att_get_value(ACCEL_DIR_VAL_HANDLE(i), &(len), &(axis_en));

                    ind->accel_en[i] = *axis_en;
                }


                attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_RANGE_VAL), &(len), &(range));

                ind->range = *range;

                // Send the message
                ke_msg_send(ind);
            }
            else
            {
                // Send the stop indication
                ke_msg_send_basic(ACCEL_STOP_IND, accel_env.con_info.appid, TASK_ACCEL);
            }
        }
        break;

        case ACCEL_IDX_ACCEL_DISPLAY1_VAL:
        case ACCEL_IDX_ACCEL_DISPLAY2_VAL:            
            if(*(uint8_t*)&(param->value[0]) == 0xFF)
            {
                if(param->length > 1 && *(uint8_t*)&(param->value[1]) > 1)
					accel_con_interval = *(uint8_t*)&(param->value[1]);
                if(param->length > 2 && *(uint8_t*)&(param->value[2]) > 1)
					accel_mode = *(uint8_t*)&(param->value[2])-2;
				if(param->length > 3 && *(uint8_t*)&(param->value[3]) > 1)
					accel_latency = *(uint8_t*)&(param->value[3])-2;
				if(param->length > 4 && *(uint8_t*)&(param->value[4]) > 1)
					accel_window = *(uint8_t*)&(param->value[4]);
            }
        {
            uint8_t line;
            uint16_t len;
            uint8_t* display;

            struct accel_write_line_ind *ind = KE_MSG_ALLOC(ACCEL_WRITE_LINE_IND,
                                                            accel_env.con_info.appid, TASK_ACCEL,
                                                            accel_write_line_ind);
            line = (param->handle == ACCEL_HANDLE(ACCEL_IDX_ACCEL_DISPLAY1_VAL))?0:1;


            attmdb_att_get_value(param->handle, &(len), &(display));

            // Fill in the parameter structure
            memcpy(ind->text, display, len);
            ind->line = line;

            // Send the message
            ke_msg_send(ind);
        }
            atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK);
            break;        
        case ACCEL_IDX_ACCEL_X_VAL:
        case ACCEL_IDX_ACCEL_X_EN:
					if(*(uint8_t*)&(param->value[0]) > 1)
					accel_adv_interval1 = *(uint8_t*)&(param->value[0]);
						atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK);
            break;
        case ACCEL_IDX_ACCEL_Y_VAL:
        case ACCEL_IDX_ACCEL_Y_EN:
					if(*(uint8_t*)&(param->value[0]) > 1)
					accel_adv_interval2 = *(uint8_t*)&(param->value[0]);
					if(*(uint8_t*)&(param->value[0]) == 255)
					accel_adv_interval2 = 0;
						atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK);
            break;
        case ACCEL_IDX_ACCEL_Z_VAL:
        case ACCEL_IDX_ACCEL_Z_EN:
					if(*(uint8_t*)&(param->value[0]) > 1)
					accel_adv_interval3 = *(uint8_t*)&(param->value[0]);
					if(*(uint8_t*)&(param->value[0]) == 255)
					accel_adv_interval3 = 0;
						atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK);
            break;
        
        default:
            atts_write_rsp_send(accel_env.con_info.conidx, param->handle, PRF_ERR_OK);
            break;
            
    }

    return (KE_MSG_CONSUMED);
}
コード例 #12
0
ファイル: hrps_task.c プロジェクト: yangchengxcy/da14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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)
{
    uint16_t value = 0x0000;
    uint8_t status = PRF_ERR_OK;

    if (KE_IDX_GET(src_id) == hrps_env.con_info.conidx)
    {
        //BP Measurement Char. - Client Char. Configuration
        if (param->handle == (hrps_env.shdl + HRS_IDX_HR_MEAS_NTF_CFG))
        {
            //Extract value before check
            memcpy(&value, &(param->value), sizeof(uint16_t));

            if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF))
            {
                if (value == PRF_CLI_STOP_NTFIND)
                {
                    hrps_env.features &= ~HRPS_HR_MEAS_NTF_CFG;
                }
                else //PRF_CLI_START_NTF
                {
                    hrps_env.features |= HRPS_HR_MEAS_NTF_CFG;
                }
            }
            else
            {
                status = PRF_APP_ERROR;
            }

            if (status == PRF_ERR_OK)
            {
                //Update the attribute value
                attmdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);
                if(param->last)
                {
                    //Inform APP of configuration change
                    struct hrps_cfg_indntf_ind * ind = KE_MSG_ALLOC(HRPS_CFG_INDNTF_IND,
                                                                    hrps_env.con_info.appid, TASK_HRPS,
                                                                    hrps_cfg_indntf_ind);

                    ind->conhdl = gapc_get_conhdl(hrps_env.con_info.conidx);
                    memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                    ke_msg_send(ind);
                }
            }
        }
        //HR Control Point Char. Value
        else
        {
            if (HRPS_IS_SUPPORTED(HRPS_ENGY_EXP_FEAT_SUP))
            {
                //Extract value
                memcpy(&value, &(param->value), sizeof(uint8_t));

                if (value == 0x1)
                {
                    //inform APP of configuration change
                    struct hrps_energy_exp_reset_ind * ind = KE_MSG_ALLOC(HRPS_ENERGY_EXP_RESET_IND,
                                                                          hrps_env.con_info.appid,
                                                                          TASK_HRPS,
                                                                          hrps_energy_exp_reset_ind);

                    ind->conhdl = gapc_get_conhdl(hrps_env.con_info.conidx);
                    ke_msg_send(ind);
                }
                else
                {
                    status = HRS_ERR_HR_CNTL_POINT_NOT_SUPPORTED;
                }
            }
            else
            {
                //Allowed to send Application Error if value inconvenient
                status = HRS_ERR_HR_CNTL_POINT_NOT_SUPPORTED;
            }
        }
    }

    //Send write response
    atts_write_rsp_send(hrps_env.con_info.conidx, param->handle, status);

    return (KE_MSG_CONSUMED);
}
コード例 #13
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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 gatt_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                      struct gatt_write_cmd_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    uint16_t value = 0x0000;
    uint8_t status = PRF_ERR_OK;
    uint8_t char_code = 0;

    if (param->conhdl == blps_env.con_info.conhdl)
    {
        //Extract value before check
        memcpy(&value, &(param->value), sizeof(uint16_t));

        //BP Measurement Char. - Client Char. Configuration
        if (param->handle == (blps_env.shdl + BPS_IDX_BP_MEAS_IND_CFG))
        {
            if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_IND))
            {
                char_code = BPS_BP_MEAS_CODE;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    blps_env.evt_cfg &= ~BLPS_BP_MEAS_IND_CFG;
                }
                else //PRF_CLI_START_IND
                {
                    blps_env.evt_cfg |= BLPS_BP_MEAS_IND_CFG;
                }
            }
            else
            {
                status = PRF_APP_ERROR;
            }
        }
        else if (param->handle == (blps_env.shdl + BPS_IDX_INTM_CUFF_PRESS_NTF_CFG))
        {
            if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF))
            {
                char_code = BPS_INTERM_CP_CODE;

                if (value == PRF_CLI_STOP_NTFIND)
                {
                    blps_env.evt_cfg &= ~BLPS_INTM_CUFF_PRESS_NTF_CFG;
                }
                else //PRF_CLI_START_NTF
                {
                    blps_env.evt_cfg |= BLPS_INTM_CUFF_PRESS_NTF_CFG;
                }
            }
            else
            {
                status = PRF_APP_ERROR;
            }
        }

        if (status == PRF_ERR_OK)
        {
            //Update the attribute value
            attsdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);
            if(param->last)
            {
                //Inform APP of configuration change
                struct blps_cfg_indntf_ind * ind = KE_MSG_ALLOC(BLPS_CFG_INDNTF_IND,
                                                                blps_env.con_info.appid, TASK_BLPS,
                                                                blps_cfg_indntf_ind);

                memcpy(&ind->conhdl, &blps_env.con_info.conhdl, sizeof(uint16_t));
                ind->char_code = char_code;
                memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                ke_msg_send(ind);
            }
        }
    }

    //Send write response
    atts_write_rsp_send(blps_env.con_info.conhdl, param->handle, status);

    return (KE_MSG_CONSUMED);
}
コード例 #14
0
ファイル: bass_task.c プロジェクト: GumpYangchh/wuzhuangbo
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_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)
{
    // Counter
    uint8_t i;
    // Status
    uint8_t status = PRF_APP_ERROR;
    // Written value
    uint16_t ntf_cfg;

    // Look for the BAS instance
    for (i = 0; ((i < bass_env.bas_nb) && (status == PRF_APP_ERROR)); i++)
    {
        if (param->handle == bass_env.shdl[i] + BAS_IDX_BATT_LVL_NTF_CFG)
        {
            // Go out of the loop
            status = PRF_ERR_OK;
        }
    }

    //Revert Last incrementation
    i--;

    // If the attribute has been found, status is PRF_ERR_OK
    if (status == PRF_ERR_OK)
    {
        // Extract value before check
        ntf_cfg = co_read16p(&param->value[0]);

        // Only update configuration if value for stop or notification enable
        if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF))
        {
            // 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);

            // Conserve information in environment
            if (ntf_cfg == PRF_CLI_START_NTF)
            {
                // Ntf cfg bit set to 1
                bass_env.features[i] |= BASS_FLAG_NTF_CFG_BIT;
            }
            else
            {
                // Ntf cfg bit set to 0
                bass_env.features[i] &= ~BASS_FLAG_NTF_CFG_BIT;
            }
            if(param->last)
            {
                // Inform APP of configuration change
                struct bass_batt_level_ntf_cfg_ind * ind = KE_MSG_ALLOC(BASS_BATT_LEVEL_NTF_CFG_IND,
                                                                        bass_env.con_info.appid, TASK_BASS,
                                                                        bass_batt_level_ntf_cfg_ind);
                ind->conhdl = gapc_get_conhdl(bass_env.con_info.conidx);
                co_write16p(&ind->ntf_cfg, ntf_cfg);
                ind->bas_instance = i;

                ke_msg_send(ind);
            }
        }
        else
        {
            status = PRF_APP_ERROR;
        }

        // Send write response
        atts_write_rsp_send(bass_env.con_info.conidx, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #15
0
ファイル: glps_task.c プロジェクト: nephen/BluetoothLamp
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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 gatt_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                      struct gatt_write_cmd_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    uint8_t status = ATT_ERR_INSUFF_AUTHOR;

    // check connection
    if (param->conhdl == glps_env.con_info.conhdl)
    {
        uint8_t att_idx = GLPS_IDX(param->handle);
        status = PRF_ERR_OK;

        // check if it's a client configuration char
        if(glps_att_db[att_idx].uuid == ATT_DESC_CLIENT_CHAR_CFG)
        {
            uint16_t cli_cfg;
            uint8_t evt_mask = GLPS_IND_NTF_EVT(att_idx);

            // get client configuration
            cli_cfg = co_read16(&(param->value));

            // stop indication/notification
            if(cli_cfg == PRF_CLI_STOP_NTFIND)
            {
                glps_env.evt_cfg &= ~evt_mask;
            }
            // start indication/notification (check that char value accept it)
            else if((((glps_att_db[att_idx-1].perm & PERM(IND, ENABLE)) != 0)
                && cli_cfg == PRF_CLI_START_IND)
               ||(((glps_att_db[att_idx-1].perm & PERM(NTF, ENABLE)) != 0)
                       && cli_cfg == PRF_CLI_START_NTF))
            {
                glps_env.evt_cfg |= evt_mask;
            }
            // improper value
            else
            {
                status = GLP_ERR_IMPROPER_CLI_CHAR_CFG;
            }

            if (status == PRF_ERR_OK)
            {
                //Inform APP of configuration change
                struct glps_cfg_indntf_ind * ind = KE_MSG_ALLOC(GLPS_CFG_INDNTF_IND,
                        glps_env.con_info.appid, TASK_GLPS,
                        glps_cfg_indntf_ind);

                //Update the attribute value
                attsdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&cli_cfg);
                ind->conhdl = glps_env.con_info.conhdl;
                ind->evt_cfg = glps_env.evt_cfg;

                ke_msg_send(ind);
            }
        }

        else if (glps_att_db[att_idx].uuid == ATT_CHAR_REC_ACCESS_CTRL_PT)
        {
            uint8_t* value;
            uint16_t length;
            struct glp_racp_req racp_req;

            // If a request is on going
            if(GLPS_IS(RACP_ON_GOING))
            {
                // if it's an abort command, execute it.
                if((param->offset == 0) && (param->value[0] == GLP_REQ_ABORT_OP))
                {
                    //forward abort operation to application
                    struct glps_racp_req_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_IND,
                            glps_env.con_info.appid, TASK_GLPS,
                            glps_racp_req_ind);

                    req->conhdl = glps_env.con_info.conhdl;
                    req->racp_req.op_code = GLP_REQ_ABORT_OP;
                    req->racp_req.filter.operator = 0;

                    ke_msg_send(req);
                }
                else
                {
                    // do nothing since a procedure already in progress
                    status = GLP_ERR_PROC_ALREADY_IN_PROGRESS;
                }
            }
            else
            {
                // Update the attribute value (note several write could be required since
                // attribute length > (ATT_MTU-3)
                attsdb_att_update_value(param->handle, param->length, param->offset,
                        (uint8_t*)&(param->value[0]));

                // retrieve full data.
                attsdb_att_get_value(param->handle, &length, &value);

                // unpack record access control point value
                status = glps_unpack_racp_req(value, length, &racp_req);

                // check unpacked status
                switch(status)
                {
                    case PRF_APP_ERROR:
                    {
                        /* Do nothing, ignore request since it's not complete and maybe
                         * requires several peer write to be performed.
                         */
                    }
                    break;
                    case PRF_ERR_OK:
                    {
                        // check wich request shall be send to api task
                        switch(racp_req.op_code)
                        {
                            case GLP_REQ_REP_STRD_RECS:
                            case GLP_REQ_DEL_STRD_RECS:
                            case GLP_REQ_REP_NUM_OF_STRD_RECS:
                            {
                                if((glps_env.evt_cfg & GLPS_RACP_IND_CFG) != 0)
                                {
                                    //forward request operation to application
                                    struct glps_racp_req_ind * req = KE_MSG_ALLOC(GLPS_RACP_REQ_IND,
                                        glps_env.con_info.appid, TASK_GLPS,
                                            glps_racp_req_ind);
    
                                    // RACP on going.
                                    GLPS_SET(RACP_ON_GOING);
    
                                    req->conhdl = glps_env.con_info.conhdl;
                                    req->racp_req = racp_req;
    
                                    ke_msg_send(req);
                                }
                                else
                                {
                                    status = PRF_CCCD_IMPR_CONFIGURED;
                                }
                            }
                            break;
                            case GLP_REQ_ABORT_OP:
                            {
                                // nothing to abort, send an error message.
                                struct glp_racp_rsp racp_rsp;

                                racp_rsp.op_code = GLP_REQ_RSP_CODE;
                                racp_rsp.operand.rsp.op_code_req =
                                        racp_req.op_code;
                                racp_rsp.operand.rsp.status = GLP_RSP_ABORT_UNSUCCESSFUL;

                                // send record access control response indication
                                glps_send_racp_rsp(&(racp_rsp),
                                        TASK_GLPS);
                            }
                            break;
                            default:
                            {
                                // nothing to do since it's handled during unpack
                            }
                            break;
                        }
                    }
                    break;
                    default:
                    {
                        /* There is an error in record access control request, inform peer
                         * device that request is incorrect. */
                        struct glp_racp_rsp racp_rsp;

                        racp_rsp.op_code = GLP_REQ_RSP_CODE;
                        racp_rsp.operand.rsp.op_code_req = racp_req.op_code;
                        racp_rsp.operand.rsp.status = status;

                        // send record access control response indication
                        glps_send_racp_rsp(&(racp_rsp),
                                TASK_GLPS);
                    }
                    break;
                }
            }
        }
        // not expected request
        else
        {
            status = ATT_ERR_WRITE_NOT_PERMITTED;
        }
    }

    if(param->response)
    {
        //Send write response
        atts_write_rsp_send(param->conhdl, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #16
0
ファイル: qpps_task.c プロジェクト: hiccchen/d-gitku
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * The handler compares the new values with current ones and notifies them if they changed.
 * @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 gatt_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                      struct gatt_write_cmd_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    uint8_t status = PRF_ERR_OK;

    if (param->conhdl == qpps_env.conhdl)
    {
        // Client Char. Configuration
		uint8_t char_index = param->handle - (qpps_env.shdl + QPPS_IDX_VAL_NTF_CFG);
        if ((param->handle > (qpps_env.shdl + QPPS_IDX_VAL_CHAR)) && ((char_index % 3) == 0))
        {
            uint16_t value = 0x0000;

            //Extract value before check
            memcpy(&value, &(param->value), sizeof(uint16_t));

            if ((value == PRF_CLI_STOP_NTFIND) || (value == PRF_CLI_START_NTF))
            {
                if (value == PRF_CLI_STOP_NTFIND)
                {
                    qpps_env.features &= ~(QPPS_VALUE_NTF_CFG << (char_index / 3));
                }
                else //PRF_CLI_START_NTF
                {
                    qpps_env.features |= QPPS_VALUE_NTF_CFG << (char_index / 3);
                }
            }
            else
            {
                status = PRF_APP_ERROR;
            }

            if (status == PRF_ERR_OK)
            {
                uint8_t *old_value;
                atts_size_t length;

                attsdb_att_get_value(param->handle, &length, &old_value);
                if (value != co_read16p(old_value))
                {
                    //Update the attribute value
                    attsdb_att_set_value(param->handle, sizeof(uint16_t), (uint8_t *)&value);

                    if(param->last)
                    {
                        //Inform APP of configuration change
                        struct qpps_cfg_indntf_ind * ind = KE_MSG_ALLOC(QPPS_CFG_INDNTF_IND,
                                                                        qpps_env.appid, TASK_QPPS,
                                                                        qpps_cfg_indntf_ind);

                        ind->char_index = (char_index / 3);
                        memcpy(&ind->cfg_val, &value, sizeof(uint16_t));

                        ke_msg_send(ind);
                    }
                }
            }
        }
        else if (param->handle == (qpps_env.shdl + QPPS_IDX_RX_DATA_VAL))
        {
			if (param->length <= QPP_DATA_MAX_LEN)
			{
				//inform APP of configuration change
				struct qpps_data_val_ind * ind = KE_MSG_ALLOC_DYN(QPPS_DAVA_VAL_IND,
																  qpps_env.appid,
																  TASK_QPPS,
																  qpps_data_val_ind, param->length);

				memcpy(&ind->conhdl, &(qpps_env.conhdl), sizeof(uint16_t));
				//Send received data to app value
				ind->length = param->length;
				memcpy(ind->data, param->value, param->length);

				ke_msg_send(ind);
			}
			else
			{
				status = QPPS_ERR_RX_DATA_EXCEED_MAX_LENGTH;
			}
        }
		else
		{
			status = QPPS_ERR_INVALID_PARAM;
		}
    }

    if (param->response)
    {
        //Send write response
        atts_write_rsp_send(qpps_env.conhdl, param->handle, status);
    }

    return (KE_MSG_CONSUMED);
}
コード例 #17
0
ファイル: anps_task.c プロジェクト: yangchengxcy/da14580
/**
 ****************************************************************************************
 * @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);
}