xref: /haiku/src/kits/bluetooth/DiscoveryListener.cpp (revision 269ebc04b9082e0081f3660bd727d9a6bc4a683d)
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