Reviving a dead DI524 router

Well, I was ploughing through the GPL’d source code of the firmware for my router as a bored person would do on the holidays. I was hoping to find a exploit somewhere on my router (the DI524 runs Linux) so I could run SSH and do some other interesting things with the router. My router was the B4 revision.

Eventually, I overflowed the Domain Name Server option in the webgui and it must have screwed something up because the router stopped responding. None of the lights came on except the Power indicator.

I rebooted the router, nope, after all the initialization, I was back to square one.

“Easy to fix,” I thought and flipped the router over and hit the reset button. No response. I unplugged it, held the reset button and plugged it in. No deal. I must have corrupted some part of the firmware so I look up some emergency recovery guides for the router. It looks like a brick.

I eventually found this. But even after following the instructions several times, I still had a non functioning router.

So after a bit of fiddling and over 12 hours of headache and grumpiness since I didn’t have internet, I finally had it booting again. Here’s the procedure to recover your DI-524 from a brick.

First, try a hardware reset. This will reset everything back to factory defaults. First, unplug your router. At the back of your router, there is a reset button. Use a toothpick or ballpoint pen to press it. Plug in your router while holding the button in place. Hold it in for exactly 2 seconds and let go of the button.

If it works, simply skip the rest of this guide and reconfigure your router.

If that didn’t work, try reflashing your firmware.

  1. Download the firmware and firmware flasher to a Windows computer.
  2. Set the IP settings of that computer to a static IP (make sure to write down the current settings before you do). The IP can be any IP between 192.168.0.2 and 192.168.0.254. Set the subnet to 255.255.255.0 and set the gateway and DNS to another random IP between 192.168.0.2-254.
  3. If your status light on the router is already flashing like crazy, skip this step. Unplug your router, hold the reset button in and plug it in. This time, keep holding it until the status light starts flickering really fast. This kicks it into recovery mode.
  4. Plug an Ethernet cable from the computer to one of the LAN ports on the router.
  5. Run the firmware flash program. It should detect the router as “192.168.0.1 crash”. Simply click Upgrade and don’t touch for a minute.

When it says that the recovery if complete, try booting the router again. If it boots successfully, reconfigure. If it doesn’t simply redo the reset technique.

And Voila, you have rescued your dead router!

Other things I observed during my experience:

  • There is a tftp server running when the router was in recovery mode.
  • Sending a read request for the file “R!” reboots the router.

And the Game Maker JSON parser WORKS!

Edit: Information on this page is out-dated. Please go here to find out more about the new JSON game maker library.

I’ve  finished writing 90% of the JSON parser it can parse all basic stuff! Still no support for ‘true’, ‘false’ and ‘null’ as values but I’ll look into it. Other quick fixes include that when parsing a number in scientific notation, the ‘e’ must be lowercase but that’s an easy fix that I can do later. I still haven’t bothered to look at error handling.

Here’s a screenie of it in action.

As promised, I’ll release the source code. It’s licensed under the BSD Free Software License and the conditions of that are (in simple speak):

  • You must include the copyright notice when distributing (whether in source or binary form) for the JSON parser.
  • You aren’t allowed to use my name to promote the final product (but credit given is appreciated).

Yes, the source code is ugly but it works!

Here’s how to use it (instructions may change as I release different versions):

  1. Call json_object_init(); But only once! And you have to make sure that the instance created by it must not be destroyed (I’m working on fixing it)
  2. Call json_parse(string); and test whether the result is -1. If it is, the string is malformed or contains grammar that the parser currently does not understand.
  3. If it was successful, you get a instance ID. Use that instance ID to get the values.
  4. Call json_get_value(obj, [key, force_instance_id_return]); Where obj is the instance ID returned from the previous call. The key is only used when returning data from an object or array. If json_get_value is called and the result is a instance ID to a end node, instead of returning a instance ID, the actual value is returned. Set the last argument to true if you want a instance ID.
  5. Call json_destroy(obj); to destroy the object when you are done. Only ever call this function on the root object. AKA the one you got from json_get_value();.

The code creates instances so be sure that won’t interfere with your game. All instances are created with no sprite at (-1,-1) in the room.

Enjoy the basic JSON parser. Please do point out suggestions and bugs.

Edit: Major bug fixes. Fixed the ‘e’ problem and some problems where objects weren’t parsed correctly. Also added a json_dump function to easily see parsed data.

Download Source Code

Edit2: Bugger, another bug discovered as I posted that. For some reason, the json_dump function some times outputs the first key twice. To fix it, simply add curr_key to the list of var’s on the top of json_dump()

Update: Writing a JSON parser

Edit: Information on this page is out-dated. Please go here to find out more about the new JSON game maker library.

