 Okay, so I'm my cuner and I'll talk to you about something that will be familiar to Well, at least a problem that we feel you familiar to most of you guys I think Okay, so you're gonna have to permit me just a little bit of Unix nerd humor here Alright, so if you look into any big Unix nerds home directory and do something like ls dash dot start at RC You see like basically it's like a badge of honor like if you don't have 12 of these suckers in there You are not cool and it and and you look in one of these RC files and each line is like some sort Has some sort of history to it like the day they were supposed to be working on the project But instead they sent eight hours customizing the perfect zish prompt You know, you know each Or this one they got from this guy. He was an Australian. It was at a conference, right? So hopefully I'll get a chance to trade some crap with you guys later on today, but but you know what what all these things are so Nerds you may notice from observation or perhaps realistic insurspection Love to customize their junk Like you need everything tricked out shined up a Beautiful buff. I love this picture like look how look how much work has gone into this thing Like I can't imagine all I know the only word I know that describes what people do in this process is buffing Like but there's like 17 other things that involves getting your wheel that shiny. I'm sure and chemicals and right I don't know anything about it, but I can tell you that the sort of customization classic customization is a big nerd thing, but It's a thing that lately I felt was sort of fraught with peril because After a while you shine up the wheels and you should have get the little dial up front going and everything and then it's like man There just doesn't seem to be all that much less to customize. I mean, yes I just got three spams in and that probably means I need to add a few lines to proc mail that RC and And you know, I bet there's just one or two Vim Plugins that would really revolutionize my life But but it's hard to imagine exactly what they do exactly Or if you're an e-max guy, you've already reached the point where you never leave e-max for any reason Like you've got a command to use the toilet. You've got a Right everything starts feeling pretty good and pretty normal and And and and then you're like man, you know, I I feel like I'm done here like my computer rocks pretty hard and then But then the question is well, what do you do now? I mean, there's these people who keep hanging out at your house Apparently you're related to them Maybe you could consider talking to them Apparently religion is good Ruby is probably know about that a little bit, but you know, you could get into that more Racketball or you could say screw all that What I'm going to do is going to tape something that essentially works and needlessly add a fishbowl to it So so yeah, so my opinion is you're not done Because what you didn't realize is that all your awesome? Customizations have been essentially happening between the screen and your computer and not in the external physical world where you could be adding more bizarre stuff and In general at least with me not shiny pure perfect stuff But more or less ugly weird stuff that ever gonna be like what's that sort of tumor hanging off your computer? And you'll be like well I sort of built this USB thing in any ways if you twiddle it around you switch between desktops or something and I thought it would be cool Right, so that's the idea like this is not about USB for like really Hardcore hardware people who are like. Oh, yeah, I'm building this thing that normal people actually want This is USB for for hackers who want to be able to take like this mouse They have in their closet sort of put it in there and then make it do something like I don't know Play like hukaracha when they jiggle it around or what have you right like? fun stuff But like this was not a project for work for me and no one would pay me to do this sort of thing This is for fun stuff All right, so the idea is you get you get USB devices and you control them using Ruby I mean boot who's would be even cooler, but I didn't have time to look into that one So USB devices Ruby and why USB devices? Well main reason is if you're if you're a primary source of hardware is the best buy bargain bin and for me it is you're gonna pretty much want something that is cheap and available and also USB devices are self-describing So you notice when you plug in that mouse that you got from the best buy bargain bin It's very pleasing to see that your windows is like hey Japanese character Japanese character Japanese character mouse has been found And you're like good. I think I think it's gonna happen for me Right, so obviously there's something in there that's letting The device know what it is and I mean those of you who remember back to the days before all this stuff when you would plug in the serial mouse Then you would try to find the driver for it and then you would you would plug it in it wouldn't work properly You would reinstall everything Still wouldn't work properly right so that's done now. You don't have to do that USB devices can tell you a lot about what they are and even more so human interface device USB devices Like your USB printer can say it's a printer and your USB little thumb drive thing can say it's a thumb drive and Actually act like a thumb drive, but USB human interface devices actually can talk a lot about Being very weird basically very non-standard and still basically work Okay, and the third thing which because it's not really having to do with ruby You know I feel hesitant to talk about it too much, but you can actually build your own USB devices So I'm gonna be sort of jamming that at the end, but it's not that hard It's it's good. It's easy enough that a retarded monkey like me can do the soldering necessary, so it's pretty easy okay, so USB has a variety of different subspecs like any good spec there are subspecs then that subspec actually has subspecs so the main USB spec says stuff like Okay, you've got the devices they can plug into hubs they can be powered or not They can have what's called Configurations which if anyone has a USB device that actually uses configurations I want you to call me because I've never found a device that actually uses this feature and I've never tested this part of ruby USB Because configurations are like you could have a totally like your USB device can act different if it has external power versus internal power from your computer And then you can have different modes and you could switch between them like go to this mode go to this mode Does anyone have a USB device like that? Anyways, it's in the spec and So they got that and then the final thing you have is basically these interfaces Which are what you normally think of as the actual thing it does only you could have more of those too You can one configuration to have like three different interfaces, so you've got your USB device Thumb drive slash salad shooter those could both be separate interfaces on the same device And and one of them conforms to the shell it salad shooter spec and one of them conforms to the drive spec So there's multiple different USB specs for different kinds of devices But the most interesting one is the hid human interface device back because it's so flexible So you can I have if you go to ruby USB dot techno fetish net You will find my website and on there. There's a thing. That's all the links for this presentation So you don't have to type in that endless pile of crap if you want to actually look up this document It's all there all the all the stuff that I reference is there So human interface devices the goal here I don't know what they were thinking in the spec deciding meeting, but I think basic I mean basically the way this thing works is you've got this human interface device and it's sending data In whatever crazy format it wants, but it before it sends that it gives you a description of the data It's gonna send you would think you know any device could actually benefit from that particularly needle feature But for some reason it's in the human interface spec that you can specify all sorts of details about The format in which the data is gonna be sent and for me That's humongous because that means that when you plug your your interface your device in and then you try to talk to it Ruby Ruby's like hey, I'm just gonna look at this little document. Okay Yes, here's the seven different numbers. This device just said me. Here's the stuff It said about what those seven different numbers mean Here's the annotation someone did on those seven different numbers. So yeah, so let's give an example Okay, so here we have what you would look at in the old days when you were trying to reverse into near some piece Of crap you found somewhere You've got some string of bits and you're like hmm I don't know those zeros seemed like nothing's happening. Which thing am I not pressing right now, right? And then the ones you're like, huh, right? Okay, and then you look at the actual thing that's happening and it's nothing like what you're actually thinking, right? Cuz okay, so so we're gonna go from left to right and the features that the USB spec has So the on the far left is the left mouse button. This is the most useful one This is the thing that lets that Taiwanese device I was talking about sort of work because USB as a the hidden devices have a spec where it's like I have this magic number and that means it's the left mouse button that you know about That you want to use for that icon clicking I do so so and then if you go into the really more obscure section of The spec you've got stuff. You don't think you need like this is a chaff release button So for all your joysticks that have chaff release buttons They can all interoperate as long as they can form to the spec that they use the chaff button release code If I'm not kidding about this. This is in there Okay, and then you can start saying things that as far as I can tell no one ever Really uses because there's no actual program or interface that I can find anywhere that utilizes this but you can say things like these numbers are logically grouped together and I'm going to annotate it with this String that describes stuff about it, and I have no idea where you would see this Unless you were like maybe Microsoft has like a secret tool that lets you get this information and be it but but as far as I Can tell it's completely inaccessible There's no way to actually see these annotations that the developers might have implicitly put in their hardware for your benefit And then there's nothing I really like nothing because if you're reverse engineering some crazy device And you see this thing and it's like it always seems to be zero I Wonder what that means you're all you always in the back of your mind are thinking Is there like like if this thing was immersed in water or something would it put the water immersion code in there? You know like what this these zeros do they ever or like, you know Something important that I should notify my users about you never quite know if it's really nothing or you just haven't triggered The right thing to be nothing to be make nothing something but in usb you can actually say yeah, these bits are just for bite alignment So the no no with Ruby USB you almost can I haven't actually added that feature, but it's pretty close So yeah, but but outside of that like like I don't know why they had this in the spec considering It was not possible to see them because no one had written any tools to see it before that as far as I could And then you can say really weird stuff like What's what's the unit that this thing is coming back with and What's the exponent on the unit this thing is coming back with and? What's the minimum value the maximum value there's actually two different kinds of those and I forget what the difference is The other nice thing I like say is yeah negative numbers right? How long would it take you to figure that one out during the reverse engineering thing that this is like the two's Compliment of what you're yeah, that wouldn't have been easy see good. They have a spec for this sort of stuff Okay, so how do you do this? This is the beginning of the language like of a piece of a mouse's descriptor So you can see over there on the right that it's basically a hexadecimal code and Then you set a variety of different things about I'm going to talk about a few of them that actually matter If you ever want to hack on USB devices, so the usages see that usage page usage Right those are about basically those are the things I was telling you about where you can Specify the code that indicates what kind of thing that people might really be looking for You can so like left mouse button is a particular usage page and usage or The keyboard Q is another usage page and usage The usage page is like the more general thing and then the usage is a more particular thing For some reason the spec rather than specifying Rather than risking repeating themselves has this very complicated set of rules about what things are global When and what's in what circumstance one of the main features of ruby USB is that it? Figures all that crap out for you But to give you a brief description the usage page actually gets appended to the usage So when you ask for a usage in ruby USB, you're actually getting both the usage page and the usage itself Which are two things or they could be specified as one thing Okay, and then you've got those collections I was telling you about those collections before where you group things together for some reason right you can do that and but and then over there is there's the you the Logical minimum logical maximum Those are the ranges I was telling you about which is sort of nice to be able to specify how stuff ranges And then the report count indicates how many things you're how many basically? Blocks in your report binary string are going to be devoted to each item and Then the report size says how long each of those blocks is going to be and Then you say input and then it makes it basically implicitly means okay that report size and report count that I previously specified somewhere in the giant stack of Input things that I could have previously specified now use whatever values you currently have for that in this context and Add that to this reports sort of list of implicit members If this seems complicated to you The good news is Ruby USB just figures all that crap out for you, so you can stop listening Okay, but that is why I've highlighted the inputs in that they're the key things they're like okay Do this stuff I've been talking about forever up to this moment Right, so that's that's the highlighted. Yes, so you can see three one bit Buttons and then one five bit empty space It's empty because let's see that CNST next to the green input that means constant So I suppose theoretically it could actually be used to send a constant value to the user's computer Like if you wanted to descend the user pie Or the first couple bits of pie you could jam that in there be like here's a constant for your convenience I don't know in the spec Okay, so enough about in slides things okay now. I have a Confession to make as much as the Unix guys I am I I didn't want to risk trying to hook my Unix laptop up to the Projector thing and figuring out whether it could output the right resolution Correctly so and this only works in Unix like operating systems. Unfortunately, there's no Windows version of Ruby USB So I have actual text files of my IRB sessions from last night So these things really 100% exist like real code just you know yesterday Okay, so Okay, so this is a part I really want you guys to ask me questions about because this is the stuff you might actually Theoretically be doing if you want to play around with you Ruby USB So I'm gonna try to explain it in somewhat detail And I'm gonna and I'm gonna try to and if you if you don't know what I'm talking about I want you to shout at me You know throw things at me. Okay, so One of the annoying things about Ruby USB is it uses C++ and C libraries And so the load library path is rather complicated Especially since you usually have to be sudo because under Linux unless you do a lot of playing around Your USB devices are owned by root, right? So see this little sudo LD IRB thing here That's my little shorthand for doing all the necessary load library path stuff I need to do to make it happen, which you're gonna have to figure out too Sorry Okay, then require lib USB see that's as easy as you'd want though Now if if I hadn't done the sudo LD business that would return to false and some really inscrutable error though Okay, so USB colon colon devices each iterate over all USB devices in the system and print out some stuff about them and Here they are here's all the USB devices that were currently connected to my computer when I did that I had an optical mouse a keyboard the USB hub for my keyboard I'm not sure what that one is these are all controllers that seem to think they're USB devices, but don't do anything the touch panel and Yeah, more controllers. So yeah, so all these different USB devices, which are USB device objects in my system And then I go ahead and grab one by using its vendor ID and product ID And there's nothing magical about the vendor ID and product ID that just goes to Ruby function. That's like You know, well the law select vendor for vendor ID and product ID. It's just convenient for me because It uniquely identifies the vice most of the time the vendor and product ID And you get a device back and then you can say things like hey, what's its name? What's its manufacturer and is it a human interface device? That's that hidden question mark Everyone following me so far Okay So the main thing to realize when it says hid question mark in this context is it's asking in any of its configurations for any of its Interfaces is there's a hidden device. Remember I was talking about that salad shooter Combination USB drive right it can be more than one thing at once So you have to be sort of careful and that makes things more complicated than they maybe ought to be Okay, speaking more complicated So now I grab my optical mouse And you can see it's Microsoft says it's a basic optical mouse And then I say okay, give me the first interface now This is mostly for shortness because what I really should say is iterate over all interfaces to find the hidden interface that this thing actually implements Except no one implements more than one interface For any reason but they could in theory Okay, yeah, so he's asking is there any sort of classic devices that you can't get information from do their performance Characteristics and stuff like that the answer is at this level. We're doing right now Not really because this is all more or less stuff It has to give up to the operating system or it ain't a usdv device So so at this point there's no issues of synchronization for the most part Although occasionally if you get certain large chunks of data it might time out in certain circumstances but Once you start actually trying to communicate with the device you might have some problems I don't know if you would well. I haven't had a problem with that so much Okay, now here comes an annoying part or maybe a good part depending on what your use case is mouse interface Stats dot detach kernel before you can do most interesting things with the usb device. You need to detach it from the kernel Otherwise the kernel is going to keep try to interpret it. However, it's going to interpret it The bad news about this is once you do detach it from the kernel There's no reattached a kernel command. So for example once I did this my mouse stopped working I'll tab and now I handle that but you can unplug your device and plug it back in but as far as I can tell That's the only thing you can do to get it reattached to the kernel Okay, so then I asked for my my interface for this for all input usages that it has Those are those usages. I was telling you before were You know the things that like what things does it support and you can see a quite a big list came back Although it would have been way longer if it was a keyboard Because it would have been like I support a I support B. I support C. I'm not kidding So so yes, you can see like it's got a wheel on there and all these different things like the first thing in the Is the usage page and then the second thing is the usage so? No No, I have a little json file that has they're in the USB spec I actually have a little program a thing in the USB framework where you can actually say Okay, listen for this usage once you get once you get to that point But we're not going to do that right here. What I do is I say, okay listen for interrupts So the one thing to keep in mind is Before you start getting info from your USB device you have to tell it to start listening Right it uses the ruby blocks and text where within the block it's open and listening and outside the block It's not and then you ask for the next interrupt and it will give you a data object and You can see over here The exciting binary string I got back from my mouse and then if I say this Data dot set usages now that seems backwards because we're trying to get the usages What it's saying is what usages were set in this data that I just got back from this thing So in a keyboard you actually can have any number of letters that are possible usages But only a few are set in any particular piece of data. You get back from it. So it gives me okay. It sent me back Button one Was on button two was off button three off x coordinate was zero y coordinate was zero and wheel was zero this is not a surprising to do my thing because mice are relative devices not absolute and so all I did was press the left button and So that was the only thing that was set in the datagram If I I could have given you a whole big line of crap in this demo if you wanted to where you know It was rolling all around and stuff, but I decided you would get the picture Okay, and now finally for my third example an actual program that uses Ruby USB and Here I want to show you the device that that it uses with let me just put this down for a sec Hello, okay. I call this the world's most ghetto TV remote control. I Found it at a thrift store on the back. It says to sheba led control module. I Really have no idea what its purpose was at all like I think it might be some sort of telephony thing Anyways, this is what the thing uses. I reversed engineered the the devices protocol in about an hour and Then the much more annoying process of figuring out how to communicate with VLC So here we go the main the stuff that's actually USB related in this code is Down here get the device Right right here Okay, find the right endpoint Detach the kernel and then here's that listen for hid interrupts. I was telling you up before And it gets the button codes and then starts doing stuff basically meanwhile. So that was about I don't know 30 lines 50 lines something like that and then all this stuff is like communicating in sockets through VLC much more annoying Okay so VLC is like a Linux Video player so when I watch my anime like all the buttons are all hooked up and I adjust the volume Yep, you can get it for Windows and one of the nice things is it's a really unixi kind of program So it has things like oh, yeah, you want to send me commands over a socket Well, of course I support that because I'm a unixi kind of thing Okay, back to the presentation here. Okay, how does it work three layers? I Won't spend too long on this Live USB, I did not write live USB somebody else did I don't really know who honestly It's a cross-platform USB library that works in theory on all unix like operating systems including Matko sx In particular Windows is exempted It's Okay, but a little funky in fact one of the major takeaways from this project is normally when you think about interfacing with C in Ruby you're like, okay It's it's see it's all good because you know most the time you're interfacing with some operating system level layer That's really rock-solid and it's been hammered on for like a million years Yeah Ruby live USB is not quite that solid so as a result of that you get really annoying behavior that you can't avoid because It's in this really low-level layer that you just haven't written and But yet Ruby people don't expect like random timeouts for no reason, you know So It's supposedly cross-platform. I have never tried this on anything but a Linux box. I just don't have anything but a Linux box And yeah, it's important to realize you have to get the latest version from CBS or it doesn't work for some reason and You already know about the kernel stuff The way this thing works is it's a very see like interface in that like You you ask it to look at a USB device and it starts filling up some C structs that that basically Constitutes the data and Advocating through them is sort of a pain. You wish they had objects, but they don't But still it works pretty well Next layer my hidden parser. Yes Well, I mean it talks to the same clonal libraries that you could Right so yeah in theory. I also have another project called Evidev for Ruby Which I'll talk about just a little bit at the end. It's a little more rock solid, but less cool Okay, here's another one of my big mistakes when doing this project take heed. I Wrote this thing in C++ because I thought I don't know maybe someone else will want to hit parser and they'll wanted in C++ dumb idea a Humongous pain in the butt to do I hate the standard template library It's a huge annoyance and the worst part is though Because I'm basically making a rich object system in C++ I then have to convert that rich object system to Ruby and it never is as rich as it needs to be to get me the data I discover I want later and So then I've got to go back in because none of the parsing is in there So for example doing things like oh, what was the original set of binary hex characters that generated this particular segment Oh, that's something I can't figure out very easily at all Right, so this is the sort of stuff in my opinion. That was a big mistake. I had to do it all over again I would write this in pure Ruby connecting to Lib USB directly Okay, the goal of this thing is to basically return what are called report descriptor objects They're like hey You're gonna this thing could send three different kinds of reports and the first one's gonna be X-coordinate Y-coordinate temperature and the other one's gonna be this thing and the other one's gonna that's the format I want from as a programming perspective Right not like this big stack-based thing But something I can always query for the exact relevant information when I've got some data coming through other other I suppose the one really smart thing I did with this Unit tests never try to implement an extremely boring humongous spec without unit tests Always use unit tests. It cannot work without unit tests. You would you'd be amazed about the times I'd be like oh new feature finally implemented and then like half the old features would be gone Also, you know, you don't have an infinite number of USB devices at your disposal So if you want to have something that has multiple configurations or something like that you've got to sort of fake it out And then my thing Tries to do the right thing as much as possible. It has good documentation It produces objects that are annotated with as much data as I currently collect about them That's the idea you get data back from the USB device and you can figure out What the heck the data is supposed to be and then ignore that information and do what you want it to do like control your Desktops or what have you but at least you know what it was thinking it was supposed to be for Okay, so that's the big picture live USB Is raw USB descriptions to the hidden parser which which trucks to the report which send a report descriptor objects to the USB library and Then you've got a complete descriptor that you can then ask for information from the USB device at best point the Ruby USB starts communicating directly to live USB, right? It knows what the data is supposed to be looking like So it basically starts sending data back and forth and then your app Gets these handy annotated objects that you can use for a maximum easy USB device manipulation and then finally if you really want to get crazy. Oh Yeah Custom-built USB devices. I particularly like the idea of a custom USB chainsaw. I think that has real potential Anyone want to help me with that project? I am there so AVR USB is what I use to build my USB devices if you've got an AVR programmer or you've got a hundred bucks you can spend on a project that's really cool and Basically a five dollar little microprocessor You can make and a few other assorted parts that probably cost two dollars or so altogether You can make a working USB device. I mean working anywhere like you can plug this sucker into Unix and it'll be like Yeah, it's a mouse and I'm totally believing that So it's really fun. I mean, it's not Ruby at all, but it is fun and you can program it in C Which I mean is Ruby guys, you know C because you have to write all your extensions in C, right? So it's not that bad So yeah, check that out. It was one of the most fun things I did as part of this project I wish I had my USB device, but one of the soldering things got sort of screwed up and Okay future stuff Main beef with my project Extremely complicated building that isn't really giveable to you guys So if one of you wants to sit with me and help me figure out how to make make work and all right on a completely bare-boned system I would really be help into that because it's a big pain to make it work Improve Ruby objects that can do more stuff. Most of the infrastructure is already there But I've got stuff. I haven't implemented yet like those string annotations that people mentioned before also Input devices work great output devices don't quite work yet, but there's no reason why they shouldn't I just haven't implemented that side of things More testing way more testing would be great Okay, and the final thing I want to mention is so if you're like, oh man make files. That doesn't sound that cool at all and You still want to have your unix system use USB devices. I have another library called evdeb for ruby It uses the Linux evdeb framework, which is basically the Linux level device layer like Your kernel converts your USB devices into evdeb devices, which is how normally Linux things access, but it's only for Linux not OS X or BSD or anything like that But the nice thing is because it's this kernel supported layer. It's really rock solid and never breaks or times out It does anything bad So anyways just an op thing if you still want to do cool stuff. Don't have time for any of this crap We're just considering. Okay, so that's it questions Okay, how does Ruby threads interoperate with this stuff? I haven't tried it with multi-threaded programs I Don't I mean I didn't go through a heck of a lot of trouble to make sure it was thread safe now The one thing I can say is that when you're listening for interrupts. It actually spawns its own thread Because the way lib USB works for some reason When you if you're not exactly listening for a USB event when an event comes in It disappears. There's absolutely no buffering at all, which is a big problem because you know well You can see why so it actually spawns its own p thread So I bet that would probably be relatively safe because I actually do have a little bit of semaphores in that particular section But as for the rest of it, I would bet you would probably see some Some bugs just because untested stuff doesn't work, right? Well, I have to say that this one I use every day, which is sort of cool My the funniest thing I did with it and this was a totally dumb idea, but I did it Was I actually glued to work keyboards together and in vi one was insert mode and one was not insert mode. I Was sort of curious if that would work no Oh, it did work. I mean it did what it was supposed to It basically at least for the time I used it it had exactly the same problem where you always were instead of being always in The wrong mode you were always typing on the wrong keyboard It was just a lot of keyboard to have on your lap, but no it's perfectly doable if you want to try it You can go for pretty easy. Well, I mean So I'd say The main thing I'd like to do is just refine this a little bit so that when I want when I want to plug stuff I mean probably next on my list of things I'm just gonna implement myself is just get another keyboard not glued to the original keyboard and just have a hundred and two keys of Like run this command run this command run this command, you know not bad for four dollars I I mean, yeah, you could I could probably get by with four But it's actually cheaper to get the keyboard than like any of the funky other devices you can get that will do that for you I mean There's always I mean I'd say if I was gonna go to something really cool The building of you see devices is particularly slick and then when you can hook up to ruby It's like okay now I can program this thing and get it to do whatever I want No, I have not although that would be really awesome I I'm actually not particularly musically inclined myself and so I but there are things where you can There's plenty of projects where you can actually get USB musical instruments So once you have that the ruby stuff is there I mean not really but I can tell you that it's it's I mean I can type on the keyboard and it's like Yep, yep, yep, yep. Yeah, so I mean I don't have any problem there, but there could be a problem with latency Can't be sure although I can tell you that because of the way I've buffered the input you're not gonna lose any information so The only possibilities that the system would just be so slow that it would That it would just sort of back up Which seems like sort of a long shot to me unless you're doing something really interesting Like it'd just be hard to imagine how that could really happen Over a long period of time, but I would say test it would probably be the best idea All right. Thanks very much