libvcomm  1.0
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
vcomm.c
1 /*
2  * vcomm.c
3  *
4  * Created on: 10.09.2012
5  * Author: tarmo
6  */
7 
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "hidapi.h"
13 #include "proto.h"
14 #include "vcomm.h"
15 
16 struct hid_device_info * Vlist(void) {
17  struct hid_device_info *devs;
19  return devs;
20 }
21 
22 VCOMMAPI void VCOMMCALL Vfree_list(struct hid_device_info *vlist) {
23 
24  hid_free_enumeration(vlist);
25  return;
26 }
27 
28 VCOMMAPI int VCOMMCALL Vopen(hid_device **vhandle, char *serial) {
29 
30  char bufserial[33];
31  struct hid_device_info *devs, *cur_dev, *v_dev; // HID dev info struct pointers
32  v_dev = NULL;
33 
34  devs = hid_enumerate(VENDOR_ID, PRODUCT_ID); // Get linked list of IRvoodoo info structs
35 
36  // Loop while last HID is found(4 EP found)
37  cur_dev = devs;
38 
39  // Find device (first or by serial)
40  while (cur_dev) {
41 
42  if (serial) {
43  sprintf(bufserial, "%ls", cur_dev->serial_number);
44  if (strcmp(serial, bufserial) == 0) {
45 
46 #ifdef mac
47  if (cur_dev->usage_page == 0xFF00 && cur_dev->usage == 0x01) {
48  v_dev = cur_dev;
49  break;
50  }
51 #else
52  if (cur_dev->interface_number == 3) {
53  v_dev = cur_dev;
54  break;
55  }
56 #endif
57  }
58  } else {
59 #ifdef mac
60  if (cur_dev->usage_page == 0xFF00 && cur_dev->usage == 0x01) {
61  v_dev = cur_dev;
62  break; // select first IRvoodoo config interface
63  }
64 #else
65  if (cur_dev->interface_number == 3) {
66  v_dev = cur_dev;
67  break; // select first IRvoodoo config interface
68  }
69 #endif
70  }
71  cur_dev = cur_dev->next;
72  }
73 
74  // IRvoodo not found
75  if (!v_dev)
76  return ERR_DEV_NOT_FOUND;
77 
78  // Open IRvoodoo confg HID interface by system path
79 
80  *vhandle = hid_open_path(v_dev->path);
81 
82  // Insufficent permissions ?
83  if (!*vhandle)
84  return ERR_OPEN_DEV;
85 
86  // free devs linked list
88  return SUCCESS;
89 }
90 
92 
93  hid_close(*vhandle);
94  *vhandle = NULL;
95  hid_exit();
96 
97  return SUCCESS;
98 }
99 
101  response_t *resp) {
102 #define BUFF_SIZE 64
103 #define HID_REPORT_ID 0
104 
105 #ifdef LOG
106  setbuf(stdout, NULL);
107  printf("-------Request------------\n");
108  printf("Type 0x%02X\n", req->type);
109 #endif
110 
111  unsigned char buff[BUFF_SIZE]; // buffer for incoming HID raport
112  int16_t num_in_reports; // number of incoming hid reports
113 
114  req->report_id = HID_REPORT_ID; // always 0, since we have only one report descriptor
115  hid_write(*vhandle, (unsigned char *) req, 65);
116 
117  // Entering ISP mode, dont wait response, end communication
118  if (req->type == REQ_ENTER_ISP) {
119  return 0;
120  }
121 
122  int res = hid_read(*vhandle, buff, BUFF_SIZE); // send report
123  if (res < 0)
124  // FAIL
125  return res; // comm err
126 
127  memcpy(resp, buff, BUFF_SIZE);
128 
129 #ifdef LOG
130  printf("-------Response------------\n");
131  printf("Response size %d bytes\n", resp->len);
132 #endif
133 
134  if (resp->len <= 60) { // 1 in report, no more incoming data
135 
136 #ifdef LOG
137  printf("Response length 1 packet \n");
138  printf("-----------End-------------\n");
139 #endif
140  return SUCCESS;
141  }
142 
143  /*
144  * receive and defragment remaining reports
145  */
146 
147  // compute number of in remaining reports
148  num_in_reports = ((resp->len + 4) / BUFF_SIZE);
149  if ((resp->len + 4) % BUFF_SIZE)
150  num_in_reports++;
151 
152 #ifdef LOG
153  printf("Response length %d packets \n", num_in_reports );
154  printf(".");
155 #endif
156 
157  // receive remaining
158  uint16_t i;
159  for (i = 1; i < num_in_reports; ++i) {
160  res = hid_read(*vhandle, buff, BUFF_SIZE);
161 #ifdef LOG
162  printf(".");
163 #endif
164  if (res < 0)
165  // FAIL
166  return res;
167  memcpy(((char *) resp) + BUFF_SIZE * i, buff, BUFF_SIZE);
168  }
169 #ifdef LOG
170  printf("\n-----------End-------------\n");
171 #endif
172  // success
173  return SUCCESS;
174 }
175 
176 VCOMMAPI unsigned int VCOMMCALL Vtest(hid_device **vhandle) {
177  request_t request;
178  response_t response;
179  memset(&response, 0x00, sizeof(response));
180 
181  unsigned int *fwver;
182  fwver = (unsigned int *) &response.data[0];
183 
184  request.type = REQ_GET_FW_VERSION;
185 
186  if (Vcomm(vhandle, &request, &response)) {
187  return 0;
188  }
189 
190  return *fwver;
191 }