/*===========================================================================
FUNCTION   ftm_nfc_dispatch
DESCRIPTION
This is the function which will be called by the NFC FTM layer callback function
registered with the DIAG service./
DEPENDENCIES
RETURN VALUE
  RETURN rsp pointer(containing the NFCC rsp packets) to the callback function
  (subsequently for DIAG service)
SIDE EFFECTS
  None
===========================================================================*/
void* ftm_nfc_dispatch(ftm_nfc_pkt_type *nfc_ftm_pkt, uint16 pkt_len)
{
    ftm_nfc_i2c_write_rsp_pkt_type *i2c_write_rsp = NULL;
    ftm_nfc_i2c_read_rsp_pkt_type *i2c_read_rsp = NULL;
    ftm_nfc_pkt_type *rsp = NULL;
    ftm_nfc_data_rsp_pkt_type *nfc_data_rsp = NULL;
    struct timespec time_sec;
    int sem_status;
    printf("NFC FTM : nfc ftm mode requested \n");
    if(nfc_ftm_pkt == NULL)
    {
        printf("Error : NULL packet recieved from DIAG \n");
        goto error_case;
    }
    /* Start nfc_ftm_thread which will process all requests as per
       state machine flow. By Default First state will be NCI_HAL_INIT*/
    if(!nfc_ftmthread)
    {
        if(sem_init(&semaphore_halcmd_complete, 0, 1) != 0)
        {
            printf("NFC FTM :semaphore_halcmd_complete creation failed \n");
            goto error_case;
        }
        if(sem_init(&semaphore_nfcftmcmd_complete, 0, 0) != 0)
        {
            printf("NFC FTM :semaphore_nfcftmcmd_complete creation failed \n");
            goto error_case;
        }
        printf("NFC FTM : nfc ftm thread is being started \n");
        pthread_create(&nfc_thread_handle, NULL, nfc_ftm_thread, NULL);
        nfc_ftmthread = TRUE;
    }
    /* parse the diag packet to identify the NFC FTM command which needs to be sent
       to QCA 1990*/
    if(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_len > 2)
    {
        len = nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_len-2;
    }
    else
    {
        /*Wrong nfc ftm packet*/
        goto error_case;
    }
    switch(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_id)
    {
        case FTM_NFC_I2C_SLAVE_WRITE:
             i2c_req_write = TRUE;
             break;
        case FTM_NFC_I2C_SLAVE_READ:
             i2c_num_of_reg_to_read = len;
             i2c_req_read = TRUE;
             break;
        case FTM_NFC_NFCC_COMMAND:
        case FTM_NFC_SEND_DATA:
             break;
        default :
             goto error_case;
             break;
    }
    /*copy command to send it further to QCA1990*/
    nfc_cmd_buff = (uint8 *)malloc(len+1);
    if(nfc_cmd_buff)
    {
        memcpy(nfc_cmd_buff, nfc_ftm_pkt->nci_data, len);
    }
    else
    {
        printf("Mem allocation failed for cmd storage");
        goto error_case;
    }
    /*send the command */
    sem_post(&semaphore_halcmd_complete);
    printf("\nwaiting for nfc ftm response \n");
    if (clock_gettime(CLOCK_REALTIME, &time_sec) == -1)
    {
        printf("get clock_gettime error");
    }
    time_sec.tv_sec += FTM_NFC_CMD_CMPL_TIMEOUT;
    sem_status = sem_timedwait(&semaphore_nfcftmcmd_complete,&time_sec);
    if(sem_status == -1)
    {
        printf("nfc ftm command timed out\n");
        goto error_case;
    }
    if(!hal_opened)
    {
        /*Hal open is failed */
        free(nfc_cmd_buff);
        hal_state = NCI_HAL_INIT;
        goto error_case;
    }
    printf("\n\n *****Framing the response to send back to Diag service******** \n\n");
    /* Frame the response as per the cmd request*/
    switch(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_id)
    {
        case FTM_NFC_I2C_SLAVE_WRITE:
             printf("Framing the response for FTM_NFC_I2C_SLAVE_WRITE cmd \n");
             i2c_write_rsp = (ftm_nfc_i2c_write_rsp_pkt_type*)diagpkt_subsys_alloc(DIAG_SUBSYS_FTM,
                                                                                   FTM_NFC_CMD_CODE,
                                                                                   sizeof(ftm_nfc_i2c_write_rsp_pkt_type));
             if(i2c_write_rsp)
             {
                 i2c_write_rsp->nfc_i2c_slave_status = i2c_status;
                 i2c_status = 0;
                 i2c_cmd_cnt = 0;
                 i2c_req_write = FALSE;
             }
             break;
       case  FTM_NFC_I2C_SLAVE_READ:
             printf("Framing the response for FTM_NFC_I2C_SLAVE_READ cmd \n");
             i2c_read_rsp = (ftm_nfc_i2c_read_rsp_pkt_type*)diagpkt_subsys_alloc(DIAG_SUBSYS_FTM,
                                                                                 FTM_NFC_CMD_CODE,
                                                                                 sizeof(ftm_nfc_i2c_read_rsp_pkt_type));
             if(i2c_read_rsp)
             {
                 i2c_read_rsp->ftm_nfc_hdr.nfc_cmd_id = FTM_NFC_I2C_SLAVE_READ;
                 i2c_read_rsp->ftm_nfc_hdr.nfc_cmd_len = 2+(2*i2c_num_of_reg_to_read);
                 i2c_read_rsp->nfc_i2c_slave_status = i2c_status;
                 if(i2c_status == 0x00)
                 {
                     i2c_read_rsp->nfc_nb_reg_reads = i2c_num_of_reg_to_read;
                 }
                 else
                 {
                     i2c_read_rsp->nfc_nb_reg_reads = 0x00; // error case so return num of read as 0x00.
                 }
                 memcpy(i2c_read_rsp->i2c_reg_read_rsp, i2c_reg_read_data, (i2c_num_of_reg_to_read*2));
                 i2c_cmd_cnt = 0;
             }
             break;
        case FTM_NFC_NFCC_COMMAND:
             printf("Framing the response for FTM_NFC_NFCC_COMMAND cmd \n");
             if(response_buff && res_len)
             {
                 rsp = (ftm_nfc_pkt_type*)diagpkt_subsys_alloc(DIAG_SUBSYS_FTM,
                                                               FTM_NFC_CMD_CODE,
                                                               sizeof(ftm_nfc_pkt_type));
                 if(rsp)
                 {
                     rsp->ftm_nfc_hdr.nfc_cmd_id = FTM_NFC_NFCC_COMMAND;
                     rsp->ftm_nfc_hdr.nfc_cmd_len = 2+res_len;
                     rsp->nfc_nci_pkt_len = res_len;
                     memcpy(rsp->nci_data, response_buff, res_len);
                     free(response_buff);
                     response_buff = 0;
                     res_len = 0;
                 }
             }
             else
                 printf("ftm_nfc_dispatch : response_buff = 0x%x, res_len = %d", response_buff, res_len);
             break;
        case FTM_NFC_SEND_DATA:
             printf("Framing the response for FTM_NFC_SEND_DATA cmd \n");
             nfc_data_rsp = (ftm_nfc_data_rsp_pkt_type*)diagpkt_subsys_alloc(DIAG_SUBSYS_FTM,
                                                                             FTM_NFC_CMD_CODE,
                                                                             sizeof(ftm_nfc_data_rsp_pkt_type));
             if(nfc_data_rsp)
             {
                 nfc_data_rsp->ftm_nfc_hdr.nfc_cmd_id = FTM_NFC_SEND_DATA;
                 nfc_data_rsp->ftm_nfc_hdr.nfc_cmd_len = 0;/*Rsp as per the NFC FTM data rsp req*/
             }
             break;
        default:
             goto error_case;
             break;
    }
    free(nfc_cmd_buff);
    hal_state = NCI_HAL_WRITE;
    if(async_msg_available)
    {
        printf(" Some async message available.. committing now.\n");
        hal_state = NCI_HAL_ASYNC_LOG;
        sem_post(&semaphore_halcmd_complete);
    }
    wait_rsp = FALSE;
    if(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_id == FTM_NFC_I2C_SLAVE_WRITE)
    {
        return(void*)i2c_write_rsp;
    }
    else if(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_id == FTM_NFC_I2C_SLAVE_READ)
    {
        i2c_req_read = FALSE;
        return(void*)i2c_read_rsp;
    }
    else if(nfc_ftm_pkt->ftm_nfc_hdr.nfc_cmd_id == FTM_NFC_NFCC_COMMAND)
    {
        return(void*)rsp;
    }
    else
    {
        return(void*)nfc_data_rsp;
    }
error_case:
    return NULL;
}
Esempio n. 2
0
1 -  CMD type
FC00 - VS Command OpCode

