xref: /haiku/src/servers/bluetooth/DeviceManager.cpp (revision 8a6724a0ee3803f1e9f487d8111bb3f6cb8d16db)
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 
25 void
26 DeviceManager::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 
82 status_t
83 DeviceManager::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 
116 status_t
117 DeviceManager::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 
144 status_t
145 DeviceManager::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 
162 DeviceManager::DeviceManager() :
163 	fLock("device manager")
164 {
165 
166 }
167 
168 
169 DeviceManager::~DeviceManager()
170 {
171 
172 }
173 
174 
175 void
176 DeviceManager::LoadState()
177 {
178 	if (!Lock())
179 		return;
180 	Run();
181 	Unlock();
182 }
183 
184 
185 void
186 DeviceManager::SaveState()
187 {
188 
189 }
190 
191 
192 status_t
193 DeviceManager::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 
272 status_t
273 DeviceManager::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