NDS WiFi programming with devkitARM

Posted in HID, NintendoDS, sensors, sockets on June 6th, 2009 by Chaos Engineer

I have a grand plan to make a beowulf cluster dedicated to computing, interfacing and manipulating chaotic systems. I have a protocol devised that would allow multiple applications running on an arbitrary number of computers in a network pool hardware resources for this task. Each application (node) would have it's own capabilities, and could be used to collect sensory data, provide a human interface, or just to crunch numbers. I could easily have a management node that would maintain a list of other nodes and their abilities, and query them as needed. I recently had a great idea to use a NintendoDS as both an interface (via the touchscreen), and a sensory device (collecting audio samples with the buit-in microphone).

So I did a bunch of NDS programming a few years back using the devkitPro toolchain, specifically devkitARM. They were at release r20 then, and dswifi had just made it on the scene. For those who don't know, dswifi is a library written by Stephen Stair that allows NintendoDS homebrew developers using devkitARM to use the wifi features of the NDS. You can connect to wireless access points, and from there you have network access and a standard Berkley sockets interface, so you can pretty much accomplish anything you set your mind to. I just downloaded the latest version of devkitARM, which is now r26. I was quite pleased with the progress the toolchain had made during my absence, and especially pleased to see dswifi so well integrated. Things pretty much went downhill from there.

NOTE: 09.06.16 - The rest of this post is for historical information only. After I isolated the bug in dswifi that was the root of my problems, I notified the maintainers of devkitPro who committed a fix. There are now new releases of libnds, dswifi and default arm 7 available that correctly handle the DS' MAC address. Please see the addendum at the end of this article for more information. Do not downgrade your devkitPro install if you are having problems. Instead get the very latest versions of all libraries, and you should be good.

There were no examples provided with the nds-examples package that showed how to connect to WEP secured Access Point (AP). The only examples provided were for either using the WFC information stored in the NDS firmware, or for connecting to an unsecured AP. They did have code to enumerate APs and to provide a keyboard interface that I happily integrated. Prior to even testing the included examples I poured a couple hours into writing a code base using the most involved methods possible (swapping out all the simple 0 argument init functions with the 8 argument equivalents) to establish a console and collect and display a list of APs. Selecting an AP from this list that was secured would then provide a prompt to specify either 40-bit or 104-bit encryption. The user could then type in the 10 or 26 character string using a tiny little keyboard on the DS touchscreen. This string was then encoded to a byte array and passed to the Wifi_ConnectAP(...) function provided by dswifi.

Wifi AP list and a tiny keyboard

Wifi AP list and a tiny keyboard

I then spent three times as long troubleshooting. It took a while for me to remember that I have MAC address filtering enabled on my router (*bonk self*). I loaded up a wifi enabled game, pulled the MAC address of my DS from Nintendo's WFC interface, and put it on my router's Access Control List. I rubbed my hands in greedy anticipation, and loaded up my homebrew app once again. No joy ensued. I still could not connect to my AP.

