From c702e0a9aa3305b96f7c6c9c2846ff2320fd354a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 02:07:48 +0200 Subject: [PATCH 01/13] Added OSX environment to travis builds --- .travis.yml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5c29618..e825252 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,18 @@ language: go +os: + - linux + - osx + go: - 1.7.x - 1.8.x + - 1.9.x + - 1.10.x + # from go 1.8.7, 1.9.4, 1.10rc2 there is a restriction on CGO see https://github.com/bugst/go-serial/issues/50 + # this restriction has some consequences on darwin build + - 1.8.6 + - 1.9.3 go_import_path: go.bug.st/serial.v1 @@ -20,6 +30,37 @@ env: - TEST_OS=openbsd TEST_ARCH=arm matrix: + exclude: + - os: linux # no point in testing go1.8.6 on Linux + go: 1.8.6 + - os: linux # no point in testing go1.9.3 on Linux + go: 1.9.3 + - os: osx # go1.8.x after 1.8.6 is not supported on OSX + go: 1.8.x + - os: osx # go1.9.x after 1.9.3 is not supported on OSX + go: 1.9.x + - os: linux + env: TEST_OS=darwin TEST_ARCH=386 + - os: linux + env: TEST_OS=darwin TEST_ARCH=amd64 + - os: osx + env: TEST_OS=linux TEST_ARCH=386 + - os: osx + env: TEST_OS=linux TEST_ARCH=amd64 + - os: osx + env: TEST_OS=linux TEST_ARCH=arm + - os: osx + env: TEST_OS=windows TEST_ARCH=386 + - os: osx + env: TEST_OS=windows TEST_ARCH=amd64 + - os: osx + env: TEST_OS=freebsd TEST_ARCH=amd64 + - os: osx + env: TEST_OS=openbsd TEST_ARCH=amd64 + - os: osx + env: TEST_OS=openbsd TEST_ARCH=386 + - os: osx + env: TEST_OS=openbsd TEST_ARCH=arm allow_failures: - env: TEST_OS=openbsd TEST_ARCH=arm From 3ee4586c58f95ffba7193e1f76a5d9f031295c66 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 17:46:38 +0200 Subject: [PATCH 02/13] Splitted usb_darwing.go in two different build units based on go version --- .../{usb_darwin.go => usb_go1.10_darwin.go} | 2 + enumerator/usb_go1.9_darwin.go | 231 ++++++++++++++++++ 2 files changed, 233 insertions(+) rename enumerator/{usb_darwin.go => usb_go1.10_darwin.go} (99%) create mode 100644 enumerator/usb_go1.9_darwin.go diff --git a/enumerator/usb_darwin.go b/enumerator/usb_go1.10_darwin.go similarity index 99% rename from enumerator/usb_darwin.go rename to enumerator/usb_go1.10_darwin.go index 4cb9f61..23416fe 100644 --- a/enumerator/usb_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -4,6 +4,8 @@ // license that can be found in the LICENSE file. // +// +build go1.10 + package enumerator // import "go.bug.st/serial.v1/enumerator" // #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -fconstant-cfstrings diff --git a/enumerator/usb_go1.9_darwin.go b/enumerator/usb_go1.9_darwin.go new file mode 100644 index 0000000..f8ed324 --- /dev/null +++ b/enumerator/usb_go1.9_darwin.go @@ -0,0 +1,231 @@ +// +// Copyright 2014-2017 Cristian Maglie. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// + +// +build !go1.10 + +// This file is here to keep compatibility with the older versions of go +// and is no more maintained or bugfixed, please update your go version +// to at least 1.10 to get the latest updates. + +// Supported versions on MacOSX +// - any go version earlier than 1.8 +// - go1.8.x series from 1.8.0 to 1.8.6 +// - go1.9.x series from 1.9.0 to 1.9.3 + +// Versions NOT supported on MacOSX +// - go1.8.x series starting from 1.8.7 +// - go1.9.x series starting from 1.9.4 + +package enumerator // import "go.bug.st/serial.v1/enumerator" + +// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -fconstant-cfstrings +// #include +// #include +// #include +import "C" +import ( + "errors" + "fmt" + "unsafe" +) + +func nativeGetDetailedPortsList() ([]*PortDetails, error) { + var ports []*PortDetails + + services, err := getAllServices("IOSerialBSDClient") + if err != nil { + return nil, &PortEnumerationError{causedBy: err} + } + for _, service := range services { + defer service.Release() + + port, err := extractPortInfo(C.io_registry_entry_t(service)) + if err != nil { + return nil, &PortEnumerationError{causedBy: err} + } + ports = append(ports, port) + } + return ports, nil +} + +func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) { + name, err := service.GetStringProperty("IOCalloutDevice") + if err != nil { + return nil, fmt.Errorf("Error extracting port info from device: %s", err.Error()) + } + port := &PortDetails{} + port.Name = name + port.IsUSB = false + + usbDevice := service + for usbDevice.GetClass() != "IOUSBDevice" { + if usbDevice, err = usbDevice.GetParent("IOService"); err != nil { + break + } + } + if err == nil { + // It's an IOUSBDevice + vid, _ := usbDevice.GetIntProperty("idVendor", C.kCFNumberSInt16Type) + pid, _ := usbDevice.GetIntProperty("idProduct", C.kCFNumberSInt16Type) + serialNumber, _ := usbDevice.GetStringProperty("USB Serial Number") + //product, _ := usbDevice.GetStringProperty("USB Product Name") + //manufacturer, _ := usbDevice.GetStringProperty("USB Vendor Name") + //fmt.Println(product + " - " + manufacturer) + + port.IsUSB = true + port.VID = fmt.Sprintf("%04X", vid) + port.PID = fmt.Sprintf("%04X", pid) + port.SerialNumber = serialNumber + } + return port, nil +} + +func getAllServices(serviceType string) ([]C.io_object_t, error) { + i, err := getMatchingServices(serviceMatching(serviceType)) + if err != nil { + return nil, err + } + defer i.Release() + + var services []C.io_object_t + tries := 0 + for tries < 5 { + // Extract all elements from iterator + if service, ok := i.Next(); ok { + services = append(services, service) + continue + } + // If iterator is still valid return the result + if i.IsValid() { + return services, nil + } + // Otherwise empty the result and retry + for _, s := range services { + s.Release() + } + services = []C.io_object_t{} + i.Reset() + tries++ + } + // Give up if the iteration continues to fail... + return nil, fmt.Errorf("IOServiceGetMatchingServices failed, data changed while iterating") +} + +// serviceMatching create a matching dictionary that specifies an IOService class match. +func serviceMatching(serviceType string) C.CFMutableDictionaryRef { + t := C.CString(serviceType) + defer C.free(unsafe.Pointer(t)) + return C.IOServiceMatching(t) +} + +// getMatchingServices look up registered IOService objects that match a matching dictionary. +func getMatchingServices(matcher C.CFMutableDictionaryRef) (C.io_iterator_t, error) { + var i C.io_iterator_t + err := C.IOServiceGetMatchingServices(C.kIOMasterPortDefault, matcher, &i) + if err != C.KERN_SUCCESS { + return 0, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err) + } + return i, nil +} + +// CFStringRef + +func cfStringCreateWithString(s string) C.CFStringRef { + c := C.CString(s) + defer C.free(unsafe.Pointer(c)) + return C.CFStringCreateWithCString( + C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman) +} + +// io_registry_entry_t + +func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, error) { + cPlane := C.CString(plane) + defer C.free(unsafe.Pointer(cPlane)) + var parent C.io_registry_entry_t + err := C.IORegistryEntryGetParentEntry(*me, cPlane, &parent) + if err != 0 { + return 0, errors.New("No parent device available") + } + return parent, nil +} + +func (me *C.io_registry_entry_t) GetClass() string { + obj := (*C.io_object_t)(me) + return obj.GetClass() +} + +func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { + k := cfStringCreateWithString(key) + defer C.CFRelease(C.CFTypeRef(k)) + property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) + if property == nil { + return "", errors.New("Property not found: " + key) + } + defer C.CFRelease(property) + + if ptr := C.CFStringGetCStringPtr((C.CFStringRef)(unsafe.Pointer(property)), 0); ptr != nil { + return C.GoString(ptr), nil + } + // in certain circumstances CFStringGetCStringPtr may return NULL + // and we must retrieve the string by copy + buff := make([]C.char, 1024) + if C.CFStringGetCString((C.CFStringRef)(property), &buff[0], 1024, 0) != C.true { + return "", fmt.Errorf("Property '%s' can't be converted", key) + } + return C.GoString(&buff[0]), nil +} + +func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) { + k := cfStringCreateWithString(key) + defer C.CFRelease(C.CFTypeRef(k)) + property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) + if property == nil { + return 0, errors.New("Property not found: " + key) + } + defer C.CFRelease(property) + var res int + if C.CFNumberGetValue((C.CFNumberRef)(property), intType, unsafe.Pointer(&res)) != C.true { + return res, fmt.Errorf("Property '%s' can't be converted or has been truncated", key) + } + return res, nil +} + +// io_iterator_t + +// IsValid checks if an iterator is still valid. +// Some iterators will be made invalid if changes are made to the +// structure they are iterating over. This function checks the iterator +// is still valid and should be called when Next returns zero. +// An invalid iterator can be Reset and the iteration restarted. +func (me *C.io_iterator_t) IsValid() bool { + return C.IOIteratorIsValid(*me) == C.true +} + +func (me *C.io_iterator_t) Reset() { + C.IOIteratorReset(*me) +} + +func (me *C.io_iterator_t) Next() (C.io_object_t, bool) { + res := C.IOIteratorNext(*me) + return res, res != 0 +} + +func (me *C.io_iterator_t) Release() { + C.IOObjectRelease(C.io_object_t(*me)) +} + +// io_object_t + +func (me *C.io_object_t) Release() { + C.IOObjectRelease(*me) +} + +func (me *C.io_object_t) GetClass() string { + class := make([]C.char, 1024) + C.IOObjectGetClass(*me, &class[0]) + return C.GoString(&class[0]) +} From 3c7a545ca253ffeb9b128e6dfd5f0714f8a2f6ec Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:09:25 +0200 Subject: [PATCH 03/13] Removed -fconstant-cfstrings CGO build flag --- enumerator/usb_go1.10_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 23416fe..4a2b7cb 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -8,7 +8,7 @@ package enumerator // import "go.bug.st/serial.v1/enumerator" -// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -fconstant-cfstrings +// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit // #include // #include // #include From ef634e5745e7081faaf3d4d83e7005f194216ed0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:11:11 +0200 Subject: [PATCH 04/13] Removed duplicated methods on (nowadays) equivalent type C.io_*_t This is due to improvements on the cgo builder related to darwin OS. --- enumerator/usb_go1.10_darwin.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 4a2b7cb..27249f8 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -140,11 +140,6 @@ func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, return parent, nil } -func (me *C.io_registry_entry_t) GetClass() string { - obj := (*C.io_object_t)(me) - return obj.GetClass() -} - func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { k := cfStringCreateWithString(key) defer C.CFRelease(C.CFTypeRef(k)) @@ -201,10 +196,6 @@ func (me *C.io_iterator_t) Next() (C.io_object_t, bool) { return res, res != 0 } -func (me *C.io_iterator_t) Release() { - C.IOObjectRelease(C.io_object_t(*me)) -} - // io_object_t func (me *C.io_object_t) Release() { From 75aa16d69f91e2c3aba76fd08b66387abd88053a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:13:24 +0200 Subject: [PATCH 05/13] CFRef are no more internally represented as pointer but as integers This is due to improvements in CGO compiler for darwin OS --- enumerator/usb_go1.10_darwin.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 27249f8..4640918 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -144,12 +144,12 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { k := cfStringCreateWithString(key) defer C.CFRelease(C.CFTypeRef(k)) property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) - if property == nil { + if property == 0 { return "", errors.New("Property not found: " + key) } defer C.CFRelease(property) - if ptr := C.CFStringGetCStringPtr((C.CFStringRef)(unsafe.Pointer(property)), 0); ptr != nil { + if ptr := C.CFStringGetCStringPtr(C.CFStringRef(property), 0); ptr != nil { return C.GoString(ptr), nil } // in certain circumstances CFStringGetCStringPtr may return NULL @@ -165,7 +165,7 @@ func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberTy k := cfStringCreateWithString(key) defer C.CFRelease(C.CFTypeRef(k)) property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) - if property == nil { + if property == 0 { return 0, errors.New("Property not found: " + key) } defer C.CFRelease(property) From ee147ffce49faca927bce509eaaed3945b08a43b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:28:40 +0200 Subject: [PATCH 06/13] Added Release method to CFStringRef --- enumerator/usb_go1.10_darwin.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 4640918..57ba106 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -127,6 +127,10 @@ func cfStringCreateWithString(s string) C.CFStringRef { C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman) } +func (ref C.CFStringRef) Release() { + C.CFRelease(C.CFTypeRef(ref)) +} + // io_registry_entry_t func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, error) { @@ -142,7 +146,7 @@ func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { k := cfStringCreateWithString(key) - defer C.CFRelease(C.CFTypeRef(k)) + defer k.Release() property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) if property == 0 { return "", errors.New("Property not found: " + key) @@ -163,7 +167,7 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) { k := cfStringCreateWithString(key) - defer C.CFRelease(C.CFTypeRef(k)) + defer k.Release() property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) if property == 0 { return 0, errors.New("Property not found: " + key) From 71fe05aedd261c89c5adbd6f7432130238cf9de1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:40:47 +0200 Subject: [PATCH 07/13] Added Release method to CFTypeRef --- enumerator/usb_go1.10_darwin.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 57ba106..e96901e 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -131,6 +131,12 @@ func (ref C.CFStringRef) Release() { C.CFRelease(C.CFTypeRef(ref)) } +// CFTypeRef + +func (ref C.CFTypeRef) Release() { + C.CFRelease(ref) +} + // io_registry_entry_t func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, error) { @@ -151,7 +157,7 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { if property == 0 { return "", errors.New("Property not found: " + key) } - defer C.CFRelease(property) + defer property.Release() if ptr := C.CFStringGetCStringPtr(C.CFStringRef(property), 0); ptr != nil { return C.GoString(ptr), nil @@ -172,7 +178,7 @@ func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberTy if property == 0 { return 0, errors.New("Property not found: " + key) } - defer C.CFRelease(property) + defer property.Release() var res int if C.CFNumberGetValue((C.CFNumberRef)(property), intType, unsafe.Pointer(&res)) != C.true { return res, fmt.Errorf("Property '%s' can't be converted or has been truncated", key) From cdac3b30e16732aa230de7b0f43996f0a3eaa428 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:41:00 +0200 Subject: [PATCH 08/13] Removed extra parenthesis --- enumerator/usb_go1.10_darwin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index e96901e..2ac257c 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -165,7 +165,7 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { // in certain circumstances CFStringGetCStringPtr may return NULL // and we must retrieve the string by copy buff := make([]C.char, 1024) - if C.CFStringGetCString((C.CFStringRef)(property), &buff[0], 1024, 0) != C.true { + if C.CFStringGetCString(C.CFStringRef(property), &buff[0], 1024, 0) != C.true { return "", fmt.Errorf("Property '%s' can't be converted", key) } return C.GoString(&buff[0]), nil From 6085517433f155a5dda1445f1fb06f9550a90527 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:41:24 +0200 Subject: [PATCH 09/13] Made error variable explicit in search loop --- enumerator/usb_go1.10_darwin.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index 2ac257c..cf19fe3 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -48,12 +48,13 @@ func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) { port.IsUSB = false usbDevice := service + var searchErr error for usbDevice.GetClass() != "IOUSBDevice" { - if usbDevice, err = usbDevice.GetParent("IOService"); err != nil { + if usbDevice, searchErr = usbDevice.GetParent("IOService"); searchErr != nil { break } } - if err == nil { + if searchErr == nil { // It's an IOUSBDevice vid, _ := usbDevice.GetIntProperty("idVendor", C.kCFNumberSInt16Type) pid, _ := usbDevice.GetIntProperty("idProduct", C.kCFNumberSInt16Type) From 338c399730b7c5ea6a9581e539ba8c031ed5ba2e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:51:07 +0200 Subject: [PATCH 10/13] Factored out C.IORegistryEntryCreateCFProperty method --- enumerator/usb_go1.10_darwin.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_go1.10_darwin.go index cf19fe3..357904b 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_go1.10_darwin.go @@ -151,12 +151,20 @@ func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, return parent, nil } -func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { +func (me *C.io_registry_entry_t) CreateCFProperty(key string) (C.CFTypeRef, error) { k := cfStringCreateWithString(key) defer k.Release() property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) if property == 0 { - return "", errors.New("Property not found: " + key) + return 0, errors.New("Property not found: " + key) + } + return property, nil +} + +func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { + property, err := me.CreateCFProperty(key) + if err != nil { + return "", err } defer property.Release() @@ -173,11 +181,9 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { } func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) { - k := cfStringCreateWithString(key) - defer k.Release() - property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) - if property == 0 { - return 0, errors.New("Property not found: " + key) + property, err := me.CreateCFProperty(key) + if err != nil { + return 0, err } defer property.Release() var res int From de1714d049b8e49f2f86fbee82bb0ad1a58e9efb Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:52:20 +0200 Subject: [PATCH 11/13] Added portlist cmd-line utility --- portlist/portlist.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 portlist/portlist.go diff --git a/portlist/portlist.go b/portlist/portlist.go new file mode 100644 index 0000000..5d4d127 --- /dev/null +++ b/portlist/portlist.go @@ -0,0 +1,37 @@ +// +// Copyright 2014-2018 Cristian Maglie. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// + +// portlist is a tool to list all the available serial ports. +// Just run it and it will produce an output like: +// +// $ go run portlist.go +// Port: /dev/cu.Bluetooth-Incoming-Port +// Port: /dev/cu.usbmodemFD121 +// USB ID 2341:8053 +// USB serial FB7B6060504B5952302E314AFF08191A +// +package main + +import "fmt" +import "log" +import "go.bug.st/serial.v1/enumerator" + +func main() { + ports, err := enumerator.GetDetailedPortsList() + if err != nil { + log.Fatal(err) + } + if len(ports) == 0 { + return + } + for _, port := range ports { + fmt.Printf("Port: %s\n", port.Name) + if port.IsUSB { + fmt.Printf(" USB ID %s:%s\n", port.VID, port.PID) + fmt.Printf(" USB serial %s\n", port.SerialNumber) + } + } +} From e42339511cf1ce55cc7f71b6acca84e8786fd179 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 18:57:32 +0200 Subject: [PATCH 12/13] Fixed wrong build tags... oops --- enumerator/{usb_go1.10_darwin.go => usb_darwin.go} | 2 +- enumerator/{usb_go1.9_darwin.go => usb_darwin_go1.9.go} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename enumerator/{usb_go1.10_darwin.go => usb_darwin.go} (99%) rename enumerator/{usb_go1.9_darwin.go => usb_darwin_go1.9.go} (99%) diff --git a/enumerator/usb_go1.10_darwin.go b/enumerator/usb_darwin.go similarity index 99% rename from enumerator/usb_go1.10_darwin.go rename to enumerator/usb_darwin.go index 357904b..c72a19a 100644 --- a/enumerator/usb_go1.10_darwin.go +++ b/enumerator/usb_darwin.go @@ -4,7 +4,7 @@ // license that can be found in the LICENSE file. // -// +build go1.10 +// +build go1.10,darwin package enumerator // import "go.bug.st/serial.v1/enumerator" diff --git a/enumerator/usb_go1.9_darwin.go b/enumerator/usb_darwin_go1.9.go similarity index 99% rename from enumerator/usb_go1.9_darwin.go rename to enumerator/usb_darwin_go1.9.go index f8ed324..24cd32f 100644 --- a/enumerator/usb_go1.9_darwin.go +++ b/enumerator/usb_darwin_go1.9.go @@ -4,7 +4,7 @@ // license that can be found in the LICENSE file. // -// +build !go1.10 +// +build !go1.10,darwin // This file is here to keep compatibility with the older versions of go // and is no more maintained or bugfixed, please update your go version From 1c2446b92c285a8f7e4fe47b2e55f41960ffb148 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 19 Aug 2018 19:13:36 +0200 Subject: [PATCH 13/13] Implementing compatibility with go latest This should allow darwin to be compatible with all the latest go1.7.x go1.8.x go1.9.x --- .travis.yml | 12 ------------ enumerator/usb_darwin_go1.9.go | 11 +---------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index e825252..8f4b14e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,6 @@ go: - 1.8.x - 1.9.x - 1.10.x - # from go 1.8.7, 1.9.4, 1.10rc2 there is a restriction on CGO see https://github.com/bugst/go-serial/issues/50 - # this restriction has some consequences on darwin build - - 1.8.6 - - 1.9.3 go_import_path: go.bug.st/serial.v1 @@ -31,14 +27,6 @@ env: matrix: exclude: - - os: linux # no point in testing go1.8.6 on Linux - go: 1.8.6 - - os: linux # no point in testing go1.9.3 on Linux - go: 1.9.3 - - os: osx # go1.8.x after 1.8.6 is not supported on OSX - go: 1.8.x - - os: osx # go1.9.x after 1.9.3 is not supported on OSX - go: 1.9.x - os: linux env: TEST_OS=darwin TEST_ARCH=386 - os: linux diff --git a/enumerator/usb_darwin_go1.9.go b/enumerator/usb_darwin_go1.9.go index 24cd32f..442278d 100644 --- a/enumerator/usb_darwin_go1.9.go +++ b/enumerator/usb_darwin_go1.9.go @@ -10,18 +10,9 @@ // and is no more maintained or bugfixed, please update your go version // to at least 1.10 to get the latest updates. -// Supported versions on MacOSX -// - any go version earlier than 1.8 -// - go1.8.x series from 1.8.0 to 1.8.6 -// - go1.9.x series from 1.9.0 to 1.9.3 - -// Versions NOT supported on MacOSX -// - go1.8.x series starting from 1.8.7 -// - go1.9.x series starting from 1.9.4 - package enumerator // import "go.bug.st/serial.v1/enumerator" -// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -fconstant-cfstrings +// #cgo LDFLAGS: -framework CoreFoundation -framework IOKit // #include // #include // #include