I just finished writing the script that puts everything into the objects. Most of the stuff is working now! All the recursive functions are working as they should and there are no leaks as far as I can tell. There are still a few bugs that need ironing (graceful error handling is a huge on on this list) and I still need to finish implementing array support (it’s about 75% done).

Here’s some screenies to enjoy :D

The JSON parser is almost done. Just about 70% completed now!


Okay, time for some news.

I redid the basic structure and data handling stuff of the parser. The initializing function first adds some object resources.

Then, each object contains pointers to other objects (except ones that actually contain the value).

Basically like the following:

A “object” object.

The object has a ‘Create’ event that initializes a ds_map and some variables.

The destroy event destroys every object that is being pointed to by the ds_map (and setting off a chain reaction so all the other ones deallocate all their resources and so on). So in the end, everything is being taken care of. That’s some pro resource management.

Each entry in the ds_map is a pointer to another object.

A “array” object.

Same as above except with a ds_list

A “nodevalue” object.

This is simple, it just holds a value. Other objects point to this one.

Overall, this system is way better than what I previously planned to do. They all point to each other and members can be easily accessed. That means, I can parse the whole thing into one object.

The only downside is it must create instances and could muck up instance counts and potentially could introduce problems into the game. Nevertheless, I’ll document it and it should be fine if the programmer is competent.

Now, on the parsing side, everything is going superbly awesomely, well. I’ve just hit the first milestone.

The parser can handle strings (and un-escapes everything except unicode representations) and numbers (even scientific notation). It has functions to skip white space and all. And at a bit over 1 microsecond to parse that little bit isn’t too bad – workable but slower than other, well developed parsers. Still, not bad considering it is my first parser with craptastic programming skills. Here’s a snippet:

I’ll eventually release all the source code. It’ll all be under the BSD License.

Other changes include that I am now using a stack to return data. It’s better because:

  • It’s less messy than working with string pointers (well, they aren’t exactly string pointers but yeah) and variable_local_set(); functions.
  • You can chain the same stack all the way down so there’s less resource management to do (the root function just calls a ds_list_destroy();)

So far, I’d say the parser is about 45% complete. At this point, the biggest challenge is handling errors gracefully.

And that is all folks.

Writing a parser

Edit: Information on this page is out-dated. Please go here to find out more about the new JSON game maker library.

As you have seen in a previous post, I designed a JSON encoder that encodes data into a JSON string for Game Maker. That was super easy to write. But, I also needed a JSON parser or decoder which is a lot harder to write.

Well, I’ve had the pleasure of working with Game Maker. It has a scripting language, but unfortunately, no built in JSON-parser or any kind of regular expression engine. So, obviously, I have to write one.

Some of you may be asking, “but dayum, why not just get an existing JSON parser and turn it into a dll for Game Maker to use?”

The answer is:

  • I suck at programming, therefore:
  • I can’t understand how to use many of the JSON parsers. Either I’m extremely stupid, there isn’t enough documentation or, most likely, both.
  • It isn’t very efficient because it cannot directly access Game Maker’s data structures. Well, using GML is technically, also very inefficient (being a scripted language) but at least you can directly access resources.
  • I also have to deal with resource management (which I hate).
  • I’m bored and I want to write a parser from scratch.

Basically troubles of putting together a library for Game Maker to use is right out of the picture for me. I’m aware of programs like YACC but I don’t think they work for Game Maker.

So, on with my parser-writing adventure. I scrapped four designs before finally getting one that actually works. It took me 4 design-scrapping to realize you can’t simply use regular expressions or string finding functions to parse JSON. Yeah, four designs.

There was also the problem of dealing with GML’s data structure limitations. My parser would have been 10 times easier had I written it in PHP. PHP, allows maps (associative arrays) of basically unlimited levels while Game Maker only allows 2 dimensional arrays. You can see from the code snippet of what I mean:

$array['foo']['bar'] = "hello world";
$array['key'] = array('hello'=> array('foo'=>'bar'));

Compared with Game Maker

[gml]
array[0,0] = “hello world”;
[/gml]

This is a pain in the ass because that means if we want to do a associative array, we’ll have to use the ds_map functions. Even that has it’s limitations since it can only go one dimension and is much more awkward to access data than arrays.

The problem with one dimensional maps is that say I get a string of json like this:

