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
21namespace Bluetooth {
22
23
24/* hooks */
25void
26DiscoveryListener::DeviceDiscovered(RemoteDevice* btDevice, DeviceClass cod)
27{
28	CALLED();
29}
30
31
32void
33DiscoveryListener::InquiryStarted(status_t status)
34{
35	CALLED();
36}
37
38
39void
40DiscoveryListener::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 */
51void
52DiscoveryListener::SetLocalDeviceOwner(LocalDevice* ld)
53{
54	CALLED();
55	fLocalDevice = ld;
56}
57
58
59RemoteDevicesList
60DiscoveryListener::GetRemoteDevicesList(void)
61{
62	CALLED();
63	return fRemoteDevicesList;
64}
65
66
67void
68DiscoveryListener::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
149DiscoveryListener::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