1 /*
2 * Copyright 2008 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * Copyright 2008 Mika Lindqvist, monni1995_at_gmail.com
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6
7
8 #include <bluetooth/DeviceClass.h>
9 #include <bluetooth/DiscoveryAgent.h>
10 #include <bluetooth/DiscoveryListener.h>
11 #include <bluetooth/bdaddrUtils.h>
12 #include <bluetooth/LocalDevice.h>
13 #include <bluetooth/RemoteDevice.h>
14
15 #include <bluetooth/HCI/btHCI_command.h>
16 #include <bluetooth/HCI/btHCI_event.h>
17
18 #include <bluetooth/debug.h>
19 #include <bluetooth/bluetooth_error.h>
20
21 #include <Catalog.h>
22 #include <CommandManager.h>
23 #include <Locale.h>
24 #include <bluetoothserver_p.h>
25
26 #include "KitSupport.h"
27
28
29 #undef B_TRANSLATION_CONTEXT
30 #define B_TRANSLATION_CONTEXT "RemoteDevice"
31
32
33 namespace Bluetooth {
34
35
36 // TODO: Check headers for valid/reserved ranges
37 static const uint16 invalidConnectionHandle = 0xF000;
38
39
40 bool
IsTrustedDevice(void)41 RemoteDevice::IsTrustedDevice(void)
42 {
43 CALLED();
44 return true;
45 }
46
47
48 BString
GetFriendlyName(bool alwaysAsk)49 RemoteDevice::GetFriendlyName(bool alwaysAsk)
50 {
51 CALLED();
52 if (!alwaysAsk) {
53 // Check if the name is already retrieved
54 // TODO: Check if It is known from a KnownDevicesList
55 return BString(B_TRANSLATE("Not implemented"));
56 }
57
58 if (fDiscovererLocalDevice == NULL)
59 return BString(B_TRANSLATE("#NoOwnerError#Not Valid name"));
60
61 if (fMessenger == NULL)
62 return BString(B_TRANSLATE("#ServerNotReady#Not Valid name"));
63
64 void* remoteNameCommand = NULL;
65 size_t size;
66
67 // Issue inquiry command
68 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
69 BMessage reply;
70
71 request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
72
73 // Fill the request
74 remoteNameCommand = buildRemoteNameRequest(fBdaddr, fPageRepetitionMode,
75 fClockOffset, &size);
76
77 request.AddData("raw command", B_ANY_TYPE, remoteNameCommand, size);
78
79 request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
80 request.AddInt16("opcodeExpected",
81 PACK_OPCODE(OGF_LINK_CONTROL, OCF_REMOTE_NAME_REQUEST));
82
83 request.AddInt16("eventExpected", HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE);
84
85
86 if (fMessenger->SendMessage(&request, &reply) == B_OK) {
87 BString name;
88 int8 status;
89
90 if ((reply.FindInt8("status", &status) == B_OK) && (status == BT_OK)) {
91
92 if ((reply.FindString("friendlyname", &name) == B_OK )) {
93 return name;
94 } else {
95 return BString(""); // should not happen
96 }
97
98 } else {
99 // seems we got a negative event
100 return BString(B_TRANSLATE("#CommandFailed#Not Valid name"));
101 }
102 }
103
104 return BString(B_TRANSLATE("#NotCompletedRequest#Not Valid name"));
105 }
106
107
108 BString
GetFriendlyName()109 RemoteDevice::GetFriendlyName()
110 {
111 CALLED();
112 return GetFriendlyName(true);
113 }
114
115
116 bdaddr_t
GetBluetoothAddress()117 RemoteDevice::GetBluetoothAddress()
118 {
119 CALLED();
120 return fBdaddr;
121 }
122
123
124 bool
Equals(RemoteDevice * obj)125 RemoteDevice::Equals(RemoteDevice* obj)
126 {
127 CALLED();
128 return bdaddrUtils::Compare(fBdaddr, obj->GetBluetoothAddress());
129 }
130
131
132 // static RemoteDevice* GetRemoteDevice(Connection conn);
133
134
135 bool
Authenticate()136 RemoteDevice::Authenticate()
137 {
138 CALLED();
139 int8 btStatus = BT_ERROR;
140
141 if (fMessenger == NULL || fDiscovererLocalDevice == NULL)
142 return false;
143
144 BluetoothCommand<typed_command(hci_cp_create_conn)>
145 createConnection(OGF_LINK_CONTROL, OCF_CREATE_CONN);
146
147 bdaddrUtils::Copy(createConnection->bdaddr, fBdaddr);
148 createConnection->pscan_rep_mode = fPageRepetitionMode;
149 createConnection->pscan_mode = fScanMode; // Reserved in spec 2.1
150 createConnection->clock_offset = fClockOffset | 0x8000; // substract!
151
152 uint32 roleSwitch;
153 fDiscovererLocalDevice->GetProperty("role_switch_capable", &roleSwitch);
154 createConnection->role_switch = (uint8)roleSwitch;
155
156 uint32 packetType;
157 fDiscovererLocalDevice->GetProperty("packet_type", &packetType);
158 createConnection->pkt_type = (uint16)packetType;
159
160 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
161 BMessage reply;
162
163 request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
164 request.AddData("raw command", B_ANY_TYPE,
165 createConnection.Data(), createConnection.Size());
166
167 // First we get the status about the starting of the connection
168 request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
169 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
170 OCF_CREATE_CONN));
171
172 // if authentication needed, we will send any of these commands
173 // to accept or deny the LINK KEY [a]
174 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
175 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
176 OCF_LINK_KEY_REPLY));
177
178 request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
179 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
180 OCF_LINK_KEY_NEG_REPLY));
181
182 // in negative case, a pincode will be replied [b]
183 // this request will be handled by sepatated by the pincode window
184 // request.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE);
185 // request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
186 // OCF_PIN_CODE_REPLY));
187
188 // [a] this is expected of authentication required
189 request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_REQ);
190 // [b] If we deny the key an authentication will be requested
191 // but this request will be handled by sepatated by the pincode
192 // window
193 // request.AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
194
195 // this almost involves already the happy end
196 request.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY);
197
198 request.AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE);
199
200 if (fMessenger->SendMessage(&request, &reply) == B_OK)
201 reply.FindInt8("status", &btStatus);
202
203 if (btStatus == BT_OK) {
204 reply.FindInt16("handle", (int16*)&fHandle);
205 return true;
206 } else
207 return false;
208 }
209
210
211 status_t
Disconnect(int8 reason)212 RemoteDevice::Disconnect(int8 reason)
213 {
214 CALLED();
215 if (fHandle != invalidConnectionHandle) {
216
217 int8 btStatus = BT_ERROR;
218
219 if (fMessenger == NULL || fDiscovererLocalDevice == NULL)
220 return false;
221
222 BluetoothCommand<typed_command(struct hci_disconnect)>
223 disconnect(OGF_LINK_CONTROL, OCF_DISCONNECT);
224
225 disconnect->reason = reason;
226 disconnect->handle = fHandle;
227
228 BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
229 BMessage reply;
230
231
232 request.AddInt32("hci_id", fDiscovererLocalDevice->ID());
233 request.AddData("raw command", B_ANY_TYPE,
234 disconnect.Data(), disconnect.Size());
235
236 request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
237 request.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL,
238 OCF_DISCONNECT));
239
240 request.AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE);
241
242 if (fMessenger->SendMessage(&request, &reply) == B_OK)
243 reply.FindInt8("status", &btStatus);
244
245 if (btStatus == BT_OK)
246 fHandle = invalidConnectionHandle;
247
248 return btStatus;
249
250 }
251
252 return B_ERROR;
253 }
254
255
256 // bool Authorize(Connection conn);
257 // bool Encrypt(Connection conn, bool on);
258
259
260 bool
IsAuthenticated()261 RemoteDevice::IsAuthenticated()
262 {
263 CALLED();
264 return true;
265 }
266
267
268 // bool IsAuthorized(Connection conn);
269
270
271 bool
IsEncrypted()272 RemoteDevice::IsEncrypted()
273 {
274 CALLED();
275 return true;
276 }
277
278
279 LocalDevice*
GetLocalDeviceOwner()280 RemoteDevice::GetLocalDeviceOwner()
281 {
282 CALLED();
283 return fDiscovererLocalDevice;
284 }
285
286
287 /* Private */
288 void
SetLocalDeviceOwner(LocalDevice * ld)289 RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld)
290 {
291 CALLED();
292 fDiscovererLocalDevice = ld;
293 }
294
295
296 /* Constructor */
RemoteDevice(const bdaddr_t address,uint8 record[3])297 RemoteDevice::RemoteDevice(const bdaddr_t address, uint8 record[3])
298 :
299 BluetoothDevice(),
300 fDiscovererLocalDevice(NULL),
301 fHandle(invalidConnectionHandle)
302 {
303 CALLED();
304 fBdaddr = address;
305 fDeviceClass.SetRecord(record);
306 fMessenger = _RetrieveBluetoothMessenger();
307 }
308
309
RemoteDevice(const BString & address)310 RemoteDevice::RemoteDevice(const BString& address)
311 :
312 BluetoothDevice(),
313 fDiscovererLocalDevice(NULL),
314 fHandle(invalidConnectionHandle)
315 {
316 CALLED();
317 fBdaddr = bdaddrUtils::FromString((const char*)address.String());
318 fMessenger = _RetrieveBluetoothMessenger();
319 }
320
321
~RemoteDevice()322 RemoteDevice::~RemoteDevice()
323 {
324 CALLED();
325 delete fMessenger;
326 }
327
328
329 BString
GetProperty(const char * property)330 RemoteDevice::GetProperty(const char* property) /* Throwing */
331 {
332 return NULL;
333 }
334
335
336 status_t
GetProperty(const char * property,uint32 * value)337 RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */
338 {
339 CALLED();
340 return B_ERROR;
341 }
342
343
344 DeviceClass
GetDeviceClass()345 RemoteDevice::GetDeviceClass()
346 {
347 CALLED();
348 return fDeviceClass;
349 }
350
351 } /* end namespace Bluetooth */
352