1/*
2 * Copyright 2007-2008 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/bluetooth_error.h>
8#include <bluetooth/DiscoveryAgent.h>
9#include <bluetooth/DiscoveryListener.h>
10#include <bluetooth/LocalDevice.h>
11#include <bluetooth/RemoteDevice.h>
12#include <bluetooth/debug.h>
13
14#include <bluetooth/HCI/btHCI_command.h>
15#include <bluetooth/HCI/btHCI_event.h>
16
17#include <bluetoothserver_p.h>
18#include <CommandManager.h>
19
20#include "KitSupport.h"
21
22
23namespace Bluetooth {
24
25
26RemoteDevicesList
27DiscoveryAgent::RetrieveDevices(int option)
28{
29	CALLED();
30    // No inquiry process initiated
31    if (fLastUsedListener == NULL)
32        return RemoteDevicesList();
33
34    return fLastUsedListener->GetRemoteDevicesList();
35}
36
37
38status_t
39DiscoveryAgent::StartInquiry(int accessCode, DiscoveryListener* listener)
40{
41	CALLED();
42    return StartInquiry(accessCode, listener, GetInquiryTime());
43}
44
45
46status_t
47DiscoveryAgent::StartInquiry(uint32 accessCode, DiscoveryListener* listener,
48	bigtime_t secs)
49{
50	CALLED();
51    size_t size;
52
53	if (fMessenger == NULL)
54		return B_ERROR;
55
56	if (secs < 1 || secs > 61 )
57		return B_TIMED_OUT;
58
59    void*  startInquiryCommand = NULL;
60
61    // keep the listener whats the current listener for our inquiry state
62    fLastUsedListener = listener;
63
64    // Inform the listener who is gonna be its owner LocalDevice
65    // and its discovered devices
66    listener->SetLocalDeviceOwner(fLocalDevice);
67
68    /* Issue inquiry command */
69    BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
70    BMessage reply;
71
72    request.AddInt32("hci_id", fLocalDevice->ID());
73
74    startInquiryCommand = buildInquiry(accessCode, secs, BT_MAX_RESPONSES,
75		&size);
76
77    // For stating the inquiry
78    request.AddData("raw command", B_ANY_TYPE, startInquiryCommand, size);
79    request.AddInt16("eventExpected", HCI_EVENT_CMD_STATUS);
80    request.AddInt16("opcodeExpected",
81		PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY));
82
83	// For getting each discovered message
84    request.AddInt16("eventExpected",  HCI_EVENT_INQUIRY_RESULT);
85
86	// For finishing each discovered message
87    request.AddInt16("eventExpected",  HCI_EVENT_INQUIRY_COMPLETE);
88
89
90    if (fMessenger->SendMessage(&request, listener) == B_OK)
91    {
92    	return B_OK;
93    }
94
95	return B_ERROR;
96
97}
98
99
100status_t
101DiscoveryAgent::CancelInquiry(DiscoveryListener* listener)
102{
103	CALLED();
104    size_t size;
105
106    if (fMessenger == NULL)
107    	return B_ERROR;
108
109    void* cancelInquiryCommand = NULL;
110    int8  bt_status = BT_ERROR;
111
112    /* Issue inquiry command */
113    BMessage request(BT_MSG_HANDLE_SIMPLE_REQUEST);
114    BMessage reply;
115
116    request.AddInt32("hci_id", fLocalDevice->ID());
117
118    cancelInquiryCommand = buildInquiryCancel(&size);
119    request.AddData("raw command", B_ANY_TYPE, cancelInquiryCommand, size);
120    request.AddInt16("eventExpected",  HCI_EVENT_CMD_STATUS);
121    request.AddInt16("opcodeExpected",
122		PACK_OPCODE(OGF_LINK_CONTROL, OCF_INQUIRY_CANCEL));
123
124    if (fMessenger->SendMessage(&request, &reply) == B_OK) {
125        if (reply.FindInt8("status", &bt_status ) == B_OK ) {
126			return bt_status;
127		}
128    }
129
130    return B_ERROR;
131}
132
133
134void
135DiscoveryAgent::SetLocalDeviceOwner(LocalDevice* ld)
136{
137	CALLED();
138    fLocalDevice = ld;
139}
140
141
142DiscoveryAgent::DiscoveryAgent(LocalDevice* ld)
143{
144	CALLED();
145	fLocalDevice = ld;
146	fMessenger = _RetrieveBluetoothMessenger();
147}
148
149
150DiscoveryAgent::~DiscoveryAgent()
151{
152	CALLED();
153	delete fMessenger;
154}
155
156
157} /* End namespace Bluetooth */
158