Detect d868uv on Mac.

This commit is contained in:
Serge Vakulenko 2018-10-26 00:29:03 -07:00
parent 56f86cfdbe
commit 68e8a5b3bd
3 changed files with 71 additions and 99 deletions

59
main.c
View File

@ -39,29 +39,29 @@ extern int optind;
void usage()
{
fprintf(stderr, _("DMR Config, Version %s, %s\n"), version, copyright);
fprintf(stderr, _("Usage:\n"));
fprintf(stderr, _(" dmrconfig -r [-t]\n"));
fprintf(stderr, _(" Read codeplug from the radio to a file 'device.img'.\n"));
fprintf(stderr, _(" Save configuration to a text file 'device.conf'.\n"));
fprintf(stderr, _(" dmrconfig -w [-t] file.img\n"));
fprintf(stderr, _(" Write codeplug to the radio.\n"));
fprintf(stderr, _(" dmrconfig -c [-t] file.conf\n"));
fprintf(stderr, _(" Apply configuration script to the radio.\n"));
fprintf(stderr, _(" dmrconfig -c file.img file.conf\n"));
fprintf(stderr, _(" Apply configuration script to the codeplug image.\n"));
fprintf(stderr, _(" Store modified copy to a file 'device.img'.\n"));
fprintf(stderr, _(" dmrconfig file.img\n"));
fprintf(stderr, _(" Display configuration from the codeplug image.\n"));
fprintf(stderr, _(" dmrconfig -u [-t] file.csv\n"));
fprintf(stderr, _(" Update contacts database from CSV file.\n"));
fprintf(stderr, _("Options:\n"));
fprintf(stderr, _(" -r Read codeplug from the radio.\n"));
fprintf(stderr, _(" -w Write codeplug to the radio.\n"));
fprintf(stderr, _(" -c Configure the radio from a text script.\n"));
fprintf(stderr, _(" -u Update contacts database.\n"));
fprintf(stderr, _(" -l List all supported radios.\n"));
fprintf(stderr, _(" -t Trace USB protocol.\n"));
fprintf(stderr, "DMR Config, Version %s, %s\n", version, copyright);
fprintf(stderr, "Usage:\n");
fprintf(stderr, " dmrconfig -r [-t]\n");
fprintf(stderr, " Read codeplug from the radio to a file 'device.img'.\n");
fprintf(stderr, " Save configuration to a text file 'device.conf'.\n");
fprintf(stderr, " dmrconfig -w [-t] file.img\n");
fprintf(stderr, " Write codeplug to the radio.\n");
fprintf(stderr, " dmrconfig -c [-t] file.conf\n");
fprintf(stderr, " Apply configuration script to the radio.\n");
fprintf(stderr, " dmrconfig -c file.img file.conf\n");
fprintf(stderr, " Apply configuration script to the codeplug image.\n");
fprintf(stderr, " Store modified copy to a file 'device.img'.\n");
fprintf(stderr, " dmrconfig file.img\n");
fprintf(stderr, " Display configuration from the codeplug image.\n");
fprintf(stderr, " dmrconfig -u [-t] file.csv\n");
fprintf(stderr, " Update contacts database from CSV file.\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -r Read codeplug from the radio.\n");
fprintf(stderr, " -w Write codeplug to the radio.\n");
fprintf(stderr, " -c Configure the radio from a text script.\n");
fprintf(stderr, " -u Update contacts database.\n");
fprintf(stderr, " -l List all supported radios.\n");
fprintf(stderr, " -t Trace USB protocol.\n");
exit(-1);
}
@ -70,18 +70,7 @@ int main(int argc, char **argv)
int read_flag = 0, write_flag = 0, config_flag = 0, csv_flag = 0;
int list_flag = 0;
// Set locale and message catalogs.
setlocale(LC_ALL, "");
#ifdef MINGW32
// Files with localized messages should be placed in
// in c:/Program Files/dmrconfig/ directory.
bindtextdomain("dmrconfig", "c:/Program Files/dmrconfig");
#else
bindtextdomain("dmrconfig", "/usr/local/share/locale");
#endif
textdomain("dmrconfig");
copyright = _("Copyright (C) 2018 Serge Vakulenko KK6ABQ");
copyright = "Copyright (C) 2018 Serge Vakulenko KK6ABQ";
trace_flag = 0;
for (;;) {
switch (getopt(argc, argv, "tcwrul")) {

View File

@ -50,10 +50,8 @@
#ifdef __APPLE__
# include <CoreFoundation/CoreFoundation.h>
# include <IOKit/IOBSD.h>
# include <IOKit/storage/IOMedia.h>
# include <IOKit/storage/IOStorageDeviceCharacteristics.h>
# include <IOKit/usb/IOUSBLib.h>
# include <IOKit/serial/IOSerialKeys.h>
#endif
static char *dev_path;
@ -436,82 +434,80 @@ static char *find_path(int vid, int pid)
return result;
#elif defined(__APPLE__)
// Create a list of the devices in the 'IOMedia' class.
CFMutableDictionaryRef dict = IOServiceMatching(kIOMediaClass);
// Create a list of the devices in the 'IOSerialBSDClient' class.
CFMutableDictionaryRef dict = IOServiceMatching(kIOSerialBSDServiceValue);
if (! dict) {
printf("Cannot create IO Service dictionary.\n");
return;
return 0;
}
// Select devices with attributes Removeable=True and Whole=True.
CFDictionarySetValue(dict, CFSTR(kIOMediaRemovableKey), kCFBooleanTrue);
CFDictionarySetValue(dict, CFSTR(kIOMediaWholeKey), kCFBooleanTrue);
io_iterator_t devices = IO_OBJECT_NULL;
kern_return_t result = IOServiceGetMatchingServices(kIOMasterPortDefault,
kern_return_t ret = IOServiceGetMatchingServices(kIOMasterPortDefault,
dict, &devices);
if (result != KERN_SUCCESS) {
if (ret != KERN_SUCCESS) {
printf("Cannot find matching IO services.\n");
return;
return 0;
}
// For each matching device, print out its information.
io_object_t device;
while ((device = IOIteratorNext(devices)) != MACH_PORT_NULL) {
// Get device path.
char devname[1024] = "/dev/r";
char devname[1024];
CFStringRef ref = (CFStringRef) IORegistryEntrySearchCFProperty(device,
kIOServicePlane, CFSTR(kIOBSDNameKey),
kIOServicePlane, CFSTR(kIOCalloutDeviceKey),
kCFAllocatorDefault, kIORegistryIterateRecursively);
if (! ref || ! CFStringGetCString(ref, devname + 6,
sizeof(devname) - 6, kCFStringEncodingUTF8)) {
if (! ref || ! CFStringGetCString(ref, devname, sizeof(devname), kCFStringEncodingUTF8)) {
// Cannot get device path.
continue;
}
#if 0
// Get device size in bytes.
long long size;
ref = IORegistryEntryCreateCFProperty(device,
CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, 0);
if (! ref || ! CFNumberGetValue((CFNumberRef)ref, kCFNumberLongLongType, &size)) {
// Cannot get device size.
continue;
}
#endif
// Get a list of device characteristics.
CFMutableDictionaryRef dict = (CFMutableDictionaryRef)
IORegistryEntrySearchCFProperty(device, kIOServicePlane,
CFSTR(kIOPropertyDeviceCharacteristicsKey),
kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively);
if (! dict) {
// Cannot get device characteristics.
//printf("%s\n", devname);
// Get device parent.
io_registry_entry_t parent = 0;
if (KERN_SUCCESS != IORegistryEntryGetParentEntry(device, kIOServicePlane, &parent)) {
//printf("Cannot get device parent.\n");
continue;
}
// Get vendor and product names.
char vendor[1024], product[1024];
ref = CFDictionaryGetValue(dict, CFSTR(kIOPropertyVendorNameKey));
if (! ref || ! CFStringGetCString(ref, vendor,
sizeof(vendor), kCFStringEncodingUTF8)) {
// Cannot get vendor name.
continue;
}
ref = CFDictionaryGetValue(dict, CFSTR(kIOPropertyProductNameKey));
if (! ref || ! CFStringGetCString(ref, product,
sizeof(product), kCFStringEncodingUTF8)) {
// Cannot get product name.
// Get device grandparent.
io_registry_entry_t grandparent = 0;
if (KERN_SUCCESS != IORegistryEntryGetParentEntry(parent, kIOServicePlane, &grandparent)) {
//printf("Cannot get device grandparent.\n");
continue;
}
char buf[1024];
sprintf(buf, "%s - size %u MB, %s %s",
devname, (unsigned) (size / 1000000), vendor, product);
IOObjectRelease(device);
devtab[ndev++] = strdup(buf);
// Get vendor ID.
int vendor_id;
ref = IORegistryEntryCreateCFProperty(grandparent,
CFSTR(kUSBVendorID), kCFAllocatorDefault, 0);
if (! ref || ! CFNumberGetValue((CFNumberRef)ref, kCFNumberIntType, &vendor_id)) {
//printf("Cannot get vendor ID.\n");
continue;
}
// Get product ID.
int product_id;
ref = IORegistryEntryCreateCFProperty(grandparent,
CFSTR(kUSBProductID), kCFAllocatorDefault, 0);
if (! ref || ! CFNumberGetValue((CFNumberRef)ref, kCFNumberIntType, &product_id)) {
//printf("Cannot get product ID.\n");
continue;
}
if (vendor_id != vid || product_id != pid) {
// Wrong ID.
continue;
}
result = strdup(devname);
break;
}
// Free the iterator object
IOObjectRelease(devices);
return result;
#else
printf("Don't know how to get the list of CD devices on this system.\n");
return 0;

13
util.h
View File

@ -26,19 +26,6 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//
// Localization.
//
#if 0
#include <libintl.h>
#define _(str) gettext(str)
#else
#define _(str) str
#define setlocale(x,y) /* empty */
#define bindtextdomain(x,y) /* empty */
#define textdomain(x) /* empty */
#endif
//
// Program version.
//