1 /* 2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com 3 * 4 * All rights reserved. Distributed under the terms of the MIT License. 5 * 6 */ 7 8 #include <stdio.h> 9 #include <fcntl.h> 10 #include <unistd.h> 11 12 13 #include <Entry.h> 14 #include <Path.h> 15 #include <Message.h> 16 #include <Directory.h> 17 #include <String.h> 18 #include <Roster.h> 19 20 21 #include <TypeConstants.h> 22 #include <syslog.h> 23 24 #include <bluetoothserver_p.h> 25 #include <bluetooth/HCI/btHCI_command.h> 26 #include <bluetooth/bluetooth_util.h> 27 28 #include "LocalDeviceImpl.h" 29 #include "BluetoothServer.h" 30 #include "Output.h" 31 32 33 BluetoothServer::BluetoothServer() : BApplication(BLUETOOTH_SIGNATURE) 34 { 35 Output::Instance()->Run(); 36 Output::Instance()->SetTitle("Bluetooth message gathering"); 37 38 Output::Instance()->AddTab("General", BLACKBOARD_GENERAL); 39 Output::Instance()->AddTab("Device Manager", BLACKBOARD_DEVICEMANAGER); 40 Output::Instance()->AddTab("Events", BLACKBOARD_EVENTS); 41 Output::Instance()->AddTab("Kit", BLACKBOARD_KIT); 42 43 44 ShowWindow(Output::Instance()); 45 46 fDeviceManager = new DeviceManager(); 47 fLocalDevicesList.MakeEmpty(); 48 49 fEventListener = spawn_thread(notification_Thread, "BT port listener" , B_DISPLAY_PRIORITY , this); 50 51 52 } 53 54 bool BluetoothServer::QuitRequested(void) 55 { 56 // Finish quitting 57 Output::Instance()->Lock(); 58 Output::Instance()->Quit(); 59 60 61 /* HCIDelegate *hd = NULL; 62 while ((hd = (HCIDelegate *)fDelegatesList.RemoveItem((int32)0)) !=NULL) 63 delete hd; 64 */ 65 66 printf("Accepting quitting of the application\n"); 67 return BApplication::QuitRequested(); 68 } 69 70 void BluetoothServer::ArgvReceived(int32 argc, char **argv) 71 { 72 if (argc>1) { 73 if (strcmp(argv[1], "--finish") == 0) 74 PostMessage(B_QUIT_REQUESTED); 75 76 else { 77 78 79 } 80 } 81 82 } 83 84 85 void BluetoothServer::ReadyToRun(void) { 86 87 fDeviceManager->StartMonitoringDevice("bluetooth/h2generic"); 88 89 90 // Launch the notifier thread 91 if ( resume_thread(fEventListener) != B_OK ) 92 { 93 Output::Instance()->Post("Bluetooth port listener failed\n", BLACKBOARD_GENERAL); 94 } 95 96 Output::Instance()->Post("Bluetooth server Ready\n", BLACKBOARD_GENERAL); 97 } 98 99 void BluetoothServer::AppActivated(bool act) { 100 101 printf("Activated %d\n",act); 102 103 } 104 105 106 107 void BluetoothServer::MessageReceived(BMessage *message) 108 { 109 BMessage reply; 110 status_t status = B_WOULD_BLOCK; // mark somehow.. do not reply anything 111 112 switch(message->what) 113 { 114 115 case BT_MSG_ADD_DEVICE: 116 { 117 BString str; 118 message->FindString("name", &str); 119 BPath path(str.String()); 120 121 (Output::Instance()->Post( str.String(), BLACKBOARD_GENERAL)); 122 (Output::Instance()->Post(" requested LocalDevice\n", BLACKBOARD_GENERAL)); 123 124 LocalDeviceImpl* ldi = LocalDeviceImpl::CreateTransportAccessor(&path); 125 126 if (ldi->GetID() >= 0) { 127 fLocalDevicesList.AddItem(ldi); 128 Output::Instance()->AddTab("Local Device", BLACKBOARD_LD_OFFSET + ldi->GetID()); 129 (Output::Instance()->Post( str.String(), BLACKBOARD_LD_OFFSET + ldi->GetID())); 130 (Output::Instance()->Post(" LocalDevice added\n", BLACKBOARD_LD_OFFSET + ldi->GetID())); 131 132 133 } else { 134 (Output::Instance()->Post("Adding LocalDevice failed\n", BLACKBOARD_GENERAL)); 135 } 136 137 status = B_WOULD_BLOCK; 138 } 139 140 case BT_MSG_COUNT_LOCAL_DEVICES: 141 status = HandleLocalDevicesCount(message, &reply); 142 break; 143 144 case BT_MSG_ACQUIRE_LOCAL_DEVICE: 145 status = HandleAcquireLocalDevice(message, &reply); 146 break; 147 148 case BT_MSG_GET_FRIENDLY_NAME: 149 status = HandleGetFriendlyName(message, &reply); 150 break; 151 152 case BT_MSG_GET_ADDRESS: 153 status = HandleGetAddress(message, &reply); 154 break; 155 156 case BT_MSG_HANDLE_SIMPLE_REQUEST: 157 status = HandleSimpleRequest(message, &reply); 158 break; 159 160 161 /* Handle if the bluetooth preferences is running?? */ 162 case B_SOME_APP_LAUNCHED: 163 { 164 const char *signature; 165 // TODO: what's this for? 166 if (message->FindString("be:signature", &signature)==B_OK) { 167 printf("input_server : %s\n", signature); 168 if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) { 169 170 } 171 } 172 return; 173 } 174 175 176 default: 177 BApplication::MessageReceived(message); 178 break; 179 } 180 181 // Can we reply right now? 182 // TOD: review this condition 183 if (status != B_WOULD_BLOCK) { 184 reply.AddInt32("status", status); 185 message->SendReply(&reply); 186 printf("Sending reply message\n"); 187 } 188 189 } 190 191 #if 0 192 #pragma mark - 193 #endif 194 195 LocalDeviceImpl* 196 BluetoothServer::LocateDelegateFromMessage(BMessage* message) 197 { 198 LocalDeviceImpl* ldi = NULL; 199 hci_id hid; 200 201 if (message->FindInt32("hci_id", &hid) == B_OK) 202 { 203 /* Try to find out when a ID was specified */ 204 int index; 205 206 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 207 208 ldi = fLocalDevicesList.ItemAt(index); 209 if (ldi->GetID() == hid) { 210 break; 211 } 212 } 213 } 214 215 return ldi; 216 } 217 218 LocalDeviceImpl* 219 BluetoothServer::LocateLocalDeviceImpl(hci_id hid) 220 { 221 222 /* Try to find out when a ID was specified */ 223 int index; 224 225 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 226 227 LocalDeviceImpl* ldi = fLocalDevicesList.ItemAt(index); 228 if (ldi->GetID() == hid) { 229 return ldi; 230 } 231 } 232 233 return NULL; 234 } 235 236 237 #if 0 238 #pragma - Messages reply 239 #endif 240 241 status_t 242 BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply) 243 { 244 return reply->AddInt32("count", fLocalDevicesList.CountItems()); 245 } 246 247 248 status_t 249 BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply) 250 { 251 hci_id hid; 252 ssize_t size; 253 bdaddr_t bdaddr; 254 LocalDeviceImpl* ldi = NULL; 255 int32 index = 0; 256 257 if (message->FindInt32("hci_id", &hid) == B_OK) 258 { 259 Output::Instance()->Post("GetLocalDevice requested with id\n", BLACKBOARD_KIT); 260 ldi = LocateDelegateFromMessage(message); 261 262 } else if (message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size ) == B_OK) 263 { 264 /* Try to find out when the user specified the address */ 265 Output::Instance()->Post("GetLocalDevice requested with bdaddr\n", BLACKBOARD_KIT); 266 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 267 268 bdaddr_t local; 269 ldi = fLocalDevicesList.ItemAt(index); 270 if ((ldi->GetAddress(&local, message) == B_OK) && bacmp(&local, &bdaddr)) { 271 break; 272 } 273 } 274 275 } else 276 { 277 /* Careless, any device not performing operations will be fine */ 278 Output::Instance()->Post("GetLocalDevice requested\n", BLACKBOARD_KIT); 279 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 280 281 ldi = fLocalDevicesList.ItemAt(index); 282 printf("Requesting local device %ld\n", ldi->GetID()); 283 if (ldi != NULL && ldi->Available()) 284 { 285 printf("dev ours %ld\n", ldi->GetID()); 286 break; 287 } 288 289 } 290 } 291 292 if (index <= fLocalDevicesList.CountItems() && ldi != NULL && ldi->Available()) 293 { 294 Output::Instance()->Post("Device acquired\n", BLACKBOARD_KIT); 295 ldi->Acquire(); 296 return reply->AddInt32("hci_id", hid); 297 } 298 299 return B_ERROR; 300 301 } 302 303 304 status_t 305 BluetoothServer::HandleGetFriendlyName(BMessage* message, BMessage* reply) 306 { 307 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 308 BString name; 309 310 if (ldi == NULL) 311 return B_ERROR; 312 313 /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */ 314 if (ldi->GetFriendlyName(name, DetachCurrentMessage()) == B_OK) { 315 316 return reply->AddString("friendlyname", name); 317 } 318 319 return B_WOULD_BLOCK; 320 } 321 322 323 status_t 324 BluetoothServer::HandleGetAddress(BMessage* message, BMessage* reply) 325 { 326 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 327 bdaddr_t bdaddr; 328 329 if (ldi == NULL) 330 return B_ERROR; 331 332 /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */ 333 status_t status = ldi->GetAddress(&bdaddr, DetachCurrentMessage()); 334 if ( status == B_OK) { 335 336 return reply->AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t)); 337 } 338 339 return status; 340 } 341 342 343 status_t 344 BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply) 345 { 346 347 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 348 BString propertyRequested; 349 350 // Find out if there is a property being requested, 351 if (message->FindString("property", &propertyRequested) == B_OK) { 352 // Check if the property has been already retrieved 353 354 if (ldi->IsPropertyAvailable(propertyRequested)) { 355 356 // Dump everything 357 reply->AddMessage("properties",ldi->GetPropertiesMessage()); 358 return B_OK; 359 } 360 361 } 362 363 // we are gonna need issue the command ... 364 if (ldi->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK) 365 return B_WOULD_BLOCK; 366 else 367 return B_ERROR; 368 369 } 370 371 372 #if 0 373 #pragma mark - 374 #endif 375 376 377 int32 378 BluetoothServer::notification_Thread(void* data) 379 { 380 BPortNot notifierd( (BluetoothServer*) data , BT_USERLAND_PORT_NAME); 381 382 notifierd.loop(); 383 return B_NO_ERROR; 384 } 385 386 int32 387 BluetoothServer::sdp_server_Thread(void* data) 388 { 389 390 return B_NO_ERROR; 391 } 392 393 394 void 395 BluetoothServer::ShowWindow(BWindow* pWindow) 396 { 397 pWindow->Lock(); 398 if (pWindow->IsHidden()) 399 pWindow->Show(); 400 else 401 pWindow->Activate(); 402 pWindow->Unlock(); 403 } 404 405 406 #if 0 407 #pragma mark - 408 #endif 409 410 int 411 main(int /*argc*/, char** /*argv*/) 412 { 413 setbuf(stdout,NULL); 414 415 BluetoothServer* bluetoothServer = new BluetoothServer; 416 417 bluetoothServer->Run(); 418 delete bluetoothServer; 419 420 return 0; 421 } 422 423