2 * Copyright © 2016 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include "libaltos_private.h"
20 #include "libaltos_posix.h"
23 #include <IOKit/usb/USBspec.h>
24 #include <IOKit/serial/IOSerialKeys.h>
25 #include <usb/IOUSBLib.h>
26 #include <usb/USBSpec.h>
27 #include <sys/param.h>
32 /* Mac OS X don't have strndup even if _GNU_SOURCE is defined */
34 altos_strndup (const char *s, size_t n)
36 size_t len = strlen (s);
48 io_iterator_t iterator;
53 get_cfstring(CFTypeRef string, char result[512])
57 got_string = CFStringGetCString(string, result, 512, kCFStringEncodingASCII);
59 strcpy(result, "CFStringGetCString failed");
64 get_string(io_object_t object, CFStringRef entry, char *result, int result_len)
66 CFTypeRef entry_as_string;
68 char entry_string[512];
70 entry_as_string = IORegistryEntrySearchCFProperty (object,
74 kIORegistryIterateRecursively);
75 if (entry_as_string) {
76 got_string = CFStringGetCString(entry_as_string,
78 kCFStringEncodingASCII);
80 CFRelease(entry_as_string);
89 get_number(io_object_t object, CFStringRef entry, int *result)
91 CFTypeRef entry_as_number;
93 char entry_string[512];
95 entry_as_number = IORegistryEntrySearchCFProperty (object,
99 kIORegistryIterateRecursively);
100 if (entry_as_number) {
101 got_number = CFNumberGetValue(entry_as_number,
111 PUBLIC struct altos_list *
112 altos_list_start(void)
114 struct altos_list *list = calloc (sizeof (struct altos_list), 1);
115 CFMutableDictionaryRef matching_dictionary;
116 io_iterator_t tdIterator;
117 io_object_t tdObject;
121 matching_dictionary = IOServiceMatching(kIOSerialBSDServiceValue);
122 if (matching_dictionary) {
123 CFDictionarySetValue(matching_dictionary,
124 CFSTR(kIOSerialBSDTypeKey),
125 CFSTR(kIOSerialBSDAllTypes));
128 ret = IOServiceGetMatchingServices(kIOMasterPortDefault, matching_dictionary, &list->iterator);
129 if (ret != kIOReturnSuccess) {
137 PUBLIC struct altos_list *
138 altos_ftdi_list_start(void)
140 struct altos_list *list = altos_list_start();
147 static io_service_t get_usb_object(io_object_t serial_device)
149 io_iterator_t iterator;
150 io_service_t usb_device;
151 io_service_t service;
154 status = IORegistryEntryCreateIterator(serial_device,
156 kIORegistryIterateParents | kIORegistryIterateRecursively,
159 if (status != kIOReturnSuccess)
162 while((service = IOIteratorNext(iterator))) {
163 io_name_t servicename;
164 status = IORegistryEntryGetNameInPlane(service, kIOServicePlane, servicename);
166 if (status == kIOReturnSuccess && IOObjectConformsTo(service, kIOUSBDeviceClassName)) {
167 IOObjectRelease(iterator);
170 IOObjectRelease(service);
172 IOObjectRelease(iterator);
177 altos_list_next(struct altos_list *list, struct altos_device *device)
181 io_service_t usb_device;
182 char serial_string[128];
185 object = IOIteratorNext(list->iterator);
190 usb_device = get_usb_object(object);
192 if (get_number (usb_device, CFSTR(kUSBVendorID), &device->vendor) &&
193 get_number (usb_device, CFSTR(kUSBProductID), &device->product) &&
194 get_string (object, CFSTR(kIOCalloutDeviceKey), device->path, sizeof (device->path)) &&
195 get_string (usb_device, CFSTR(kUSBProductString), device->name, sizeof (device->name)) &&
196 get_string (usb_device, CFSTR(kUSBSerialNumberString), serial_string, sizeof (serial_string))) {
197 device->serial = atoi(serial_string);
198 IOObjectRelease(object);
199 IOObjectRelease(usb_device);
202 IOObjectRelease(object);
203 IOObjectRelease(usb_device);
208 altos_list_finish(struct altos_list *list)
210 IOObjectRelease (list->iterator);
214 struct altos_bt_list {
221 #define INQUIRY_MAX_RSP 255
223 struct altos_bt_list *
224 altos_bt_list_start(int inquiry_time)
230 altos_bt_list_next(struct altos_bt_list *bt_list,
231 struct altos_bt_device *device)
237 altos_bt_list_finish(struct altos_bt_list *bt_list)
242 altos_bt_fill_in(char *name, char *addr, struct altos_bt_device *device)
244 strncpy(device->name, name, sizeof (device->name));
245 device->name[sizeof(device->name)-1] = '\0';
246 strncpy(device->addr, addr, sizeof (device->addr));
247 device->addr[sizeof(device->addr)-1] = '\0';
251 altos_bt_open(struct altos_bt_device *device)