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