1 /*
2 * Copyright 2007 Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6
7 #include <bluetooth/DiscoveryAgent.h>
8 #include <bluetooth/DiscoveryListener.h>
9 #include <bluetooth/RemoteDevice.h>
10 #include <bluetooth/DeviceClass.h>
11 #include <bluetooth/bdaddrUtils.h>
12 #include <bluetooth/debug.h>
13
14 #include <bluetooth/HCI/btHCI_event.h>
15
16 #include <bluetoothserver_p.h>
17
18 #include <Message.h>
19
20
21 namespace Bluetooth {
22
23
24 /* hooks */
25 void
DeviceDiscovered(RemoteDevice * btDevice,DeviceClass cod)26 DiscoveryListener::DeviceDiscovered(RemoteDevice* btDevice, DeviceClass cod)
27 {
28 CALLED();
29 }
30
31
32 void
InquiryStarted(status_t status)33 DiscoveryListener::InquiryStarted(status_t status)
34 {
35 CALLED();
36 }
37
38
39 void
InquiryCompleted(int discType)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
SetLocalDeviceOwner(LocalDevice * ld)52 DiscoveryListener::SetLocalDeviceOwner(LocalDevice* ld)
53 {
54 CALLED();
55 fLocalDevice = ld;
56 }
57
58
59 RemoteDevicesList
GetRemoteDevicesList(void)60 DiscoveryListener::GetRemoteDevicesList(void)
61 {
62 CALLED();
63 return fRemoteDevicesList;
64 }
65
66
67 void
MessageReceived(BMessage * message)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
DiscoveryListener()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 } /* end namespace Bluetooth */
160