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(ldi->GetID())); 129 (Output::Instance()->Post( str.String(), BLACKBOARD_LD(ldi->GetID()))); 130 (Output::Instance()->Post(" LocalDevice added\n", BLACKBOARD_LD(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 /* TODO: This should be by user request only! */ 140 ldi->Launch(); 141 } 142 143 case BT_MSG_COUNT_LOCAL_DEVICES: 144 status = HandleLocalDevicesCount(message, &reply); 145 break; 146 147 case BT_MSG_ACQUIRE_LOCAL_DEVICE: 148 status = HandleAcquireLocalDevice(message, &reply); 149 break; 150 151 case BT_MSG_GET_FRIENDLY_NAME: 152 status = HandleGetFriendlyName(message, &reply); 153 break; 154 155 case BT_MSG_GET_ADDRESS: 156 status = HandleGetAddress(message, &reply); 157 break; 158 159 case BT_MSG_HANDLE_SIMPLE_REQUEST: 160 status = HandleSimpleRequest(message, &reply); 161 break; 162 163 164 /* Handle if the bluetooth preferences is running?? */ 165 case B_SOME_APP_LAUNCHED: 166 { 167 const char *signature; 168 // TODO: what's this for? 169 if (message->FindString("be:signature", &signature)==B_OK) { 170 printf("input_server : %s\n", signature); 171 if (strcmp(signature, "application/x-vnd.Be-TSKB")==0) { 172 173 } 174 } 175 return; 176 } 177 178 179 default: 180 BApplication::MessageReceived(message); 181 break; 182 } 183 184 // Can we reply right now? 185 // TOD: review this condition 186 if (status != B_WOULD_BLOCK) { 187 reply.AddInt32("status", status); 188 message->SendReply(&reply); 189 printf("Sending reply message\n"); 190 } 191 192 } 193 194 #if 0 195 #pragma mark - 196 #endif 197 198 LocalDeviceImpl* 199 BluetoothServer::LocateDelegateFromMessage(BMessage* message) 200 { 201 LocalDeviceImpl* ldi = NULL; 202 hci_id hid; 203 204 if (message->FindInt32("hci_id", &hid) == B_OK) 205 { 206 /* Try to find out when a ID was specified */ 207 int index; 208 209 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 210 211 ldi = fLocalDevicesList.ItemAt(index); 212 if (ldi->GetID() == hid) { 213 break; 214 } 215 } 216 } 217 218 return ldi; 219 } 220 221 LocalDeviceImpl* 222 BluetoothServer::LocateLocalDeviceImpl(hci_id hid) 223 { 224 225 /* Try to find out when a ID was specified */ 226 int index; 227 228 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 229 230 LocalDeviceImpl* ldi = fLocalDevicesList.ItemAt(index); 231 if (ldi->GetID() == hid) { 232 return ldi; 233 } 234 } 235 236 return NULL; 237 } 238 239 240 #if 0 241 #pragma - Messages reply 242 #endif 243 244 status_t 245 BluetoothServer::HandleLocalDevicesCount(BMessage* message, BMessage* reply) 246 { 247 return reply->AddInt32("count", fLocalDevicesList.CountItems()); 248 } 249 250 251 status_t 252 BluetoothServer::HandleAcquireLocalDevice(BMessage* message, BMessage* reply) 253 { 254 hci_id hid; 255 ssize_t size; 256 bdaddr_t bdaddr; 257 LocalDeviceImpl* ldi = NULL; 258 int32 index = 0; 259 260 if (message->FindInt32("hci_id", &hid) == B_OK) 261 { 262 Output::Instance()->Post("GetLocalDevice requested with id\n", BLACKBOARD_KIT); 263 ldi = LocateDelegateFromMessage(message); 264 265 } else if (message->FindData("bdaddr", B_ANY_TYPE, (const void**)&bdaddr, &size ) == B_OK) 266 { 267 /* Try to find out when the user specified the address */ 268 Output::Instance()->Post("GetLocalDevice requested with bdaddr\n", BLACKBOARD_KIT); 269 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 270 271 bdaddr_t local; 272 ldi = fLocalDevicesList.ItemAt(index); 273 if ((ldi->GetAddress(&local, message) == B_OK) && bacmp(&local, &bdaddr)) { 274 break; 275 } 276 } 277 278 } else 279 { 280 /* Careless, any device not performing operations will be fine */ 281 Output::Instance()->Post("GetLocalDevice requested\n", BLACKBOARD_KIT); 282 for (index = 0; index < fLocalDevicesList.CountItems() ; index ++) { 283 284 ldi = fLocalDevicesList.ItemAt(index); 285 printf("Requesting local device %ld\n", ldi->GetID()); 286 if (ldi != NULL && ldi->Available()) 287 { 288 printf("dev ours %ld\n", ldi->GetID()); 289 break; 290 } 291 292 } 293 } 294 295 if (index <= fLocalDevicesList.CountItems() && ldi != NULL && ldi->Available()) 296 { 297 Output::Instance()->Post("Device acquired\n", BLACKBOARD_KIT); 298 ldi->Acquire(); 299 return reply->AddInt32("hci_id", hid); 300 } 301 302 return B_ERROR; 303 304 } 305 306 307 status_t 308 BluetoothServer::HandleGetFriendlyName(BMessage* message, BMessage* reply) 309 { 310 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 311 BString name; 312 313 if (ldi == NULL) 314 return B_ERROR; 315 316 /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */ 317 if (ldi->GetFriendlyName(name, DetachCurrentMessage()) == B_OK) { 318 319 return reply->AddString("friendlyname", name); 320 } 321 322 return B_WOULD_BLOCK; 323 } 324 325 326 status_t 327 BluetoothServer::HandleGetAddress(BMessage* message, BMessage* reply) 328 { 329 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 330 bdaddr_t bdaddr; 331 332 if (ldi == NULL) 333 return B_ERROR; 334 335 /* If the device was ocupied... Autlock?->LocalDeviceImpl will decide */ 336 status_t status = ldi->GetAddress(&bdaddr, DetachCurrentMessage()); 337 if ( status == B_OK) { 338 339 return reply->AddData("bdaddr", B_ANY_TYPE, &bdaddr, sizeof(bdaddr_t)); 340 } 341 342 return status; 343 } 344 345 346 status_t 347 BluetoothServer::HandleSimpleRequest(BMessage* message, BMessage* reply) 348 { 349 350 LocalDeviceImpl* ldi = LocateDelegateFromMessage(message); 351 BString propertyRequested; 352 353 // Find out if there is a property being requested, 354 if (message->FindString("property", &propertyRequested) == B_OK) { 355 // Check if the property has been already retrieved 356 357 if (ldi->IsPropertyAvailable(propertyRequested)) { 358 359 // Dump everything 360 reply->AddMessage("properties",ldi->GetPropertiesMessage()); 361 return B_OK; 362 } 363 364 } 365 366 // we are gonna need issue the command ... 367 if (ldi->ProcessSimpleRequest(DetachCurrentMessage()) == B_OK) 368 // if (ldi->ProcessSimpleRequest(message) == B_OK) 369 return B_WOULD_BLOCK; 370 else 371 return B_ERROR; 372 373 } 374 375 376 #if 0 377 #pragma mark - 378 #endif 379 380 381 int32 382 BluetoothServer::notification_Thread(void* data) 383 { 384 BPortNot notifierd( (BluetoothServer*) data , BT_USERLAND_PORT_NAME); 385 386 notifierd.loop(); 387 return B_NO_ERROR; 388 } 389 390 int32 391 BluetoothServer::sdp_server_Thread(void* data) 392 { 393 394 return B_NO_ERROR; 395 } 396 397 398 void 399 BluetoothServer::ShowWindow(BWindow* pWindow) 400 { 401 pWindow->Lock(); 402 if (pWindow->IsHidden()) 403 pWindow->Show(); 404 else 405 pWindow->Activate(); 406 pWindow->Unlock(); 407 } 408 409 410 #if 0 411 #pragma mark - 412 #endif 413 414 int 415 main(int /*argc*/, char** /*argv*/) 416 { 417 setbuf(stdout,NULL); 418 419 BluetoothServer* bluetoothServer = new BluetoothServer; 420 421 bluetoothServer->Run(); 422 delete bluetoothServer; 423 424 return 0; 425 } 426 427