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 <bluetooth/DiscoveryAgent.h> 9 #include <bluetooth/DiscoveryListener.h> 10 #include <bluetooth/RemoteDevice.h> 11 #include <bluetooth/DeviceClass.h> 12 #include <bluetooth/bdaddrUtils.h> 13 14 #include <bluetooth/HCI/btHCI_event.h> 15 16 #include <bluetoothserver_p.h> 17 18 #include <Message.h> 19 20 namespace Bluetooth { 21 22 23 /* hooks */ 24 void 25 DiscoveryListener::DeviceDiscovered(RemoteDevice* btDevice, DeviceClass cod) 26 { 27 28 } 29 30 31 void 32 DiscoveryListener::InquiryStarted(status_t status) 33 { 34 35 } 36 37 38 void 39 DiscoveryListener::InquiryCompleted(int discType) 40 { 41 42 } 43 44 45 /* private */ 46 47 /* A LocalDevice is always referenced in any request to the 48 * Bluetooth server therefore is going to be needed in any 49 */ 50 void 51 DiscoveryListener::SetLocalDeviceOwner(LocalDevice* ld) 52 { 53 fLocalDevice = ld; 54 } 55 56 57 RemoteDevicesList 58 DiscoveryListener::GetRemoteDevicesList(void) 59 { 60 return fRemoteDevicesList; 61 } 62 63 64 void 65 DiscoveryListener::MessageReceived(BMessage* message) 66 { 67 int8 status; 68 69 switch (message->what) { 70 case BT_MSG_INQUIRY_DEVICE: 71 { 72 const struct inquiry_info* inquiryInfo; 73 ssize_t size; 74 RemoteDevice* rd = NULL; 75 bool duplicatedFound = false; 76 77 // TODO: Loop for all inquiryInfo! 78 if (message->FindData("info", B_ANY_TYPE, 0, 79 (const void**)&inquiryInfo, &size) == B_OK) { 80 // Skip duplicated replies 81 for (int32 index = 0 ; index < fRemoteDevicesList.CountItems(); 82 index++) { 83 bdaddr_t b1 = fRemoteDevicesList.ItemAt(index) 84 ->GetBluetoothAddress(); 85 86 if (bdaddrUtils::Compare(inquiryInfo->bdaddr, b1)) { 87 // update these values 88 fRemoteDevicesList.ItemAt(index)->fPageRepetitionMode 89 = inquiryInfo->pscan_rep_mode; 90 fRemoteDevicesList.ItemAt(index)->fScanPeriodMode 91 = inquiryInfo->pscan_period_mode; 92 fRemoteDevicesList.ItemAt(index)->fScanMode 93 = inquiryInfo->pscan_mode; 94 fRemoteDevicesList.ItemAt(index)->fClockOffset 95 = inquiryInfo->clock_offset; 96 97 duplicatedFound = true; 98 break; 99 } 100 } 101 102 if (!duplicatedFound) { 103 rd = new RemoteDevice(inquiryInfo->bdaddr, 104 (uint8*)inquiryInfo->dev_class); 105 fRemoteDevicesList.AddItem(rd); 106 // keep all inquiry reported data 107 rd->SetLocalDeviceOwner(fLocalDevice); 108 rd->fPageRepetitionMode = inquiryInfo->pscan_rep_mode; 109 rd->fScanPeriodMode = inquiryInfo->pscan_period_mode; 110 rd->fScanMode = inquiryInfo->pscan_mode; 111 rd->fClockOffset = inquiryInfo->clock_offset; 112 113 DeviceDiscovered( rd, rd->GetDeviceClass()); 114 } 115 } 116 break; 117 } 118 119 case BT_MSG_INQUIRY_STARTED: 120 if (message->FindInt8("status", &status) == B_OK) { 121 fRemoteDevicesList.MakeEmpty(); 122 InquiryStarted(status); 123 } 124 break; 125 126 case BT_MSG_INQUIRY_COMPLETED: 127 InquiryCompleted(BT_INQUIRY_COMPLETED); 128 break; 129 130 case BT_MSG_INQUIRY_TERMINATED: /* inquiry was cancelled */ 131 InquiryCompleted(BT_INQUIRY_TERMINATED); 132 break; 133 134 case BT_MSG_INQUIRY_ERROR: 135 InquiryCompleted(BT_INQUIRY_ERROR); 136 break; 137 138 default: 139 BLooper::MessageReceived(message); 140 break; 141 } 142 } 143 144 145 DiscoveryListener::DiscoveryListener() 146 : 147 BLooper(), 148 fRemoteDevicesList(BT_MAX_RESPONSES) 149 { 150 // TODO: Make a better handling of the running not running state 151 Run(); 152 } 153 154 155 } 156