Exemplo n.º 1
0
/**
 ****************************************************************************************
 * @brief Handles @ref GATT_HANDLE_VALUE_CFM message meaning that Measurement indication
 * has been correctly sent to peer device.
 *
 * Convey this information to appli task using @ref GLPS_MEAS_SEND_CFM
 *
 * @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 gatt_handle_value_cfm_handler(ke_msg_id_t const msgid,
                                        struct gatt_handle_value_cfm const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    // verify if indication should be conveyed to application task
    if(glps_env.racp_ind_src == glps_env.con_info.appid)
    {
        // send completed information to APP task
        struct glps_req_cmp_evt * cmp_evt = KE_MSG_ALLOC(GLPS_REQ_CMP_EVT, glps_env.con_info.appid,
                                                     TASK_GLPS, glps_req_cmp_evt);

        cmp_evt->conhdl     = glps_env.con_info.conhdl;
        cmp_evt->request    = GLPS_SEND_RACP_RSP_IND_CMP;
        cmp_evt->status     = param->status;

        ke_msg_send(cmp_evt);
    }
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 2
0
void pasps_send_cmp_evt(ke_task_id_t src_id, ke_task_id_t dest_id, uint16_t conhdl,
                        uint8_t operation, uint8_t status)
{
    // Come back to the Connected state if the state was busy.
    if (ke_state_get(src_id) == PASPS_BUSY)
    {
        ke_state_set(src_id, PASPS_CONNECTED);
    }

    // Send the message to the application
    struct pasps_cmp_evt *evt = KE_MSG_ALLOC(PASPS_CMP_EVT,
                                             dest_id, src_id,
                                             pasps_cmp_evt);

    evt->conhdl      = conhdl;
    evt->operation   = operation;
    evt->status      = status;

    ke_msg_send(evt);
}
Exemplo n.º 3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CHAR_RESP message.
 * Generic event received after every simple write command sent to peer server.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gatt_write_char_rsp_handler(ke_msg_id_t const msgid,
                                       struct gatt_write_char_resp const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    // Get the address of the environment
    struct htpc_env_tag *htpc_env = PRF_CLIENT_GET_ENV(dest_id, htpc);

    struct htpc_wr_char_rsp *wr_cfm = KE_MSG_ALLOC(HTPC_WR_CHAR_RSP,
                                                   htpc_env->con_info.appid, dest_id,
                                                   htpc_wr_char_rsp);

    wr_cfm->conhdl    = htpc_env->con_info.conhdl;
    //it will be a GATT status code
    wr_cfm->status    = param->status;
    // send the message
    ke_msg_send(wr_cfm);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 4
0
void app_proxr_enable(void)
{
		
    // Allocate the message
    struct proxr_enable_req * req = KE_MSG_ALLOC(PROXR_ENABLE_REQ, TASK_PROXR, TASK_APP,
                                                 proxr_enable_req);

  	// init application alert state
		app_proxr_alert_stop();
	
    // Fill in the parameter structure
        req->conhdl = app_env.conhdl;
		req->sec_lvl = PERM(SVC, ENABLE);
		req->lls_alert_lvl = (uint8_t) alert_state.ll_alert_lvl;  
		req->txp_lvl = alert_state.txp_lvl; 
	
    // Send the message
    ke_msg_send(req);

}
Exemplo n.º 5
0
void app_adc_notify_enable(void)
{
		
    // Allocate the message
    struct adc_notify_enable_req* req = KE_MSG_ALLOC(ADC_NOTIFY_ENABLE_REQ, TASK_ADC_NOTIFY, TASK_APP,
                                                 adc_notify_enable_req);
  	
    req->conhdl = app_env.conhdl;
	req->sec_lvl = PERM(SVC, ENABLE);
    
	adc_init(GP_ADC_SE, ADC_POLARITY_UNSIGNED); // Single ended mode
	adc_enable_channel(ADC_CHANNEL_P01);  //
    
    req->adc_notify_val = SWAP(adc_get_sample());//dummy value
    req->feature = 0x00; //client CFG notif/ind disable
    
    // Send the message
    ke_msg_send(req);

}
Exemplo n.º 6
0
/**
 ****************************************************************************************
 * @brief Handles ready indication from the GAP. - Reset the stack
 *
 * @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 (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
int gapm_device_ready_ind_handler(ke_msg_id_t const msgid,
                                         void const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id)
{
    if (ke_state_get(dest_id) == APP_DISABLED) {
        // reset the lower layers.
        struct gapm_reset_cmd* cmd = KE_MSG_ALLOC(GAPM_RESET_CMD, TASK_GAPM, TASK_APP,
                                                  gapm_reset_cmd);

        cmd->operation = GAPM_RESET;
        ke_msg_send(cmd);
    }
    else {
        // APP_DISABLED state is used to wait the GAP_READY_EVT message
        ASSERT_ERR(0);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 7
0
void bass_disable(void)
{
    // Counter
    uint8_t i;
    // Information get in the DB
    atts_size_t att_length;
    uint8_t *att_value;

    // Send current configuration to the application
    struct bass_disable_ind *ind = KE_MSG_ALLOC(BASS_DISABLE_IND,
                                                bass_env.con_info.appid, TASK_BASS,
                                                bass_disable_ind);

    ind->conhdl = bass_env.con_info.conhdl;

    for (i = 0; i < bass_env.bas_nb; i++)
    {
        if((bass_env.features[i] & BASS_FLAG_NTF_CFG_BIT)
                                 == BASS_FLAG_NTF_CFG_BIT)
        {
            ind->batt_level_ntf_cfg[i] = PRF_CLI_START_NTF;

            // Reset ntf cfg bit in features
            bass_env.features[i] &= ~BASS_FLAG_NTF_CFG_BIT;
        }
        else
        {
            ind->batt_level_ntf_cfg[i] = PRF_CLI_STOP_NTFIND;
        }

        // Get Battery Level value
        attsdb_att_get_value(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL,
                             &att_length, &att_value);
        ind->batt_lvl[i] = *att_value;
    }

    ke_msg_send(ind);

    // Go to idle state
    ke_state_set(TASK_BASS, BASS_IDLE);
}
void app_send_ltk_exch_func(struct gapc_bond_req_ind *param)
{
    
    struct gapc_bond_cfm* cfm = KE_MSG_ALLOC(GAPC_BOND_CFM, TASK_GAPC, TASK_APP, gapc_bond_cfm);

    // generate ltk
    app_sec_gen_ltk(param->data.key_size);

    cfm->request = GAPC_LTK_EXCH;

    cfm->accept = true;

    cfm->data.ltk.key_size = app_sec_env.key_size;
    cfm->data.ltk.ediv = app_sec_env.ediv;

    memcpy(&(cfm->data.ltk.randnb), &(app_sec_env.rand_nb) , RAND_NB_LEN);
    memcpy(&(cfm->data.ltk.ltk), &(app_sec_env.ltk) , KEY_LEN);

    ke_msg_send(cfm);

}
Exemplo n.º 9
0
/**
 ****************************************************************************************
 * @brief Handles start indication from the SPOTAR profile.
 *
 * @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 (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
int spotar_create_db_cfm_handler(ke_msg_id_t const msgid,
                                      struct spotar_create_db_cfm const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    // If state is not idle, ignore the message
    if (ke_state_get(dest_id) == APP_DB_INIT)
    {						
    
        // Inform the Application Manager
        struct app_module_init_cmp_evt *cfm = KE_MSG_ALLOC(APP_MODULE_INIT_CMP_EVT,
                                                       TASK_APP, TASK_APP,
                                                       app_module_init_cmp_evt);

        cfm->status = param->status;

        ke_msg_send(cfm);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 10
0
/*
 ****************************************************************************************
 * @brief Start the Heart Rate Collector profile - at connection. *//**
 * @param[in] hrs           Heart Rate Service Content Structure.
 * @param[in] conhdl        Connection handle for which the profile Heart Rate Collector role is enabled.
 * @response  HRPC_ENABLE_CFM
 * @description
 *
 *  This API is used for enabling the Collector role of the Heart Rate profile. This function contains 
 *  BLE connection handle, the connection type and the previously saved discovered HRS details on peer. 
 *  The connection type may be 0 = Connection for discovery/initial configuration or 1 = Normal connection. This 
 *  parameter is used by Application to discover peer device services once at first connection. Application shall save those 
 *  information to reuse them for other connections. During normal connection, previously discovered device 
 *  information can be reused.
 *
 *  This is useful since most use cases allow Heart Rate Sensor to disconnect the link once all measurements have been 
 *  sent to Collector.
 *
 *  If it is a discovery /configuration type of connection, the HRS parameters are useless, they will be filled with 0's. 
 *  Otherwise they will contain pertinent data which will be kept in the Collector environment while enabled. It allows for 
 *  the Application to not be aware of attribute details.
 *
 *  For a normal connection, the response to this request is sent right away after saving the HRS content in the 
 *  environment and registering HRPC in GATT to receive the indications and notifications for the known attribute 
 *  handles in HRS that would be notified/indicated. For a discovery connection, discovery of the peer HRS is started and 
 *  the response will be sent at the end of the discovery with the discovered attribute details. 
 *
 ****************************************************************************************
 */
