vfs: check userland buffers before reading them.
[haiku.git] / src / servers / bluetooth / DeviceManager.cpp
blob4470ecd36f64647d0ac605503aa9f1aff44fb7ba
1 #include <Application.h>
2 #include <Autolock.h>
3 #include <String.h>
5 #include <Directory.h>
6 #include <Entry.h>
7 #include <FindDirectory.h>
8 #include <Path.h>
9 #include <NodeMonitor.h>
12 #include <image.h>
13 #include <stdio.h>
14 #include <string.h>
16 #include "DeviceManager.h"
17 #include "LocalDeviceImpl.h"
19 #include "Debug.h"
20 #include "BluetoothServer.h"
22 #include <bluetoothserver_p.h>
25 void
26 DeviceManager::MessageReceived(BMessage* msg)
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:
35 entry_ref ref;
36 const char *name;
37 BDirectory dir;
39 TRACE_BT("Something new in the bus ... ");
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;
46 TRACE_BT("DeviceManager: -> %s\n", name);
48 ref.set_name(name);
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);
57 } else {
58 printf("%s: Entry %s is taken as a file\n", __FUNCTION__, name);
59 AddDevice(&ref);
62 break;
63 case B_ENTRY_REMOVED:
65 TRACE_BT("Something removed from the bus ...\n");
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;
82 status_t
83 DeviceManager::AddDirectory(node_ref *nref)
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;
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;
98 // BPath path(*nref);
99 // BString str(path.Path());
101 // TRACE_BT("DeviceManager: Exploring entries in %s\n", str.String());
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);
110 TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error));
112 return (error == B_OK || error == B_ENTRY_NOT_FOUND)?B_OK:error;
116 status_t
117 DeviceManager::RemoveDirectory(node_ref* nref)
119 BDirectory directory(nref);
120 status_t status = directory.InitCheck();
121 if (status != B_OK)
122 return status;
124 status = watch_node(nref, B_STOP_WATCHING, this);
125 if (status != B_OK)
126 return status;
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);
140 return B_OK;
144 status_t
145 DeviceManager::AddDevice(entry_ref* ref)
147 BPath path(ref);
148 BString* str = new BString(path.Path());
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);
155 msg->AddString("name", *str );
157 TRACE_BT("DeviceManager: Device %s registered\n", path.Path());
158 return be_app_messenger.SendMessage(msg);
162 DeviceManager::DeviceManager() :
163 fLock("device manager")
169 DeviceManager::~DeviceManager()
175 void
176 DeviceManager::LoadState()
178 if (!Lock())
179 return;
180 Run();
181 Unlock();
185 void
186 DeviceManager::SaveState()
192 status_t
193 DeviceManager::StartMonitoringDevice(const char *device)
196 status_t err;
197 node_ref nref;
198 BDirectory directory;
199 BPath path("/dev");
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;
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;
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;
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;
228 // start monitoring the root
229 status_t error = watch_node(&nref, B_WATCH_DIRECTORY, this);
230 if (error != B_OK)
231 return error;
233 TRACE_BT("DeviceManager: %s path being monitored\n", path.Path());
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) {
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);
247 TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error));
249 #if 0
250 HCIDelegate *tmphd = NULL;
251 int32 i = 0;
253 // TODO!! ask the server if this needs to be monitored
255 while ((tmphd = (HCIDelegate *)fDelegatesList.ItemAt(i++)) !=NULL) {
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;
266 #endif
268 return B_OK;
272 status_t
273 DeviceManager::StopMonitoringDevice(const char *device)
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;
284 // test if still monitored
286 bool stillMonitored = false;
287 int32 i = 0;
288 while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++)) !=NULL) {
289 if (addon == tmpaddon)
290 continue;
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;
300 if (stillMonitored)
301 break;
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;
313 j++;
316 // stop monitoring if needed
317 if (!stillMonitored) {
318 if ((err = RemoveDirectory(&nref, addon)) != B_OK)
319 return err;
322 return B_OK;