{ "foo": { "hello": "world }, "foobar": "helloworld" }

I can’t simply put the whole thing into one map, unlike PHP.

In the end, I went with parsing one dimension and just storing the rest into a string for further processing when required. So the above JSON string would be stored like so:

Key Value
foo { “hello”: “world }
foobar helloworld

The next thing that really got me was ignoring whitespace. I have to iterate through strings and I decided to break it up into parts rather than do the whole thing at once.

So, I’d keep iterating until I got a number, bracket or quotation mark then select the appropriate function to deal with the rest. That function automatically trims out parsed data and passes the string back to the calling function which does another iteration until there are no more to parse.

The string parser, iterates through every character and stores it’s state (whether the next character needs escaping, etc) until it reaches a quotation mark. Then it stores the acquired data and returns to the caller.

So, first parser I’m writing. I hope it turns out successful. I’ll post snippets of code tomorrow of what I have. If anyone reading this has experience in writing a parser or knows a better way of doing things, please leave a comment. Because, quite frankly, I’m not doing so well.

That’s all, good night.

Some open source releases

As part of the WBGL Project, I’m writing smaller aspects of the game such as online highscores.

Here are some stuff I’ve written for Game Maker. They’re GML implementations of commonly used functions when interfacing via HTTP. All scripts are licenced under the BSD Licence.

JSON Encoder

A better, awesomer, JSON library is available here.

URL Encoder

Encodes a string so it can be passed in a URL. It has the same function as PHP’s urlencode and is compatible with PHP.

url_encode

Happy to be part of the WBGL project

Yay, I am now part of the WBGL project. It’s a joint project between class mates that I’m participating in.

It’s my job to look after the smaller details and aspects of the project like legality and websites and stuff like that.

I’m also working on the online highscores. It shouldn’t be long before that is done.

I gotta say, though my jobs are somewhat less rewarding, I’m really happy to be part of the project.

Mouse rumble mod

My first teensy experience was pretty unsuccessful. I failed miserably at my first project with a microcontroller. So, I’m aiming for something a little bit easier.

You know the light underneath the mouse? It powers down and when there is action, it suddenly lights up again. What if, every time it lights up, the mouse rumbles? That would be pretty cool. This is my adventure so far.

So, I took apart my el’cheapo mouse and discovered the LED gets ~1.6v when idle and ~1.9v when fully powered. The ADC on the Teensy should pick it up easily.

So, it’s time to solder. Solder two wires to the legs of the LED and connect them to the Teensy. Unfortunately, I stupidly forgot to disconnect the mouse from the computer before soldering and busted the LED :-( so disconnect before soldering.

Also, solder a wire to the 5v and GND rail and connect it to a Mini-USB plug to act as a power supply to the Teensy.

Rip a little vibrator thingy off an old mobile phone and solder it to the Teensy as well.

Edit: Okay, it wasn’t as successful as I hoped it would be. I spent the whole of yesterday’s afternoon wondering why the ADC on the Teensy wasn’t picking anything up. It turned out that it was current that was varying, not the voltage, which meant the Teensy couldn’t pick it up.

So, I spent the afternoon and today’s morning rolling my own shunt resistor and even opto-isolator. No dice. I’m just too noob at physics.

After a bit, I decided to scrap the original plan and go for rumble on mouse click.

If you haven’t found a source of power yet, wire up a Mini-USB plug that steals power from the mouse.

For this, you’ll need to intercept the signals from the clicky button thing. The easiest way is to cut off and reroute the point on the circuit board to the Teensy. Here’s a picture

Then connect a pin from the Teensy to where the path ends on the +5v signal line. Usually, just follow the pin that isn’t ground to the mouse IC. In the picture, it’s yellow though it’s covered. Connect the other pin (white in this picture) to GND on the Teensy. And connect the middle pin to a pin on the Teensy (red).

The logic is that a 5v signal is given to the IC when the circuit completes (i.e a click). We are simply checking the state of the push button and sending the signal to the mouse as appropriate. Since the Teensy and the mouse share the same ground, it will work fine.

Hook up the vibrator to Pin 3 of the teensy.

Here’s a crappy schematic.

Once everything is wired up, it’s time to program the AVR. Download Arduino and the Teensyduino add-on. Write up your own software. I whacked a simple one up in 5 minutes.

/*Copyright (C) 2010 Daniel Tang

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/

#define INPUT_PIN 0
#define OUTPUT_PIN 1
#define RUMBLE_PIN 2

void setup ()
{
  pinMode(INPUT_PIN, INPUT_PULLUP);
  pinMode(OUTPUT_PIN, OUTPUT);
  pinMode(RUMBLE_PIN, OUTPUT);
  Serial.begin(9600);
  digitalWrite(11, HIGH);
}

void loop()
{
  if (digitalRead(INPUT_PIN)) /*High state*/
  {
        digitalWrite(OUTPUT_PIN, HIGH);
        digitalWrite(RUMBLE_PIN, HIGH);
  }
  else
  {
    digitalWrite(OUTPUT_PIN, LOW);
    digitalWrite(RUMBLE_PIN, LOW);
  }
}

Load it onto the Teensy and try out your new mouse mod.

Conclusion: It’s lame, it wastes battery power, it gets really annoying after a while (I’m working on a new firmware to fix it though), has high-ish latency and is totally pointless. But hey, it’s something to do after the exams (and it’s awesome for gaming too).

Pics (yeah, my soldering skills are so un-uber):

Edit2: New and improved code. Uses interrupts to control the vibrator so it comes out as short bursts rather than annoying long bursts.

/*Copyright (C) 2010 Daniel Tang

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/

#define INPUT_PIN 0
#define OUTPUT_PIN 1
#define RUMBLE_PIN 2
#include "TimerOne.h"
volatile bool already_rumbling = 0;
bool clicked = false;

void rumble()
{
  if (!already_rumbling)
  {
    digitalWrite(RUMBLE_PIN, HIGH);
    already_rumbling = 1;
    Timer1.start();
  }
}

void setup ()
{
  pinMode(INPUT_PIN, INPUT_PULLUP);
  pinMode(OUTPUT_PIN, OUTPUT);
  pinMode(RUMBLE_PIN, OUTPUT);
  digitalWrite(11, HIGH);
  
  Timer1.initialize(100000);
  Timer1.attachInterrupt(off, 100000);
  
}

void off()
{
  digitalWrite(RUMBLE_PIN, LOW);
  already_rumbling = 0;
  Timer1.stop();
}

void loop()
{
  if (!digitalRead(INPUT_PIN)) /*High state*/
  {
        digitalWrite(OUTPUT_PIN, HIGH);
        if (!clicked)
        {
          rumble();
          clicked = 1;
        }
  }
  else
  {
    digitalWrite(OUTPUT_PIN, LOW);
    clicked = 0;
  }
}

Teensy Gameboy Multiboot adapter

Started work on this but didn’t have much time to finish it.

It’s a Teensyduino port of the multiboot serial converter for use on the Gameboy Advance.

Sorry, I’m terrible at programming. Here are the sources (includes the two originals)

MSMCcable-1.02

Edit 1/11/10: Resumed work on this. Figured it didn’t work because I used the delayMicroseconds function rather than a hardware timer which didn’t give enough resolution. I also fixed the passthrough problem. Once I finish learning how to use hardware timers, I shall get back to you.

Tips for a great Powerpoint presentation

I’ve seen too many crappy presentations. Here are some tips so your reader doesn’t fall asleep during your presentation. View the presentations at the bottom of the page for a better demonstration.

Key data only!

Try to only put key data on your presentation. You are presenting the data. The slides are to remind your readers about the specifics and to take notes.

They are NOT your cue cards and you shouldn’t be reading off the slides.

KISS

It stands for: Keep it simple stupid! You want your readers to read your slides!

  • One slide should not have more than 50 words in it.
  • Do not ever, have a whole essay on a slide. Everyone hates it and will definitely not read through it.
  • Keep it minimal!
  • If presenting a picture or graph, put it on it’s own slide, annotate it and explain it.

Present, don’t read

Don’t read off the Powerpoint – present the Powerpoint! If you just read a massive block of text, you just look unprofessional and boring.

  • Come prepared with cue cards of some sort and glance at it every now and then.
  • Make sure to only have key data on the slides.
  • Humor!

Layout and look

The golden rules of a good looking presentation:

  1. No scribbly motion path animations. You want the reader to read the text – not chase it randomly around the screen.
  2. Contrasting colors. Make sure you can actually read the text clearly. Black on white or Yellow on Black-Dark blue gradient is perfect.
  3. Consistency. Every slide layout should be consistent – only the content should be different.
  4. Fonts. Two fonts are the ideal number to use. One for the title page and titles. Another for content. Also, use readable fonts. Times New Roman, Arial, Helvetica are some good examples. Some to avoid include; Comic Sans MS, any joined/block writing and Wingdings. Use really big fonts (no smaller than 18pt)

Because I’m such a nice guy, I compiled two Powerpoints, both with the same information. Which one is better?

How NOT to do a presentation

How to do a good presentation

Recovering data from a CD

Well, I thought, I’d share a little something I discovered today while trying to recover a movie from a badly scratched CD.

When the disc you’re trying to recover from is a CD (not a DVD), you’ll recover more if you use a CD-ROM drive instead of a DVD drive.

When recovering from a disc, I discovered that my laptop has it’s own retry count which made the recovery process extremely slow when combined with a recovery program. So, I took out an external DVD drive to try and recover.

In the end, I managed to get about 47% of real data which isn’t very good. I could play the CD on my DVD player and it could play at least 90% of the disc perfectly without glitching.

It, then, occurred to me that DVD drives may be more sensitive and error prone. So, I disassembled the external drive and hacked in a CD-ROM drive. So far, it has recovered at least 70% legit data – a huge improvement over using a DVD drive.

So next time, use a CD-ROM drive instead of a DVD drive for recovering if the disc is a CD.