void app_hrpc_enable_req(struct hrs_content *hrs, uint16_t conhdl)
{
    struct hrpc_enable_req * msg = KE_MSG_ALLOC(HRPC_ENABLE_REQ, KE_BUILD_ID(TASK_HRPC, conhdl), TASK_APP,
                                                 hrpc_enable_req);

    ///Connection handle
    msg->conhdl = conhdl;
    ///Connection type
    if (hrs == NULL)
    {
        msg->con_type = PRF_CON_DISCOVERY;
    }
    else
    {
        msg->con_type = PRF_CON_NORMAL;
        memcpy(&msg->hrs, hrs, sizeof(struct hrs_content));
    }

    // Send the message
    ke_msg_send(msg);
}
Exemplo n.º 11
0
void app_neb_msg_rx_resp_flow(struct app_neb_msg_resp_flow* msg)
{
    uint8_t status = NEB_ERR_SUCCESS;

    if(ke_state_get(TASK_APP_NEB) == APP_NEB_CONNECTED)
    {
        ASSERT_INFO(app_neb_env.resp_flow_sample_nb < NEB_RESP_FLOW_PCK_NB, app_neb_env.resp_flow_sample_nb, NEB_RESP_FLOW_PCK_NB);

        // Store sample
        app_neb_env.resp_flow_sample_buf[app_neb_env.resp_flow_sample_nb++] = msg->flow;

        // Check the buffer size
        if(app_neb_env.resp_flow_sample_nb == NEB_RESP_FLOW_PCK_NB)
        {
            // Allocate message to profile
            struct nbps_neb_record_send_req *req = KE_MSG_ALLOC(NBPS_NEB_RECORD_SEND_REQ,
                    TASK_NBPS, TASK_APP_NEB,
                    nbps_neb_record_send_req);
            req->conhdl = app_neb_env.conhdl;
            req->neb_rec.neb_id = app_neb_env.curr_neb_id;
            req->neb_rec.rec_id = app_neb_env.next_rec_id;
            req->neb_rec.flags = NEB_REC_RESP_RATE_FLAG;

            // Parameters
            req->neb_rec.nb_resp_rate = NEB_RESP_FLOW_PCK_NB;
            memcpy(&req->neb_rec.resp_rate[0], &app_neb_env.resp_flow_sample_buf[0], NEB_RESP_FLOW_PCK_NB * sizeof(uint16_t));

            ke_msg_send(req);

            // Clear number of samples
            app_neb_env.resp_flow_sample_nb = 0;

            // Increment record ID
            app_neb_env.next_rec_id++;
        }
    }

    // Confirm the message
    app_neb_msg_tx_confirm_basic(NEB_MSG_ID_RESP_FLOW, status);
}
Exemplo n.º 12
0
void app_smpc_start_enc_req(uint8_t idx, 
                               uint8_t auth_req,
                               uint16_t ediv,
                               struct rand_nb *rand_nb,
                               struct smp_key *ltk)
{
    struct smpc_start_enc_req *msg = KE_MSG_ALLOC(SMPC_START_ENC_REQ, TASK_SMPC, TASK_APP,
                                                  smpc_start_enc_req);

