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