At this point, I decided to try something simple just to verify the functionality of dswifi (yes, I'm backasswards when it comes to programming), so I loaded up one of the basic dswifi examples. Strangely, it did not work either. I knew it wasn't my DS or router anymore, because I would connect with a proper DS game that was wifi enabled. I didn't see anyone else complaining in the devkitPro forums, but r26 was *just* released and the forums over there aren't exactly teeming with DS programmers. I thought maybe the devkitPro toolchain for x64 Linux might have been the culprit, so I tried in Windows XP as well. Still no joy.

Operating under the assumption that dswifi worked at SOME point in devkitPro, I decided it was time to start digging backwards through the releases, and testing the functionality as I went with the most simple example possible... one that loaded the AP information from the WFC info stored in the DS and automatically tried to connect. This simple example did indeed work back in devkitPro r25 (2009.02.20). I then increased my resolution to try and find *exactly* where dswifi broke in devkitPro.

<SNIP>
Several paragraphs removed at the request of the devkitPro maintainers.

This section basically highlighted my procedures to somewhat subvert the available devkitPro library distributions to create a tool chain that pre-dated issues with the DS MAC address handling. As noted above, the bug I isolated has been fixed in the latest devkitPro library distributions, so this information is no longer pertinent. I found out that in my setup, the simple WFC autoconnect example worked fine when built with dswifi 0.3.7, but refused to work in dswifi 0.3.8. So I configured a motley devkitPro toolchain with different versions of specific libraries in order to get dswifi working for me.
</SNIP>

Telnetting into my NintendoDS Echo Server.

Telnetting into my NintendoDS Echo Server.

I now have code running on my DS that allows me to connect to my WEP secured AP, and from there get a socket connection to my workstation. Its pretty blasted awesome to be able to telnet into your DS and see what you type into your computer appear on the screen. Its several magnitudes more awesome to use the DS touchscreen and keys to remotely manipulate a 3D chaotic system in realtime. Add the ability to pipe recorded audio data from the DS microphone over the network and into that system where the fourier-tranformed signal is then used to modulate said system, and you might as well be dividing by zero.

UPDATE 2009.06.07:

After butting heads with the maintainers of devkitPro on the forum (they deleted a few of my posts because they don't like people telling users to downgrade or linking to obsolete libraries -- support headaches) who said the examples worked fine in r26, I pulled the source code for dswifi 0.3.7 and 0.3.8 than ran diff against the versions, excluding the svn nonsense:

diff -urNp -x '*svn*'  dswifi-src-0.3.7 dswifi-src-0.3.8 > dswifi.patch

Thanks to diff and a little persistence reading through the patch file, I found exactly where my problem was originating.

Remember how I said I had MAC address filtering enabled on my router? Well recent changes to dswifi did indeed break the example, for me at least... the MAC address bytes were being read from the firmware but written to a main data structure incorrectly:

 
for(i=0;i<3;i++)
	WifiData->MacAddr[i]= ReadFlashByte(0x36+i) + (ReadFlashByte(0x36+i+1)<<8);
 

This loop doesn't write the data to MacAddr as intended. After the loop, MacAddr is filled with the bytes from the following firmware addresses : 0x36, 0x37, 0x37, 0x38, 0x38, 0x39. The intention is obviously to write the bytes from 0x36, 0x37, 0x38, 0x39, 0x40, 0x41. Simple mistake, simple solution. I notified the maintainers, so when you download devkitPro r27, you can thank me when connecting to APs with MAC address filtering. =)

ADDENDUM 2009.06.16:

A fix for the MAC address bug in dswifi was submitted to the devkitPro svn on June 11th. The maintainers built new distributions of three libraries the same day. So if you get the following versions of libnds, dswifi and default arm7, your DS' MAC will be properly presented to access points:

libnds 1.3.5
dswifi 0.3.9
default arm7 0.5.4

Way to go, devkitPro.

You can see the full discourse on the forums here.

With this issue now past tense, I'll work on posting a PART 2 of this article with some actually useful programming information.

Tags: , , , ,

Chaotic Background

Posted in fractals, strange attractors on May 21st, 2009 by Chaos Engineer

I started my foray into chaos over four years ago now, at the end of 2004. I stumbled across a book by Clifford Pickover and Elahe Khorasani in the local library. It was about chaos, fractals and computer graphics.

First Julia

First Julia

At the time I was working on a game engine in Direct3D, so I quickly created a templated complex number library and set to work visualising some systems. Nothing worked at first, I was just getting pure black images as a result. Then... I thought I saw something. I increased the contrast of an image, and sure enough there was *something* hiding there in the darkness. I tweaked and adjusted my code some more. Finally, this Julia set materialised out of the void.

It may look meager, and by all counts really *is*, but at the time when those chaotic curls first appeared on my screen as a result of a some complex math, I was floored. I carefully adjusted the boundaries and sampling frequency of the system, and effectively zoomed in.

First Julia Zoom

First Julia Zoom

The tiny crevices in the curls opened up and spewed forth more detail. Where would it end? I spent hours rewriting this recursive routine and recompiling in order to change parameters of this Julia set rendering, and soon realised that I needed a better way to interface with these complex systems.

I adapted my rendering engine and created a Fractal Playground, where I could explore and play in the infinite number of fractal landscapes out there. I was limited only by the speed of my processor and the precision of 64-bit floating point maths. To me, exploring these fractal landscapes was as exciting as going on vacation to some new place. Rewriting the governing equation, defining new complex math operations, adding and modifying terms... it was like a grab bag of free vacations. I never knew where I would end up next. Some of these places were drab and repetitive, while others astounded me as soon as I stepped off the tarmac. The ones that I really remember are the ones that were drab on the outside, but with a little digging revealed themselves as fractal geodes... containing an unrivalled inner beauty encased within a plain shroud.

Buried Treasure

Buried Treasure

This image which is aptly named 'Buried Treasure' I found about 10E30 deep into a fractal landscape that seemed totally composed of white noise. I followed just a hint of a crevice in the noise down to this treasure. There were no real discernible features until this image appeared. Quite beautiful as well... it looks like the fancy sort of wood carving you would see on antique furniture.

I moved on from the typical convergence digrams where the color of a sample was defined by the number of iterations required to push it's magnitude past a threshold value. It was possible as well to track the actual orbit of a sample in complex space as you iterated it. Instead of just looking at the magnitude of a sample as it was iterated, I started plotting the values on the complex plane.

Encapsulating Sine

Encapsulating Sine

I referred to these as vector diagrams. The first time I plotted the orbits, as with many things, it didn't seem to work or make sense. There was far too much going on to understand the nuances. I needed a reference, and to start with a limited set of points. I first drew a convergence map, and then plotted the orbit of each sample on every 16th row or something. The results were intriguing. I soon found that plotting orbits in an aesthetically pleasing and efficient manner was quite difficult. Many wild and very strange images resulted from my experiments with this temperamental routine.

There was much more to be done however. This playground was fine for exploring, and giving brief reports on these landscapes, but it vastly lacked "production" features. The images I saved were limited in size to my screen resolution. The playground had a fullscreen mode, and I resorted to using the windows PrntScrn functionality to copy the full screen images to the clipboard and saving them off that way. I knew it was possible to create fractal images of arbitrary resolution... sometimes I hard coded a routine to dump a huge image of a system. It was a clunky way of accomplishing things, and many times while exploring I wished for the ability to do this dynamically. I also needed a better way to interface with the complex systems. Bringing up a dialog box and tabbing through controls, or even clicking on menu items was an annoyance while exploring. Fullscreen mode and modifying parameters (besides the zoom and pan) were mutually exclusive.

I was a bit daunted at first at the notion of entirely reworking the playground. My main code module (the one that contained the Windows entry point) had like a hundred global variables and was just under ten thousand lines long. In my state of fractal fervor, every new feature on the playground, every little test and modification was implemented as a kludge. I only cared about immediate results, and had cast maintainability to the wind. I built an empire out of bubblegum and bailing twine.

I rewrote the core routines, and this time built them out of brick instead of sticks and mud. I encapsulated everything, and made the multitude of non-exclusive boolean options for the system into a bitfield. There was now a single "state" variable where each individual bit represented a switch I could flip for a given option. One of the biggest and most effective changes was implementing a physically-based camera that existed in complex space. Physically-based, meaning the camera had momentum and friction, and moving it was all based on applying forces. When zooming/panning the weight of the camera would carry it for a bit even after releasing the controls. Note that this pre-dated the weighted interface of the iPhone by quite some time, and this idea was purely my own.

Now with the interface exclusive from the OS, I had a platform for fractal exploration that I never needed to bring out of fullscreen mode. With input and update routines built much like a game engine, I could define esoteric keypresses to my heart's desire, and the only change would be in the class's UpdateInput method. As I thought of new options, I defined a new bit in the bitfield and added accessors. It was simple to add routines for dumping the current scene to a huge detailed image, or saving each frame to make videos from. Now THIS was the kind of vehicle I needed for traversing the world of complex geometry.

Around this time I was an active member of the electronica scene in my area. I talked with some of the people setting up shows and got myself an invite to be a VJ for an upcoming event. I secured myself a projector and hauled my behemoth number cruncher (thanks, Stu!) to the venue. I had myself a little electroluminescent keyboard that worked perfect for manipulating the system in the darkness of the drum & bass arena. People were definitely impressed. One dude recognized the Mandelbrot set and was amazed to see it in such a dynamic light. That was probably the biggest compliment of the night. Everyone thought the convolving text routine where I feed text into a vector diagram and let the system swirl it around was mighty badass. All in all, it was quite a success.

Bolstered by the positive feedback from my first VJ gig, I was determined to expand the capabilities of this new application. Around this time I started experimenting with strange attractors. I used vector vector maps in the original fractal playground to build a "hit map" where computed locations of sample orbits were added to two-dimensional array that far exceeded the depth of a typical image. After subsampling the complex field and running thousands of iterations, I ran some statistical routines to get an idea of the spread of this data. I managed to clamp this data into a range acceptable by images, and interpolated the data into this clamped region to get some visual output. The results reminded me of images of strange attractors I had seen before. I didn't really know what a strange attractor was, but I figured they must be scads easier to work with than these complex vector diagrams.

I created a new application (again using parts from my game engine) for visualizing and manipulating strange attractors. These strange attractors proved to be quite varied and appealing. I especially enjoyed the way they moved when modulating the parameters over time. I produced hundreds of high resolution images and a few videos of these systems, all which were received well. I needed to get this new form of chaos integrated into my VJ software so I could switch between the systems on the fly. It was around this time that I migrated out of Windows and into linux, so this application would be the first to be resurrected in OpenGL.

Iconic Engineered Attractor

Iconic Engineered Attractor

Tags: , ,

Impetus

Posted in Uncategorized on May 15th, 2009 by Chaos Engineer

Well, this is it. I've become a blogger.

I spend hours every day wrestling with new software tools and devising new feedback systems and ways to exploit those systems. Some ideas that rattle around in my head are too grand to implement directly, so I just mull over them for a period, and then often forget about them entirely. I could fill a library with all the great ideas I've forgotten.

I thought that perhaps given a medium where I could get those ideas written down and out in the open, perhaps I would benefit from them more. In the process, why not share them with those who are willing to listen... perhaps they can benefit from them as well?

The blogosphere is an increasingly crowded space. As much as I would like to have one place where I can vet all my ideas, there is a need to hone my focus. Deviating from this norm once in a while should be acceptable, but in the interest of keeping ChaosEngineer coherent these deviations should be kept as infrequent as possible.

Thus this will be a place where one can come to find technical insight on using Linux, OpenGL and various other open source technologies. The general focus of this usage will be for the purpose of creating, interfacing with, manipulating or visualizing chaotic systems. Getting Linux to do what you want, and then streamlining it would be part of this process as well. I hope to expose plenty of generally useful information along this somewhat narrow road.

Tags: , ,