*/

PACK(void *) cnss_wlan_handle(PACK(void *)req_pkt, uint16_t pkt_len)
{
    PACK(void *)rsp = NULL;
    uint8_t *pkt_ptr = (uint8_t *)req_pkt + 4;
    uint16_t p_len, p_opcode;
    int32_t ret = 0, i = 0;
    char cmd[BUF_SIZ] = {0};

   /* Allocate the same length as the request
   */
    rsp = diagpkt_subsys_alloc( DIAG_SUBSYS_WLAN, CNSS_WLAN_DIAG, pkt_len);
    if (rsp  != NULL && pkt_len > 3)
    {
        p_len = *(pkt_ptr+3); /* VS Command packet length */
        p_opcode = (*(pkt_ptr+2) << 8) | *(pkt_ptr+1);
        debug_printf(
            "%s : p_len: %d, pkt_len -8: %d, p_opcode:%.04x  cmd = %d\n",
              __func__, p_len, pkt_len -8, p_opcode, *pkt_ptr
                 );
        if (p_len !=(pkt_len - 8) || ( p_opcode != 0xFD00)) {
            debug_printf("%s:Error in p_len or p_opcode ", __func__ );
            return rsp;
        }
        memcpy(rsp, req_pkt, pkt_len);
        if (*pkt_ptr == CNSS_WLAN_SSR_TYPE && p_len > 1) {
            /* get ID */