[serial-mapper] Get mac and serial number
Change serial mapper to get the mac address and serial number of each
device along with then nodename.
Change-Id: I1c6dcf85a0c3771699d9d7a231a9a0b24e248c88
diff --git a/cmd/serial_mapper/main.go b/cmd/serial_mapper/main.go
index 1465c22..5c01d66 100644
--- a/cmd/serial_mapper/main.go
+++ b/cmd/serial_mapper/main.go
@@ -15,8 +15,11 @@
"fmt"
"io"
"io/ioutil"
+ "os/exec"
"path"
"regexp"
+ "strings"
+ "sync"
"time"
"go.fuchsia.dev/tools/logger"
@@ -29,6 +32,83 @@
serialDir = "/dev/serial/by-id"
)
+type DeviceInfo struct {
+ mac string
+ nodename string
+ serial string
+}
+
+func getDeviceInfo(fPath string) (*DeviceInfo, error) {
+ device, err := serial.Open(fPath)
+ defer device.Close()
+ if err != nil {
+ return nil, err
+ }
+
+ if _, err = io.WriteString(device, "\ndlog\n"); err != nil {
+ return nil, err
+ }
+
+ nodenameRe := regexp.MustCompile("nodename='(.*?)'")
+ macRe := regexp.MustCompile("macaddr: ([0-9a-f]{2}[:]){5}([0-9a-f]{2})")
+
+ scanner := bufio.NewScanner(device)
+ info := &DeviceInfo{
+ nodename: "",
+ mac: "",
+ serial: "",
+ }
+ for scanner.Scan() {
+ line := scanner.Text()
+ nodenameMatch := nodenameRe.FindStringSubmatch(line)
+ macMatch := macRe.FindStringSubmatch(line)
+
+ if nodenameMatch != nil {
+ info.nodename = nodenameMatch[1]
+ } else if macMatch != nil {
+ info.mac = strings.Split(macMatch[0], " ")[1]
+ }
+
+ if info.nodename != "" && info.mac != "" {
+ break
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, err
+ } else if info.nodename == "" && info.mac == "" {
+ return nil, fmt.Errorf("info not found")
+ }
+
+ return info, nil
+}
+
+func runFastbootDevices() string {
+ cmd := exec.Command("fastboot", "devices")
+ output, err := cmd.Output()
+ if err != nil {
+ return ""
+ }
+ return strings.Split(string(output), "\t")[0]
+}
+
+func getSerialNumber(fPath string) (string, error) {
+ device, err := serial.Open(fPath)
+ defer device.Close()
+ if err != nil {
+ return "", err
+ }
+ if _, err := io.WriteString(device, "\ndm reboot-bootloader\n"); err != nil {
+ return "", err
+ }
+ time.Sleep(15 * time.Second)
+ if serial := runFastbootDevices(); serial != "" {
+ io.WriteString(device, "\x03")
+ return serial, nil
+ }
+ return "", fmt.Errorf("could not get device into fastboot")
+}
+
func main() {
ctx := context.Background()
@@ -37,62 +117,34 @@
logger.Fatalf(ctx, "failed to readdir() %s: %s", serialDir, err)
}
- mapping := make(map[string]string)
- re := regexp.MustCompile("nodename='(.*?)'")
+ mapping := make(map[string]*DeviceInfo)
+ var mapLock sync.Mutex
+ var wg sync.WaitGroup
+ wg.Add(len(files))
for _, f := range files {
fPath := path.Join(serialDir, f.Name())
-
- device, err := serial.Open(fPath)
- if err != nil {
- logger.Errorf(ctx, "unable to open() %s: %s", fPath, err)
- }
-
- _, err = io.WriteString(device, "\ndlog\n")
- if err != nil {
- logger.Errorf(ctx, "failed to writestring() to %s: %s", fPath, err)
- }
-
- errs := make(chan error)
- c := make(chan string)
-
go func() {
- defer close(c)
- defer close(errs)
-
- scanner := bufio.NewScanner(device)
- for scanner.Scan() {
- line := scanner.Text()
- match := re.FindStringSubmatch(line)
- if match != nil {
- c <- match[1]
- break
- }
- }
- if err := scanner.Err(); err != nil {
- errs <- fmt.Errorf("scan() error: %s", err)
+ defer wg.Done()
+ info, err := getDeviceInfo(fPath)
+ if err != nil {
+ logger.Errorf(ctx, "could not get device info from %s: %v", fPath, err)
+ } else {
+ mapLock.Lock()
+ mapping[fPath] = info
+ mapLock.Unlock()
}
}()
-
- select {
- case err := <-errs:
- logger.Errorf(ctx, "%s", err)
- // Timeout after 10 seconds.
- case <-time.After(10 * time.Second):
- logger.Errorf(ctx, "timed out %s", fPath)
- case nodename := <-c:
- mapping[nodename] = fPath
- }
-
- device.Close()
}
-
- if len(mapping) > 0 {
- fmt.Println("device:serial mapping:")
- for k, v := range mapping {
- fmt.Printf("%s\t%s\n", k, v)
+ wg.Wait()
+ fmt.Printf("\n\nserial\tnodename\tmac\tfastbootSernum\n")
+ for k, v := range mapping {
+ serial, err := getSerialNumber(k)
+ if err != nil {
+ fmt.Printf("err: %v\n", err)
+ continue
}
- } else {
- fmt.Println("found nothing!")
+ v.serial = serial
+ fmt.Printf("%s\t%s\t%s\t%s\n", k, v.nodename, v.mac, v.serial)
}
}