@@ -7,11 +7,11 @@ import (
7
7
"sync"
8
8
9
9
"github.com/brutella/hc/db"
10
+ "github.com/brutella/hc/event"
10
11
"github.com/brutella/hc/model/accessory"
11
12
"github.com/brutella/hc/model/characteristic"
12
13
"github.com/brutella/hc/model/container"
13
14
"github.com/brutella/hc/netio"
14
- "github.com/brutella/hc/netio/event"
15
15
"github.com/brutella/hc/server"
16
16
"github.com/brutella/hc/util"
17
17
"github.com/brutella/log"
@@ -30,6 +30,8 @@ type ipTransport struct {
30
30
name string
31
31
device netio.SecuredDevice
32
32
container * container.Container
33
+
34
+ emitter event.Emitter
33
35
}
34
36
35
37
// NewIPTransport creates a transport to provide accessories over IP.
@@ -71,25 +73,34 @@ func NewIPTransport(pin string, a *accessory.Accessory, as ...*accessory.Accesso
71
73
container : container .NewContainer (),
72
74
mutex : & sync.Mutex {},
73
75
context : netio .NewContextForSecuredDevice (device ),
76
+ emitter : event .NewEmitter (),
74
77
}
75
78
76
79
t .addAccessory (a )
77
80
for _ , a := range as {
78
81
t .addAccessory (a )
79
82
}
80
83
84
+ t .emitter .AddListener (t )
85
+
81
86
return t , err
82
87
}
83
88
84
89
func (t * ipTransport ) Start () {
85
- s := server .NewServer (t .context , t .database , t .container , t .device , t .mutex )
90
+ s := server .NewServer (t .context , t .database , t .container , t .device , t .mutex , t . emitter )
86
91
t .server = s
87
92
port := to .Int64 (s .Port ())
88
93
89
94
mdns := NewMDNSService (t .name , t .device .Name (), int (port ))
90
95
t .mdns = mdns
91
96
97
+ if t .isPaired () {
98
+ // Paired accessories must not be reachable for other clients since iOS 9
99
+ mdns .SetReachable (false )
100
+ }
101
+
92
102
mdns .Publish ()
103
+
93
104
// Listen until server.Stop() is called
94
105
s .ListenAndServe ()
95
106
}
@@ -105,6 +116,26 @@ func (t *ipTransport) Stop() {
105
116
}
106
117
}
107
118
119
+ // isPaired returns true when the transport is already paired
120
+ func (t * ipTransport ) isPaired () bool {
121
+
122
+ // If more than one entity is stored in the database, we are paired with a device.
123
+ // The transport itself is a device and is stored in the database, therefore
124
+ // we have to check for more than one entity.
125
+ if es , err := t .database .Entities (); err == nil && len (es ) > 1 {
126
+ return true
127
+ }
128
+
129
+ return false
130
+ }
131
+
132
+ func (t * ipTransport ) updateMDNSReachability () {
133
+ if mdns := t .mdns ; mdns != nil {
134
+ mdns .SetReachable (t .isPaired () == false )
135
+ mdns .Update ()
136
+ }
137
+ }
138
+
108
139
func (t * ipTransport ) addAccessory (a * accessory.Accessory ) {
109
140
t .container .AddAccessory (a )
110
141
@@ -136,7 +167,7 @@ func (t *ipTransport) notifyListener(a *accessory.Accessory, c *characteristic.C
136
167
if conn == except {
137
168
continue
138
169
}
139
- resp , err := event .New (a , c )
170
+ resp , err := netio .New (a , c )
140
171
if err != nil {
141
172
log .Fatal (err )
142
173
}
@@ -146,7 +177,7 @@ func (t *ipTransport) notifyListener(a *accessory.Accessory, c *characteristic.C
146
177
var buffer = new (bytes.Buffer )
147
178
resp .Write (buffer )
148
179
bytes , err := ioutil .ReadAll (buffer )
149
- bytes = event .FixProtocolSpecifier (bytes )
180
+ bytes = netio .FixProtocolSpecifier (bytes )
150
181
log .Printf ("[VERB] %s <- %s" , conn .RemoteAddr (), string (bytes ))
151
182
conn .Write (bytes )
152
183
}
@@ -166,3 +197,17 @@ func transportUUIDInStorage(storage util.Storage) string {
166
197
}
167
198
return string (uuid )
168
199
}
200
+
201
+ // Handles event which are sent when pairing with a device is added or removed
202
+ func (t * ipTransport ) Handle (ev interface {}) {
203
+ switch ev .(type ) {
204
+ case event.DevicePaired :
205
+ log .Printf ("[INFO] Event: paired with device" )
206
+ t .updateMDNSReachability ()
207
+ case event.DeviceUnpaired :
208
+ log .Printf ("[INFO] Event: unpaired with device" )
209
+ t .updateMDNSReachability ()
210
+ default :
211
+ break
212
+ }
213
+ }
0 commit comments