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 41 RemoteDevice::IsTrustedDevice(void) 42 { 43 CALLED(); 44 return true; 45 } 46 47 48 BString 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 109 RemoteDevice::GetFriendlyName() 110 { 111 CALLED(); 112 return GetFriendlyName(true); 113 } 114 115 116 bdaddr_t 117 RemoteDevice::GetBluetoothAddress() 118 { 119 CALLED(); 120 return fBdaddr; 121 } 122 123 124 bool 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 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 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 261 RemoteDevice::IsAuthenticated() 262 { 263 CALLED(); 264 return true; 265 } 266 267 268 // bool IsAuthorized(Connection conn); 269 270 271 bool 272 RemoteDevice::IsEncrypted() 273 { 274 CALLED(); 275 return true; 276 } 277 278 279 LocalDevice* 280 RemoteDevice::GetLocalDeviceOwner() 281 { 282 CALLED(); 283 return fDiscovererLocalDevice; 284 } 285 286 287 /* Private */ 288 void 289 RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld) 290 { 291 CALLED(); 292 fDiscovererLocalDevice = ld; 293 } 294 295 296 /* Constructor */ 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 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 322 RemoteDevice::~RemoteDevice() 323 { 324 CALLED(); 325 delete fMessenger; 326 } 327 328 329 BString 330 RemoteDevice::GetProperty(const char* property) /* Throwing */ 331 { 332 return NULL; 333 } 334 335 336 status_t 337 RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */ 338 { 339 CALLED(); 340 return B_ERROR; 341 } 342 343 344 DeviceClass 345 RemoteDevice::GetDeviceClass() 346 { 347 CALLED(); 348 return fDeviceClass; 349 } 350 351 } /* end namespace Bluetooth */ 352