Mac OS X gamepad emulator for serial RC transmitters
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Serial.m 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //
  2. // Serial.m
  3. // SerialGamepad
  4. //
  5. // For more informations refer to this document:
  6. // https://developer.apple.com/library/mac/documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/SerialDevices.html
  7. //
  8. // Created by Thomas Buck on 14.12.15.
  9. // Copyright © 2015 xythobuz. All rights reserved.
  10. //
  11. #import <IOKit/serial/IOSerialKeys.h>
  12. #import "Serial.h"
  13. @implementation Serial
  14. + (NSArray *)listSerialPorts {
  15. // Get Iterator with all serial ports
  16. io_iterator_t serialPortIterator;
  17. kern_return_t kernResult = findSerialPorts(&serialPortIterator);
  18. // Create 2D array
  19. char **portList;
  20. portList = malloc(100 * sizeof(char *));
  21. for (int i = 0; i < 100; i++) portList[i] = malloc(200 * sizeof(char));
  22. // Copy device name into C-String array
  23. kernResult = getSerialPortPath(serialPortIterator, portList, 100, 200);
  24. IOObjectRelease(serialPortIterator);
  25. // Copy contents into NSString Array
  26. NSString *stringList[100];
  27. NSUInteger realCount = 0;
  28. while (portList[realCount] != NULL) {
  29. stringList[realCount] = [NSString stringWithCString:portList[realCount] encoding:NSUTF8StringEncoding];
  30. realCount++;
  31. }
  32. // Destroy 2D array
  33. for (int i = 0; i < 100; i++) free(portList[i]);
  34. free(portList);
  35. // And return them as NSArray
  36. return [[NSArray alloc] initWithObjects:stringList count:realCount];
  37. }
  38. @end
  39. kern_return_t findSerialPorts(io_iterator_t *matches) {
  40. kern_return_t kernResult;
  41. mach_port_t masterPort;
  42. CFMutableDictionaryRef classesToMatch;
  43. kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
  44. if (KERN_SUCCESS != kernResult) {
  45. NSLog(@"IOMasterPort returned %d\n", kernResult);
  46. return kernResult;
  47. }
  48. // Serial devices are instances of class IOSerialBSDClient.
  49. classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
  50. if (classesToMatch == NULL) {
  51. NSLog(@"IOServiceMatching returned a NULL dictionary.\n");
  52. } else {
  53. CFDictionarySetValue(classesToMatch,
  54. CFSTR(kIOSerialBSDTypeKey),
  55. CFSTR(kIOSerialBSDRS232Type));
  56. // Each serial device object has a property with key
  57. // kIOSerialBSDTypeKey and a value that is one of
  58. // kIOSerialBSDAllTypes, kIOSerialBSDModemType,
  59. // or kIOSerialBSDRS232Type. You can change the
  60. // matching dictionary to find other types of serial
  61. // devices by changing the last parameter in the above call
  62. // to CFDictionarySetValue.
  63. }
  64. kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, matches);
  65. if (KERN_SUCCESS != kernResult) {
  66. NSLog(@"IOServiceGetMatchingServices returned %d\n", kernResult);
  67. return kernResult;
  68. }
  69. return kernResult;
  70. }
  71. kern_return_t getSerialPortPath(io_iterator_t serialPortIterator, char **deviceFilePath, CFIndex maxPathCount, CFIndex maxPathSize) {
  72. io_object_t modemService;
  73. kern_return_t kernResult = KERN_FAILURE;
  74. CFIndex i = 0;
  75. while ((modemService = IOIteratorNext(serialPortIterator)) && (i < (maxPathCount - 1))) {
  76. CFTypeRef deviceFilePathAsCFString;
  77. // Get the callout device's path (/dev/cu.xxxxx).
  78. // The callout device should almost always be
  79. // used. You would use the dialin device (/dev/tty.xxxxx) when
  80. // monitoring a serial port for
  81. // incoming calls, for example, a fax listener.
  82. deviceFilePathAsCFString = IORegistryEntryCreateCFProperty(modemService,
  83. CFSTR(kIODialinDeviceKey),
  84. kCFAllocatorDefault,
  85. 0);
  86. if (deviceFilePathAsCFString) {
  87. Boolean result;
  88. deviceFilePath[i][0] = '\0';
  89. // Convert the path from a CFString to a NULL-terminated C string
  90. // for use with the POSIX open() call.
  91. result = CFStringGetCString(deviceFilePathAsCFString,
  92. deviceFilePath[i],
  93. maxPathSize,
  94. kCFStringEncodingASCII);
  95. CFRelease(deviceFilePathAsCFString);
  96. if (result) {
  97. NSLog(@"BSD path: %s\n", deviceFilePath[i]);
  98. i++;
  99. kernResult = KERN_SUCCESS;
  100. }
  101. }
  102. // Release the io_service_t now that we are done with it.
  103. (void) IOObjectRelease(modemService);
  104. }
  105. deviceFilePath[i] = NULL;
  106. return kernResult;
  107. }