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 void 50 DiscoveryListener::SetLocalDeviceOwner(LocalDevice* ld) 51 { 52 fLocalDevice = ld; 53 } 54 55 56 RemoteDevicesList 57 DiscoveryListener::GetRemoteDevicesList(void) 58 { 59 return fRemoteDevicesList; 60 } 61 62 63 void 64 DiscoveryListener::MessageReceived(BMessage* message) 65 { 66 int8 status; 67 68 switch (message->what) 69 { 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 if (message->FindData("info", B_ANY_TYPE, 0, (const void**)&inquiryInfo, &size) == B_OK ) 78 { 79 80 // Skip duplicated replies 81 for (int32 index = 0 ; index < fRemoteDevicesList.CountItems(); index++) { 82 83 bdaddr_t b1 = fRemoteDevicesList.ItemAt(index)->GetBluetoothAddress(); 84 85 if (bdaddrUtils::Compare( (bdaddr_t*) &inquiryInfo->bdaddr, &b1 )) { 86 87 // update these values 88 fRemoteDevicesList.ItemAt(index)->fPageRepetitionMode = inquiryInfo->pscan_rep_mode; 89 fRemoteDevicesList.ItemAt(index)->fScanPeriodMode = inquiryInfo->pscan_period_mode; 90 fRemoteDevicesList.ItemAt(index)->fScanMode = inquiryInfo->pscan_mode; 91 fRemoteDevicesList.ItemAt(index)->fClockOffset = inquiryInfo->clock_offset; 92 93 duplicatedFound = true; 94 break; 95 } 96 97 } 98 99 if (!duplicatedFound) { 100 101 // TODO: DeviceClass(inquiryInfo->dev_class[0] | inquiryInfo->dev_class[1]<<8 | inquiryInfo->dev_class[2]<<16 ) 102 rd = new RemoteDevice(inquiryInfo->bdaddr); 103 fRemoteDevicesList.AddItem(rd); 104 // keep all inquiry reported data 105 rd->SetLocalDeviceOwner(fLocalDevice); 106 rd->fPageRepetitionMode = inquiryInfo->pscan_rep_mode; 107 rd->fScanPeriodMode = inquiryInfo->pscan_period_mode; 108 rd->fScanMode = inquiryInfo->pscan_mode; 109 rd->fClockOffset = inquiryInfo->clock_offset; 110 111 DeviceDiscovered( rd, DeviceClass(inquiryInfo->dev_class[0] | 112 inquiryInfo->dev_class[1]<<8 | 113 inquiryInfo->dev_class[2]<<16 )); 114 } 115 } 116 } 117 break; 118 119 case BT_MSG_INQUIRY_STARTED: 120 if (message->FindInt8("status", &status) == B_OK){ 121 fRemoteDevicesList.MakeEmpty(); 122 InquiryStarted(status); 123 } 124 125 break; 126 127 case BT_MSG_INQUIRY_COMPLETED: 128 129 InquiryCompleted(BT_INQUIRY_COMPLETED); 130 131 break; 132 case BT_MSG_INQUIRY_TERMINATED: /* inquiry was cancelled */ 133 134 InquiryCompleted(BT_INQUIRY_TERMINATED); 135 136 break; 137 case BT_MSG_INQUIRY_ERROR: 138 139 InquiryCompleted(BT_INQUIRY_ERROR); 140 141 break; 142 143 default: 144 145 BLooper::MessageReceived(message); 146 147 break; 148 149 } 150 151 } 152 153 154 DiscoveryListener::DiscoveryListener() : BLooper() , fRemoteDevicesList(BT_MAX_RESPONSES) 155 { 156 // TODO: Make a better handling of the running not running state 157 Run(); 158 } 159 160 161 } 162