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