Exemplo n.º 1
0
/*
 ****************************************************************************************
 * @brief Handles the generic message Boot Mouse Input Report value send to APP
 *        (after Read Request or Notification) . *//**
 *
 * @param[in] msgid     HOGPRH_REPORT_IND 
 * @param[in] param     Pointer to the struct hogprh_report_ind
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_HOGPRH
 *
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used to inform the application about the read Client Characteristic Configuration 
 *  Descriptor value. 
 *
 *  The following table present all the possible values for the ind_type parameter: 
 *  - HOGPRH_IND_NTF (0x00): The Report Characteristic value has been received has a 
 *  notification and the value is complete. 
 *  - HOGPRH_IND_RD_RSP (0x01): The Report Characteristic value has been received has a read 
 *  response. 
 *  - HOGPRH_IND_INCOMPLETE_NTF (0x02): The Report Characteristic value has been received has a 
 *  notification and the value is not complete. See the note below. 
 *
 *  @note
 *
 *  Here is an extract of the BLE HIDS specification, 
 *  "Notification of characteristic values can contain at most [ATT_MTU-3] bytes of data by definition. Data beyond 
 *  [ATT_MTU-3] bytes long is not included in a notification, and must instead be read using the GATT Read Long 
 *  Characteristic Value sub-procedure. The possibility that data to be notified in a Report characteristic value could 
 *  change before the HID Host completed an outstanding Read Long Characteristic Value sub-procedure, and therefore be 
 *  lost, exists. For this reason it is strongly recommended that HID Devices support an ATT_MTU large enough to transfer 
 *  their largest possible Report characteristic value in a single transaction."
 *
 *  Thus when an indication in received with an indication type set to HOGPRH_IND_INCOMPLETE_NTF, the application 
 *  can begin to parse this incomplete Report value. Then it must wait for another indication whose the indication type 
 *  will be set to HOGPRH_IND_RD_RSP and which will contain the whole Report Characteristic value (the first indication 
 *  can be discarded if needed). 
 *
 ****************************************************************************************
 */
int app_hogprh_report_ind_handler(ke_msg_id_t const msgid,
                      struct hogprh_report_ind *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);
    switch (param->ind_type)
    {
    case HOGPRH_IND_RD_RSP:
        QPRINTF("HOGPRH Read HIDS Report(%d).\r\n", param->hids_nb);
        QTRACE(param->report, param->report_length, 0, 2);
        QPRINTF("\r\n");
        break;
    case HOGPRH_IND_NTF:
        QPRINTF("HOGPRH Notification(%d).\r\n", param->hids_nb);
        QTRACE(param->report, param->report_length, 0, 2);
        QPRINTF("\r\n");
        if ((!app_hogprh_env[idx].cur_code) && (param->hids_nb+1 < app_hogprh_env[idx].hids_nb)) {
            // start notification
            app_hogprh_cfg_ntf_req(0, PRF_CLI_START_NTF, param->hids_nb+1, param->conhdl); /* 0 is our demo input report */
            app_hogprh_env[idx].cur_code = 1;
        }
        break;
    default:
        break;
    }
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 2
0
/*
 ****************************************************************************************
 * @brief Handles the generic message Boot Report value send to APP. (after Read Request or Notification) *//**
 *
 * @param[in] msgid     HOGPBH_BOOT_REPORT_IND
 * @param[in] param     Pointer to the struct hogpbh_boot_report_ind
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_HOGPBH
 *
 * @return If the message was consumed or not.
 * @description
 *
 *  This API  is used to inform the application about the read Boot Keyboard Input Report 
 *  Characteristic value. 
 *
 ****************************************************************************************
 */
