blob: 0b9bc8c289162a33fbd4b634f54331630bda103e [file] [log] [blame]
Jiri Simsa4419f232014-07-23 17:56:06 -07001// +build veyronbluetooth,!android
2
Jiri Simsa5293dcb2014-05-10 09:56:38 -07003package bluetooth
4
5import (
6 "bytes"
7 "fmt"
8 "net"
9 "strconv"
10 "strings"
11)
12
Asim Shankar13752172014-07-09 11:29:07 -070013// addr represents an RFCOMM over bluetooth address in the <MAC-channelID>
14// format, where channelID denotes one of the available RFCOMM channels.
15//
Jiri Simsa5293dcb2014-05-10 09:56:38 -070016// It implements the net.Addr interface.
17type addr struct {
Asim Shankar13752172014-07-09 11:29:07 -070018 mac net.HardwareAddr
19 channel int
Jiri Simsa5293dcb2014-05-10 09:56:38 -070020}
21
22// anyMAC is a MAC address "00:00:00:00:00:00", which means first available
23// (bluetooth) device.
24var anyMAC net.HardwareAddr
25
26func init() {
27 var err error
28 if anyMAC, err = net.ParseMAC("00:00:00:00:00:00"); err != nil {
29 panic("can't parse address 00:00:00:00:00:00")
30 }
31}
32
Asim Shankar13752172014-07-09 11:29:07 -070033// parseAddress parses an address string in the <MAC-channelID> format (e.g.,
34// "01:23:45:67:89:AB-1"). It returns an error if the address is in the wrong
Jiri Simsa5293dcb2014-05-10 09:56:38 -070035// format. It is legal for a MAC address sub-part to be empty, in which case
36// it will be treated as anyMAC (i.e., "00:00:00:00:00:00").
37func parseAddress(address string) (*addr, error) {
Asim Shankar13752172014-07-09 11:29:07 -070038 parts := strings.Split(address, "-")
Jiri Simsa5293dcb2014-05-10 09:56:38 -070039 if len(parts) != 2 {
Asim Shankar13752172014-07-09 11:29:07 -070040 return nil, fmt.Errorf("too many or too few \"-\" in address: %s", address)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070041 }
42 ms := parts[0]
43 ps := parts[1]
44 if len(ms) == 0 {
Asim Shankar13752172014-07-09 11:29:07 -070045 channel, err := strconv.ParseInt(ps, 0, 32)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070046 if err != nil {
47 return nil, err
48 }
Asim Shankar13752172014-07-09 11:29:07 -070049 return &addr{anyMAC, int(channel)}, nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -070050 } else {
51 mac, err := net.ParseMAC(ms)
52 if err != nil {
53 return nil, err
54 }
Asim Shankar13752172014-07-09 11:29:07 -070055 channel, err := strconv.ParseInt(ps, 0, 32)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070056 if err != nil {
57 return nil, err
58 }
Asim Shankar13752172014-07-09 11:29:07 -070059 return &addr{mac, int(channel)}, nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -070060 }
61}
62
63// Implements the net.Addr interface.
64func (a *addr) Network() string {
Asim Shankar13752172014-07-09 11:29:07 -070065 return Network
Jiri Simsa5293dcb2014-05-10 09:56:38 -070066}
67
68// Implements the net.Addr interface.
69func (a *addr) String() string {
Asim Shankar13752172014-07-09 11:29:07 -070070 return fmt.Sprintf("%s-%d", a.mac, a.channel)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070071}
72
73// isAnyMAC returns true iff the mac address is "any" (i.e.,
74// "00:00:00:00:00:00")
75func (a *addr) isAnyMAC() bool {
76 return bytes.Equal(a.mac, anyMAC)
77}