forked from currantlabs/ble
-
Notifications
You must be signed in to change notification settings - Fork 2
/
handler.go
187 lines (150 loc) · 4.07 KB
/
handler.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package ble
import (
"bytes"
"context"
"io"
)
// A ReadHandler handles GATT requests.
type ReadHandler interface {
ServeRead(req Request, rsp ResponseWriter)
}
// ReadHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
type ReadHandlerFunc func(req Request, rsp ResponseWriter)
// ServeRead returns f(r, maxlen, offset).
func (f ReadHandlerFunc) ServeRead(req Request, rsp ResponseWriter) {
f(req, rsp)
}
// A WriteHandler handles GATT requests.
type WriteHandler interface {
ServeWrite(req Request, rsp ResponseWriter)
}
// WriteHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
type WriteHandlerFunc func(req Request, rsp ResponseWriter)
// ServeWrite returns f(r, maxlen, offset).
func (f WriteHandlerFunc) ServeWrite(req Request, rsp ResponseWriter) {
f(req, rsp)
}
// A NotifyHandler handles GATT requests.
type NotifyHandler interface {
ServeNotify(req Request, n Notifier)
}
// NotifyHandlerFunc is an adapter to allow the use of ordinary functions as Handlers.
type NotifyHandlerFunc func(req Request, n Notifier)
// ServeNotify returns f(r, maxlen, offset).
func (f NotifyHandlerFunc) ServeNotify(req Request, n Notifier) {
f(req, n)
}
// Request ...
type Request interface {
Conn() Conn
Data() []byte
Offset() int
}
// NewRequest returns a default implementation of Request.
func NewRequest(conn Conn, data []byte, offset int) Request {
return &request{conn: conn, data: data, offset: offset}
}
// Default implementation of request.
type request struct {
conn Conn
data []byte
offset int
}
func (r *request) Conn() Conn { return r.conn }
func (r *request) Data() []byte { return r.data }
func (r *request) Offset() int { return r.offset }
// ResponseWriter ...
type ResponseWriter interface {
// Write writes data to return as the characteristic value.
Write(b []byte) (int, error)
// Status reports the result of the request.
Status() ATTError
// SetStatus reports the result of the request.
SetStatus(status ATTError)
// Len ...
Len() int
// Cap ...
Cap() int
}
// NewResponseWriter ...
func NewResponseWriter(buf *bytes.Buffer) ResponseWriter {
return &responseWriter{buf: buf}
}
// responseWriter implements Response
type responseWriter struct {
buf *bytes.Buffer
status ATTError
}
// Status reports the result of the request.
func (r *responseWriter) Status() ATTError {
return r.status
}
// SetStatus reports the result of the request.
func (r *responseWriter) SetStatus(status ATTError) {
r.status = status
}
// Len returns length of the buffer.
// Len returns 0 if it is a dummy write response for WriteCommand.
func (r *responseWriter) Len() int {
if r.buf == nil {
return 0
}
return r.buf.Len()
}
// Cap returns capacity of the buffer.
// Cap returns 0 if it is a dummy write response for WriteCommand.
func (r *responseWriter) Cap() int {
if r.buf == nil {
return 0
}
return r.buf.Cap()
}
// Write writes data to return as the characteristic value.
// Cap returns 0 with error set to ErrReqNotSupp if it is a dummy write response for WriteCommand.
func (r *responseWriter) Write(b []byte) (int, error) {
if r.buf == nil {
return 0, ErrReqNotSupp
}
if len(b) > r.buf.Cap()-r.buf.Len() {
return 0, io.ErrShortWrite
}
return r.buf.Write(b)
}
// Notifier ...
type Notifier interface {
// Context sends data to the central.
Context() context.Context
// Write sends data to the central.
Write(b []byte) (int, error)
// Close ...
Close() error
// Cap returns the maximum number of bytes that may be sent in a single notification.
Cap() int
}
type notifier struct {
ctx context.Context
maxlen int
cancel func()
send func([]byte) (int, error)
}
// NewNotifier ...
func NewNotifier(send func([]byte) (int, error)) Notifier {
n := ¬ifier{}
n.ctx, n.cancel = context.WithCancel(context.Background())
n.send = send
// n.maxlen = cap
return n
}
func (n *notifier) Context() context.Context {
return n.ctx
}
func (n *notifier) Write(b []byte) (int, error) {
return n.send(b)
}
func (n *notifier) Close() error {
n.cancel()
return nil
}
func (n *notifier) Cap() int {
return n.maxlen
}