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