#include #include #include #include #include #include #include #include #include #include #include #include "DeviceManager.h" #include "LocalDeviceImpl.h" #include "Debug.h" #include "BluetoothServer.h" #include void DeviceManager::MessageReceived(BMessage* msg) { if (msg->what == B_NODE_MONITOR) { int32 opcode; if (msg->FindInt32("opcode", &opcode) == B_OK) { switch (opcode) { case B_ENTRY_CREATED: case B_ENTRY_MOVED: { entry_ref ref; const char *name; BDirectory dir; TRACE_BT("Something new in the bus ... "); if ((msg->FindInt32("device", &ref.device)!=B_OK) || (msg->FindInt64("directory", &ref.directory)!=B_OK) || (msg->FindString("name", &name) != B_OK)) return; TRACE_BT("DeviceManager: -> %s\n", name); ref.set_name(name); // Check if the entry is a File or a directory if (dir.SetTo(&ref) == B_OK) { printf("%s: Entry %s is taken as a dir\n", __FUNCTION__, name); node_ref nref; dir.GetNodeRef(&nref); AddDirectory(&nref); } else { printf("%s: Entry %s is taken as a file\n", __FUNCTION__, name); AddDevice(&ref); } } break; case B_ENTRY_REMOVED: { TRACE_BT("Something removed from the bus ...\n"); } break; case B_STAT_CHANGED: case B_ATTR_CHANGED: case B_DEVICE_MOUNTED: case B_DEVICE_UNMOUNTED: default: BLooper::MessageReceived(msg); break; } } } } status_t DeviceManager::AddDirectory(node_ref *nref) { BDirectory directory(nref); status_t status = directory.InitCheck(); if (status != B_OK) { TRACE_BT("AddDirectory::Initcheck Failed\n"); return status; } status = watch_node(nref, B_WATCH_DIRECTORY, this); if (status != B_OK) { TRACE_BT("AddDirectory::watch_node Failed\n"); return status; } // BPath path(*nref); // BString str(path.Path()); // // TRACE_BT("DeviceManager: Exploring entries in %s\n", str.String()); entry_ref ref; status_t error; while ((error = directory.GetNextRef(&ref)) == B_OK) { // its suposed to be devices ... AddDevice(&ref); } TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error)); return (error == B_OK || error == B_ENTRY_NOT_FOUND)?B_OK:error; } status_t DeviceManager::RemoveDirectory(node_ref* nref) { BDirectory directory(nref); status_t status = directory.InitCheck(); if (status != B_OK) return status; status = watch_node(nref, B_STOP_WATCHING, this); if (status != B_OK) return status; BEntry entry; while (directory.GetNextEntry(&entry, true) == B_OK) { entry_ref ref; entry.GetRef(&ref); BMessage msg(B_NODE_MONITOR); msg.AddInt32("opcode", B_ENTRY_REMOVED); msg.AddInt32("device", nref->device); msg.AddInt64("directory", nref->node); msg.AddString("name", ref.name); //addon->fDevice->Control(NULL, NULL, msg.what, &msg); } return B_OK; } status_t DeviceManager::AddDevice(entry_ref* ref) { BPath path(ref); BString* str = new BString(path.Path()); BMessage* msg = new BMessage(BT_MSG_ADD_DEVICE); msg->AddInt32("opcode", B_ENTRY_CREATED); msg->AddInt32("device", ref->device); msg->AddInt64("directory", ref->directory); msg->AddString("name", *str ); TRACE_BT("DeviceManager: Device %s registered\n", path.Path()); return be_app_messenger.SendMessage(msg); } DeviceManager::DeviceManager() : fLock("device manager") { } DeviceManager::~DeviceManager() { } void DeviceManager::LoadState() { if (!Lock()) return; Run(); Unlock(); } void DeviceManager::SaveState() { } status_t DeviceManager::StartMonitoringDevice(const char *device) { status_t err; node_ref nref; BDirectory directory; BPath path("/dev"); /* Build the path */ if ((err = path.Append(device)) != B_OK) { printf("DeviceManager::StartMonitoringDevice BPath::Append() error %s: %s\n", path.Path(), strerror(err)); return err; } /* Check the path */ if ((err = directory.SetTo(path.Path())) != B_OK) { /* Entry not there ... */ if (err != B_ENTRY_NOT_FOUND) { // something else we cannot handle printf("DeviceManager::StartMonitoringDevice SetTo error %s: %s\n", path.Path(), strerror(err)); return err; } /* Create it */ if ((err = create_directory(path.Path(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != B_OK || (err = directory.SetTo(path.Path())) != B_OK) { printf("DeviceManager::StartMonitoringDevice CreateDirectory error %s: %s\n", path.Path(), strerror(err)); return err; } } // get noderef if ((err = directory.GetNodeRef(&nref)) != B_OK) { printf("DeviceManager::StartMonitoringDevice GetNodeRef error %s: %s\n", path.Path(), strerror(err)); return err; } // start monitoring the root status_t error = watch_node(&nref, B_WATCH_DIRECTORY, this); if (error != B_OK) return error; TRACE_BT("DeviceManager: %s path being monitored\n", path.Path()); // We are monitoring the root we may have already directories inside // to be monitored entry_ref driverRef; while ((error = directory.GetNextRef(&driverRef)) == B_OK) { // its suposed to be directories that needs to be monitored... BNode driverNode(&driverRef); node_ref driverNRef; driverNode.GetNodeRef(&driverNRef); AddDirectory(&driverNRef); } TRACE_BT("DeviceManager: Finished exploring entries(%s)\n", strerror(error)); #if 0 HCIDelegate *tmphd = NULL; int32 i = 0; // TODO!! ask the server if this needs to be monitored while ((tmphd = (HCIDelegate *)fDelegatesList.ItemAt(i++)) !=NULL) { /* Find out the reference*/ node_ref *dnref = (node_ref *)tmphd->fMonitoredRefs ; if (*dnref == nref) { printf("StartMonitoringDevice already monitored\n"); alreadyMonitored = true; break; } } #endif return B_OK; } status_t DeviceManager::StopMonitoringDevice(const char *device) { status_t err; node_ref nref; BDirectory directory; BPath path("/dev"); if (((err = path.Append(device)) != B_OK) || ((err = directory.SetTo(path.Path())) != B_OK) || ((err = directory.GetNodeRef(&nref)) != B_OK)) return err; // test if still monitored /* bool stillMonitored = false; int32 i = 0; while ((tmpaddon = (_BDeviceAddOn_ *)fDeviceAddons.ItemAt(i++)) !=NULL) { if (addon == tmpaddon) continue; int32 j=0; node_ref *dnref = NULL; while ((dnref = (node_ref *)tmpaddon->fMonitoredRefs.ItemAt(j++)) != NULL) { if (*dnref == nref) { stillMonitored = true; break; } } if (stillMonitored) break; } // remove from list node_ref *dnref = NULL; int32 j=0; while ((dnref = (node_ref *)addon->fMonitoredRefs.ItemAt(j)) != NULL) { if (*dnref == nref) { addon->fMonitoredRefs.RemoveItem(j); delete dnref; break; } j++; } // stop monitoring if needed if (!stillMonitored) { if ((err = RemoveDirectory(&nref, addon)) != B_OK) return err; } */ return B_OK; }