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