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 33namespace Bluetooth { 34 35 36// TODO: Check headers for valid/reserved ranges 37static const uint16 invalidConnectionHandle = 0xF000; 38 39 40bool 41RemoteDevice::IsTrustedDevice(void) 42{ 43 CALLED(); 44 return true; 45} 46 47 48BString 49RemoteDevice::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 108BString 109RemoteDevice::GetFriendlyName() 110{ 111 CALLED(); 112 return GetFriendlyName(true); 113} 114 115 116bdaddr_t 117RemoteDevice::GetBluetoothAddress() 118{ 119 CALLED(); 120 return fBdaddr; 121} 122 123 124bool 125RemoteDevice::Equals(RemoteDevice* obj) 126{ 127 CALLED(); 128 return bdaddrUtils::Compare(fBdaddr, obj->GetBluetoothAddress()); 129} 130 131 132// static RemoteDevice* GetRemoteDevice(Connection conn); 133 134 135bool 136RemoteDevice::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 211status_t 212RemoteDevice::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 260bool 261RemoteDevice::IsAuthenticated() 262{ 263 CALLED(); 264 return true; 265} 266 267 268// bool IsAuthorized(Connection conn); 269 270 271bool 272RemoteDevice::IsEncrypted() 273{ 274 CALLED(); 275 return true; 276} 277 278 279LocalDevice* 280RemoteDevice::GetLocalDeviceOwner() 281{ 282 CALLED(); 283 return fDiscovererLocalDevice; 284} 285 286 287/* Private */ 288void 289RemoteDevice::SetLocalDeviceOwner(LocalDevice* ld) 290{ 291 CALLED(); 292 fDiscovererLocalDevice = ld; 293} 294 295 296/* Constructor */ 297RemoteDevice::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 310RemoteDevice::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 322RemoteDevice::~RemoteDevice() 323{ 324 CALLED(); 325 delete fMessenger; 326} 327 328 329BString 330RemoteDevice::GetProperty(const char* property) /* Throwing */ 331{ 332 return NULL; 333} 334 335 336status_t 337RemoteDevice::GetProperty(const char* property, uint32* value) /* Throwing */ 338{ 339 CALLED(); 340 return B_ERROR; 341} 342 343 344DeviceClass 345RemoteDevice::GetDeviceClass() 346{ 347 CALLED(); 348 return fDeviceClass; 349} 350 351} /* end namespace Bluetooth */ 352