void sendKeys(u8* buffer)
{
  u32 i;
#ifdef NOT_USED
  if (bDeviceState == CONFIGURED)
  {
    while(!PrevXferComplete);
      
    PrevXferComplete = 0;
  /* Use the memory interface function to write to the selected endpoint */
    UserToPMABufferCopy(buffer, ENDP4_TXADDR, 8);
   
  /* Update the data length in the control register */
    SetEPTxCount(ENDP4, 8);
    SetEPTxStatus (ENDP4, EP_TX_VALID);
      
  }
#endif

  while (Is_usb_endpoint_stall_requested(EP_KB_IN))
  {
    if (Is_usb_setup_received())
    {
      usb_process_request();
    }
  }

  // MSC Compliance - Free BAD out receive during SCSI command
  while( Is_usb_out_received(EP_CCID_OUT) ) {
    Usb_ack_out_received_free(EP_CCID_OUT);
  }

  while (!Is_usb_in_ready(EP_KB_IN))
  {
     if(!Is_usb_endpoint_enabled(EP_KB_IN))
     {
       i = 0; // todo USB Reset
     }
  }

  Usb_reset_endpoint_fifo_access(EP_KB_IN);
/*
  Usb_write_endpoint_data(EP_KB_IN, 8, 'D');
  Usb_write_endpoint_data(EP_KB_IN, 8, 'D');
  Usb_write_endpoint_data(EP_KB_IN, 8, 'D');
  Usb_write_endpoint_data(EP_KB_IN, 8, 'D');
*/
  usb_write_ep_txpacket(EP_KB_IN, buffer, 8, NULL);
//  Usb_send_in(EP_CONTROL);

  Usb_ack_in_ready_send(EP_KB_IN);


  // MSC Compliance - Wait end of all transmitions on USB line
  while( 0 != Usb_nb_busy_bank(EP_KB_IN) )
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

}
//!
//! @brief USB Command Status Wrapper (CSW) management
//!
//! This function sends the status in relation with the last CBW.
//!
static void usb_mass_storage_csw(void)
{
  while (Is_usb_endpoint_stall_requested(EP_MS_IN))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  while (Is_usb_endpoint_stall_requested(EP_MS_OUT))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  while (!Is_usb_in_ready(EP_MS_IN));

  Usb_reset_endpoint_fifo_access(EP_MS_IN);

  //! Write CSW Signature
  Usb_write_endpoint_data(EP_MS_IN, 32, *(U32 *)&"USBS");

  //! Write stored CBW Tag
  Usb_write_endpoint_data(EP_MS_IN, 32, dCBWTag);

  //! Write data residual value
  Usb_write_endpoint_data(EP_MS_IN, 32,
                          usb_format_mcu_to_usb_data(32, g_scsi_data_remaining));

  //! Write command status
  Usb_write_endpoint_data(EP_MS_IN, 8, g_scsi_status);

  Usb_ack_in_ready_send(EP_MS_IN);
}
static void USB_CCID_SendDataToUSB (void)
{
    int USB_Datalen_s32;
    int i;

    while (Is_usb_endpoint_stall_requested (EP_CCID_IN))
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }

    while (Is_usb_endpoint_stall_requested (EP_CCID_OUT))
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }

    // MSC Compliance - Free BAD out receive during SCSI command

    while (Is_usb_out_received (EP_CCID_OUT))
    {
        Usb_ack_out_received_free (EP_CCID_OUT);
    }

    while (!Is_usb_in_ready (EP_CCID_IN))
    {
        if (!Is_usb_endpoint_enabled (EP_CCID_IN))
        {
            i = 0;  // todo USB Reset
        }
    }

    Usb_reset_endpoint_fifo_access (EP_CCID_IN);

    USB_Datalen_s32 = USB_CCID_data_st.CCID_datalen + 10;

    for (i = 0; i < USB_Datalen_s32; i++)
    {
        Usb_write_endpoint_data (EP_CCID_IN, 8, USB_CCID_data_st.USB_data[i]);
    }

    Usb_ack_in_ready_send (EP_CCID_IN);

    USB_Log_st.CCID_ReadCalls_u32++;
    USB_Log_st.CCID_BytesRead_u32 += USB_Datalen_s32;


    // MSC Compliance - Wait end of all transmitions on USB line
    while (0 != Usb_nb_busy_bank (EP_CCID_IN))
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }
}
//!
//! @brief USB Command Status Wrapper (CSW) management
//!
//! This function sends the status in relation with the last CBW.
//!
static void usb_mass_storage_csw(void)
{
  while (Is_usb_endpoint_stall_requested(EP_MS_IN))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  while (Is_usb_endpoint_stall_requested(EP_MS_OUT))
  {
    if (Is_usb_setup_received()) usb_process_request();
  }

  // MSC Compliance - Free BAD out receive during SCSI command
  while( Is_usb_out_received(EP_MS_OUT) ) {
    Usb_ack_out_received_free(EP_MS_OUT);
  }

  while (!Is_usb_in_ready(EP_MS_IN));

  Usb_reset_endpoint_fifo_access(EP_MS_IN);

  //! Write CSW Signature
  Usb_write_endpoint_data(EP_MS_IN, 32, *(U32 *)&"USBS");

  //! Write stored CBW Tag
  Usb_write_endpoint_data(EP_MS_IN, 32, dCBWTag);

  //! Write data residual value
  Usb_write_endpoint_data(EP_MS_IN, 32,
                          usb_format_mcu_to_usb_data(32, g_scsi_data_remaining));

  //! Write command status
  Usb_write_endpoint_data(EP_MS_IN, 8, g_scsi_status);

  Usb_ack_in_ready_send(EP_MS_IN);

  // MSC Compliance - Wait end of all transmissions on USB line
  while( 0 != Usb_nb_busy_bank(EP_MS_IN) )
  {
    if (Is_usb_setup_received()) usb_process_request();
  }


  // Release the USB Mutex.
  if( true == xGiveUsbMutex )
  {
    x_supervisor_SemaphoreGive( xUSBMutex );
  }
}
void USB_CCID_send_INT_Message (void)
{
    unsigned short Message_u16;
    int i, i1;
    /* todo while (Is_usb_endpoint_stall_requested(EP_CCID_IN)) { if (Is_usb_setup_received()) usb_process_request(); }

       while (Is_usb_endpoint_stall_requested(EP_CCID_OUT)) { if (Is_usb_setup_received()) usb_process_request(); }

       // MSC Compliance - Free BAD out receive during SCSI command while( Is_usb_out_received(EP_CCID_OUT) ) {
       Usb_ack_out_received_free(EP_CCID_OUT); } */
    while (!Is_usb_in_ready (EP_CCID_INT));

    Usb_reset_endpoint_fifo_access (EP_CCID_INT);

    Message_u16 = 0x5003;

    i = Usb_byte_count (EP_CCID_INT);

    Usb_write_endpoint_data (EP_CCID_INT, 16, Message_u16);

    i1 = Usb_byte_count (EP_CCID_INT);

    Usb_ack_in_ready_send (EP_CCID_INT);

    // MSC Compliance - Wait end of all transmitions on USB line
    for (i = 0; i < 100; i++)
    {
        if (0 != Usb_nb_busy_bank (EP_CCID_INT))
        {
            if (Is_usb_setup_received ())
                usb_process_request ();
        }
        else
        {
            break;
        }
    }

}
// !
// ! @brief USB Command Status Wrapper (CSW) management
// !
// ! This function sends the status in relation with the last CBW.
// !
static void usb_mass_storage_csw (void)
{
    int i;
    /*
       i = 1; while (1 == i) { i = 0; if (Is_usb_endpoint_stall_requested(EP_MS_IN)) { i = 1; if (Is_usb_setup_received()) { usb_process_request(); }
       }

       if (Is_usb_endpoint_stall_requested(EP_MS_OUT)) { i = 1; if (Is_usb_setup_received()) { usb_process_request(); } } } */


    while (Is_usb_endpoint_stall_requested (EP_MS_IN))
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }

    while (Is_usb_endpoint_stall_requested (EP_MS_OUT))
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }


    // MSC Compliance - Free BAD out receiv during SCSI command
    while (Is_usb_out_received (EP_MS_OUT))
    {
        Usb_ack_out_received_free (EP_MS_OUT);
    }

    while (!Is_usb_in_ready (EP_MS_IN));
    /*
       // for (i=0;i<100000;i++) // Make break out { if (Is_usb_in_ready(EP_MS_IN)) { break; } } */
    Usb_reset_endpoint_fifo_access (EP_MS_IN);

    // ! Write CSW Signature
    Usb_write_endpoint_data (EP_MS_IN, 32, *(U32 *) & "USBS");

    // ! Write stored CBW Tag
    Usb_write_endpoint_data (EP_MS_IN, 32, dCBWTag);

    // ! Write data residual value
    Usb_write_endpoint_data (EP_MS_IN, 32, usb_format_mcu_to_usb_data (32, g_scsi_data_remaining));

    // ! Write command status
    Usb_write_endpoint_data (EP_MS_IN, 8, g_scsi_status);

    Usb_ack_in_ready_send (EP_MS_IN);

    // MSC Compliance - Wait end of all transmitions on USB line
    for (i = 0; i < 1000; i++)
    {
        if (0 != Usb_nb_busy_bank (EP_MS_IN))
        {
            if (Is_usb_setup_received ())
                usb_process_request ();
        }
        else
        {
            break;
        }
    }
    /*
       while( 0 != Usb_nb_busy_bank(EP_MS_IN) ) { if (Is_usb_setup_received()) usb_process_request(); } */
}
static void usb_mass_storage_csw(void)
{
	volatile U32 timeoutTickCount = g_lifetimeHalfSecondTickCount + 6;

  while (Is_usb_endpoint_stall_requested(EP_MS_IN))
  {
	if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset
	if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; }

    if (Is_usb_setup_received())
	{
		usb_process_request();
		  timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6;
	}
  }

  timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6;

  while (Is_usb_endpoint_stall_requested(EP_MS_OUT))
  {
	if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset
	if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; }

    if (Is_usb_setup_received())
	{
		usb_process_request();
		  timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6;
	}
  }

  // MSC Compliance - Free BAD out receive during SCSI command
  while( Is_usb_out_received(EP_MS_OUT) ) {
    Usb_ack_out_received_free(EP_MS_OUT);
  }

  timeoutTickCount = (volatile U32)g_lifetimeHalfSecondTickCount + 6;

  while (!Is_usb_in_ready(EP_MS_IN))
  {
	if (!Is_usb_endpoint_enabled(g_scsi_ep_ms_in)) { return; } // USB Reset
	if ((volatile U32)timeoutTickCount == (volatile U32)g_lifetimeHalfSecondTickCount) { return; }
  }

  Usb_reset_endpoint_fifo_access(EP_MS_IN);

  //! Write CSW Signature
  Usb_write_endpoint_data(EP_MS_IN, 32, *(uint32_t *)&"USBS");

  //! Write stored CBW Tag
  Usb_write_endpoint_data(EP_MS_IN, 32, dCBWTag);

  //! Write data residual value
  Usb_write_endpoint_data(EP_MS_IN, 32,
                          usb_format_mcu_to_usb_data(32, g_scsi_data_remaining));

  //! Write command status
  Usb_write_endpoint_data(EP_MS_IN, 8, g_scsi_status);

  Usb_ack_in_ready_send(EP_MS_IN);

  // MSC Compliance - Wait end of all transmissions on USB line
  while( 0 != Usb_nb_busy_bank(EP_MS_IN) )
  {
    if (Is_usb_setup_received()) usb_process_request();
  }
}
void USB_CCID_task (void* pvParameters)
{
    unsigned char Startup_b = TRUE;
    portTickType xLastWakeTime;

    ISO7816_InitSC ();
    /*
       CI_LocalPrintf ("USB_CCID : USB CCID raise IN ready - %d\n",xTaskGetTickCount()); */
    // Start CCID interface
    while (0 != Usb_nb_busy_bank (EP_CCID_IN))  // MSC Compliance - Wait end of all transmitions on USB line
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }
    Usb_raise_in_ready (EP_CCID_IN);

    // Start keyboard interface
    while (0 != Usb_nb_busy_bank (EP_KB_IN))    // MSC Compliance - Wait end of all transmitions on USB line
    {
        if (Is_usb_setup_received ())
            usb_process_request ();
    }
    Usb_raise_in_ready (EP_KB_IN);


    xLastWakeTime = xTaskGetTickCount ();

    while (TRUE)
    {
        vTaskDelayUntil (&xLastWakeTime, configTSK_USB_CCID_PERIOD);

        // First, check the device enumeration state
        if (!Is_device_enumerated ())
            continue;

        // If smartcard is ready send it over usb
        if (TRUE == Startup_b)
        {
            Startup_b = FALSE;
            // CI_LocalPrintf ("USB_CCID : USB CCID started - %d\n",xTaskGetTickCount());
            DelayMs (100);  // Wait 100 ms
            USB_CCID_send_INT_Message ();   // We are always online
        }

        // If we receive something in the OUT endpoint, parse it
        if (Is_usb_out_received (EP_CCID_OUT))
        {
#ifdef TIME_MEASURING_ENABLE
            TIME_MEASURING_Start (TIME_MEASURING_TIME_CCID_USB_GET);
#endif
            USB_CCID_GetDataFromUSB ();
#ifdef TIME_MEASURING_ENABLE
            TIME_MEASURING_Stop (TIME_MEASURING_TIME_CCID_USB_GET);
            TIME_MEASURING_Start (TIME_MEASURING_TIME_CCID_USB_SEND);
#endif
            USB_CCID_SendDataToUSB ();

            USB_to_CRD_DispatchUSBMessage_v (&USB_CCID_data_st);

// Clear buffer after transmission
            memset (USB_CCID_data_st.USB_data,0,CCID_MAX_XFER_LENGTH);

#ifdef TIME_MEASURING_ENABLE
            TIME_MEASURING_Stop (TIME_MEASURING_TIME_CCID_USB_SEND);
#endif
        }
    }
}