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