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.
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>
14 #include <bluetooth/HCI/btHCI_command.h>
15 #include <bluetooth/HCI/btHCI_event.h>
17 #include <bluetooth/debug.h>
18 #include <bluetooth/bluetooth_error.h>
21 #include <CommandManager.h>
23 #include <bluetoothserver_p.h>
25 #include "KitSupport.h"
27 #undef B_TRANSLATION_CONTEXT
28 #define B_TRANSLATION_CONTEXT "RemoteDevice"
33 // TODO: Check headers for valid/reserved ranges
34 static const uint16 invalidConnectionHandle
= 0xF000;
37 RemoteDevice::IsTrustedDevice(void)
45 RemoteDevice::GetFriendlyName(bool 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"));
54 if (fDiscovererLocalDevice
== NULL
)
55 return BString(B_TRANSLATE("#NoOwnerError#Not Valid name"));
57 if (fMessenger
== NULL
)
58 return BString(B_TRANSLATE("#ServerNotReady#Not Valid name"));
60 void* remoteNameCommand
= NULL
;
63 // Issue inquiry command
64 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
67 request
.AddInt32("hci_id", fDiscovererLocalDevice
->ID());
70 remoteNameCommand
= buildRemoteNameRequest(fBdaddr
, fPageRepetitionMode
,
73 request
.AddData("raw command", B_ANY_TYPE
, remoteNameCommand
, size
);
75 request
.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS
);
76 request
.AddInt16("opcodeExpected",
77 PACK_OPCODE(OGF_LINK_CONTROL
, OCF_REMOTE_NAME_REQUEST
));
79 request
.AddInt16("eventExpected", HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE
);
82 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
) {
86 if ((reply
.FindInt8("status", &status
) == B_OK
) && (status
== BT_OK
)) {
88 if ((reply
.FindString("friendlyname", &name
) == B_OK
)) {
91 return BString(""); // should not happen
95 // seems we got a negative event
96 return BString(B_TRANSLATE("#CommandFailed#Not Valid name"));
100 return BString(B_TRANSLATE("#NotCompletedRequest#Not Valid name"));
105 RemoteDevice::GetFriendlyName()
108 return GetFriendlyName(true);
113 RemoteDevice::GetBluetoothAddress()
121 RemoteDevice::Equals(RemoteDevice
* obj
)
124 return bdaddrUtils::Compare(fBdaddr
, obj
->GetBluetoothAddress());
128 // static RemoteDevice* GetRemoteDevice(Connection conn);
132 RemoteDevice::Authenticate()
135 int8 btStatus
= BT_ERROR
;
137 if (fMessenger
== NULL
|| fDiscovererLocalDevice
== NULL
)
140 BluetoothCommand
<typed_command(hci_cp_create_conn
)>
141 createConnection(OGF_LINK_CONTROL
, OCF_CREATE_CONN
);
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!
149 fDiscovererLocalDevice
->GetProperty("role_switch_capable", &roleSwitch
);
150 createConnection
->role_switch
= (uint8
)roleSwitch
;
153 fDiscovererLocalDevice
->GetProperty("packet_type", &packetType
);
154 createConnection
->pkt_type
= (uint16
)packetType
;
156 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
159 request
.AddInt32("hci_id", fDiscovererLocalDevice
->ID());
160 request
.AddData("raw command", B_ANY_TYPE
,
161 createConnection
.Data(), createConnection
.Size());
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
,
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
));
174 request
.AddInt16("eventExpected", HCI_EVENT_CMD_COMPLETE
);
175 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL
,
176 OCF_LINK_KEY_NEG_REPLY
));
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));
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
189 // request.AddInt16("eventExpected", HCI_EVENT_PIN_CODE_REQ);
191 // this almost involves already the happy end
192 request
.AddInt16("eventExpected", HCI_EVENT_LINK_KEY_NOTIFY
);
194 request
.AddInt16("eventExpected", HCI_EVENT_CONN_COMPLETE
);
196 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
197 reply
.FindInt8("status", &btStatus
);
199 if (btStatus
== BT_OK
) {
200 reply
.FindInt16("handle", (int16
*)&fHandle
);
208 RemoteDevice::Disconnect(int8 reason
)
211 if (fHandle
!= invalidConnectionHandle
) {
213 int8 btStatus
= BT_ERROR
;
215 if (fMessenger
== NULL
|| fDiscovererLocalDevice
== NULL
)
218 BluetoothCommand
<typed_command(struct hci_disconnect
)>
219 disconnect(OGF_LINK_CONTROL
, OCF_DISCONNECT
);
221 disconnect
->reason
= reason
;
222 disconnect
->handle
= fHandle
;
224 BMessage
request(BT_MSG_HANDLE_SIMPLE_REQUEST
);
228 request
.AddInt32("hci_id", fDiscovererLocalDevice
->ID());
229 request
.AddData("raw command", B_ANY_TYPE
,
230 disconnect
.Data(), disconnect
.Size());
232 request
.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS
);
233 request
.AddInt16("opcodeExpected", PACK_OPCODE(OGF_LINK_CONTROL
,
236 request
.AddInt16("eventExpected", HCI_EVENT_DISCONNECTION_COMPLETE
);
238 if (fMessenger
->SendMessage(&request
, &reply
) == B_OK
)
239 reply
.FindInt8("status", &btStatus
);
241 if (btStatus
== BT_OK
)
242 fHandle
= invalidConnectionHandle
;
252 // bool Authorize(Connection conn);
253 // bool Encrypt(Connection conn, bool on);
257 RemoteDevice::IsAuthenticated()
264 // bool IsAuthorized(Connection conn);
268 RemoteDevice::IsEncrypted()
276 RemoteDevice::GetLocalDeviceOwner()
279 return fDiscovererLocalDevice
;
285 RemoteDevice::SetLocalDeviceOwner(LocalDevice
* ld
)
288 fDiscovererLocalDevice
= ld
;
293 RemoteDevice::RemoteDevice(const bdaddr_t address
, uint8 record
[3])
296 fDiscovererLocalDevice(NULL
),
297 fHandle(invalidConnectionHandle
)
301 fDeviceClass
.SetRecord(record
);
302 fMessenger
= _RetrieveBluetoothMessenger();
306 RemoteDevice::RemoteDevice(const BString
& address
)
309 fDiscovererLocalDevice(NULL
),
310 fHandle(invalidConnectionHandle
)
313 fBdaddr
= bdaddrUtils::FromString((const char*)address
.String());
314 fMessenger
= _RetrieveBluetoothMessenger();
318 RemoteDevice::~RemoteDevice()
326 RemoteDevice::GetProperty(const char* property
) /* Throwing */
333 RemoteDevice::GetProperty(const char* property
, uint32
* value
) /* Throwing */
341 RemoteDevice::GetDeviceClass()