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