Пример #1
0
int hogprh_err_rsp_handler(ke_msg_id_t const msgid,
                                    struct hogprh_char_req_rsp const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    arch_printf("HOGPRH: Error for msgid=%d, conhdl=%d, att_code=%d\r\n", msgid, param->conhdl, param->att_code);
    
    switch(param->status)
    {
        case PRF_ERR_INEXISTENT_HDL:
            arch_puts("Handle not found!\r\n");
            break;
        case PRF_ERR_INVALID_PARAM:
            arch_puts("Invalid param!\r\n");
            break;
        case PRF_ERR_NOT_WRITABLE:
            arch_puts("Not writable!\r\n");
            break;
        default:
            arch_printf("--> Status=%d\r\n", param->status);
            if ( (param->status == ATT_ERR_INSUFF_AUTHEN) || (param->status == ATT_ERR_INSUFF_ENC) ){
#if MITM_REQUIRED
                struct gapc_bond_cmd *req = KE_MSG_ALLOC(GAPC_BOND_CMD,
                                                           KE_BUILD_ID(TASK_GAPC, app_env.conidx), TASK_APP,
                                                           gapc_bond_cmd);

                // Fill in the parameter structure
                req->operation          = GAPC_BOND;
                // OOB information
                req->pairing.oob        = GAP_OOB_AUTH_DATA_NOT_PRESENT;
                // Encryption key size
                req->pairing.key_size   = KEY_LEN;
                // IO capabilities
                req->pairing.iocap      = GAP_IO_CAP_KB_DISPLAY;
                // Authentication requirements
                req->pairing.auth       = GAP_AUTH_REQ_MITM_BOND;
                //Security requirements
                req->pairing.sec_req    = GAP_SEC1_AUTH_PAIR_ENC;
                //Initiator key distribution
                req->pairing.ikey_dist  = GAP_KDIST_SIGNKEY;
                //Responder key distribution
                req->pairing.rkey_dist  = GAP_KDIST_ENCKEY;

                // Send the message
                ke_msg_send(req);
#else
                struct gapc_bond_cmd *req = KE_MSG_ALLOC(GAPC_BOND_CMD,
                                                           KE_BUILD_ID(TASK_GAPC, app_env.conidx), TASK_APP,
                                                           gapc_bond_cmd);

                // Fill in the parameter structure
                req->operation          = GAPC_BOND;
                // OOB information
                req->pairing.oob        = GAP_OOB_AUTH_DATA_NOT_PRESENT;
                // Encryption key size
                req->pairing.key_size   = KEY_LEN;
                // IO capabilities
                req->pairing.iocap      = GAP_IO_CAP_KB_DISPLAY;
                // Authentication requirements
                req->pairing.auth       = GAP_AUTH_REQ_NO_MITM_BOND;
                //Security requirements
                req->pairing.sec_req    = GAP_NO_SEC;
                //Initiator key distribution
                req->pairing.ikey_dist  = GAP_KDIST_SIGNKEY;
                //Responder key distribution
                req->pairing.rkey_dist  = GAP_KDIST_ENCKEY;

                // Send the message
                ke_msg_send(req);
#endif
            }
            break;
    }
    
    return (KE_MSG_CONSUMED);
}
Пример #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);
}
Пример #3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref ANPS_CREATE_DB_REQ message.
 * @param[in] msgid Id of the message received.
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance.
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int anps_create_db_req_handler(ke_msg_id_t const msgid,
                                      struct anps_create_db_req *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    // Service Configuration Flag - All attributes have to be added in the database
    uint16_t cfg_flag = ANPS_DB_CONFIG_MASK;
    // Database Creation Status
    uint8_t status;
    // Counter
    uint8_t counter;

    // Check if an ANS has already been added in the database
    if (ke_state_get(TASK_ANPS) == ANPS_DISABLED)
    {
        // Check the provided values (Supported New Alert Category Char value - shall not be 0)
        if ((param->supp_new_alert_cat.cat_id_mask_0 != 0) ||
            (param->supp_new_alert_cat.cat_id_mask_1 != 0))
        {
            // Add service in the database
            status = attm_svc_create_db(&anps_env.ans_shdl, (uint8_t *)&cfg_flag, ANS_IDX_NB, NULL,
                                        dest_id, &ans_att_db[0]);

            // Go to Idle State
            if (status == ATT_ERR_NO_ERROR)
            {
                uint8_t length = sizeof(uint8_t);

                // Mask the Category ID Bit Mask 1 values to have a good value
                param->supp_new_alert_cat.cat_id_mask_1    &= ANP_CAT_ID_1_MASK;
                param->supp_unread_alert_cat.cat_id_mask_1 &= ANP_CAT_ID_1_MASK;

                // The second part of a supported category value is optional is set to 0, remove it
                if (param->supp_new_alert_cat.cat_id_mask_1 != 0x00)
                {
                    length *= 2;
                }

                // Set the value of the Supported New Alert Category characteristic
                attmdb_att_set_value(anps_env.ans_shdl + ANS_IDX_SUPP_NEW_ALERT_CAT_VAL, length,
                                     (uint8_t *)&param->supp_new_alert_cat);

                length = sizeof(uint8_t);

                // The second part of a supported category value is optional is set to 0, remove it
                if (param->supp_unread_alert_cat.cat_id_mask_1 != 0x00)
                {
                    length *= 2;
                }

                // Set the value of the Supported Unread Alert Category characteristic
                attmdb_att_set_value(anps_env.ans_shdl + ANS_IDX_SUPP_UNREAD_ALERT_CAT_VAL, length,
                                     (uint8_t *)&param->supp_unread_alert_cat);

                // Keep the supported categories in the environment
                anps_env.supp_new_alert_cat    = ((param->supp_new_alert_cat.cat_id_mask_0) |
                                                  (param->supp_new_alert_cat.cat_id_mask_1 << 8));
                anps_env.supp_unread_alert_cat = ((param->supp_unread_alert_cat.cat_id_mask_0) |
                                                  (param->supp_unread_alert_cat.cat_id_mask_1 << 8));

                // Disable ANS
                attmdb_svc_set_permission(anps_env.ans_shdl, PERM(SVC, DISABLE));

                for (counter = 0; counter < ANPS_IDX_MAX; counter++)
                {
                    // If we are here, database has been fulfilled with success, go to idle state
                    ke_state_set(KE_BUILD_ID(TASK_ANPS, counter), ANPS_IDLE);
                }
            }
        }
        else
        {
            // One of the provided value in not within the defined range
            status = PRF_ERR_INVALID_PARAM;
        }
    }
    else
    {
        // Request is disallowed, an ANS has already been added
        status = PRF_ERR_REQ_DISALLOWED;
    }

    // Send response to application
    anps_send_cmp_evt(TASK_ANPS, src_id, GAP_INVALID_CONHDL, ANPS_CREATE_DB_OP_CODE, status);

    return (KE_MSG_CONSUMED);
}
void prf_cleanup_func(uint8_t conidx, uint16_t conhdl, uint8_t reason)
{
    #if (BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_PAS_SERVER || BLE_AN_SERVER)
    ke_task_id_t prf_task_id;
    #endif //(BLE_CLIENT_PRF || BLE_TIP_SERVER || BLE_PAS_SERVER || BLE_AN_SERVER)

    //All profiles get this event, they must disable clean
    #if (BLE_ACCEL)
    if (ke_state_get(TASK_ACCEL) == ACCEL_ACTIVE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_ACCEL);
    }
    #endif // (BLE_ACCEL)

    #if (BLE_PROX_REPORTER)
    if (ke_state_get(TASK_PROXR) == PROXR_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_PROXR);
    }
    #endif // #if BLE_PROX_REPORTER

    #if (BLE_PROX_MONITOR)
    prf_task_id = KE_BUILD_ID(TASK_PROXM, conidx);

    if (ke_state_get(prf_task_id) != PROXM_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_PROX_MONITOR
	#if (BLE_STREAMDATA_DEVICE)
    if (ke_state_get(TASK_STREAMDATAD) == STREAMDATAD_ACTIVE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_STREAMDATAD);
    }
    #endif // #if BLE_STREAMDATA_DEVICE
    #if (BLE_STREAMDATA_HOST)
    prf_task_id = KE_BUILD_ID(TASK_STREAMDATAH, conidx);
    if (ke_state_get(prf_task_id) != STREAMDATAH_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_STREAMDATA_HOST
    #if (BLE_SPOTA_RECEIVER)
    if (ke_state_get(TASK_SPOTAR) == SPOTAR_ACTIVE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_SPOTAR);
    }
    #endif // #if BLE_SPOTA_RECEIVER
    #if (BLE_FINDME_TARGET)
    if (ke_state_get(TASK_FINDT) == FINDT_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_FINDT);
    }
    #endif // #if BLE_PROX_REPORTER

    #if (BLE_FINDME_LOCATOR)
    prf_task_id = KE_BUILD_ID(TASK_FINDL, conidx);

    if (ke_state_get(prf_task_id) != FINDL_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_PROX_MONITOR

    #if (BLE_HT_THERMOM)
    if (ke_state_get(TASK_HTPT) == HTPT_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_HTPT);
    }
    #endif // #if BLE_HT_THERMOM

    #if (BLE_HT_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_HTPC, conidx);

    if (ke_state_get(prf_task_id) != HTPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_HT_COLLECTOR

    #if (BLE_DIS_SERVER)
    if (ke_state_get(TASK_DISS) == DISS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_DISS);
    }
    #endif // #BLE_DIS_SERVER

    #if (BLE_DIS_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_DISC, conidx);

    if (ke_state_get(prf_task_id) != DISC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_DIS_CLIENT

    #if (BLE_TIP_SERVER)
    prf_task_id = KE_BUILD_ID(TASK_TIPS, conidx);

    if (ke_state_get(prf_task_id) == TIPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #BLE_TIP_SERVER

    #if (BLE_TIP_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_TIPC, conidx);

    if (ke_state_get(prf_task_id) != TIPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_TIP_CLIENT

    #if (BLE_BP_SENSOR)
    if (ke_state_get(TASK_BLPS) == BLPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_BLPS);
    }
    #endif // #BLE_BP_SENSOR

    #if (BLE_BP_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_BLPC, conidx);

    if (ke_state_get(prf_task_id) != BLPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_BP_COLLECTOR

    #if (BLE_HR_SENSOR)
    if (ke_state_get(TASK_HRPS) == HRPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_HRPS);
    }
    #endif // #BLE_HR_SENSOR

    #if (BLE_HR_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_HRPC, conidx);

    if (ke_state_get(prf_task_id) != HRPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_HR_COLLECTOR

    #if (BLE_SP_SERVER)
    if (ke_state_get(TASK_SCPPS) == SCPPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_SCPPS);
    }
    #endif // #BLE_SP_SERVER

    #if (BLE_SP_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_SCPPC, conidx);

    if (ke_state_get(prf_task_id) != SCPPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_SP_CLIENT

    #if (BLE_BATT_SERVER)
    if (ke_state_get(TASK_BASS) == BASS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_BASS);
    }
    #endif // #BLE_SP_SERVER

    #if (BLE_BATT_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_BASC, conidx);

    if (ke_state_get(prf_task_id) != BASC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_BATT_CLIENT

    #if (BLE_HID_DEVICE)
    if (ke_state_get(TASK_HOGPD) == HOGPD_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_HOGPD);
    }
    #endif // #if BLE_HID_DEVICE

    #if (BLE_HID_BOOT_HOST)
    prf_task_id = KE_BUILD_ID(TASK_HOGPBH, conidx);

    if (ke_state_get(prf_task_id) != HOGPBH_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_HID_BOOT_HOST

    #if (BLE_HID_REPORT_HOST)
    prf_task_id = KE_BUILD_ID(TASK_HOGPRH, conidx);

    if (ke_state_get(prf_task_id) != HOGPRH_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // #if BLE_HID_REPORT_HOST

    #if (BLE_GL_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_GLPC, conidx);

    if (ke_state_get(prf_task_id) != GLPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // (BLE_GL_COLLECTOR)

    #if (BLE_GL_SENSOR)
    if (ke_state_get(TASK_GLPS) == GLPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_GLPS);
    }
    #endif // (BLE_GL_SENSOR)

    #if (BLE_NEB_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_NBPC, conidx);

    if (ke_state_get(prf_task_id) >= NBPC_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // (BLE_NEB_CLIENT)

    #if (BLE_NEB_SERVER)
    if ((ke_state_get(TASK_NBPS) >= NBPS_CONNECTED))
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_NBPS);
    }
    #endif // (BLE_NEB_SERVER)

    #if (BLE_RSC_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_RSCPC, conidx);

    if (ke_state_get(prf_task_id) != RSCPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
	}
    #endif // (BLE_RSC_COLLECTOR)

    #if (BLE_RSC_SENSOR)
    if (ke_state_get(TASK_RSCPS) >= RSCPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_RSCPS);
    }
    #endif // (BLE_RSC_SENSOR)

    #if (BLE_CSC_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_CSCPC, conidx);

    if (ke_state_get(prf_task_id) != CSCPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // (BLE_CSC_COLLECTOR)

    #if (BLE_CSC_SENSOR)
    if (ke_state_get(TASK_CSCPS) >= CSCPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_CSCPS);
    }
    #endif // (BLE_CSC_SENSOR)

    #if (BLE_CP_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_CPPC, conidx);

    if (ke_state_get(prf_task_id) != CPPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // (BLE_CP_COLLECTOR)

    #if (BLE_CP_SENSOR)
    if (ke_state_get(TASK_CPPS) >= CPPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_CPPS);
    }
    #endif // (BLE_CP_SENSOR)

    #if (BLE_LN_COLLECTOR)
    prf_task_id = KE_BUILD_ID(TASK_LANC, conidx);

    if (ke_state_get(prf_task_id) != LANC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif // (BLE_LN_COLLECTOR)

    #if (BLE_LN_SENSOR)
    if (ke_state_get(TASK_LANS) >= LANS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_LANS);
    }
    #endif // (BLE_LN_SENSOR)

    #if (BLE_AN_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_ANPC, conidx);

    if (ke_state_get(prf_task_id) != ANPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_AN_CLIENT)

    #if (BLE_AN_SERVER)
    prf_task_id = KE_BUILD_ID(TASK_ANPS, conidx);

    if (ke_state_get(prf_task_id) >= ANPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_AN_SERVER)

    #if (BLE_ANC_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_ANCC, conidx);

    if (ke_state_get(prf_task_id) != ANCC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_ANC_CLIENT)

    #if (BLE_PAS_SERVER)
    prf_task_id = KE_BUILD_ID(TASK_PASPS, conidx);

    if (ke_state_get(prf_task_id) == PASPS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_PAS_SERVER)

    #if (BLE_PAS_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_PASPC, conidx);

    if (ke_state_get(prf_task_id) != PASPC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_PAS_CLIENT)

    #if (BLE_SAMPLE128)
    if (ke_state_get(TASK_SAMPLE128) == SAMPLE128_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_SAMPLE128);
    }
    #endif //(BLE_PAS_SERVER)
    
    #if (BLE_IEU)  
    if (ke_state_get(TASK_IEU) == IEU_ACTIVE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_IEU);
    }
    #endif // (BLE_IEU)
    
    #if (BLE_MPU)   
    if (ke_state_get(TASK_MPU) == MPU_ACTIVE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_MPU);
    }
    #endif // (BLE_MPU)
    
	#if (BLE_WPT_CLIENT)
    prf_task_id = KE_BUILD_ID(TASK_WPTC, conidx);
    if (ke_state_get(prf_task_id) != WPTC_IDLE)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, prf_task_id);
    }
    #endif //(BLE_WPT_CLIENT)

    #if (BLE_WPTS)
    if (ke_state_get(TASK_WPTS) == WPTS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_WPTS);
    }
    #endif //(BLE_WPTS)

    #if (BLE_UDS_SERVER)
    if (ke_state_get(TASK_UDSS) >= UDSS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_UDSS);
    }
    #endif // (BLE_UDS_SERVER)
    
    #if (BLE_WSS_SERVER)
    if (ke_state_get(TASK_WSSS) >= WSSS_CONNECTED)
    {
        gapc_send_disconect_ind(conidx, reason, conhdl, TASK_WSSS);
    }
    #endif // (BLE_WSS_SERVER)
    
}