xref: /haiku/src/servers/bluetooth/DeviceManager.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 
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 					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 
83 status_t
84 DeviceManager::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 
119 status_t
120 DeviceManager::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 
147 status_t
148 DeviceManager::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 
165 DeviceManager::DeviceManager() :
166 	fLock("device manager")
167 {
168 
169 }
170 
171 
172 DeviceManager::~DeviceManager()
173 {
174 
175 }
176 
177 
178 void
179 DeviceManager::LoadState()
180 {
181 	if (!Lock())
182 		return;
183 	Run();
184 	Unlock();
185 }
186 
187 
188 void
189 DeviceManager::SaveState()
190 {
191 
192 }
193 
194 
195 status_t
196 DeviceManager::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 
275 status_t
276 DeviceManager::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