    ///Connection index
    msg->idx = idx;
    ///Authentication Requirements - needed if slave
    msg->auth_req = auth_req;
    ///EDIV
    msg->ediv = ediv;
    ///Random number
    msg->randnb = *rand_nb;
    ///LTK
    msg->ltk = *ltk;

    ke_msg_send(msg);
}
/**
 ****************************************************************************************
 * @brief       Clears both the normal and the virtual White Lists.
 *
 * @param       void
 *
 * @return      void
 ****************************************************************************************
 */
void clear_white_list(void)
{
    int i;

    if (con_fsm_params.has_white_list) {
        struct gapm_white_list_mgt_cmd * req = KE_MSG_ALLOC(GAPM_WHITE_LIST_MGT_CMD, 
                                                            TASK_GAPM, TASK_APP, 
                                                            gapm_white_list_mgt_cmd);

        // Fill in the parameter structure
        req->operation = GAPM_CLEAR_WLIST;
        req->nb = 0;
        ke_msg_send(req);
    }
    else if (con_fsm_params.has_virtual_white_list) {
        for (i = 0; i < MAX_BOND_PEER; i++) {
            virtual_white_list[i].status = UNUSED;
        }
        virtual_wlist_policy = ADV_ALLOW_SCAN_ANY_CON_ANY;
    }
    white_list_written = 0;
}
Exemplo n.º 14
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref STREAMDATAD_CREATE_DB_REQ message.
 * The handler adds STREAMDATAD Service into the database using the database
 * configuration value given in param.
 * @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 streamdatad_create_db_req_handler(ke_msg_id_t const msgid,
                                      struct streamdatad_create_db_req const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    //Service Configuration Flag
    uint32_t cfg_flag = 0xFFFFFFFF;
    //Database Creation Status
    uint8_t status;

    //Save Application ID
    streamdatad_env.appid = src_id;


    // set start handle or automatically set it when creating database (start_hdl = 0)
    streamdatad_env.shdl=param->start_hdl;

    //Add Service Into Database
    status = attm_svc_create_db(&streamdatad_env.shdl, (uint8_t *)&cfg_flag,  STREAMDATAD_IDX_NB, NULL,
                               dest_id, &streamdatad_att_db[0]);

    //Disable GLS
    attmdb_svc_set_permission(streamdatad_env.shdl, PERM(SVC, DISABLE));

    //Go to Idle State
    if (status == ATT_ERR_NO_ERROR)
    {
        //If we are here, database has been fulfilled with success, go to idle test
        ke_state_set(TASK_STREAMDATAD, STREAMDATAD_IDLE);
    }

    //Send response to application
    struct streamdatad_create_db_cfm * cfm = KE_MSG_ALLOC(STREAMDATAD_CREATE_DB_CFM, streamdatad_env.appid,
                                                    TASK_STREAMDATAD, streamdatad_create_db_cfm);
    cfm->status = status;
    ke_msg_send(cfm);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 15
0
void app_smpc_chk_bd_addr_req_rsp(uint8_t idx, 
                                    uint8_t found_flag,
                                    uint8_t sec_status,
                                    uint8_t type,
                                    struct bd_addr *addr)
{
    struct smpc_chk_bd_addr_rsp *msg = KE_MSG_ALLOC(SMPC_CHK_BD_ADDR_REQ_RSP, TASK_SMPC, TASK_APP,
                                                smpc_chk_bd_addr_rsp);

    ///Connection index -may be a free task index
    msg->idx = idx;
    ///Status - found or not
    msg->found_flag = found_flag;
    ///Saved link security status from higher layer
    msg->lk_sec_status = sec_status;
    ///Type of address to check
    msg->type = type;
    ///Random address to resolve or Public address to check in APP
    msg->addr = *addr;

    ke_msg_send(msg);
}
Exemplo n.º 16
0
void tips_disable(struct tips_idx_env_tag *tips_idx_env, uint16_t conhdl)
{
    // Disable CTS
    attmdb_svc_set_permission(tips_env.cts_shdl, PERM(SVC, DISABLE));

    if (TIPS_IS_SUPPORTED(TIPS_NDCS_SUP))
    {
        // Disable NDCS
        attmdb_svc_set_permission(tips_env.ndcs_shdl, PERM(SVC, DISABLE));
    }

    if (TIPS_IS_SUPPORTED(TIPS_RTUS_SUP))
    {
        // Disable RTUS
        attmdb_svc_set_permission(tips_env.rtus_shdl, PERM(SVC, DISABLE));
    }

    // Send APP cfg every time, C may have changed it
    struct tips_disable_ind *ind = KE_MSG_ALLOC(TIPS_DISABLE_IND,
                                                tips_idx_env->con_info.appid, tips_idx_env->con_info.prf_id,
                                                tips_disable_ind);

    ind->conhdl = conhdl;

    if ((tips_idx_env->ntf_state & TIPS_CTS_CURRENT_TIME_CFG) == TIPS_CTS_CURRENT_TIME_CFG)
    {
        ind->current_time_ntf_en    = PRF_CLI_START_NTF;

        //Reset notifications bit field
        tips_idx_env->ntf_state &= ~TIPS_CTS_CURRENT_TIME_CFG;
    }

    ke_msg_send(ind);

    //Go to idle state
    ke_state_set(tips_idx_env->con_info.prf_id, TIPS_IDLE);

    PRF_CLIENT_DISABLE(tips_idx_envs, KE_IDX_GET(tips_idx_env->con_info.prf_id), TIPS);
}
Exemplo n.º 17
0
/*
 ****************************************************************************************
 * @brief Start the Phone Alert Status Profile Client role - at connection. *//**
 * @param[in] pass   Service structure previously discovered in the database of the peer device. 
 * @param[in] conhdl  Connection handle for which the Alert Notification Status Client role is enabled.
 * @response  PASPC_PASS_CONTENT_IND and PASPC_CMP_EVT
 * @description
 *
 * This API is used by Application to send message to TASK_PASPC for enabling the Collector role 
 * of the Phone Alert Status profile, and it contains the connection handle for the connection  
 * this profile is activated, the connection type and the previously saved discovered PASS details on peer. 
 * 
 * The connection type may be PRF_CON_DISCOVERY (0x00) for discovery/initial configuration or
 * PRF_CON_NORMAL (0x01) for a normal connection with a bonded device. Application shall save
 * those information to reuse them for other connections. During normal connection, previously
 * discovered device information can be reused.
 * 
 * For a normal connection, the response to this request is sent right away after saving the 
 * PASS content in the environment and registering PASPC in GATT to receive the notifications
 * for the known attribute handles in PASS that would be notified.
 * 
 * For a discovery connection, discovery of the peer PASS is started and the response will be
 * sent at the end of the discovery with the discovered attribute details.
 * 
 ****************************************************************************************
 */
void app_paspc_enable_req(struct paspc_pass_content *pass, uint16_t conhdl)
{
    
    struct paspc_enable_cmd * msg = KE_MSG_ALLOC(PASPC_ENABLE_CMD, KE_BUILD_ID(TASK_PASPC, conhdl), TASK_APP,
                                                 paspc_enable_cmd);

    ///Connection handle
    msg->conhdl = conhdl;
    ///Connection type
    if (pass == NULL)
    {
        msg->con_type = PRF_CON_DISCOVERY;
    }
    else
    {
        msg->con_type = PRF_CON_NORMAL;
        memcpy(&msg->pass, pass, sizeof(struct paspc_pass_content));
    }

    // Send the message
    ke_msg_send(msg);
}
Exemplo n.º 18
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_HANDLE_VALUE_NTF 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 gatt_handle_value_ntf_handler(ke_msg_id_t const msgid,
                                         struct gatt_handle_value_notif const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id)
{
    // BAS Instance
    uint8_t bas_nb;
    // Attribute found
    uint8_t found = PRF_APP_ERROR;
    // 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)
    {
        //Battery Level - BAS instance is unknown.
        for (bas_nb = 0; ((bas_nb < basc_env->bas_nb) && (found != PRF_ERR_OK)); bas_nb++)
        {
            if (param->charhdl == basc_env->bas[bas_nb].chars[BAS_CHAR_BATT_LEVEL].val_hdl)
            {
                found = PRF_ERR_OK;

                struct basc_batt_level_ind * ind = KE_MSG_ALLOC(BASC_BATT_LEVEL_IND,
                                                                basc_env->con_info.appid, dest_id,
                                                                basc_batt_level_ind);

                ind->conhdl     = param->conhdl;
                ind->ind_type   = BASC_BATT_LEVEL_NTF;
                ind->batt_level = param->value[0];
                ind->bas_nb     = bas_nb;

                //Send Battery Level value to APP
                ke_msg_send(ind);
            }
        }
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 19
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref FINDT_CREATE_DB_REQ message.
 * The handler adds IAS into the database using the database
 * configuration value given in param.
 * @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 findt_create_db_req_handler(ke_msg_id_t const msgid,
                                       struct findt_create_db_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    //Service Configuration Flag
    uint8_t cfg_flag = FINDT_MANDATORY_MASK;
    //Database Creation Status
    uint8_t status;

    //Save Profile ID
    findt_env.con_info.prf_id = TASK_FINDT;

    /*---------------------------------------------------*
     * Immediate Alert Service Creation
     *---------------------------------------------------*/

    //Add Service Into Database
    status = attm_svc_create_db(&findt_env.shdl, (uint8_t *)&cfg_flag, FINDT_IAS_IDX_NB, NULL,
                               dest_id, &findt_att_db[0]);
    //Disable IAS
    attmdb_svc_set_permission(findt_env.shdl, PERM(SVC, DISABLE));

    //Go to Idle State
    if (status == ATT_ERR_NO_ERROR)
    {
        //If we are here, database has been fulfilled with success, go to idle state
        ke_state_set(TASK_FINDT, FINDT_IDLE);
    }

    //Send CFM to application
    struct findt_create_db_cfm * cfm = KE_MSG_ALLOC(FINDT_CREATE_DB_CFM, src_id,
                                                    TASK_FINDT, findt_create_db_cfm);
    cfm->status = status;
    ke_msg_send(cfm);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 20
0
void cscps_send_cmp_evt(uint8_t src_id, uint8_t dest_id, uint16_t conhdl,
                        uint8_t operation, uint8_t status)
{
    // Go back to the Connected state if the state is busy
    if (ke_state_get(src_id) == CSCPS_BUSY)
    {
        ke_state_set(src_id, CSCPS_CONNECTED);
    }

    // Set the operation code
    cscps_env.operation = CSCPS_RESERVED_OP_CODE;

    // Send the message
    struct cscps_cmp_evt *evt = KE_MSG_ALLOC(CSCPS_CMP_EVT,
                                             dest_id, src_id,
                                             cscps_cmp_evt);

    evt->conhdl     = conhdl;
    evt->operation  = operation;
    evt->status     = status;

    ke_msg_send(evt);
}
Exemplo n.º 21
0
/*
 ****************************************************************************************
 * @brief Start the HID Over GATT profile - at connection. *//**
 *
 * @param[in] hids_nb  Number of instances of the HID Service that have been found during the last discovery
 * @param[in] hids     Information about HID Services that have been found during the last discovery
 * @param[in] conhdl   Connection handle
 * @response  HOGPBH_ENABLE_CFM 
 * @description
 *
 *  This API is used for enabling the Boot Host role of the HOGP. This function contains 
 *  BLE connection handle, the connection type and the previously saved discovered HIDS details on peer. 
 *
 *  The connection type may be PRF_CON_DISCOVERY (0x00) for discovery/initial configuration or PRF_CON_NORMAL 
 *  (0x01) for a normal connection with a bonded device. Application shall save those information to reuse them for 
 *  other connections. During normal connection, previously discovered device information can be reused. 
 *
 *  If it is a discovery/configuration type of connection, it is useless to fill the HIDS parameters (hids_nb and hids) are 
 *  useless. Otherwise they will contain pertinent data which will be kept in the Boot Host environment while enabled. 
 *
 *  For a normal connection, the response to this request is sent right away after saving the HIDS content in the 
 *  environment and registering HOGPBH in GATT to receive the notifications for the known attribute handles in HIDS that 
 *  would be notified (Boot Keyboard Input Report and Boot Mouse Input Report). For a discovery connection, discovery 
 *  of the peer HIDS is started and the response will be sent at the end of the discovery with the discovered attribute 
 *  details. 
 *
 ****************************************************************************************
 */
void app_hogpbh_enable_req(uint8_t hids_nb, struct hids_content *hids, uint16_t conhdl)
{
    struct hogpbh_enable_req * msg = KE_MSG_ALLOC(HOGPBH_ENABLE_REQ, KE_BUILD_ID(TASK_HOGPBH, conhdl), TASK_APP,
                                                 hogpbh_enable_req);

    ///Connection handle
    msg->conhdl = conhdl;
    ///Number of HIDS instances
    msg->hids_nb = hids_nb;
    ///Connection type
    if (hids == NULL || hids_nb == 0)
    {
        msg->con_type = PRF_CON_DISCOVERY;
    }
    else
    {
        msg->con_type = PRF_CON_NORMAL;
        memcpy(&msg->hids[0], hids, hids_nb*sizeof(struct hids_content));
    }

    // Send the message
    ke_msg_send(msg);
}
Exemplo n.º 22
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_READ_IND message.
 * Generic event received after every simple read command sent to peer server.
 * @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_read_ind_handler(ke_msg_id_t const msgid,
                                    struct gattc_read_ind const *param,
                                    ke_task_id_t const dest_id,
                                    ke_task_id_t const src_id)
{
    // Get the address of the environment
    struct glpc_env_tag *glpc_env = PRF_CLIENT_GET_ENV(dest_id, glpc);

    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 = ATT_ERR_NO_ERROR;

    // unpack feature information
    rsp->features = co_read16p(param->value);

    ke_msg_send(rsp);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 23
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
 * The message is redirected from TASK_SVC because at profile enable, the ATT handle is
 * register for TASK_FINDT. In the handler, an ATT Write Response/Error Response should
 * be sent for ATT protocol, but Alert Level Characteristic only supports WNR so no
 * response PDU is needed.
 * @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 alert_lvl = 0x0000;

    if (KE_IDX_GET(src_id) == findt_env.con_info.conidx)
    {
        if(param->handle == findt_env.shdl + FINDT_IAS_IDX_ALERT_LVL_VAL)
        {
            alert_lvl = param->value[0];

            //Check if Alert Level is valid
            if ((param->value[0] <= FINDT_ALERT_HIGH))
            {
                //Update the attribute value
                attmdb_att_set_value(param->handle, sizeof(uint8_t), (uint8_t *)&alert_lvl);
                if(param->last)
                {
                    // Allocate the alert value change indication
                    struct findt_alert_ind *ind = KE_MSG_ALLOC(FINDT_ALERT_IND, findt_env.con_info.appid,
                                                               TASK_FINDT, findt_alert_ind);
                    // Fill in the parameter structure
                    ind->conhdl    = gapc_get_conhdl(findt_env.con_info.conidx);
                    ind->alert_lvl = alert_lvl;

                    // Send the message
                    ke_msg_send(ind);
                }
                // It was a Write Without Response so no RSP needed.
            }
        }
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 24
0
/**
 ****************************************************************************************
 * @brief Handles reception of encrypt request command
 *
 * @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 (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
int gapc_encrypt_req_ind_handler(ke_msg_id_t const msgid,
        struct gapc_encrypt_req_ind *param,
        ke_task_id_t const dest_id,
        ke_task_id_t const src_id)
{
    struct gapc_encrypt_cfm* cfm = KE_MSG_ALLOC(GAPC_ENCRYPT_CFM, src_id, dest_id, gapc_encrypt_cfm);
    
    if (!app_validate_encrypt_req_func(param))
    {
        cfm->found = false;
    }
    else
    {
        if(((app_sec_env.auth & GAP_AUTH_BOND) != 0)
            && (memcmp(&(app_sec_env.rand_nb), &(param->rand_nb), RAND_NB_LEN) == 0)
            && (app_sec_env.ediv == param->ediv))
        {
            cfm->found = true;
            cfm->key_size = app_sec_env.key_size;
            memcpy(&(cfm->ltk), &(app_sec_env.ltk), KEY_LEN);
            // update connection auth
            app_connect_confirm(app_sec_env.auth);
            app_sec_encrypt_complete_func();
        }
        else
        {
            cfm->found = false;
        }
    }
    
    ke_msg_send(cfm);
    
    if (cfm->found == false)
        app_disconnect();

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 25
0
void prf_disc_char_desc_send(struct prf_con_info* con_info, struct prf_char_inf * charact)
{
    // Check if there is at least one descriptor to find
    if ((charact->val_hdl + 1) <= (charact->char_hdl + charact->char_ehdl_off - 1))
    {

        // Ask for handles of a certain uuid
        struct gattc_disc_cmd * dsc_req = KE_MSG_ALLOC_DYN(GATTC_DISC_CMD,
                                          KE_BUILD_ID(TASK_GATTC, con_info->conidx), con_info->prf_id,
                                          gattc_disc_cmd, ATT_UUID_16_LEN);

        dsc_req->req_type  = GATTC_DISC_DESC_CHAR;
        dsc_req->start_hdl = charact->val_hdl + 1;
        dsc_req->end_hdl   = charact->char_hdl + charact->char_ehdl_off - 1;

        // UUID info - Don't care
        dsc_req->uuid_len = ATT_UUID_16_LEN;
        //set the first two bytes to the value array, LSB to MSB:Health Thermometer Service UUID first
        co_write16p(&(dsc_req->uuid[0]), ATT_INVALID_UUID);

        //send the message to GATT;there should be only one handle response every time
        ke_msg_send(dsc_req);
    }
    else
    {
        // TODO [FBE] to be changed if SDP task implemented
        // Send a GATT complete event message
        struct gattc_cmp_evt *evt = KE_MSG_ALLOC(GATTC_CMP_EVT, con_info->prf_id,
                                    KE_BUILD_ID(TASK_GATTC , con_info->conidx),
                                    gattc_cmp_evt);

        evt->status = PRF_ERR_OK;

        // Send the message
        ke_msg_send(evt);
    }
}
/**
 ****************************************************************************************
 * @brief Handles read command characteristic event indication from device_config profile
 *
 * @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 (TASK_GAP).
 * @param[in] src_id    ID of the sending task instance.
 *
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
int app_device_read_request_ind_handler(ke_msg_id_t const msgid,
                                      struct device_config_read_request_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    uint8_t status = 0;
    
    // Allocate message
   struct device_config_read_response_cmd *cmd = KE_MSG_ALLOC(DEVICE_READ_RESPONSE_CMD,
                                              TASK_DEVICE_CONFIG, TASK_APP,
                                              device_config_read_response_cmd);

    if (param->param_id >=  app_device_config_env.params_num)
    {
        status = 1;
    }
    
    if (!status)
    {
        
        cmd->size = app_device_config_env.params[param->param_id].size;
        memcpy(cmd->val, app_device_config_env.params[param->param_id].p_data, cmd->size );
        
    }
    else
    {
        cmd->size = 0;
    }
    
    cmd->param_id = param->param_id;
    cmd->conhdl = app_env.conhdl;    
    cmd->status = status;
    
    ke_msg_send(cmd);
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 27
0
/*
 ****************************************************************************************
 * @brief Gatt Read Characteristic request. *//**
 *
 * @param[in] req_type      GATT request type:
 * - GATT_READ_CHAR
 * - GATT_READ_BY_UUID_CHAR
 * - GATT_READ_LONG_CHAR
 * - GATT_READ_MULT_LONG_CHAR
 * - GATT_READ_DESC
 * - GATT_READ_LONG_DESC
 * @param[in] conhdl        Connection handle.
 * @param[in] valhdl        Value handle.
 * @response  GATT_READ_CHAR_RESP or GATT_READ_CHAR_MULTI_RESP
 * @description
 *
 *  This API is used by the application to send a GATT_READ_CHAR_REQ mssage.
 *  Upon reception of this message, GATT will checks whether the parameters are correct,
 *  if not correct then the GATT_CMP_EVT message with error code GATT_INVALID_PARAM_ERR 
 *  will be generically built and sent to Application directly. If parameter is correct,
 *  the GATT_READ_CHAR_RESP message will be received.
 *
 ****************************************************************************************
 */
void app_gatt_read_char_req(uint8_t req_type, uint16_t conhdl, uint16_t valhdl)
{
    struct gatt_read_char_req *msg = KE_MSG_ALLOC(GATT_READ_CHAR_REQ, TASK_GATT, TASK_APP,
                                                  gatt_read_char_req);

    //Connection handle
    msg->conhdl = conhdl;
    //GATT request type
    msg->req_type = req_type;
    //Read offset
    msg->offset = 0;
    //Start handle range
    msg->start_hdl = 0x0001;
    //End handle range
    msg->end_hdl = GATT_MAX_ATTR_HDL;
    //Number of UUID
    msg->nb_uuid = 0x01;
    //Handle of char value
    msg->uuid[0].expect_resp_size = ATT_UUID_16_LEN;
    msg->uuid[0].value_size = ATT_UUID_16_LEN;
    co_write16p(&msg->uuid[0].value[0], valhdl);

    ke_msg_send(msg);
}
Exemplo n.º 28
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref HPSS_CREATE_DB_REQ message.
 * The handler adds HPS into the database.
 * @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 hpss_create_db_req_handler(ke_msg_id_t const msgid,
                                      struct hpss_create_db_req const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    //Database Creation Status
    uint8_t status;

    //Save Profile ID
    hpss_env.con_info.prf_id = TASK_HPSS;

    /*---------------------------------------------------*
     * HTTP Proxy Service Creation
     *---------------------------------------------------*/

    //Add Service Into Database
    status = attm_svc_create_db(&hpss_env.hps_shdl, NULL, HPS_IDX_NB, NULL,
                                dest_id, &hpss_att_db[0]);
    //Disable HPS
    attmdb_svc_set_permission(hpss_env.hps_shdl, PERM(SVC, DISABLE));

    //Go to Idle State
    if (status == ATT_ERR_NO_ERROR)
    {
        //If we are here, database has been fulfilled with success, go to idle state
        ke_state_set(TASK_HPSS, HPSS_IDLE);
    }

    //Send CFM to application
    struct hpss_create_db_cfm * cfm = KE_MSG_ALLOC(HPSS_CREATE_DB_CFM, src_id,
                                      TASK_HPSS, hpss_create_db_cfm);
    cfm->status = status;
    ke_msg_send(cfm);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 29
0
void app_hrps_enable(void)
{
    // Allocate the message
    struct hrps_enable_req * req = KE_MSG_ALLOC(HRPS_ENABLE_REQ, TASK_HRPS, TASK_APP,
                                                 hrps_enable_req);
		//结构体填充部分需要后续改善
    // Fill in the parameter structure
    ///Connection handle
    req->conhdl = app_env.conhdl;
    /// security level: b0= nothing, b1=unauthenticated, b2=authenticated, b3=authorized;
    /// b1 or b2 and b3 can go together
    req->sec_lvl = PERM(SVC, ENABLE);
    ///Type of connection - will someday depend on button press length; can be CFG or DISCOVERY
    req->con_type = PRF_CON_NORMAL;// PRF_CON_DISCOVERY;

    /// Heart Rate Notification configuration
    req->hr_meas_ntf_en = 1;//PRF_CLI_START_NTF;//PRF_CLI_STOP_NTFIND

    ///Body Sensor Location
    req->body_sensor_loc = 1;

    // Send the message
    ke_msg_send(req);
}
Exemplo n.º 30
0
void app_custom_connection(struct gapc_connection_req_ind const *param)
{
#if BLE_ACCEL
    int temp=4;
    uint8_t *temp_v;
    
    app_accel_adv_stopped();
    
    if (!param->con_latency)
    {
        // Not completely verified, but this improves the stability of the connection.
        
        struct gapc_param_update_req_ind * req = KE_MSG_ALLOC(GAPC_PARAM_UPDATE_REQ_IND, TASK_GAPC, TASK_APP, gapc_param_update_req_ind);

        // Fill in the parameter structure
        //req->conhdl = param->conn_info.conhdl;
        //GZ req->conn_par.intv_min = param->conn_info.con_interval;
        //GZ req->conn_par.intv_max = param->conn_info.con_interval;
        attmdb_att_get_value(ACCEL_HANDLE(ACCEL_IDX_ACCEL_X_EN), &(temp), &(temp_v));
        if(temp_v[1] > 1)
            accel_con_interval = temp_v[1];
        
        req->params.intv_min = (accel_con_interval-1)*10/1.25;
        req->params.intv_max = (accel_con_interval)*10/1.25;
        req->params.latency = param->con_latency;
        if(param->sup_to * 8 / 1.25 <= 3200)
            req->params.time_out = param->sup_to * 8 / 1.25;
        else
            req->params.time_out = 3200/1.25;
    #if BLE_HID_DEVICE
        puts("Send GAP_PARAM_UPDATE_REQ");
    #endif
        ke_msg_send(req);
    }    
#endif
}