int app_hogpbh_boot_report_ind_handler(ke_msg_id_t const msgid,
                                       struct hogpbh_boot_report_ind *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);
    switch (param->ind_type)
    {
    case HOGPBH_IND_RD_RSP:
        break;
    case HOGPBH_IND_NTF:
        if (param->char_code == HOGPBH_CHAR_BOOT_KB_IN_REPORT) {
            QPRINTF("HOGPBH Keyboard in report notification(%d):\r\n", param->hids_nb);
            QTRACE(param->report, param->report_length, 0, 2);
            QPRINTF("\r\n");
            if (app_hogpbh_env[idx].cur_code == 2) {
                // Start Mouse Notify here
                app_hogpbh_cfg_ntf_req(HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG, PRF_CLI_START_NTF, 
                                        app_hogpbh_env[idx].hids_mouse, param->conhdl);
                app_hogpbh_env[idx].cur_code = 0;
            }
        }
        else if (param->char_code == HOGPBH_CHAR_BOOT_MOUSE_IN_REPORT) {
            QPRINTF("HOGPBH Mouse in report notification(%d):\r\n", param->hids_nb);
            QTRACE(param->report, param->report_length, 0, 2);
            QPRINTF("\r\n");
        }
        break;
    default:
        break;
    }
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 3
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_EVENT_IND message.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_event_ind_handler(ke_msg_id_t const msgid,
                                        struct gattc_event_ind const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    // Get the address of the environment
    struct blpc_env_tag *blpc_env = PRF_CLIENT_GET_ENV(dest_id, blpc);

    if(KE_IDX_GET(src_id) == blpc_env->con_info.conidx)
    {
        if((param->handle == blpc_env->bps.chars[BLPC_CHAR_CP_MEAS].val_hdl)
            || ((param->handle == blpc_env->bps.chars[BLPC_CHAR_BP_MEAS].val_hdl)))
        {
            //build a BLPC_BP_MEAD_IND message with stable blood pressure value code.
            struct blpc_meas_ind * ind = KE_MSG_ALLOC(BLPC_BP_MEAS_IND,
                                                      blpc_env->con_info.appid, dest_id,
                                                      blpc_meas_ind);
            // retrieve connection handle
            ind->conhdl = gapc_get_conhdl(blpc_env->con_info.conidx);

            // Intermediate cuff pressure value
            ind->flag_interm_cp = ((param->type == GATTC_NOTIFY) ? 0x01 : 0x00);

            // unpack blood pressure measurement.
            blpc_unpack_meas_value(&(ind->meas_val), (uint8_t*) param->value);

            ke_msg_send(ind);
        }
    }
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 4
0
void prf_client_disable_ind_send(prf_env_struct ***p_envs, ke_msg_id_t msg_id,
                                 ke_task_id_t task_id, uint8_t state, uint16_t conhdl)
{
    // retrieve current state
    uint8_t cur_state = ke_state_get(task_id);

    // prevent doing freeing structure if state already of profile is already free.
    if(cur_state != state)
    {
        // Get the address of the environment
        prf_env_struct *env = prf_client_get_env(*p_envs, task_id);

        ASSERT_WARN(env != NULL);

        if (env != NULL)
        {
            struct prf_client_disable_ind *ind = KE_MSG_ALLOC(msg_id,
                                                 env->con_info.appid, env->con_info.prf_id,
                                                 prf_client_disable_ind);

            ind->conhdl    = conhdl;
            ind->status    = prf_client_disable(p_envs, KE_IDX_GET(env->con_info.prf_id));

            // Send the message
            ke_msg_send(ind);

            // Go to idle state
            ke_state_set(task_id, state);
        }
    }
}
Exemplo n.º 5
0
void pasps_disable(struct pasps_idx_env_tag *idx_env)
{
    // Disable PAS service
    attsdb_svc_set_permission(pasps_env.pass_shdl, PERM(SVC, DISABLE));

    struct pasps_disable_ind *ind = KE_MSG_ALLOC(PASPS_DISABLE_IND,
                                                 idx_env->con_info.appid, idx_env->con_info.prf_id,
                                                 pasps_disable_ind);

    memset(ind, 0x00, sizeof(struct pasps_disable_ind));

    ind->conhdl = idx_env->con_info.conhdl;

    if (PASPS_IS_NTF_ENABLED(idx_env, PASPS_FLAG_ALERT_STATUS_CFG))
    {
        ind->alert_status_ntf_cfg = PRF_CLI_START_NTF;
    }

    if (PASPS_IS_NTF_ENABLED(idx_env, PASPS_FLAG_RINGER_SETTING_CFG))
    {
        ind->ringer_setting_ntf_cfg = PRF_CLI_START_NTF;
    }

    ke_msg_send(ind);

    // Go to idle state
    ke_state_set(idx_env->con_info.prf_id, PASPS_IDLE);

    // Free the environment allocated for this connection
    prf_client_disable((prf_env_struct ***)&pasps_idx_envs, KE_IDX_GET(idx_env->con_info.prf_id));
}
Exemplo n.º 6
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_EVENT_IND message.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_event_ind_handler(ke_msg_id_t const msgid,
                                        struct gattc_event_ind const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    // Get the address of the environment
    struct scppc_env_tag *scppc_env = PRF_CLIENT_GET_ENV(dest_id, scppc);

    if (KE_IDX_GET(src_id) == scppc_env->con_info.conidx)
    {
        //Scan Refresh
        if (param->handle == scppc_env->scps.chars[SCPPC_CHAR_SCAN_REFRESH].val_hdl)
        {
            if (param->value[0] == SCPP_SERVER_REQUIRES_REFRESH)
            {
                // Rewrite the most recent settings written on the server
                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);
            }
        }
    }
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 7
0
int gapc_connection_req_ind_handler(ke_msg_id_t msgid,
                                    struct gapc_connection_req_ind *param,
                                    ke_task_id_t dest_id,
                                    ke_task_id_t src_id)
{
  start_pair = 1;

  if (app_env.state == APP_IDLE)
  {
      // We are now connected
      app_env.state = APP_CONNECTED;

      // Retrieve the connection info from the parameters
      app_env.peer_device.device.conhdl = param->conhdl;
      // Retrieve the connection index from the src_id
      app_env.peer_device.device.conidx = KE_IDX_GET(src_id);

      // On Reconnection check if device is bonded and send pairing request. Otherwise it is not bonded.
      if (bdaddr_compare(&app_env.peer_device.device.adv_addr, &param->peer_addr))
      {
          if (app_env.peer_device.bonded)
              start_pair = 0;
      }
      
      memcpy(app_env.peer_device.device.adv_addr.addr, param->peer_addr.addr, sizeof(struct bd_addr));

      app_connect_confirm(GAP_AUTH_REQ_NO_MITM_NO_BOND);

      app_security_enable();
    }

    return 0;
}
Exemplo n.º 8
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATTC_EVENT_IND message.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_event_ind_handler(ke_msg_id_t const msgid,
                                        struct gattc_event_ind const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    // Get the address of the environment
    struct tipc_env_tag *tipc_env = PRF_CLIENT_GET_ENV(dest_id, tipc);

    if(KE_IDX_GET(src_id) == tipc_env->con_info.conidx)
    {
        if(param->handle == tipc_env->cts.chars[TIPC_CHAR_CTS_CURR_TIME].val_hdl)
        {
            //Build a TIPC_CT_IND message
            struct tipc_ct_ind * ind = KE_MSG_ALLOC(TIPC_CT_IND,
                                                    tipc_env->con_info.appid, dest_id,
                                                    tipc_ct_ind);
            // retrieve connection handle
            ind->conhdl = gapc_get_conhdl(tipc_env->con_info.conidx);

            // Unpack Current Time Value.
            tipc_unpack_curr_time_value(&(ind->ct_val), (uint8_t*) param->value);

            // Indication Type
            ind->ind_type = TIP_NTF;

            ke_msg_send(ind);
        }
    }
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 9
0
/*
 ****************************************************************************************
 * @brief Handles the enable confirmation from the HOGPBH. *//**
 *
 * @param[in] msgid     HOGPBH_ENABLE_CFM
 * @param[in] param     Pointer to the struct hogpbh_enable_cfm
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_HOGPBH
 *
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used by the Boot Host to either send the discovery results of HIDS on the HID device 
 *  and confirm enabling of the Boot Host role, or to simply confirm enabling of Boot Host role if it is a normal connection 
 *  and the attribute details are already known. 
 *
 ****************************************************************************************
 */
int app_hogpbh_enable_cfm_handler(ke_msg_id_t const msgid,
                      struct hogpbh_enable_cfm *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    QPRINTF("HOGPBH enable confirmation status: 0x%X.\r\n", param->status);
    if (param->status == CO_ERROR_NO_ERROR)
    {
        uint8_t idx = KE_IDX_GET(src_id);
        app_hogpbh_env[idx].conhdl = param->conhdl;
        app_hogpbh_env[idx].enabled = true;
        app_hogpbh_env[idx].cur_code = 0;

        // Get keyboard instance number here
        if (param->hids[0].descs[HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG].desc_hdl != 0)
            app_hogpbh_env[idx].hids_kb = 0;
        else if (param->hids[1].descs[HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG].desc_hdl != 0)
            app_hogpbh_env[idx].hids_kb = 1;
        else
            app_hogpbh_env[idx].hids_kb = 0xFF;

        // Get mouse instance number here
        if (param->hids[0].descs[HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG].desc_hdl != 0)
            app_hogpbh_env[idx].hids_mouse = 0;
        else if (param->hids[1].descs[HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG].desc_hdl != 0)
            app_hogpbh_env[idx].hids_mouse = 1;
        else
            app_hogpbh_env[idx].hids_mouse = 0xFF;

        if (app_hogpbh_env[idx].hids_kb < HOGPBH_NB_HIDS_INST_MAX)
        {
            // Set Keyboard to Boot report mode
            app_hogpbh_set_boot_proto_mode_req(app_hogpbh_env[idx].hids_kb, param->conhdl);
            // Start Keybaord Notify here
            app_hogpbh_cfg_ntf_req(HOGPBH_DESC_BOOT_KB_IN_REPORT_CFG, PRF_CLI_START_NTF, 
                                    app_hogpbh_env[idx].hids_kb, param->conhdl);
            app_hogpbh_env[idx].cur_code = 1;
        }
        
        if (app_hogpbh_env[idx].hids_mouse != app_hogpbh_env[idx].hids_kb
         && app_hogpbh_env[idx].hids_mouse  < HOGPBH_NB_HIDS_INST_MAX)
        {
            // Set Mouse to Boot protocol mode
            app_hogpbh_set_boot_proto_mode_req(app_hogpbh_env[idx].hids_mouse, param->conhdl);
            if (!app_hogpbh_env[idx].cur_code) {
                // Start Mouse Notify here
                app_hogpbh_cfg_ntf_req(HOGPBH_DESC_BOOT_MOUSE_IN_REPORT_CFG, PRF_CLI_START_NTF, 
                                        app_hogpbh_env[idx].hids_mouse, param->conhdl);
            }
            else {
                app_hogpbh_env[idx].cur_code = 2;
            }
        }
    }
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 10
0
/**
 ****************************************************************************************
 * @brief Handles reception of the @ref GATT_WRITE_CMD_IND message.
 * @param[in] msgid Id of the message received (probably unused).
 * @param[in] param Pointer to the parameters of the message.
 * @param[in] dest_id ID of the receiving task instance (probably unused).
 * @param[in] src_id ID of the sending task instance.
 * @return If the message was consumed or not.
 ****************************************************************************************
 */
static int gattc_write_cmd_ind_handler(ke_msg_id_t const msgid,
                                      struct gattc_write_cmd_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    uint8_t char_code = ADC_NOTIFY_ERR_CHAR;
    uint8_t status = PRF_APP_ERROR;

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

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

    // Send Write Response
    atts_write_rsp_send(adc_notify_env.con_info.conidx, param->handle, status);
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 11
0
uint8_t prf_client_enable(prf_env_struct ***p_envs, struct prf_con_info *p_con_info,
                          void const *p_param, uint16_t env_size)
{
    // Status
    uint8_t status = PRF_ERR_OK;
    // Index
    uint8_t conidx;
    // Pointer to an environment structure
    prf_env_struct *env;

    // Get the index matching this connection handle
    conidx = p_con_info->conidx;

    // Check if the connection exists
    if (conidx != GAP_INVALID_CONIDX)
    {
        // Check if we are in the good task instance
        if (conidx != KE_IDX_GET(p_con_info->prf_id))
        {
            // Forward the message to the good instance of the task
            ke_msg_forward(p_param, KE_BUILD_ID(KE_TYPE_GET(p_con_info->prf_id), conidx), p_con_info->appid);

            /*
             * Here, the status PRF_ERR_FEATURE_NOT_SUPPORTED is used to inform that the message
             * has been forwarded.
             */
            status = PRF_ERR_FEATURE_NOT_SUPPORTED;
        }
        else
        {
            // Create the environment for the provided connection.
            status = prf_client_env_alloc(p_envs, conidx, env_size);

            // Check if the environment has been successfully created.
            if (status == PRF_ERR_OK)
            {
                // Get the profile environment address
                env = *(*p_envs + conidx);

                /*
                 * Save the connection information in the environment.
                 * The first parameter of a profile client role environment is:
                 * struct prf_con_info con_info
                 */
                memcpy(&env->con_info, p_con_info, sizeof(struct prf_con_info));
            }
        }
    }
    else
    {
        // The connection doesn't exists
        status = PRF_ERR_REQ_DISALLOWED;
    }

    return status;
}
Exemplo n.º 12
0
/*
 ****************************************************************************************
 * @brief Handles Indicate the content of the pointer device Phone Alert Status service. *//**
 *
 * @param[in] msgid     PASPC_PASS_CONTENT_IND
 * @param[in] param     Pointer to struct paspc_pass_content
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_PASPC
 * @return If the message was consumed or not.
 * @description
 *
 * This handler message is sent to the application at the end of the discovery procedure
 * performed after the connection establishment. It contains the structure of the peer
 * device PASS. 
 *
 ****************************************************************************************
 */
int app_paspc_pass_content_handler(ke_msg_id_t const msgid,
                                   struct paspc_pass_content_ind *param,
                                   ke_task_id_t const dest_id,
                                   ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);
    app_paspc_env[idx].conhdl = param->conhdl;
    app_paspc_env[idx].enabled = true;
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 13
0
/*
 ****************************************************************************************
 * @brief Handles the result of discovery procedure from TASK_RSCPC. *//**
 *
 * @param[in] msgid     RSCPC_RSCS_CONTENT_IND
 * @param[in] param     Pointer to struct rscpc_rscs_content_ind
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_RSCPC
 * @return If the message was consumed or not.
 * @description
 *
 * This handler is used to inform the application that the result of discovery
 * Running Speed and Cadence Profile Sensor. It contains the structure of the peer
 * device RSCS.
 *
 ****************************************************************************************
 */
int app_rscpc_rscs_content_ind_handler(ke_msg_id_t const msgid,
                                       struct rscpc_rscs_content_ind *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);
    app_rscpc_env[idx].conhdl = param->conhdl;
    app_rscpc_env[idx].enabled = true;
    //app_rscpc_env[app_env.select_idx].rscs = param->rscs;
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 14
0
/**
 ****************************************************************************************
 * @brief Disconnection indication to HTPT.
 * @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 gapc_disconnect_ind_handler(ke_msg_id_t const msgid,
                                      struct gapc_disconnect_ind const *param,
                                      ke_task_id_t const dest_id,
                                      ke_task_id_t const src_id)
{
    if (KE_IDX_GET(src_id) == htpt_env.con_info.conidx)
    {
        htpt_disable(param->conhdl);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 15
0
/*
 ****************************************************************************************
 * @brief Handles the disable indication to APP. *//*
 *
 * @param[in] msgid     GLPC_DISABLE_IND
 * @param[in] param     Pointer to struct prf_client_disable_ind
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_GLPC
 * @return If the message was consumed or not.
 * @description
 *
 * This handler is used to inform the application that the Glucose collector Client
 * Role task has been correctly disabled or if an error has occurred during this process.
 *
 ****************************************************************************************
 */
int app_glpc_disable_ind_handler(ke_msg_id_t const msgid,
                      struct prf_client_disable_ind *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    app_glpc_env[idx].op_state = OPERATION_STATE_IDLE;
    QPRINTF("GLPC disable ind\r\n");

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 16
0
/*
 ****************************************************************************************
 * @brief Handles the QPPC disable indication. *//**
 *
 * @param[in] msgid     QPPC_DISABLE_IND
 * @param[in] param     Pointer to struct prf_client_disable_ind
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_QPPC
 * @return If the message was consumed or not.
 * @description
 * This handler is used to inform the application that the Client Role task has been
 * correctly disabled or if an error has occurred during this process.
 *
 ****************************************************************************************
 */
int app_qppc_disable_ind_handler(ke_msg_id_t const msgid,
                                 struct prf_client_disable_ind *param,
                                 ke_task_id_t const dest_id,
                                 ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);
    QPRINTF("idx = %d\r\n", idx);
    app_qppc_env[idx].conhdl = 0xFFFF;
    app_qppc_env[idx].enabled = false;
    app_qppc_env[idx].nb_ntf_char = 0;

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 17
0
/**
 ****************************************************************************************
 * @brief Disconnection indication to GLPS.
 * @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 gapc_disconnect_ind_handler(ke_msg_id_t const msgid,
                                        struct gapc_disconnect_ind const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{
    //Check Connection Handle
    if (KE_IDX_GET(src_id) == glps_env.con_info.conidx)
    {
        glps_disable(PRF_ERR_DISCONNECTED, param->conhdl);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 18
0
/*
 ****************************************************************************************
 * @brief Handles the generic message for read responses for APP. *//**
 *
 * @param[in] msgid     HRPC_RD_CHAR_RSP
 * @param[in] param     Pointer to struct hrpc_rd_char_rsp
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_HRPC
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used by the Collector role to inform the Application of a received read response. The 
 *  status and the data from the read response are passed directly to Application, which must interpret them based on 
 *  the request it made. 
 * @note 
 * Response for read Body Sensor Location and Heart Rate Measurement Client Cfg.Desc
 *
 ****************************************************************************************
 */
int app_hrpc_rd_char_rsp_handler(ke_msg_id_t const msgid,
                      struct hrpc_rd_char_rsp *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    QPRINTF("HRPC read char response status: 0x%x.\r\n",
        param->status);

    switch (app_hrpc_env[idx].cur_code)
    {
    case 1:
 #if QN_DBG_TRACE_MORE 
        QPRINTF("HRPC Body Sensor Location is ");
        switch (param->data.data[0])
        {
        case HRS_LOC_CHEST:
            QPRINTF("Chest.\r\n");
            break;
        case HRS_LOC_WRIST:
            QPRINTF("Wrist.\r\n");
            break;
        case HRS_LOC_FINGER:
            QPRINTF("Finger.\r\n");
            break;
        case HRS_LOC_HAND:
            QPRINTF("Hand.\r\n");
            break;
        case HRS_LOC_EAR_LOBE:
            QPRINTF("Ear Lobe.\r\n");
            break;
        case HRS_LOC_FOOT:
            QPRINTF("Foot.\r\n");
            break;
        case HRS_LOC_OTHER:
        default:
            QPRINTF("Other.\r\n");
            break;
        }
#endif
        break;
    default:
        break;
    }
    app_task_msg_hdl(msgid, param);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 19
0
prf_env_struct *prf_client_get_env(prf_env_struct **p_envs, ke_task_id_t task_id)
{
    // Address of the environement
    prf_env_struct *env = NULL;

    // Check if the provided pool of environments has been allocated
    if (p_envs != NULL)
    {
        // Get the address stored in the pool
        env = *(p_envs + KE_IDX_GET(task_id));
    }

    // Return the address of the environment
    return env;
}
Exemplo n.º 20
0
/*
 ****************************************************************************************
 * @brief Handles the generic message for read responses for APP. *//**
 *
 * @param[in] msgid     QPPC_RD_CHAR_RSP
 * @param[in] param     Pointer to struct qppc_rd_char_rsp
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_QPPC
 * @return If the message was consumed or not.
 * @description
 * This API is used by the Client role to inform the Application of a received read response. The 
 * status and the data from the read response are passed directly to Application, which must interpret 
 * them based on the request it made.
 *
 ****************************************************************************************
 */
int app_qppc_rd_char_rsp_handler(ke_msg_id_t const msgid,
                                 struct qppc_rd_char_rsp *param,
                                 ke_task_id_t const dest_id,
                                 ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    if (app_qppc_env[idx].cur_code == QPPC_QPPS_RX_CHAR_VALUE_USER_DESP)
    {
        app_qppc_cfg_indntf_req(PRF_CLI_START_NTF, app_qppc_env[idx].conhdl, QPPC_QPPS_FIRST_TX_VALUE_CLI_CFG);
        app_qppc_env[idx].cur_code = QPPC_QPPS_FIRST_TX_VALUE_CLI_CFG;
    }
    app_task_msg_hdl(msgid, param);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 21
0
/**
 ****************************************************************************************
 * @brief Disconnection indication to sample128.
 * @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 gap_disconnnect_ind_handler(ke_msg_id_t const msgid,
                                        struct gapc_disconnect_ind const *param,
                                        ke_task_id_t const dest_id,
                                        ke_task_id_t const src_id)
{

    // Check Connection Handle
    if (KE_IDX_GET(src_id) == sample128_env.con_info.conidx)
    {
        
        // In any case, inform APP about disconnection
        sample128_disable();
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 22
0
int app_qppc_data_ind_handler(ke_msg_id_t const msgid,
                              struct qppc_data_ind *param,
                              ke_task_id_t const dest_id,
                              ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    if ((data_pack%200) == 0 && (data_pack != 0))
    {
        QPRINTF("(%d)Received %d bytes data[%02X] from characteristic %d\r\n", idx, param->length, param->data[0], param->char_code);
    }
    app_task_msg_hdl(msgid, param);
    data_pack ++;

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 23
0
/*
 ****************************************************************************************
 * @brief Handles the enable confirmation from the TIPC. *//**
 *
 * @param[in] msgid     TIPC_ENABLE_CFM
 * @param[in] param     Pointer to struct tipc_enable_cfm
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_TIPC
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used by the Client to either send the discovery results of CTS, NDCS or 
 *  RTUS and confirm enabling of the Client role (status = PRF_ERR_OK), or to simply confirm 
 *  enabling of Client role if it is a normal connection and the attribute details are already known 
 *  (status = PRF_ERR_OK), or to inform the application that the discovery process has been 
 *  stopped because of a missing attribute (status = PRF_ERR_STOP_DISC_CHAR_MISSING).
 *
 ****************************************************************************************
 */
int app_tipc_enable_cfm_handler(ke_msg_id_t const msgid,
                      struct tipc_enable_cfm *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    QPRINTF("TIPC enable confirmation status: 0x%X.\r\n", param->status);
    if (param->status == CO_ERROR_NO_ERROR)
    {
        uint8_t idx = KE_IDX_GET(src_id);
        app_tipc_env[idx].conhdl = param->conhdl;
        app_tipc_env[idx].enabled = true;
    }
    app_task_msg_hdl(msgid, param);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 24
0
/*
 ****************************************************************************************
 * @brief Handles the generic message for write characteristic response status to APP.  *//**
 *
 * @param[in] msgid     QPPC_WR_CHAR_RSP
 * @param[in] param     Pointer to struct qppc_wr_char_rsp
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_QPPC
 * @return If the message was consumed or not.
 * @description
 * This API is used by the Client role to inform the Application of a received write response.  
 * The status and the data from the write response are passed directly to Application, which 
 * must interpret them based on the request it made.
 *
 ****************************************************************************************
 */
int app_qppc_wr_char_rsp_handler(ke_msg_id_t const msgid,
                                 struct qppc_wr_char_rsp *param,
                                 ke_task_id_t const dest_id,
                                 ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    if (param->status == CO_ERROR_NO_ERROR)
    {
        if (app_qppc_env[idx].cur_code < app_qppc_env[idx].nb_ntf_char)
        {
            app_qppc_cfg_indntf_req(PRF_CLI_START_NTF, app_qppc_env[idx].conhdl, ++app_qppc_env[idx].cur_code);
        }
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 25
0
/**
 ****************************************************************************************
 * @brief Handles connection complete event from the GAP. Will enable 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 gapc_connection_req_ind_handler(ke_msg_id_t const msgid,
                                           struct gapc_connection_req_ind const *param,
                                           ke_task_id_t const dest_id,
                                           ke_task_id_t const src_id)
{
    // Connection Index
    if (ke_state_get(dest_id) == APP_CONNECTABLE) {
        app_env.conidx = KE_IDX_GET(src_id);
        app_connection_func(param);
    }
    else {
        // APP_CONNECTABLE state is used to wait the GAP_LE_CREATE_CONN_REQ_CMP_EVT message
        ASSERT_ERR(0);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 26
0
/**
 ****************************************************************************************
 * @brief Handles connection complete event from the GAP. Will enable 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 gapc_connection_req_ind_handler(ke_msg_id_t const msgid,
                                           struct gapc_connection_req_ind const *param,
                                           ke_task_id_t const dest_id,
                                           ke_task_id_t const src_id)
{
		// Connection Index
		if (ke_state_get(dest_id) == APP_CONNECTABLE)
		{
				app_env.conidx = KE_IDX_GET(src_id);
				
				if (app_env.conidx != GAP_INVALID_CONIDX)
				{
						//Disable timer of the establishment of the connection
						ke_timer_clear(APP_CONN_TIMER, TASK_APP);
						
						ke_state_set(dest_id, APP_CONNECTED);
						
						app_connection_func(param);
						
						// Retrieve the connection info from the parameters
						app_env.conhdl = param->conhdl;
						
						app_env.peer_addr_type = param->peer_addr_type;
						memcpy(app_env.peer_addr.addr, param->peer_addr.addr, BD_ADDR_LEN);
             
						// send connection confirmation    // 发送连接确认aiwesky 20151004
						app_connect_confirm(GAP_AUTH_REQ_NO_MITM_NO_BOND);            
						
						// Start param update
						app_param_update_start();         // 此时,就可以进行profile读取了  aiwesky 20151004
				}
				else
				{
						// No connection has been establish, restart advertising
						app_adv_start();    // 如果没有连接,则继续进行广播 aiwesky 20151005
				}        
				
		}
		else
		{
				// APP_CONNECTABLE state is used to wait the GAP_LE_CREATE_CONN_REQ_CMP_EVT message
				ASSERT_ERR(0);
    }

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 27
0
/*
 ****************************************************************************************
 * @brief Handles the generic message for Send Read Report Map value to APP. *//**
 *
 * @param[in] msgid     HOGPRH_REPORT_MAP_RD_RSP 
 * @param[in] param     Pointer to the struct hogprh_report_map_rd_rsp
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_HOGPRH
 *
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used to inform the application about the read Report Map Characteristic value. 
 *
 ****************************************************************************************
 */
int app_hogprh_report_map_rd_rsp_handler(ke_msg_id_t const msgid,
                      struct hogprh_report_map_rd_rsp *param,
                      ke_task_id_t const dest_id,
                      ke_task_id_t const src_id)
{
    QPRINTF("HOGPRH report map read response(%d):\r\n", param->hids_nb);
    QTRACE(param->report_map, param->report_map_length, 0, 2);
    QPRINTF("\r\n");
    uint8_t idx = KE_IDX_GET(src_id);
    if (param->hids_nb+1 < app_hogprh_env[idx].hids_nb) {
        app_hogprh_rd_char_req(HOGPRH_RD_HIDS_REPORT_MAP, 0, param->hids_nb+1, param->conhdl);
    }
    else {
        app_hogprh_rd_char_req(HOGPRH_RD_HIDS_HID_INFO, 0, 0, param->conhdl);
    }
    
    return (KE_MSG_CONSUMED);
}
Exemplo n.º 28
0
void prf_client_enable_error(prf_env_struct ***p_envs, ke_task_id_t prf_task_id,
                             ke_state_t disc_state, ke_state_t idle_state)
{
    /* An error has been raised, three possibilities:
     *      - Either the state is IDLE, no environment has been created, nothing to do,
     *      - Or the state is DISCOVERING, we need to come back to the IDLE state and to remove the
     * environment,
     *      - Or the state is CONNECTED, the profile was already connected for the provided connection,
     * nothing to do
     */
    if (ke_state_get(prf_task_id) == disc_state)
    {
        // Come back to IDLE State
        ke_state_set(prf_task_id, idle_state);

        // Remove the allocated environment
        prf_client_disable(p_envs, KE_IDX_GET(prf_task_id));
    }
}
Exemplo n.º 29
0
/*
 ****************************************************************************************
 * @brief Handles the generic message for read responses for APP. *//**
 *
 * @param[in] msgid     PROXM_RD_CHAR_RSP
 * @param[in] param     Pointer to struct proxm_rd_char_rsp
 * @param[in] dest_id   TASK_APP
 * @param[in] src_id    TASK_PROXM
 * @return If the message was consumed or not.
 * @description
 *
 *  This API is used by the Monitor role to send the Application the
 *  characteristic read response data and the status of the read characteristic request. The
 *  application is in charge of deciphering the data or of the next step if an error is received.
 *
 ****************************************************************************************
 */
int app_proxm_rd_char_rsp_handler(ke_msg_id_t const msgid,
                                  struct proxm_rd_char_rsp *param,
                                  ke_task_id_t const dest_id,
                                  ke_task_id_t const src_id)
{
    uint8_t idx = KE_IDX_GET(src_id);

    QPRINTF("PROXM read char response status: 0x%X.\r\n", param->status);

    if (param->status == CO_ERROR_NO_ERROR)
    {
        if (app_proxm_env[idx].cur_code == 1)
            QPRINTF("Alert Level: ");
        else
            QPRINTF("TX Power Level: ");

        if (app_proxm_env[idx].cur_code == 1)
        {
            switch (param->val)
            {
            case PROXM_ALERT_NONE:
                QPRINTF("None.");
                break;
            case PROXM_ALERT_MILD:
                QPRINTF("Mild.");
                break;
            case PROXM_ALERT_HIGH:
                QPRINTF("High.");
                break;
            default:
                QPRINTF("Error.");
                break;
            }
        }
        else
            QPRINTF("%+d dbm", (int8_t)param->val);
        QPRINTF("\r\n");
    }
    app_task_msg_hdl(msgid, param);

    return (KE_MSG_CONSUMED);
}
Exemplo n.º 30
0
/**
 ****************************************************************************************
 * @brief Disconnection indication to HTTP Server.
 *
 * @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 gapc_disconnect_ind_handler(ke_msg_id_t const msgid,
                                       struct gapc_disconnect_ind const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
{
    // Check Connection Handle
    if (KE_IDX_GET(src_id) == hpss_env.con_info.conidx)
    {
        // Abnormal reason
        if ((param->reason != CO_ERROR_REMOTE_USER_TERM_CON) &&
                (param->reason != CO_ERROR_CON_TERM_BY_LOCAL_HOST))
        {
        }

        // In any case, inform APP about disconnection
        hpss_disable(param->conhdl);
    }

    return (KE_MSG_CONSUMED);
}