#include "atca_hal.h"
#include "hal_win_kit_hid.h"
#include "kit_protocol.h"
#include "kit_phy.h"
#include <SetupAPI.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
atcahid_t _gHid;
#define HID_GUID { 0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 }
ATCA_STATUS hal_kit_hid_init(void* hal, ATCAIfaceCfg* cfg)
{
ATCA_STATUS status = ATCA_SUCCESS;
ATCAHAL_t *phal = NULL;
GUID hid_guid = HID_GUID;
HDEVINFO dev_info;
SP_DEVICE_INTERFACE_DATA dev_data;
PSP_DEVICE_INTERFACE_DETAIL_DATA dev_detail_data;
DWORD required_size = 0;
BOOL result = FALSE;
DWORD device_index = 0;
int i = 0;
int index = 0;
TCHAR hid_filter[32];
if ((hal == NULL) || (cfg == NULL))
{
return ATCA_BAD_PARAM;
}
phal = (ATCAHAL_t*)hal;
memset(&_gHid, 0, sizeof(_gHid));
for (i = 0; i < HID_DEVICES_MAX; i++)
{
_gHid.kits[i].read_handle = INVALID_HANDLE_VALUE;
_gHid.kits[i].write_handle = INVALID_HANDLE_VALUE;
}
_gHid.num_kits_found = 0;
dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
if (dev_info == INVALID_HANDLE_VALUE)
{
return ATCA_COMM_FAIL;
}
memset(&dev_data, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
dev_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
memset(hid_filter, 0, sizeof(hid_filter));
_stprintf(hid_filter, _T("vid_%04x&pid_%04x"), cfg->atcahid.vid, cfg->atcahid.pid);
while (SetupDiEnumDeviceInterfaces(dev_info, NULL, &hid_guid, device_index, &dev_data))
{
SetupDiGetDeviceInterfaceDetail(dev_info, &dev_data, NULL, 0, &required_size, NULL);
dev_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(required_size);
dev_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
result = SetupDiGetDeviceInterfaceDetail(dev_info, &dev_data, dev_detail_data,
required_size, &required_size, NULL);
if (_tcsstr(dev_detail_data->DevicePath, hid_filter) != NULL)
{
if (_gHid.kits[index].read_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(_gHid.kits[index].read_handle);
}
if (_gHid.kits[index].write_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(_gHid.kits[index].write_handle);
}
_gHid.kits[index].read_handle = CreateFile(dev_detail_data->DevicePath,
GENERIC_READ,
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
0,
NULL);
_gHid.kits[index].write_handle = CreateFile(dev_detail_data->DevicePath,
GENERIC_WRITE,
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
0,
NULL);
index++;
}
free(dev_detail_data);
if (index == HID_DEVICES_MAX)
{
break;
}
device_index++;
}
SetupDiDestroyDeviceInfoList(dev_info);
_gHid.num_kits_found = index;
phal->hal_data = &_gHid;
if (_gHid.num_kits_found == 0)
{
status = ATCA_NO_DEVICES;
}
return status;
}
ATCA_STATUS hal_kit_hid_discover_buses(int cdc_buses[], int max_buses)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_kit_hid_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int *found)
{
return ATCA_UNIMPLEMENTED;
}
ATCA_STATUS hal_kit_hid_post_init(ATCAIface iface)
{
ATCA_STATUS status = ATCA_SUCCESS;
atcahid_t* pHid = atgetifacehaldat(iface);
ATCAIfaceCfg *pCfg = atgetifacecfg(iface);
int i = 0;
do
{
if (pHid == NULL || pCfg == NULL)
{
status = ATCA_BAD_PARAM;
BREAK(status, "NULL pointers in hal_kit_hid_post_init");
}
for (i = 0; i < pHid->num_kits_found; i++)
{
status = kit_init(iface);
if (status != ATCA_SUCCESS)
{
BREAK(status, "kit_init() Failed");
}
}
}
while (0);
return status;
}
ATCA_STATUS kit_phy_send(ATCAIface iface, const char* txdata, int txlength)
{
ATCA_STATUS status = ATCA_SUCCESS;
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int hidid = cfg->atcahid.idx;
atcahid_t* pHid = (atcahid_t*)atgetifacehaldat(iface);
uint8_t buffer[HID_PACKET_MAX];
DWORD bytes_to_send = 0;
DWORD bytes_left = 0;
DWORD bytes_sent = 0;
BOOL result = FALSE;
if ((txdata == NULL) || (pHid == NULL))
{
return ATCA_BAD_PARAM;
}
if (pHid->kits[hidid].write_handle == INVALID_HANDLE_VALUE)
{
return ATCA_COMM_FAIL;
}
bytes_left = txlength;
while (bytes_left > 0)
{
memset(buffer, 0, (HID_PACKET_MAX));
if (bytes_left >= cfg->atcahid.packetsize)
{
bytes_to_send = cfg->atcahid.packetsize;
}
else
{
bytes_to_send = bytes_left;
}
memcpy(&buffer[1], &txdata[(txlength - bytes_left)], bytes_to_send);
result = WriteFile(pHid->kits[hidid].write_handle, buffer, (cfg->atcahid.packetsize + 1), &bytes_sent, NULL);
if (result == FALSE)
{
return ATCA_TX_FAIL;
}
bytes_left -= bytes_to_send;
}
return status;
}
ATCA_STATUS kit_phy_receive(ATCAIface iface, char* rxdata, int* rxsize)
{
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
int hidid = cfg->atcahid.idx;
atcahid_t* pHid = (atcahid_t*)atgetifacehaldat(iface);
uint8_t buffer[HID_PACKET_MAX] = { 0 };
BOOL continue_read = TRUE;
DWORD bytes_read = 0;
DWORD total_bytes = 0;
BOOL result = true;
char* location = NULL;
int bytes_remain = 0;
int bytes_to_cpy = 0;
int size_adjust = 0;
if ((rxdata == NULL) || (rxsize == NULL) || (pHid == NULL))
{
return ATCA_BAD_PARAM;
}
if (pHid->kits[hidid].read_handle == INVALID_HANDLE_VALUE)
{
return ATCA_COMM_FAIL;
}
while (continue_read == true)
{
result = ReadFile(pHid->kits[hidid].read_handle, buffer, (cfg->atcahid.packetsize + 1), &bytes_read, NULL);
if (result == false)
{
return ATCA_RX_FAIL;
}
location = strchr((char*)&buffer[1], '\n');
if (location == NULL)
{
bytes_to_cpy = bytes_read;
size_adjust = 1;
}
else
{
bytes_to_cpy = (uint8_t)(location - (char*)buffer);
size_adjust = 0;
continue_read = false;
}
memcpy(&rxdata[total_bytes], &buffer[1], bytes_to_cpy);
total_bytes += bytes_to_cpy - size_adjust;
}
*rxsize = total_bytes;
return ATCA_SUCCESS;
}
ATCA_STATUS kit_phy_num_found(int8_t* num_found)
{
*num_found = _gHid.num_kits_found;
return ATCA_SUCCESS;
}
ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t* txdata, int txlength)
{
return kit_send(iface, txdata, txlength);
}
ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t* rxdata, uint16_t* rxsize)
{
return kit_receive(iface, rxdata, rxsize);
}
ATCA_STATUS hal_kit_hid_wake(ATCAIface iface)
{
return kit_wake(iface);
}
ATCA_STATUS hal_kit_hid_idle(ATCAIface iface)
{
return kit_idle(iface);
}
ATCA_STATUS hal_kit_hid_sleep(ATCAIface iface)
{
return kit_sleep(iface);
}
ATCA_STATUS hal_kit_hid_release(void* hal_data)
{
int i = 0;
atcahid_t* phaldat = (atcahid_t*)hal_data;
if ((hal_data == NULL))
{
return ATCA_BAD_PARAM;
}
for (i = 0; i < phaldat->num_kits_found; i++)
{
if (phaldat->kits[i].read_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(phaldat->kits[i].read_handle);
phaldat->kits[i].read_handle = INVALID_HANDLE_VALUE;
}
if (phaldat->kits[i].write_handle != INVALID_HANDLE_VALUE)
{
CloseHandle(phaldat->kits[i].write_handle);
phaldat->kits[i].write_handle = INVALID_HANDLE_VALUE;
}
}
return ATCA_SUCCESS;
}