示例#1
0
文件: blpc_task.c 项目: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref BLPC_CFG_INDNTF_REQ message.
 * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 blpc_cfg_indntf_req_handler(ke_msg_id_t const msgid,
                                       struct blpc_cfg_indntf_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint16_t cfg_hdl = 0x0000;
    // Get the address of the environment
    struct blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc);

    if(param->conhdl == gapc_get_conhdl(blpc_env->con_info.conidx))
    {
        //get handle of the configuration characteristic to set and check if value matches property
        switch(param->char_code)
        {
            case BPS_BP_MEAS_CODE://can only IND
                cfg_hdl = blpc_env->bps.descs[BLPC_DESC_BP_MEAS_CLI_CFG].desc_hdl;
                if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                     (param->cfg_val == PRF_CLI_START_IND)))
                {
                    blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM);
                }
                break;

            case BPS_INTERM_CP_CODE://can only NTF
                cfg_hdl = blpc_env->bps.descs[BLPC_DESC_IC_MEAS_CLI_CFG].desc_hdl;
                if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                     (param->cfg_val == PRF_CLI_START_NTF)))
                {
                    blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM);
                }
                break;

            default:
                //let app know that one of the request params is incorrect
                blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM);
                return (KE_MSG_CONSUMED);
        }

        //if we get here, then the APP request looks OK

        //check if the handle value exists
        if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
        {
            // Send GATT Write Request
            prf_gatt_write_ntf_ind(&blpc_env->con_info, cfg_hdl, param->cfg_val);
        }
        else
        {
            blpc_error_ind_send(blpc_env, PRF_ERR_INEXISTENT_HDL);
        }
    }
    else
    {
        blpc_error_ind_send(blpc_env, PRF_ERR_INVALID_PARAM);
    }

    return (KE_MSG_CONSUMED);
}
示例#2
0
文件: glpc_task.c 项目: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GLPC_REGISTER_REQ message.
 * When receiving this request, Glucose collector register to measurement notifications
 * and RACP indications.
 *
 * @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 glpc_register_req_handler(ke_msg_id_t const msgid,
                                     struct glpc_register_req const *param,
                                     ke_task_id_t const dest_id,
                                     ke_task_id_t const src_id)
{
    uint8_t status = PRF_ERR_OK;
    // Get the address of the environment
    struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc);

    // check if collector enabled
    if(param->conhdl == gapc_get_conhdl(glpc_env->con_info.conidx))
    {
        // check if client characteristics are present
        if ((glpc_env->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE)
            || (glpc_env->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE)
            || ((param->meas_ctx_en)
                && (glpc_env->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl == ATT_INVALID_HANDLE)))
        {
            status = PRF_ERR_INEXISTENT_HDL;
        }
    }
    else
    {
        status = PRF_ERR_REQ_DISALLOWED;
    }

    if(status == PRF_ERR_OK)
    {
        // register to notification
        prf_gatt_write_ntf_ind(&(glpc_env->con_info),
                                 glpc_env->gls.descs[GLPC_DESC_MEAS_CLI_CFG].desc_hdl,
                                 PRF_CLI_START_NTF);
        glpc_env->last_uuid_req = GLPC_DESC_MEAS_CLI_CFG;

        // save if measurement context notification should be register in an unused variable
        glpc_env->last_char_code = param->meas_ctx_en;
    }
    // inform application that request cannot be performed
    else
    {
        struct glpc_register_cfm * cfm = KE_MSG_ALLOC(GLPC_REGISTER_CFM,
                                                      glpc_env->con_info.appid, dest_id,
                                                      glpc_register_cfm);
        // set error status
        cfm->conhdl = param->conhdl;
        cfm->status = status;

        ke_msg_send(cfm);
    }


    return (KE_MSG_CONSUMED);
}
示例#3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref QPPC_CFG_INDNTF_REQ message.
 * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 qppc_cfg_indntf_req_handler(ke_msg_id_t const msgid,
                                       struct qppc_cfg_indntf_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint8_t status = PRF_ERR_OK;
    uint16_t cfg_hdl = 0x0000;

    // Get the address of the environment
    struct qppc_env_tag *qppc_env = PRF_CLIENT_GET_ENV(dest_id, qppc);

    do {
        if(param->conhdl != qppc_env->con_info.conhdl)
        {
            status = PRF_ERR_INVALID_PARAM;
            break;
        }

        if(!(param->char_code < qppc_env->nb_char))
        {
            status = PRF_ERR_INVALID_PARAM;
            break;
        }

        if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                (param->cfg_val == PRF_CLI_START_NTF)))
        {
            status = PRF_ERR_INVALID_PARAM;
            break;
        }

        //get handle of the configuration characteristic to set and check if value matches property
        cfg_hdl = qppc_env->qpps.descs[param->char_code].desc_hdl;
        if (cfg_hdl == ATT_INVALID_SEARCH_HANDLE)
        {
            status = PRF_ERR_INEXISTENT_HDL;
            break;
        }

        qppc_env->last_char_code = param->char_code;
        // Send GATT Write Request
        prf_gatt_write_ntf_ind(&qppc_env->con_info, cfg_hdl, param->cfg_val);
    } while(0);

    if (status != PRF_ERR_OK)
    {
        qppc_error_ind_send(qppc_env, status);
    }

    return (KE_MSG_CONSUMED);
}
示例#4
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HOGPBH_CFG_INDNTF_REQ message.
 * It allows configuration of the peer ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 hogpbh_cfg_ntf_req_handler(ke_msg_id_t const msgid,
                                         struct hogpbh_cfg_ntf_req const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id)
{
    // Descriptor handle
    uint16_t cfg_hdl;
    // Status
    uint8_t status = PRF_ERR_INVALID_PARAM;
    // Descriptor Code
    uint8_t desc_code = param->desc_code & ~HOGPBH_DESC_MASK;
    // Get the address of the environment
    struct hogpbh_env_tag *hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh);

    // Save the attribute read code
    hogpbh_env->last_char_code = param->desc_code;

    if((param->conhdl == hogpbh_env->con_info.conhdl) &&
       (param->hids_nb < HOGPBH_NB_HIDS_INST_MAX) &&
       (desc_code < HOGPBH_DESC_MAX))
    {
        // Check value to write
        if((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF))
        {
            cfg_hdl = hogpbh_env->hids[param->hids_nb].descs[desc_code].desc_hdl;

            // Check if the handle value exists
            if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
            {
                // Send GATT Write Request
                prf_gatt_write_ntf_ind(&hogpbh_env->con_info, cfg_hdl, param->ntf_cfg);

                status = PRF_ERR_OK;
            }
            else
            {
                status = PRF_ERR_INEXISTENT_HDL;
            }
        }
    }

    if (status != PRF_ERR_OK)
    {
        hogpbh_char_req_rsp_send(hogpbh_env, HOGPBH_WR_CHAR_RSP, status);
    }

    return (KE_MSG_CONSUMED);
}
示例#5
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref BASC_BATT_LEVEL_NTF_CFG_REQ message.
 * It allows configuration of the peer ntf/stop characteristic for Battery Level Characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 basc_batt_level_ntf_cfg_req_handler(ke_msg_id_t const msgid,
                                               struct basc_batt_level_ntf_cfg_req const *param,
                                               ke_task_id_t const dest_id,
                                               ke_task_id_t const src_id)
{
    // Descriptor handle
    uint16_t cfg_hdl;
    // Get the address of the environment
    struct basc_env_tag *basc_env = PRF_CLIENT_GET_ENV(dest_id, basc);

    if((param->conhdl == basc_env->con_info.conhdl) &&
       (param->bas_nb < BASC_NB_BAS_INSTANCES_MAX))
    {
        cfg_hdl = basc_env->bas[param->bas_nb].descs[BAS_DESC_BATT_LEVEL_CFG].desc_hdl;

        // Check value to write
        if(!((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF)))
        {
            basc_error_ind_send(basc_env, PRF_ERR_INVALID_PARAM);
        }
        else
        {
            // Check if the handle value exists
            if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
            {
                // Send GATT Write Request
                prf_gatt_write_ntf_ind(&basc_env->con_info, cfg_hdl, param->ntf_cfg);
            }
            else
            {
                basc_error_ind_send(basc_env, PRF_ERR_INEXISTENT_HDL);
            }
        }
    }
    else
    {
        basc_error_ind_send(basc_env, PRF_ERR_INVALID_PARAM);
    }

    return (KE_MSG_CONSUMED);
}
示例#6
0
文件: tipc_task.c 项目: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPC_CT_NTF_CFG_REQ message.
 * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 tipc_ct_ntf_cfg_req_handler(ke_msg_id_t const msgid,
                                       struct tipc_ct_ntf_cfg_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint16_t cfg_hdl = 0x0000;
    // Get the address of the environment
    struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc);

    if(param->conhdl == gapc_get_conhdl(tipc_env->con_info.conidx))
    {
        cfg_hdl = tipc_env->cts.descs[TIPC_DESC_CTS_CURR_TIME_CLI_CFG].desc_hdl;

        //Only NTF
        if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||(param->cfg_val == PRF_CLI_START_NTF)))
        {
            tipc_error_ind_send(tipc_env, PRF_ERR_INVALID_PARAM);
        }
        else
        {
            //check if the handle value exists
            if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
            {
                // Send GATT Write Request
                prf_gatt_write_ntf_ind(&tipc_env->con_info, cfg_hdl, param->cfg_val);
            }
            else
            {
                tipc_error_ind_send(tipc_env, PRF_ERR_INEXISTENT_HDL);
            }
        }
    }
    else
    {
        tipc_error_ind_send(tipc_env, PRF_ERR_INVALID_PARAM);
    }

    return (KE_MSG_CONSUMED);
}
示例#7
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref SCPPC_SCAN_REFRESH_NTF_CFG_REQ message.
 * It allows configuration of the peer ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 scppc_scan_refresh_ntf_cfg_req_handler(ke_msg_id_t const msgid,
                                                  struct scppc_scan_refresh_ntf_cfg_req const *param,
                                                  ke_task_id_t const dest_id,
                                                  ke_task_id_t const src_id)
{
    uint16_t cfg_hdl = 0x0000;
    // Get the address of the environment
    struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc);

    if(param->conhdl == gapc_get_conhdl(scppc_env->con_info.conidx))
    {
        cfg_hdl = scppc_env->scps.descs[SCPPC_DESC_SCAN_REFRESH_CFG].desc_hdl;

        //check value to write
        if(!((param->ntf_cfg == PRF_CLI_STOP_NTFIND) || (param->ntf_cfg == PRF_CLI_START_NTF)))
        {
            scppc_error_ind_send(scppc_env, PRF_ERR_INVALID_PARAM);
        }
        else
        {
            //check if the handle value exists
            if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
            {
                // Send GATT Write Request
                prf_gatt_write_ntf_ind(&scppc_env->con_info, cfg_hdl, param->ntf_cfg);
            }
            else
            {
                scppc_error_ind_send(scppc_env, PRF_ERR_INEXISTENT_HDL);
            }
        }
    }
    else
    {
        scppc_error_ind_send(scppc_env, PRF_ERR_INVALID_PARAM);
    }

    return (KE_MSG_CONSUMED);
}
示例#8
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HRPC_CFG_INDNTF_REQ message.
 * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 hrpc_cfg_indntf_req_handler(ke_msg_id_t const msgid,
                                       struct hrpc_cfg_indntf_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint16_t cfg_hdl = 0x0000;
    // Get the address of the environment
    struct hrpc_env_tag *hrpc_env = PRF_CLIENT_GET_ENV(dest_id, hrpc);

    if(param->conhdl == hrpc_env->con_info.conhdl)
    {
        //get handle of the configuration characteristic to set and check if value matches property
        cfg_hdl = hrpc_env->hrs.descs[HRPC_DESC_HR_MEAS_CLI_CFG].desc_hdl;
        if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                (param->cfg_val == PRF_CLI_START_NTF)))
        {
            hrpc_error_ind_send(hrpc_env, PRF_ERR_INVALID_PARAM);
        }

        //if we get here, then the APP request looks OK

        //check if the handle value exists
        if (cfg_hdl != ATT_INVALID_SEARCH_HANDLE)
        {
            // Send GATT Write Request
            prf_gatt_write_ntf_ind(&hrpc_env->con_info, cfg_hdl, param->cfg_val);
        }
        else
        {
            hrpc_error_ind_send(hrpc_env, PRF_ERR_INEXISTENT_HDL);
        }
    }
    else
    {
        hrpc_error_ind_send(hrpc_env, PRF_ERR_INVALID_PARAM);
    }

    return (KE_MSG_CONSUMED);
}
示例#9
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HTPC_CFG_INDNTF_REQ message.
 * It allows configuration of the peer ind/ntf/stop characteristic for a specified characteristic.
 * Will return an error code if that cfg char does not exist.
 * @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 htpc_cfg_indntf_req_handler(ke_msg_id_t const msgid,
                                       struct htpc_cfg_indntf_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    // Client Characteristic Configuration Descriptor Handle
    uint16_t cfg_hdl = 0x0000;
    // Status
    uint8_t status = PRF_ERR_OK;
    // Get the address of the environment
    struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc);

    if(param->conhdl == htpc_env->con_info.conhdl)
    {
        switch(param->char_code)
        {
            case HTPC_CHAR_HTS_TEMP_MEAS://can only IND
                cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_TEMP_MEAS_CLI_CFG].desc_hdl;
                if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                     (param->cfg_val == PRF_CLI_START_IND)))
                {
                    status = PRF_ERR_INVALID_PARAM;
                }
                break;

            case HTPC_CHAR_HTS_MEAS_INTV://can only IND
                cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_MEAS_INTV_CLI_CFG].desc_hdl;
                if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                     (param->cfg_val == PRF_CLI_START_IND)))
                {
                    status = PRF_ERR_INVALID_PARAM;
                }
                break;

            case HTPC_CHAR_HTS_INTM_TEMP://can only NTF
                cfg_hdl = htpc_env->hts.descs[HTPC_DESC_HTS_INTM_MEAS_CLI_CFG].desc_hdl;
                if(!((param->cfg_val == PRF_CLI_STOP_NTFIND)||
                     (param->cfg_val == PRF_CLI_START_NTF)))
                {
                    status = PRF_ERR_INVALID_PARAM;
                }
                break;

            default:
                //Let app know that one of the request params is incorrect
                status = PRF_ERR_INVALID_PARAM;
                break;
        }

        if (status == PRF_ERR_OK)
        {
            //Check if the handle value exists
            if ((cfg_hdl == ATT_INVALID_SEARCH_HANDLE))
            {
                status = PRF_ERR_INEXISTENT_HDL;
            }
            else
            {
                // Send GATT Write Request
                prf_gatt_write_ntf_ind(&htpc_env->con_info, cfg_hdl, param->cfg_val);
            }
        }
    }
    else
    {
        status = PRF_ERR_INVALID_PARAM;
    }

    if (status != PRF_ERR_OK)
    {
        htpc_error_ind_send(htpc_env, status);
    }

    return (KE_MSG_CONSUMED);
}
示例#10
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref CSCPC_CFG_NTFIND_CMD message.
 * @param[in] msgid Id of the message received.
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance.
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int cscpc_cfg_ntfind_cmd_handler(ke_msg_id_t const msgid,
                                        struct cscpc_cfg_ntfind_cmd *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    // Message status
    uint8_t msg_status = KE_MSG_CONSUMED;
    // Get the address of the environment
    struct cscpc_env_tag *cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc);

    if (cscpc_env != NULL)
    {
        // Status
        uint8_t status     = PRF_ERR_OK;
        // Handle
        uint16_t handle    = ATT_INVALID_SEARCH_HANDLE;

        do
        {
            ASSERT_ERR(ke_state_get(dest_id) != CSCPC_IDLE);

            // Check the provided connection handle
            if (param->conhdl != cscpc_env->con_info.conhdl)
            {
                status = PRF_ERR_INVALID_PARAM;
                break;
            }

            if (ke_state_get(dest_id) == CSCPC_BUSY)
            {
                // Another procedure is pending, keep the command for later
                msg_status = KE_MSG_SAVED;
                // Status is PRF_ERR_OK, no message will be sent to the application
                break;
            }

            // state = CSCPC_CONNECTED
            ASSERT_ERR(cscpc_env->operation == NULL);

            switch(param->desc_code)
            {
                // Write CSC Measurement Characteristic Client Char. Cfg. Descriptor Value
                case (CSCPC_RD_WR_CSC_MEAS_CFG):
                {
                    if (param->ntfind_cfg <= PRF_CLI_START_NTF)
                    {
                        handle = cscpc_env->cscs.descs[CSCPC_DESC_CSC_MEAS_CL_CFG].desc_hdl;

                        // The descriptor is mandatory
                        ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE);
                    }
                    else
                    {
                        status = PRF_ERR_INVALID_PARAM;
                    }
                } break;

                // Write SC Control Point Characteristic Client Char. Cfg. Descriptor Value
                case (CSCPC_RD_WR_SC_CTNL_PT_CFG):
                {
                    if ((param->ntfind_cfg == PRF_CLI_STOP_NTFIND) ||
                        (param->ntfind_cfg == PRF_CLI_START_IND))
                    {
                        handle = cscpc_env->cscs.descs[CSCPC_DESC_SC_CTNL_PT_CL_CFG].desc_hdl;

                        if (handle == ATT_INVALID_SEARCH_HANDLE)
                        {
                            // The descriptor has not been found.
                            status = PRF_ERR_INEXISTENT_HDL;
                        }
                    }
                    else
                    {
                        status = PRF_ERR_INVALID_PARAM;
                    }
                } break;

                default:
                {
                    status = PRF_ERR_INVALID_PARAM;
                } break;
            }
        } while (0);

        if (status == PRF_ERR_OK)
        {
            ASSERT_ERR(handle != ATT_INVALID_SEARCH_HANDLE);

            // Set the operation code
            param->operation = CSCPC_CFG_NTF_IND_OP_CODE;

            // Store the command structure
            cscpc_env->operation   = param;
            msg_status = KE_MSG_NO_FREE;

            // Go to the Busy state
            ke_state_set(dest_id, CSCPC_BUSY);

            // Send GATT Write Request
            prf_gatt_write_ntf_ind(&cscpc_env->con_info, handle, param->ntfind_cfg);
        }
        else
        {
            cscpc_send_cmp_evt(cscpc_env, CSCPC_CFG_NTF_IND_OP_CODE, status);
        }
    }
    else
    {
        cscpc_send_no_conn_cmp_evt(dest_id, src_id, param->conhdl, CSCPC_CFG_NTF_IND_OP_CODE);
    }

    return (int)msg_status;
}
示例#11
0
文件: glpc_task.c 项目: imGit/DA14580
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_CMP_EVT message.
 * This generic event is received for different requests, so need to keep track.
 * @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_cmp_evt_handler(ke_msg_id_t const msgid,
                                struct gattc_cmp_evt const *param,
                                ke_task_id_t const dest_id,
                                ke_task_id_t const src_id)
{
    uint8_t state = ke_state_get(dest_id);
    uint8_t status;
    // Get the address of the environment
    struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc);

    if(state == GLPC_DISCOVERING)
    {
        if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)||
                (param->status == ATT_ERR_NO_ERROR))
        {
            // service start/end handles has been received
            if(glpc_env->last_uuid_req == ATT_SVC_GLUCOSE)
            {
                // check if service handles are not ok
                if(glpc_env->gls.svc.shdl == ATT_INVALID_HANDLE)
                {
                    // stop discovery procedure.
                    glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING);
                }
                //too many services found only one such service should exist
                else if(glpc_env->nb_svc != 1)
                {
                    // stop discovery procedure.
                    glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                }
                else
                {
                    //discover all GLS characteristics
                    prf_disc_char_all_send(&(glpc_env->con_info), &(glpc_env->gls.svc));
                    glpc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                }
            }
            else if(glpc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
            {
                status = prf_check_svc_char_validity(GLPC_CHAR_MAX, glpc_env->gls.chars,
                        glpc_gls_char);

                // Check for characteristic properties.
                if(status == PRF_ERR_OK)
                {
                    glpc_env->last_uuid_req = ATT_INVALID_HANDLE;
                    glpc_env->last_char_code = glpc_gls_char_desc[GLPC_DESC_MEAS_CLI_CFG].char_code;

                    //Discover Glucose Measurement Char. Descriptor - Mandatory
                    prf_disc_char_desc_send(&(glpc_env->con_info),
                            &(glpc_env->gls.chars[glpc_env->last_char_code]));
                }
                else
                {
                    // Stop discovery procedure.
                    glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status);
                }
            }
            else
            {
                //If Glucose Measurement Context Char. found, discover its descriptor
                if ((glpc_env->gls.chars[GLPC_CHAR_MEAS_CTX].char_hdl != ATT_INVALID_HANDLE) &&
                        (glpc_env->last_char_code == GLPC_CHAR_MEAS))
                {
                    glpc_env->last_char_code = GLPC_CHAR_MEAS_CTX;
                    //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory
                    prf_disc_char_desc_send(&(glpc_env->con_info),
                            &(glpc_env->gls.chars[glpc_env->last_char_code]));
                }
                // discover Record access control point descriptor
                else if (glpc_env->last_char_code != GLPC_CHAR_RACP)
                {
                    glpc_env->last_char_code = GLPC_CHAR_RACP;
                    //Discover Intermediate Cuff Pressure Char. Descriptor - Mandatory
                    prf_disc_char_desc_send(&(glpc_env->con_info),
                            &(glpc_env->gls.chars[glpc_env->last_char_code]));
                }
                else
                {
                    status = prf_check_svc_char_desc_validity(GLPC_DESC_MAX,
                            glpc_env->gls.descs,
                            glpc_gls_char_desc,
                            glpc_env->gls.chars);

                    glpc_enable_cfm_send(glpc_env, &glpc_env->con_info, status);
                }
            }
        }
    }
    else if (state == GLPC_CONNECTED)
    {
        switch(param->req_type)
        {
            case GATTC_WRITE:
            case GATTC_WRITE_NO_RESPONSE:
            {
                // RACP write done.
                if(glpc_env->last_uuid_req == ATT_CHAR_REC_ACCESS_CTRL_PT)
                {
                    // an error occurs while writing RACP command
                    if(param->status != PRF_ERR_OK)
                    {
                        struct glpc_racp_rsp * rsp = KE_MSG_ALLOC(GLPC_RACP_RSP,
                                glpc_env->con_info.appid, dest_id,
                                glpc_racp_rsp);

                        // retrieve connection handle
                        rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx);
                        // set error status
                        rsp->status = param->status;

                        // stop timer.
                        ke_timer_clear(GLPC_RACP_REQ_TIMEOUT, dest_id);

                        ke_msg_send(rsp);
                        glpc_env->last_uuid_req = 0;
                    }
                }
                else
                {
                    bool finished = false;

                    // Restore if measurement context notification should be register in from
                    // unused variable
                    bool meas_ctx_en = glpc_env->last_char_code;

                    // Registration succeed
                    if(param->status == PRF_ERR_OK)
                    {
                        // Glucose measurement  notification registration done
                        if(glpc_env->last_uuid_req == GLPC_DESC_MEAS_CLI_CFG)
                        {
                            // register to RACP indications
                            prf_gatt_write_ntf_ind(&(glpc_env->con_info),
                                    glpc_env->gls.descs[GLPC_DESC_RACP_CLI_CFG].desc_hdl,
                                    PRF_CLI_START_IND);
                            glpc_env->last_uuid_req = GLPC_DESC_RACP_CLI_CFG;
                        }
                        // Record access control point indication registration done
                        // Register to Glucose Measurement Context notifications if requested.
                        else if((glpc_env->last_uuid_req == GLPC_DESC_RACP_CLI_CFG)
                                && meas_ctx_en)
                        {
                            // register to Glucose Measurement Context notifications
                            prf_gatt_write_ntf_ind(&(glpc_env->con_info),
                                    glpc_env->gls.descs[GLPC_DESC_MEAS_CTX_CLI_CFG].desc_hdl,
                                    PRF_CLI_START_NTF);
                            glpc_env->last_uuid_req = GLPC_DESC_MEAS_CTX_CLI_CFG;
                        }
                        // All registration done
                        else
                        {
                            // indication/notification registration finished
                            finished = true;
                        }
                    }

                    // send status if registration done or if an error occurs.
                    if((param->status != PRF_ERR_OK) || (finished))
                    {
                        struct glpc_register_cfm * cfm = KE_MSG_ALLOC(GLPC_REGISTER_CFM,
                                glpc_env->con_info.appid, dest_id,
                                glpc_register_cfm);
                        // set error status
                        cfm->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx);
                        cfm->status = param->status;

                        ke_msg_send(cfm);
                    }
                }
            }
            break;

            case GATTC_READ:
            {
                if(param->status != GATT_ERR_NO_ERROR)
                {
                    struct glpc_read_features_rsp * rsp = KE_MSG_ALLOC(GLPC_READ_FEATURES_RSP,
                            glpc_env->con_info.appid, dest_id,
                            glpc_read_features_rsp);

                    // set connection handle
                    rsp->conhdl = gapc_get_conhdl(glpc_env->con_info.conidx);
                    // set error status
                    rsp->status = param->status;

                    ke_msg_send(rsp);
                }
            }
            break;
            default: break;
        }
    }

    return (KE_MSG_CONSUMED);
}