Exemplo n.º 1
0
/**
 ****************************************************************************************
 * @brief Enable the Proximity Monitor role, used after connection.
 * @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 proxm_enable_req_handler(ke_msg_id_t const msgid,
                                    struct proxm_enable_req const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Device Information Service Client Role Task Environment
    struct proxm_env_tag *proxm_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conidx = gapc_get_conidx(param->conhdl);
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status =  PRF_CLIENT_ENABLE(con_info, param, proxm);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm);

        // Discovery connection
        if (param->con_type == PRF_CON_DISCOVERY)
        {
            // Start discovering LLS on peer
            prf_disc_svc_send(&proxm_env->con_info, ATT_SVC_LINK_LOSS);

            proxm_env->last_uuid_req     = ATT_SVC_LINK_LOSS;
            proxm_env->last_svc_req      = ATT_SVC_LINK_LOSS;

            // Set state to discovering
            ke_state_set(dest_id, PROXM_DISCOVERING);
        }
        else
        {
            //copy over data that has been stored
            proxm_env->ias     = param->ias;
            proxm_env->lls     = param->lls;
            proxm_env->txps    = param->txps;

            //send confirmation of enable request to application
            proxm_enable_cfm_send(proxm_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        proxm_enable_cfm_send(NULL, &con_info, status);
    }

    // message is consumed
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 2
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref TIPC_ENABLE_REQ message.
 * The handler enables the Time Profile Client Role.
 * @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_enable_req_handler(ke_msg_id_t const msgid,
                                   struct tipc_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Battery Service Client Role Task Environment
    struct tipc_env_tag *tipc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conidx = gapc_get_conidx(param->conhdl);
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status = PRF_CLIENT_ENABLE(con_info, param, tipc);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc);

        //config connection, start discovering
        if(param->con_type == PRF_CON_DISCOVERY)
        {
            //start discovering CTS on peer
            prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_CURRENT_TIME);

            tipc_env->last_uuid_req = ATT_SVC_CURRENT_TIME;
            tipc_env->last_svc_req  = ATT_SVC_CURRENT_TIME;

            // Go to DISCOVERING state
            ke_state_set(dest_id, TIPC_DISCOVERING);
        }
        //normal connection, get saved att details
        else
        {
            tipc_env->cts = param->cts;
            tipc_env->ndcs = param->ndcs;
            tipc_env->rtus = param->rtus;

            //send APP confirmation that can start normal connection
            tipc_enable_cfm_send(tipc_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        // Send confirmation that can start normal connection
        tipc_enable_cfm_send(NULL, &con_info, status);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref BASC_ENABLE_REQ message.
 * The handler enables the Battery Service Client Role.
 * @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_enable_req_handler(ke_msg_id_t const msgid,
                                   struct basc_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Battery Service Client Role Task Environment
    struct basc_env_tag *basc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conhdl = param->conhdl;
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status = PRF_CLIENT_ENABLE(con_info, param, basc);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        basc_env = PRF_CLIENT_GET_ENV(dest_id, basc);

        // Config connection, start discovering
        if(param->con_type == PRF_CON_DISCOVERY)
        {
            // Start discovering BAS on peer
            prf_disc_svc_send(&(basc_env->con_info), ATT_SVC_BATTERY_SERVICE);

            basc_env->last_uuid_req = ATT_SVC_BATTERY_SERVICE;

            // Go to DISCOVERING state
            ke_state_set(dest_id, BASC_DISCOVERING);
        }
        // Normal connection, get saved att details
        else
        {
            memcpy(&basc_env->bas[0], &param->bas[0], BASC_NB_BAS_INSTANCES_MAX*sizeof(struct bas_content));
            basc_env->bas_nb = param->bas_nb;

            // Send APP confirmation that can start normal connection to TH
            basc_enable_cfm_send(basc_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        // An error has been raised during the process, env is NULL and won't be handled
        basc_enable_cfm_send(NULL, &con_info, status);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 4
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HTPC_ENABLE_REQ message.
 * The handler enables the Health Thermometer Profile Collector Role.
 * @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_enable_req_handler(ke_msg_id_t const msgid,
                                   struct htpc_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Health Thermometer Profile Collector Role Task Environment
    struct htpc_env_tag *htpc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conhdl = param->conhdl;
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status = PRF_CLIENT_ENABLE(con_info, param, htpc);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc);

        //Config connection, start discovering
        if(param->con_type == PRF_CON_DISCOVERY)
        {
            htpc_env->last_uuid_req = ATT_SVC_HEALTH_THERMOM;

            // Start discovering HTS on peer
            prf_disc_svc_send(&htpc_env->con_info, ATT_SVC_HEALTH_THERMOM);

            // Go to DISCOVERING state
            ke_state_set(dest_id, HTPC_DISCOVERING);
        }
        // Normal connection, get saved att details
        else
        {
            htpc_env->hts = param->hts;

            //send APP confirmation that can start normal connection to TH
            htpc_enable_cfm_send(htpc_env, &htpc_env->con_info, PRF_ERR_OK);
        }
    }
    else
    {
        // An error has been raised during the process, hts is NULL and won't be handled
        htpc_enable_cfm_send(NULL, &con_info, status);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 5
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HOGPBH_ENABLE_REQ message.
 * The handler enables the HID Over GATT Profile Boot Host Role.
 * @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_enable_req_handler(ke_msg_id_t const msgid,
                                   struct hogpbh_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // HID Over GATT Profile Client Role Task Environment
    struct hogpbh_env_tag *hogpbh_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conhdl = param->conhdl;
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status =  PRF_CLIENT_ENABLE(con_info, param, hogpbh);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        hogpbh_env = PRF_CLIENT_GET_ENV(dest_id, hogpbh);

        //config connection, start discovering
        if(param->con_type == PRF_CON_DISCOVERY)
        {
            //start discovering HIDS on peer
            prf_disc_svc_send(&(hogpbh_env->con_info), ATT_SVC_HID);

            hogpbh_env->last_uuid_req = ATT_SVC_HID;

            // Go to DISCOVERING state
            ke_state_set(dest_id, HOGPBH_DISCOVERING);
        }
        //normal connection, get saved att details
        else
        {
            memcpy(&hogpbh_env->hids[0], &param->hids[0], HOGPBH_NB_HIDS_INST_MAX*sizeof(struct hids_content));
            hogpbh_env->hids_nb = param->hids_nb;

            //send APP confirmation that can start normal connection to TH
            hogpbh_enable_cfm_send(hogpbh_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        hogpbh_enable_cfm_send(NULL, &con_info, status);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 6
0
/**
 ****************************************************************************************
 * @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 tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc);
    if(state == TIPC_DISCOVERING)
    {
        if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)||
                (param->status == ATT_ERR_NO_ERROR))
        {
            // Currently Discovering Current Time service characteristics.
            if(tipc_env->last_svc_req  == ATT_SVC_CURRENT_TIME)
            {
                // service start/end handles has been received
                if(tipc_env->last_uuid_req == ATT_SVC_CURRENT_TIME)
                {
                    // check if service handles are not ok
                    if (tipc_env->cts.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING);
                    }
                    //too many services found only one such service should exist
                    else if(tipc_env->nb_svc != 1)
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                    }
                    // check if service handles are ok
                    else
                    {
                        //discover all CTS characteristics
                        prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->cts.svc));
                        tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }

                }
                else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(TIPC_CHAR_CTS_MAX, tipc_env->cts.chars,
                            tipc_cts_char);

                    //  check for characteristic properties.
                    if(status == PRF_ERR_OK)
                    {
                        tipc_env->last_uuid_req = ATT_INVALID_HANDLE;
                        tipc_env->last_char_code = TIPC_CHAR_CTS_CURR_TIME;
                        //request all service characteristic description for CTS
                        prf_disc_char_desc_send(&(tipc_env->con_info), &(tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME]));
                    }
                    else
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                    }
                }
                else
                {
                    status = prf_check_svc_char_desc_validity(TIPC_DESC_CTS_MAX,
                            tipc_env->cts.descs,
                            tipc_cts_char_desc,
                            tipc_env->cts.chars);

                    if(status == PRF_ERR_OK)
                    {
                        // reset number of services
                        tipc_env->nb_svc = 0;

                        //start discovering NDCS on peer
                        prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_NEXT_DST_CHANGE);

                        tipc_env->last_uuid_req = ATT_SVC_NEXT_DST_CHANGE;
                        tipc_env->last_svc_req  = ATT_SVC_NEXT_DST_CHANGE;
                    }
                    else
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                    }
                }
            }

            // Currently Next DST Change service characteristics.
            else if(tipc_env->last_svc_req  == ATT_SVC_NEXT_DST_CHANGE)
            {
                // service start/end handles has been received
                if(tipc_env->last_uuid_req == ATT_SVC_NEXT_DST_CHANGE)
                {
                    if (tipc_env->ndcs.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        // reset number of services
                        tipc_env->nb_svc = 0;

                        //start discovering RTUS on peer
                        prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE);

                        tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE;
                        tipc_env->last_svc_req  = ATT_SVC_REF_TIME_UPDATE;
                    }
                    //too many services found only one such service should exist
                    else if(tipc_env->nb_svc != 1)
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                    }
                    // check if service handles are ok
                    else
                    {
                        //discover all NDCS characteristics
                        prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->ndcs.svc));
                        tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }
                }
                else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(TIPC_CHAR_NDCS_MAX, tipc_env->ndcs.chars,
                            tipc_ndcs_char);

                    //  check for characteristic properties.
                    if(status == PRF_ERR_OK)
                    {
                        // reset number of services
                        tipc_env->nb_svc = 0;

                        //start discovering RTUS on peer
                        prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE);

                        tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE;
                        tipc_env->last_svc_req  = ATT_SVC_REF_TIME_UPDATE;
                    }
                    else
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                    }
                }
            }

            // Currently Reference Time Update service characteristics.
            else if(tipc_env->last_svc_req  == ATT_SVC_REF_TIME_UPDATE)
            {
                // service start/end handles has been received
                if(tipc_env->last_uuid_req == ATT_SVC_REF_TIME_UPDATE)
                {
                    if (tipc_env->rtus.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        // send app the details about the discovered TIPS DB to save
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK);
                    }
                    //too many services found only one such service should exist
                    else if(tipc_env->nb_svc != 1)
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                    }
                    // check if service handles are ok
                    else
                    {
                        //discover all RTUS characteristics
                        prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->rtus.svc));
                        tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }
                }
                else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(TIPC_CHAR_RTUS_MAX, tipc_env->rtus.chars,
                            tipc_rtus_char);

                    //  check for characteristic properties.
                    if(status == PRF_ERR_OK)
                    {
                        // send app the details about the discovered TIPS DB to save
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK);
                    }
                    else
                    {
                        // stop discovery procedure.
                        tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                    }
                }
            }
        }
    }
    else if(state == TIPC_CONNECTED)
    {
        switch(param->req_type)
        {
            case GATTC_WRITE:
            case GATTC_WRITE_NO_RESPONSE:
            {
                struct tipc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(TIPC_WR_CHAR_RSP,
                        tipc_env->con_info.appid, dest_id, tipc_wr_char_rsp);

                wr_cfm->conhdl    = gapc_get_conhdl(tipc_env->con_info.conidx);
                //it will be a GATT status code
                wr_cfm->status    = param->status;
                // send the message
                ke_msg_send(wr_cfm);
            }
            break;
            case GATTC_READ:
            {
                // an error occurs while reading peer attribute, inform app
                if(param->status != GATT_ERR_NO_ERROR)
                {
                    tipc_error_ind_send(tipc_env, param->status);
                }
            }
            break;
            default: break;
        }
    }
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 7
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref SCPPC_ENABLE_REQ message.
 * The handler enables the Scan Parameters Profile Client Role.
 * @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_enable_req_handler(ke_msg_id_t const msgid,
                                   struct scppc_enable_req const *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Scan Parameters Profile Client Role Task Environment
    struct scppc_env_tag *scppc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conidx = gapc_get_conidx(param->conhdl);
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status = PRF_CLIENT_ENABLE(con_info, param, scppc);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc);

        // Save Scan Interval Window value
        memcpy(&scppc_env->scan_intv_wd, &param->scan_intv_wd, sizeof(struct scan_intv_wd));

        // Config connection, start discovering
        if(param->con_type == PRF_CON_DISCOVERY)
        {
            //start discovering SCPS on peer
            prf_disc_svc_send(&(scppc_env->con_info), ATT_SVC_SCAN_PARAMETERS);

            scppc_env->last_uuid_req = ATT_SVC_SCAN_PARAMETERS;

            // Go to DISCOVERING state
            ke_state_set(dest_id, SCPPC_DISCOVERING);
        }
        // Normal connection, get saved att details
        else
        {
            scppc_env->scps = param->scps;

            if (scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].char_hdl != ATT_INVALID_HANDLE)
            {
                /* If connected to a bonded Scan Server, the Scan Client shall enable notifications of the
                 * Scan Refresh characteristic using the Client Characteristic Configuration descriptor.
                 */
                struct scppc_scan_refresh_ntf_cfg_req *req = KE_MSG_ALLOC(SCPPC_SCAN_REFRESH_NTF_CFG_REQ,
                                                                          dest_id, dest_id,
                                                                          scppc_scan_refresh_ntf_cfg_req);

                req->conhdl    = gapc_get_conhdl(scppc_env->con_info.conidx);
                req->ntf_cfg    = PRF_CLI_START_NTF;

                // send the message
                ke_msg_send(req);
            }
            else
            {
                // Write Scan Interval Windows value
                struct scppc_scan_intv_wd_wr_req * req = KE_MSG_ALLOC(SCPPC_SCAN_INTV_WD_WR_REQ,
                                                                      dest_id, dest_id,
                                                                      scppc_scan_intv_wd_wr_req);

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

                co_write16p(&req->scan_intv_wd.le_scan_intv, scppc_env->scan_intv_wd.le_scan_intv);
                co_write16p(&req->scan_intv_wd.le_scan_window, scppc_env->scan_intv_wd.le_scan_window);

                ke_msg_send(req);
            }


            scppc_enable_cfm_send(scppc_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        // An error has been raised during the process, scps is NULL and won't be handled
        scppc_enable_cfm_send(NULL, &con_info, status);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 8
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref CSCPC_ENABLE_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_enable_cmd_handler(ke_msg_id_t const msgid,
                                    struct cscpc_enable_cmd *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    // Status
    uint8_t status     = PRF_ERR_OK;
    // Message status
    uint8_t msg_status = KE_MSG_CONSUMED;
    // Cycling Speed and Cadence Profile Collector Role Task Environment
    struct cscpc_env_tag *cscpc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Check if the provided conhdl is valid
    if (gap_get_rec_idx(param->conhdl) != GAP_INVALID_CONIDX)
    {
        // Fill the Connection Information structure
        con_info.conhdl = param->conhdl;
        con_info.prf_id = dest_id;
        con_info.appid  = src_id;

        // Add an environment for the provided connection
        status = PRF_CLIENT_ENABLE(con_info, param, cscpc);
    }
    else
    {
        status = PRF_ERR_REQ_DISALLOWED;
    }

    if (status == PRF_ERR_OK)
    {
        // Get the newly created environment
        cscpc_env = PRF_CLIENT_GET_ENV(dest_id, cscpc);

        // Keep the connection info
        memcpy(&cscpc_env->con_info, &con_info, sizeof(struct prf_con_info));

        // Start discovering
        if (param->con_type == PRF_CON_DISCOVERY)
        {
            // Configure the environment for a discovery procedure
            cscpc_env->last_req  = ATT_SVC_CYCLING_SPEED_CADENCE;
            // Force the operation value
            param->operation     = CSCPC_ENABLE_OP_CODE;

            prf_disc_svc_send(&(cscpc_env->con_info), ATT_SVC_CYCLING_SPEED_CADENCE);

            // Keep the operation
            cscpc_env->operation = (void *)param;
            // Do not free the message
            msg_status = KE_MSG_NO_FREE;

            // Go to BUSY state
            ke_state_set(dest_id, CSCPC_BUSY);
        }
        // Bond information are provided
        else
        {
            // Keep the provided database content
            memcpy(&cscpc_env->cscs, &param->cscs, sizeof(struct cscpc_cscs_content));

            // Register in GATT for notifications/indications
            prf_register_atthdl2gatt(&cscpc_env->con_info, &cscpc_env->cscs.svc);

            // Send a complete event status to the application
            cscpc_send_cmp_evt(cscpc_env, CSCPC_ENABLE_OP_CODE, PRF_ERR_OK);
        }
    }
    else if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message will be forwarded towards the good task instance
        msg_status = KE_MSG_NO_FREE;
    }
    else
    {
        // The request is disallowed (profile already enabled for this connection, or not enough memory, ...)
        cscpc_send_no_conn_cmp_evt(dest_id, src_id, param->conhdl, CSCPC_ENABLE_OP_CODE);
    }

    return (int)msg_status;
}
Exemplo n.º 9
0
/**
 ****************************************************************************************
 * @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 = 0;
    // Get the address of the environment
    struct proxm_env_tag *proxm_env = PRF_CLIENT_GET_ENV(dest_id, proxm);

    if(state == PROXM_DISCOVERING)
    {
        if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)||
                (param->status == ATT_ERR_NO_ERROR))
        {
            //Currently discovering Link Loss Service
            if (proxm_env->last_svc_req == ATT_SVC_LINK_LOSS)
            {
                if (proxm_env->last_uuid_req == ATT_SVC_LINK_LOSS)
                {
                    if (proxm_env->lls.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING);
                    }
                    // Too many services found only one such service should exist
                    else if(proxm_env->nb_svc > 1)
                    {
                        // stop discovery procedure.
                        proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_MULTIPLE_SVC);
                    }
                    else
                    {
                        // Discover LLS characteristics
                        prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->lls.svc));

                        // Keep last UUID requested and for which service in env
                        proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }
                }
                else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(1, &proxm_env->lls.charact,
                                                         &proxm_lls_char);

                    if (status == PRF_ERR_OK)
                    {
                        proxm_env->nb_svc = 0;

                        // Start discovering TXPS on peer
                        prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_TX_POWER);

                        proxm_env->last_uuid_req = ATT_SVC_TX_POWER;
                        proxm_env->last_svc_req = ATT_SVC_TX_POWER;
                    }
                    else
                    {
                        // Stop discovery procedure.
                        proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status);
                    }

                }
            }

            //Currently discovering TX Power Service
            else if (proxm_env->last_svc_req == ATT_SVC_TX_POWER)
            {
                if (proxm_env->last_uuid_req == ATT_SVC_TX_POWER)
                {
                    // TXPS is optional
                    if (proxm_env->txps.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        proxm_env->nb_svc = 0;

                        // Start discovering IAS on peer
                        prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT);

                        proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT;
                        proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT;
                    }
                    else
                    {
                        // Discover TXPS characteristics
                        prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->txps.svc));

                        // Keep last UUID requested and for which service in env
                        proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }
                }
                else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(1, &proxm_env->txps.charact,
                                                         &proxm_txps_char);

                    if (status == PRF_ERR_OK)
                    {
                        proxm_env->nb_svc = 0;

                        // Start discovering IAS on peer
                        prf_disc_svc_send(&(proxm_env->con_info), ATT_SVC_IMMEDIATE_ALERT);

                        proxm_env->last_uuid_req = ATT_SVC_IMMEDIATE_ALERT;
                        proxm_env->last_svc_req = ATT_SVC_IMMEDIATE_ALERT;
                    }
                    else
                    {
                        // Stop discovery procedure.
                        proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status);
                    }

                }
            }

            //Currently discovering Immediate Alert Service
            else if (proxm_env->last_svc_req == ATT_SVC_IMMEDIATE_ALERT)
            {
                if (proxm_env->last_uuid_req == ATT_SVC_IMMEDIATE_ALERT)
                {
                    // IAS is optional
                    if (proxm_env->ias.svc.shdl == ATT_INVALID_HANDLE)
                    {
                        proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, PRF_ERR_OK);
                    }
                    else
                    {
                        // Discover IAS characteristics
                        prf_disc_char_all_send(&(proxm_env->con_info), &(proxm_env->ias.svc));

                        // Keep last UUID requested and for which service in env
                        proxm_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                    }
                }
                else if (proxm_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
                {
                    status = prf_check_svc_char_validity(1, &proxm_env->txps.charact,
                                                         &proxm_txps_char);

                    proxm_enable_cfm_send(proxm_env, &proxm_env->con_info, status);
                }
            }
        }
    }
    else if (state == PROXM_CONNECTED)
    {
        switch(param->req_type)
        {
        case GATTC_WRITE:
        case GATTC_WRITE_NO_RESPONSE:
        {
            proxm_write_char_rsp_send(proxm_env, param->status);
        }
        break;

        case GATTC_READ:
        {
            if(param->status != GATT_ERR_NO_ERROR)
            {
                // an error occurs while reading peer device attribute
                prf_client_att_info_rsp((prf_env_struct*) proxm_env, PROXM_RD_CHAR_RSP,
                                        param->status, NULL);
            }
        }
        break;
        default:
            break;
        }
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 10
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref ANPC_ENABLE_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 anpc_enable_cmd_handler(ke_msg_id_t const msgid,
                                   struct anpc_enable_cmd *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    // Status
    uint8_t status     = PRF_ERR_OK;
    // Message status
    uint8_t msg_status = KE_MSG_CONSUMED;
    // Alert Notification Profile Client Role Task Environment
    struct anpc_env_tag *anpc_env;
    // Connection Information
    struct prf_con_info con_info;

    // Check if the provided connection handle is valid
    if (gapc_get_conidx(param->conhdl) != GAP_INVALID_CONIDX)
    {
        // Fill the Connection Information structure
        con_info.conidx = gapc_get_conidx(param->conhdl);
        con_info.prf_id = dest_id;
        con_info.appid  = src_id;

        // Add an environment for the provided connection
        status = PRF_CLIENT_ENABLE(con_info, param, anpc);
    }
    else
    {
        status = PRF_ERR_REQ_DISALLOWED;
    }

    if (status == PRF_ERR_OK)
    {
        // Get the newly created environment
        anpc_env = PRF_CLIENT_GET_ENV(dest_id, anpc);

        // Keep the connection info
        memcpy(&anpc_env->con_info, &con_info, sizeof(struct prf_con_info));

        // Start discovering
        if (param->con_type == PRF_CON_DISCOVERY)
        {
            // Configure the environment for a discovery procedure
            anpc_env->last_req  = ATT_SVC_ALERT_NTF;
            // Force the operation value
            param->operation    = ANPC_ENABLE_OP_CODE;

            prf_disc_svc_send(&(anpc_env->con_info), ATT_SVC_ALERT_NTF);
        }
        // Bond information are provided
        else
        {
            // Keep the provided database content
            memcpy(&anpc_env->ans, &param->ans, sizeof(struct anpc_ans_content));

            // Register in GATT for notifications/indications
            prf_register_atthdl2gatt(&anpc_env->con_info, &anpc_env->ans.svc);

            // Force the operation value
            param->operation = ANPC_ENABLE_RD_NEW_ALERT_OP_CODE;

            // Check Supported New Alert Category
            prf_read_char_send(&(anpc_env->con_info), anpc_env->ans.svc.shdl,
                               anpc_env->ans.svc.ehdl, anpc_env->ans.chars[ANPC_CHAR_SUP_NEW_ALERT_CAT].val_hdl);
        }

        // Keep the operation
        anpc_env->operation = (void *)param;
        // Do not free the message
        msg_status = KE_MSG_NO_FREE;

        // Go to BUSY state
        ke_state_set(dest_id, ANPC_BUSY);
    }
    else if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message will be forwarded towards the good task instance
        msg_status = KE_MSG_NO_FREE;
    }
    else
    {
        // The request is disallowed (profile already enabled for this connection, or not enough memory, ...)
        anpc_send_no_conn_cmp_evt(dest_id, src_id, param->conhdl, ANPC_ENABLE_OP_CODE);
    }

    return (int)msg_status;
}
Exemplo n.º 11
0
/**
 ****************************************************************************************
 * @brief Enable the StreamData Host role, used after connection.
 * @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 streamdatah_enable_req_handler(ke_msg_id_t const msgid,
                                    struct streamdatah_enable_req const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    // Status
    uint8_t status;
    // Device Information Service Client Role Task Environment
    struct streamdatah_env_tag *streamdatah_env;
    // Connection Information
    struct prf_con_info con_info;

    // Fill the Connection Information structure
    con_info.conhdl = param->conhdl;
    con_info.prf_id = dest_id;
    con_info.appid  = src_id;

    // Add an environment for the provided device
    status =  PRF_CLIENT_ENABLE(con_info, param, streamdatah);

    if (status == PRF_ERR_FEATURE_NOT_SUPPORTED)
    {
        // The message has been forwarded to another task id.
        return (KE_MSG_NO_FREE);
    }
    else if (status == PRF_ERR_OK)
    {
        streamdatah_env = PRF_CLIENT_GET_ENV(dest_id, streamdatah);
		
		streamdatah_env->streamon = 0;
		streamdatah_env->next_attribute_idx = 0;
		streamdatah_env->receive_sequence_number = 0;

        // Discovery connection
        if (param->con_type == PRF_CON_DISCOVERY)
        {
            // Start discovering LLS on peer
            streamdatah_env->last_uuid_req     = STREAMDATAD_SERVICE_UUID;
            streamdatah_env->last_svc_req      = STREAMDATAD_SERVICE_UUID;
            prf_disc_svc_send(&streamdatah_env->con_info, streamdatah_env->last_svc_req);

            // Set state to discovering
            ke_state_set(dest_id, STREAMDATAH_DISCOVERING);
        }
        else
        {
            //copy over data that has been stored
            streamdatah_env->streamdatad     = param->streamdatad;

            //send confirmation of enable request to application
            streamdatah_enable_cfm_send(streamdatah_env, &con_info, PRF_ERR_OK);
        }
    }
    else
    {
        streamdatah_enable_cfm_send(NULL, &con_info, status);
    }

    // message is consumed
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 12
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_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 gatt_cmp_evt_handler(ke_msg_id_t const msgid,
                                struct gatt_cmp_evt const *param,
                                ke_task_id_t const dest_id,
                                ke_task_id_t const src_id)
{
    uint8_t status;
    // Get the address of the environment
    struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc);

    if ((param->status == ATT_ERR_ATTRIBUTE_NOT_FOUND)||
        (param->status == ATT_ERR_NO_ERROR))
    {
        // Currently Discovering Current Time service characteristics.
        if(tipc_env->last_svc_req  == ATT_SVC_CURRENT_TIME)
        {
            // service start/end handles has been received
            if(tipc_env->last_uuid_req == ATT_SVC_CURRENT_TIME)
            {
                // check if service handles are not ok
                if (tipc_env->cts.svc.shdl == ATT_INVALID_HANDLE)
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_STOP_DISC_CHAR_MISSING);
                }
                //too many services found only one such service should exist
                else if(tipc_env->nb_svc != 1)
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                }
                // check if service handles are ok
                else
                {
                    //discover all CTS characteristics
                    prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->cts.svc));
                    tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                }

            }
            else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
            {
                status = prf_check_svc_char_validity(TIPC_CHAR_CTS_MAX, tipc_env->cts.chars,
                                                     tipc_cts_char);

                //  check for characteristic properties.
                if(status == PRF_ERR_OK)
                {
                    tipc_env->last_uuid_req = ATT_INVALID_HANDLE;
                    tipc_env->last_char_code = TIPC_CHAR_CTS_CURR_TIME;
                    //request all service characteristic description for CTS
                    prf_disc_char_desc_send(&(tipc_env->con_info), &(tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME]));
                }
                else
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                }
            }
            else
            {
                status = prf_check_svc_char_desc_validity(TIPC_DESC_CTS_MAX,
                                                          tipc_env->cts.descs,
                                                          tipc_cts_char_desc,
                                                          tipc_env->cts.chars);

                if(status == PRF_ERR_OK)
                {
                    // reset number of services
                    tipc_env->nb_svc = 0;

                    //start discovering NDCS on peer
                    prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_NEXT_DST_CHANGE);

                    tipc_env->last_uuid_req = ATT_SVC_NEXT_DST_CHANGE;
                    tipc_env->last_svc_req  = ATT_SVC_NEXT_DST_CHANGE;
                }
                else
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                }
            }
        }

        // Currently Next DST Change service characteristics.
        else if(tipc_env->last_svc_req  == ATT_SVC_NEXT_DST_CHANGE)
        {
            // service start/end handles has been received
            if(tipc_env->last_uuid_req == ATT_SVC_NEXT_DST_CHANGE)
            {
                if (tipc_env->ndcs.svc.shdl == ATT_INVALID_HANDLE)
                {
                    // reset number of services
                    tipc_env->nb_svc = 0;

                    //start discovering RTUS on peer
                    prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE);

                    tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE;
                    tipc_env->last_svc_req  = ATT_SVC_REF_TIME_UPDATE;
                }
                //too many services found only one such service should exist
                else if(tipc_env->nb_svc != 1)
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                }
                // check if service handles are ok
                else
                {
                    //discover all NDCS characteristics
                    prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->ndcs.svc));
                    tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                }
            }
            else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
            {
                status = prf_check_svc_char_validity(TIPC_CHAR_NDCS_MAX, tipc_env->ndcs.chars,
                                                                         tipc_ndcs_char);

                //  check for characteristic properties.
                if(status == PRF_ERR_OK)
                {
                    // reset number of services
                    tipc_env->nb_svc = 0;

                    //start discovering RTUS on peer
                    prf_disc_svc_send(&(tipc_env->con_info), ATT_SVC_REF_TIME_UPDATE);

                    tipc_env->last_uuid_req = ATT_SVC_REF_TIME_UPDATE;
                    tipc_env->last_svc_req  = ATT_SVC_REF_TIME_UPDATE;
                }
                else
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                }
            }
        }

        // Currently Reference Time Update service characteristics.
        else if(tipc_env->last_svc_req  == ATT_SVC_REF_TIME_UPDATE)
        {
            // service start/end handles has been received
            if(tipc_env->last_uuid_req == ATT_SVC_REF_TIME_UPDATE)
            {
                if (tipc_env->rtus.svc.shdl == ATT_INVALID_HANDLE)
                {
                    // send app the details about the discovered TIPS DB to save
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK);
                }
                //too many services found only one such service should exist
                else if(tipc_env->nb_svc != 1)
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_MULTIPLE_SVC);
                }
                // check if service handles are ok
                else
                {
                    //discover all RTUS characteristics
                    prf_disc_char_all_send(&(tipc_env->con_info), &(tipc_env->rtus.svc));
                    tipc_env->last_uuid_req = ATT_DECL_CHARACTERISTIC;
                }
            }
            else if(tipc_env->last_uuid_req == ATT_DECL_CHARACTERISTIC)
            {
                status = prf_check_svc_char_validity(TIPC_CHAR_RTUS_MAX, tipc_env->rtus.chars,
                                                     tipc_rtus_char);

                //  check for characteristic properties.
                if(status == PRF_ERR_OK)
                {
                    // send app the details about the discovered TIPS DB to save
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, PRF_ERR_OK);
                }
                else
                {
                    // stop discovery procedure.
                    tipc_enable_cfm_send(tipc_env, &tipc_env->con_info, status);
                }
            }
        }
    }
    return (KE_MSG_CONSUMED);
}