2 * Copyright 2007-2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
10 #include <Directory.h>
13 #include <Messenger.h>
15 #include <NodeMonitor.h>
24 WatchedEntry(BUSBRoster
*roster
,
25 BMessenger
*messenger
, entry_ref
*ref
);
28 bool EntryCreated(entry_ref
*ref
);
29 bool EntryRemoved(ino_t node
);
33 BMessenger
* fMessenger
;
39 WatchedEntry
* fEntries
;
44 class RosterLooper
: public BLooper
{
46 RosterLooper(BUSBRoster
*roster
);
50 virtual void MessageReceived(BMessage
*message
);
55 BMessenger
* fMessenger
;
59 WatchedEntry::WatchedEntry(BUSBRoster
*roster
, BMessenger
*messenger
,
62 fMessenger(messenger
),
69 entry
.GetNodeRef(&fNode
);
72 if (entry
.IsDirectory() && directory
.SetTo(ref
) >= B_OK
) {
75 while(directory
.GetNextEntry(&entry
) >= B_OK
) {
76 if (entry
.GetRef(ref
) < B_OK
)
79 WatchedEntry
*child
= new(std::nothrow
) WatchedEntry(fRoster
,
84 child
->fLink
= fEntries
;
88 watch_node(&fNode
, B_WATCH_DIRECTORY
, *fMessenger
);
90 // filter pseudoentry that only handles ioctls
91 if (strncmp(ref
->name
, "raw", 3) == 0)
96 fDevice
= new(std::nothrow
) BUSBDevice(path
.Path());
97 if (fDevice
!= NULL
) {
98 if (fRoster
->DeviceAdded(fDevice
) != B_OK
) {
107 WatchedEntry::~WatchedEntry()
110 watch_node(&fNode
, B_STOP_WATCHING
, *fMessenger
);
112 WatchedEntry
*child
= fEntries
;
114 WatchedEntry
*next
= child
->fLink
;
121 fRoster
->DeviceRemoved(fDevice
);
128 WatchedEntry::EntryCreated(entry_ref
*ref
)
133 if (ref
->directory
!= fNode
.node
) {
134 WatchedEntry
*child
= fEntries
;
136 if (child
->EntryCreated(ref
))
138 child
= child
->fLink
;
144 WatchedEntry
*child
= new(std::nothrow
) WatchedEntry(fRoster
, fMessenger
,
149 child
->fLink
= fEntries
;
156 WatchedEntry::EntryRemoved(ino_t node
)
161 WatchedEntry
*child
= fEntries
;
162 WatchedEntry
*lastChild
= NULL
;
164 if (child
->fNode
.node
== node
) {
166 lastChild
->fLink
= child
->fLink
;
168 fEntries
= child
->fLink
;
174 if (child
->EntryRemoved(node
))
178 child
= child
->fLink
;
185 RosterLooper::RosterLooper(BUSBRoster
*roster
)
186 : BLooper("BUSBRoster looper"),
191 BEntry
entry("/dev/bus/usb");
192 if (!entry
.Exists()) {
193 fprintf(stderr
, "USBKit: usb_raw not published\n");
198 fMessenger
= new(std::nothrow
) BMessenger(this);
199 if (fMessenger
== NULL
)
205 fRoot
= new(std::nothrow
) WatchedEntry(fRoster
, fMessenger
, &ref
);
221 RosterLooper::MessageReceived(BMessage
*message
)
224 if (message
->FindInt32("opcode", &opcode
) < B_OK
)
228 case B_ENTRY_CREATED
: {
232 if (message
->FindInt32("device", &device
) < B_OK
233 || message
->FindInt64("directory", &directory
) < B_OK
234 || message
->FindString("name", &name
) < B_OK
)
237 entry_ref
ref(device
, directory
, name
);
238 fRoot
->EntryCreated(&ref
);
242 case B_ENTRY_REMOVED
: {
244 if (message
->FindInt64("node", &node
) < B_OK
)
247 fRoot
->EntryRemoved(node
);
254 BUSBRoster::BUSBRoster()
260 BUSBRoster::~BUSBRoster()
272 fLooper
= new(std::nothrow
) RosterLooper(this);
282 ((RosterLooper
*)fLooper
)->Stop();
287 // definition of reserved virtual functions
288 void BUSBRoster::_ReservedUSBRoster1() {};
289 void BUSBRoster::_ReservedUSBRoster2() {};
290 void BUSBRoster::_ReservedUSBRoster3() {};
291 void BUSBRoster::_ReservedUSBRoster4() {};
292 void BUSBRoster::_ReservedUSBRoster5() {};