44#include " deps/Fusion/Fusion/Fusion.h"
55#include < iostream>
66#include < mutex>
7-
7+ #include < array>
8+ #include < cstdint>
9+ #include < vector>
810// Air USB VID and PID
911#define AIR_VID 0x3318
1012#define AIR_PID 0x0424
1113
1214// Is Tracking
1315bool g_isTracking = false ;
1416
17+ // Is Listening
18+ bool g_isListening = false ;
19+
1520// ticks are in nanoseconds, 1000 Hz packets
1621#define TICK_LEN (1 .0f / 1E9f)
1722
@@ -27,15 +32,16 @@ static FusionVector earth;
2732static FusionQuaternion qt;
2833
2934HANDLE trackThread;
35+ HANDLE listenThread;
3036
3137hid_device* device;
3238
33-
39+ hid_device* device4;
3440
3541#define SAMPLE_RATE (1000 ) // replace this with actual sample rate
3642
3743std::mutex mtx;
38-
44+ std::mutex it4;
3945
4046typedef struct {
4147 uint64_t tick;
@@ -202,7 +208,7 @@ process_accel(const int32_t in_accel[3], float out_vec[])
202208 out_vec[0 ] = (float )(in_accel[0 ]) * ACCEL_SCALAR;
203209 out_vec[1 ] = (float )(in_accel[2 ]) * ACCEL_SCALAR;
204210 out_vec[2 ] = (float )(in_accel[1 ]) * ACCEL_SCALAR;
205-
211+
206212}
207213
208214
@@ -216,6 +222,28 @@ open_device()
216222 while (devs) {
217223 if (cur_dev->interface_number == 3 ) {
218224 device = hid_open_path (cur_dev->path );
225+ std::cout << " Interface 3 bound" << std::endl;
226+ break ;
227+ }
228+
229+ cur_dev = cur_dev->next ;
230+ }
231+
232+ hid_free_enumeration (devs);
233+ return device;
234+ }
235+
236+ static hid_device*
237+ open_device4 ()
238+ {
239+ struct hid_device_info * devs = hid_enumerate (AIR_VID, AIR_PID);
240+ struct hid_device_info * cur_dev = devs;
241+ hid_device* device = NULL ;
242+
243+ while (devs) {
244+ if (cur_dev->interface_number == 4 ) {
245+ device = hid_open_path (cur_dev->path );
246+ std::cout << " Interface 4 bound" << std::endl;
219247 break ;
220248 }
221249
@@ -269,7 +297,7 @@ DWORD WINAPI track(LPVOID lpParam) {
269297 .rejectionTimeout = 5 * SAMPLE_RATE, /* 5 seconds */
270298 };
271299 FusionAhrsSetSettings (&ahrs, &settings);
272-
300+
273301
274302 while (g_isTracking) {
275303
@@ -324,7 +352,51 @@ DWORD WINAPI track(LPVOID lpParam) {
324352 }
325353 return 0 ;
326354}
355+ int brightness = 0 ;
356+ DWORD WINAPI interface4Handler (LPVOID lpParam) {
357+
358+ // get initial brightness from device
359+ std::array<uint8_t , 17 > initBrightness = { 0x00 , 0xfd , 0x1e , 0xb9 , 0xf0 , 0x68 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x03 };
360+ hid_write (device4, initBrightness.data (), initBrightness.size ());
361+
327362
363+ while (g_isListening) {
364+ std::array<uint8_t , 65 > recv = {};
365+ int res = hid_read (device4, recv.data (), recv.size ());
366+ if (res > 0 ) {
367+ switch (recv[22 ]) {
368+
369+ case 0x03 : // Brightness down press
370+ it4.lock ();
371+ brightness = recv[30 ];
372+ it4.unlock ();
373+ break ;
374+
375+ case 0x02 : // Brightness up press
376+ it4.lock ();
377+ brightness = recv[30 ];
378+ it4.unlock ();
379+ break ;
380+ default :
381+ // std::cout << "Unknown Packet! " << (int)recv[22] << std::endl;
382+ break ;
383+ }
384+
385+ switch (recv[15 ]) {
386+
387+ case 0x03 : // Brightness from cmd
388+ it4.lock ();
389+ brightness = recv[23 ];
390+ it4.unlock ();
391+ break ;
392+
393+ default :
394+ // todo
395+ break ;
396+ }
397+ }
398+ }
399+ }
328400
329401
330402int StartConnection ()
@@ -339,7 +411,8 @@ int StartConnection()
339411 std::cout << " Opening Device" << std::endl;
340412 // open device
341413 device = open_device ();
342- if (!device) {
414+ device4 = open_device4 ();
415+ if (!device || !device4) {
343416 std::cout << " Unable to open device" << std::endl;
344417 return 1 ;
345418 }
@@ -348,23 +421,34 @@ int StartConnection()
348421 std::cout << " Sending Payload" << std::endl;
349422 // open the floodgates
350423 uint8_t magic_payload[] = { 0x00 , 0xaa , 0xc5 , 0xd1 , 0x21 , 0x42 , 0x04 , 0x00 , 0x19 , 0x01 };
424+
425+
351426 int res = hid_write (device, magic_payload, sizeof (magic_payload));
352427 if (res < 0 ) {
353428 std::cout << " Unable to write to device" << std::endl;
354429 return 1 ;
355430 }
356- ThreadParams params = { device };
431+ ThreadParams trackParams = { device };
357432 g_isTracking = true ;
358- std::cout << " Starting Thread" << std::endl;
433+ std::cout << " Tracking Starting Thread" << std::endl;
359434
360435
361436 // Start Tracking Thread
362- trackThread = CreateThread (NULL , 0 , track, ¶ms , 0 , NULL );
437+ trackThread = CreateThread (NULL , 0 , track, &trackParams , 0 , NULL );
363438 if (trackThread == NULL ) {
364439 std::cout << " Failed to create thread" << std::endl;
365440 return 1 ;
366441 }
367- std::cout << " Thread Started" << std::endl;
442+
443+ ThreadParams listenParams = { };
444+ g_isListening = true ;
445+ // Start Interface 4 listener
446+ listenThread = CreateThread (NULL , 0 , interface4Handler, &listenParams, 0 , NULL );
447+ if (listenThread == NULL ) {
448+ std::cout << " Failed to create thread" << std::endl;
449+ return 1 ;
450+ }
451+ std::cout << " Listenr Thread Started" << std::endl;
368452
369453 return 1 ;
370454 }
@@ -375,20 +459,27 @@ int StopConnection()
375459{
376460 if (g_isTracking) {
377461 g_isTracking = false ;
378- // Wait for the thread to finish
462+ g_isListening = false ;
463+ // Wait for the track thread to finish
379464 WaitForSingleObject (trackThread, INFINITE);
380465 TerminateThread (trackThread, 0 );
381466 CloseHandle (trackThread);
467+
468+ // Wait for the listen thread to finish
469+ WaitForSingleObject (listenThread, INFINITE);
470+ TerminateThread (listenThread, 0 );
471+ CloseHandle (listenThread);
382472 return 1 ;
383473 }
384474 else {
385475 return -1 ;
386476 }
387477}
388478
479+ float * q = new float [4 ];
480+
389481float * GetQuaternion ()
390482{
391- float * q = new float [4 ];
392483 mtx.lock ();
393484 q[0 ] = qt.array [0 ];
394485 q[1 ] = qt.array [1 ];
@@ -398,13 +489,26 @@ float* GetQuaternion()
398489 return q;
399490}
400491
492+ float * e = new float [3 ];
493+
401494float * GetEuler ()
402495{
403- float * e = new float [ 3 ];
496+
404497 mtx.lock ();
405498 e[0 ] = euler.angle .pitch ;
406499 e[1 ] = euler.angle .roll ;
407500 e[2 ] = euler.angle .yaw ;
408501 mtx.unlock ();
409502 return e;
410- }
503+ }
504+
505+
506+ int GetBrightness ()
507+ {
508+ int curBrightness;
509+ it4.lock ();
510+ curBrightness = brightness;
511+ it4.unlock ();
512+
513+ return curBrightness;
514+ }
0 commit comments