forked from currantlabs/ble
-
Notifications
You must be signed in to change notification settings - Fork 0
/
conn.go
135 lines (107 loc) · 2.36 KB
/
conn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package darwin
import (
"sync"
"golang.org/x/net/context"
"github.com/currantlabs/ble"
"github.com/raff/goble/xpc"
)
func newConn(d *Device, a ble.Addr) *conn {
return &conn{
dev: d,
rxMTU: 23,
txMTU: 23,
addr: a,
done: make(chan struct{}),
notifiers: make(map[uint16]ble.Notifier),
subs: make(map[uint16]*sub),
rspc: make(chan msg),
}
}
type conn struct {
sync.RWMutex
dev *Device
role int
ctx context.Context
rxMTU int
txMTU int
addr ble.Addr
done chan struct{}
rspc chan msg
connInterval int
connLatency int
supervisionTimeout int
notifiers map[uint16]ble.Notifier // central connection only
subs map[uint16]*sub
}
func (c *conn) Context() context.Context {
return c.ctx
}
func (c *conn) SetContext(ctx context.Context) {
c.ctx = ctx
}
func (c *conn) LocalAddr() ble.Addr {
// return c.dev.Address()
return c.addr // FIXME
}
func (c *conn) RemoteAddr() ble.Addr {
return c.addr
}
func (c *conn) RxMTU() int {
return c.rxMTU
}
func (c *conn) SetRxMTU(mtu int) {
c.rxMTU = mtu
}
func (c *conn) TxMTU() int {
return c.txMTU
}
func (c *conn) SetTxMTU(mtu int) {
c.txMTU = mtu
}
func (c *conn) Read(b []byte) (int, error) {
return 0, nil
}
func (c *conn) Write(b []byte) (int, error) {
return 0, nil
}
func (c *conn) Close() error {
return nil
}
// Disconnected returns a receiving channel, which is closed when the connection disconnects.
func (c *conn) Disconnected() <-chan struct{} {
return c.done
}
// server (peripheral)
func (c *conn) subscribed(char *ble.Characteristic) {
h := char.Handle
if _, found := c.notifiers[h]; found {
return
}
send := func(b []byte) (int, error) {
c.dev.sendCmd(c.dev.pm, 15, xpc.Dict{
"kCBMsgArgUUIDs": [][]byte{},
"kCBMsgArgAttributeID": h,
"kCBMsgArgData": b,
})
return len(b), nil
}
n := ble.NewNotifier(send)
c.notifiers[h] = n
req := ble.NewRequest(c, nil, 0) // convey *conn to user handler.
go char.NotifyHandler.ServeNotify(req, n)
}
// server (peripheral)
func (c *conn) unsubscribed(char *ble.Characteristic) {
if n, found := c.notifiers[char.Handle]; found {
n.Close()
delete(c.notifiers, char.Handle)
}
}
func (c *conn) sendReq(id int, args xpc.Dict) msg {
c.dev.sendCmd(c.dev.cm, id, args)
m := <-c.rspc
return msg(m.args())
}
func (c *conn) sendCmd(id int, args xpc.Dict) {
c.dev.sendCmd(c.dev.pm, id, args)
}