#include <Application.h>
#include <Autolock.h>
#include <String.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <Path.h>
#include <NodeMonitor.h>
#include <image.h>
#include <stdio.h>
#include <string.h>
#include "DeviceManager.h"
#include "LocalDeviceImpl.h"
#include "Debug.h"
#include "BluetoothServer.h"
#include <bluetoothserver_p.h>
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);
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;
}
entry_ref ref;
status_t error;
while ((error = directory.GetNextRef(&ref)) == B_OK) {
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);
}
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");
if ((err = path.Append(device)) != B_OK) {
printf("DeviceManager::StartMonitoringDevice BPath::Append() error %s: %s\n", path.Path(), strerror(err));
return err;
}
if ((err = directory.SetTo(path.Path())) != B_OK) {
if (err != B_ENTRY_NOT_FOUND) {
printf("DeviceManager::StartMonitoringDevice SetTo error %s: %s\n", path.Path(), strerror(err));
return err;
}
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;
}
}
if ((err = directory.GetNodeRef(&nref)) != B_OK) {
printf("DeviceManager::StartMonitoringDevice GetNodeRef error %s: %s\n", path.Path(), strerror(err));
return err;
}
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());
entry_ref driverRef;
while ((error = directory.GetNextRef(&driverRef)) == B_OK) {
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;
while ((tmphd = (HCIDelegate *)fDelegatesList.ItemAt(i++)) !=NULL) {
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;
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;
}