1#include <Application.h>
2#include <Autolock.h>
3#include <String.h>
4
5#include <Directory.h>
6#include <Entry.h>
7#include <FindDirectory.h>
8#include <Path.h>
9#include <NodeMonitor.h>
10
11
12#include <image.h>
13#include <stdio.h>
14#include <string.h>
15
16#include "DeviceManager.h"
17#include "LocalDeviceImpl.h"
18
19#include "Debug.h"
20#include "BluetoothServer.h"
21
22#include <bluetoothserver_p.h>
23
24
25void
26DeviceManager::MessageReceived(BMessage* msg)
27{
28	if (msg->what == B_NODE_MONITOR) {
29		int32 opcode;
30		if (msg->FindInt32("opcode", &opcode) == B_OK) {
31			switch (opcode)	{
32				case B_ENTRY_CREATED:
33				case B_ENTRY_MOVED:
34				{
35					entry_ref ref;
36					const char *name;
37					BDirectory dir;
38
39					TRACE_BT("Something new in the bus ... ");
40
41					if ((msg->FindInt32("device", &ref.device)!=B_OK)
42						|| (msg->FindInt64("directory", &ref.directory)!=B_OK)
43						|| (msg->FindString("name",	&name) != B_OK))
44						return;
45
46					TRACE_BT("DeviceManager: -> %s\n", name);
47
48					ref.set_name(name);
49
50					// Check if	the	entry is a File	or a directory
51					if (dir.SetTo(&ref) == B_OK) {
52						printf("%s: Entry %s is taken as a dir\n", __FUNCTION__, name);
53					    node_ref nref;
54					    dir.GetNodeRef(&nref);
55						AddDirectory(&nref);
56
57					} else {
58						printf("%s: Entry %s is taken as a file\n", __FUNCTION__, name);
59                        AddDevice(&ref);
60					}
61				}
62				break;
63				case B_ENTRY_REMOVED:
64				{
65					TRACE_BT("Something removed from the bus ...\n");
66
67				}
68				break;
69				case B_STAT_CHANGED:
70				case B_ATTR_CHANGED:
71				case B_DEVICE_MOUNTED:
72				case B_DEVICE_UNMOUNTED:
73				default:
74					BLooper::MessageReceived(msg);
75				break;
76			}
77		}
78	}
79}
80
81
82status_t
83DeviceManager::AddDirectory(node_ref *nref)
84{
85	BDirectory directory(nref);
86	status_t status	= directory.InitCheck();
87	if (status != B_OK)	{
88		TRACE_BT("AddDirectory::Initcheck Failed\n");
89		return status;
90	}
91
92	status = watch_node(nref, B_WATCH_DIRECTORY, this);
93	if (status != B_OK)	{
94		TRACE_BT("AddDirectory::watch_node	Failed\n");
95		return status;
96	}
97
98//	BPath path(*nref);
99//	BString	str(path.Path());
100//
101//	TRACE_BT("DeviceManager: Exploring entries in %s\n", str.String());
102
103	entry_ref ref;
104	status_t error;
105	while ((error =	directory.GetNextRef(&ref))	== B_OK) {
106		// its suposed to be devices ...
107		AddDevice(&ref);
108	}
109
110	TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error));
111
112	return (error == B_OK || error == B_ENTRY_NOT_FOUND)?B_OK:error;
113}
114
115
116status_t
117DeviceManager::RemoveDirectory(node_ref* nref)
118{
119	BDirectory directory(nref);
120	status_t status	= directory.InitCheck();
121	if (status != B_OK)
122		return status;
123
124	status = watch_node(nref, B_STOP_WATCHING, this);
125	if (status != B_OK)
126		return status;
127
128	BEntry entry;
129	while (directory.GetNextEntry(&entry, true)	== B_OK) {
130		entry_ref ref;
131		entry.GetRef(&ref);
132		BMessage msg(B_NODE_MONITOR);
133		msg.AddInt32("opcode", B_ENTRY_REMOVED);
134		msg.AddInt32("device", nref->device);
135		msg.AddInt64("directory", nref->node);
136		msg.AddString("name", ref.name);
137		//addon->fDevice->Control(NULL,	NULL, msg.what,	&msg);
138	}
139
140	return B_OK;
141}
142
143
144status_t
145DeviceManager::AddDevice(entry_ref* ref)
146{
147	BPath path(ref);
148	BString* str = new BString(path.Path());
149
150	BMessage* msg =	new	BMessage(BT_MSG_ADD_DEVICE);
151	msg->AddInt32("opcode",	B_ENTRY_CREATED);
152	msg->AddInt32("device",	ref->device);
153	msg->AddInt64("directory", ref->directory);
154
155	msg->AddString("name", *str	);
156
157	TRACE_BT("DeviceManager: Device %s registered\n", path.Path());
158	return be_app_messenger.SendMessage(msg);
159}
160
161
162DeviceManager::DeviceManager() :
163	fLock("device manager")
164{
165
166}
167
168
169DeviceManager::~DeviceManager()
170{
171
172}
173
174
175void
176DeviceManager::LoadState()
177{
178	if (!Lock())
179		return;
180	Run();
181	Unlock();
182}
183
184
185void
186DeviceManager::SaveState()
187{
188
189}
190
191
192status_t
193DeviceManager::StartMonitoringDevice(const char	*device)
194{
195
196	status_t err;
197	node_ref nref;
198	BDirectory directory;
199	BPath path("/dev");
200
201	/* Build the path */
202	if ((err = path.Append(device))	!= B_OK) {
203		printf("DeviceManager::StartMonitoringDevice BPath::Append() error %s: %s\n", path.Path(), strerror(err));
204		return err;
205	}
206
207	/* Check the path */
208	if ((err = directory.SetTo(path.Path())) !=	B_OK) {
209		/* Entry not there ... */
210		if (err	!= B_ENTRY_NOT_FOUND) {	// something else we cannot	handle
211			printf("DeviceManager::StartMonitoringDevice SetTo error %s: %s\n",	path.Path(), strerror(err));
212			return err;
213		}
214		/* Create it */
215		if ((err = create_directory(path.Path(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != B_OK
216			|| (err	= directory.SetTo(path.Path()))	!= B_OK) {
217			printf("DeviceManager::StartMonitoringDevice CreateDirectory error %s: %s\n", path.Path(), strerror(err));
218			return err;
219		}
220	}
221
222	// get noderef
223	if ((err = directory.GetNodeRef(&nref))	!= B_OK) {
224		printf("DeviceManager::StartMonitoringDevice GetNodeRef	error %s: %s\n", path.Path(), strerror(err));
225		return err;
226	}
227
228	// start monitoring	the	root
229	status_t error = watch_node(&nref, B_WATCH_DIRECTORY, this);
230	if (error != B_OK)
231		return error;
232
233	TRACE_BT("DeviceManager: %s	path being monitored\n", path.Path());
234
235	// We are monitoring the root we may have already directories inside
236	// to be monitored
237	entry_ref driverRef;
238	while ((error =	directory.GetNextRef(&driverRef)) == B_OK) {
239
240		// its suposed to be directories that needs	to be monitored...
241		BNode driverNode(&driverRef);
242		node_ref driverNRef;
243		driverNode.GetNodeRef(&driverNRef);
244		AddDirectory(&driverNRef);
245	}
246
247    TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error));
248
249#if	0
250	HCIDelegate	*tmphd = NULL;
251	int32 i	= 0;
252
253	// TODO!! ask the server if	this needs to be monitored
254
255	while ((tmphd =	(HCIDelegate *)fDelegatesList.ItemAt(i++)) !=NULL) {
256
257		/* Find	out	the	reference*/
258		node_ref *dnref	= (node_ref	*)tmphd->fMonitoredRefs	;
259		if (*dnref == nref)	{
260			printf("StartMonitoringDevice already monitored\n");
261			alreadyMonitored = true;
262			break;
263		}
264
265	}
266#endif
267
268	return B_OK;
269}
270
271
272status_t
273DeviceManager::StopMonitoringDevice(const char *device)
274{
275	status_t err;
276	node_ref nref;
277	BDirectory directory;
278	BPath path("/dev");
279	if (((err =	path.Append(device)) !=	B_OK)
280		|| ((err = directory.SetTo(path.Path())) !=	B_OK)
281		|| ((err = directory.GetNodeRef(&nref))	!= B_OK))
282		return err;
283
284	// test	if still monitored
285/*
286	bool stillMonitored	= false;
287	int32 i	= 0;
288	while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++))	!=NULL)	{
289		if (addon == tmpaddon)
290			continue;
291
292		int32 j=0;
293		node_ref *dnref	= NULL;
294		while ((dnref =	(node_ref *)tmpaddon->fMonitoredRefs.ItemAt(j++)) != NULL) {
295			if (*dnref == nref)	{
296				stillMonitored = true;
297				break;
298			}
299		}
300		if (stillMonitored)
301			break;
302	}
303
304	// remove from list
305	node_ref *dnref	= NULL;
306	int32 j=0;
307	while ((dnref =	(node_ref *)addon->fMonitoredRefs.ItemAt(j)) !=	NULL) {
308		if (*dnref == nref)	{
309			addon->fMonitoredRefs.RemoveItem(j);
310			delete dnref;
311			break;
312		}
313		j++;
314	}
315
316	// stop	monitoring if needed
317	if (!stillMonitored) {
318		if ((err = RemoveDirectory(&nref, addon)) != B_OK)
319			return err;
320	}
321*/
322	return B_OK;
323}
324