Mac OS X gamepad emulator for serial RC transmitters
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Thread.m 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. // Thread.m
  3. // SerialGamepad
  4. //
  5. // Created by Thomas Buck on 15.12.15.
  6. // Copyright © 2015 xythobuz. All rights reserved.
  7. //
  8. #import <termios.h>
  9. #import <fcntl.h>
  10. #import <unistd.h>
  11. #import "Thread.h"
  12. #import "fooHID.h"
  13. @implementation Thread
  14. @synthesize running, fd, portName;
  15. - (NSInteger)openPort {
  16. if (portName == nil) {
  17. return 1;
  18. }
  19. fd = open([portName UTF8String], O_RDONLY | O_NOCTTY | O_NONBLOCK);
  20. if (fd == -1) {
  21. NSLog(@"Error opening serial port \"%@\"!\n", portName);
  22. return 1;
  23. }
  24. fcntl(fd, F_SETFL, 0);
  25. struct termios options;
  26. tcgetattr(fd, &options);
  27. options.c_lflag = 0;
  28. options.c_oflag = 0;
  29. options.c_iflag = 0;
  30. options.c_cflag = 0;
  31. options.c_cflag |= CS8;
  32. options.c_cflag |= CREAD;
  33. options.c_cflag |= CLOCAL;
  34. cfsetispeed(&options, B115200);
  35. cfsetospeed(&options, B115200);
  36. options.c_cc[VMIN] = 0;
  37. options.c_cc[VTIME] = 1;
  38. tcsetattr(fd, TCSANOW, &options);
  39. tcflush(fd, TCIOFLUSH);
  40. return 0;
  41. }
  42. #define PACKETSIZE 18
  43. #define HEADERBYTES 2
  44. #define CHECKSUMBYTES 2
  45. #define PAYLOADBYTES (PACKETSIZE - HEADERBYTES - CHECKSUMBYTES)
  46. #define HEADERBYTE_A 85
  47. #define HEADERBYTE_B 252
  48. enum ThreadState {
  49. READ_FIRST_BYTE,
  50. READ_SECOND_BYTE,
  51. READ_PAYLOAD,
  52. READ_CHECKSUM
  53. };
  54. - (void)main {
  55. enum ThreadState state = READ_FIRST_BYTE;
  56. unsigned char c = 0;
  57. unsigned char buffer[PACKETSIZE];
  58. unsigned char checksum[CHECKSUMBYTES];
  59. int received = 0;
  60. NSLog(@"Connection running...\n");
  61. running = YES;
  62. while (running) {
  63. if (state == READ_FIRST_BYTE) {
  64. if (read(fd, &c, 1) == 1) {
  65. if (c == HEADERBYTE_A) {
  66. state = READ_SECOND_BYTE;
  67. }
  68. }
  69. } else if (state == READ_SECOND_BYTE) {
  70. if (read(fd, &c, 1) == 1) {
  71. if (c == HEADERBYTE_B) {
  72. state = READ_PAYLOAD;
  73. received = 0;
  74. } else {
  75. state = READ_FIRST_BYTE;
  76. }
  77. }
  78. } else if (state == READ_PAYLOAD) {
  79. ssize_t ret = read(fd, buffer + received, PAYLOADBYTES - received);
  80. if (ret >= 0) received += ret;
  81. if (received >= PAYLOADBYTES) {
  82. state = READ_CHECKSUM;
  83. received = 0;
  84. }
  85. } else if (state == READ_CHECKSUM) {
  86. ssize_t ret = read(fd, checksum + received, CHECKSUMBYTES - received);
  87. if (ret >= 0) received += ret;
  88. if (received >= CHECKSUMBYTES) {
  89. state = READ_FIRST_BYTE;
  90. // TODO got something
  91. }
  92. } else {
  93. NSLog(@"Invalid state?!\n");
  94. state = READ_FIRST_BYTE;
  95. }
  96. }
  97. close(fd);
  98. NSLog(@"Connection closed...\n");
  99. fd = -1;
  100. }
  101. @end