Things are starting to look better now. After some elbow grease over the weekend and much research on Linux' interprocess communications, I was finally able to get my simple simulator up and running and connected to Contiki. The development process wasn't easy, but it took about a week (of hard work) to get it to the point where I can actually start simulating actual nodes. I'm actually quite satisfied with it. It's not as sophisticated as Cooja or Netsim (Contiki's native simulators) but it can do what I want and give me fine-grained control over how the simulation is run. Here are some of the details.
The simulator starts up as a command line shell. To add a node, you type "add". The simulator will then fork a process and run the FreakZ stack on it. The command shell also has two duplex communications channels to the node. One of the duplex communications channels is for data tx and rx. The other is for command tx and rx.
The node runs a simple command parser and is constantly listening to the command rx pipe for instructions. When the user types in a command and addresses that node, the command will be sent directly to that node. Once the node receives the instruction, the command parser will then parse the instruction and arguments and carry out the task.
Probably the toughest part was the radio medium. To simulate a radio medium in the simplest case, when one node transmits, all nodes should ideally be able to hear. I know, I know...it's impossible due to range, fading, etc...but I'm just talking about a simple case. When one node transmits, the data needs to be broadcast to all the nodes. The nodes will then check the address and determine if it should be discarded or sent up the stack. This is how a standard 802.15.4 radio works.
The broadcasting part was difficult because there's not really a good way to do one-to-many interprocess communication on Linux. Some of the candidates were "named pipes", shared memory, and client/server using sockets. However each of them had some drawbacks, mostly in complexity. I experimented a bit with some of them, but after awhile, I decided to take the easy way out. I just keep a list of all the nodes, and when one of them transmits data, it goes to the main shell which then forwards the data to each listening node. Its brute force and crude, but it was the easiest way to broadcast data to all my processes reliably. In the future, I'd like to add some features like transmission range or noise to the radio medium to make it more realistic. But right now, I just want to see how the nodes perform in a network setting.
So that brings me to today. I simulated my first node where I actually brought up all the layers and started a network formation request. Unfortunately, I found a bug immediately so I'm working on the fix now. Actually, it's strange because that same bug should have come up in my old test fixture (the single-process one), but I never saw it before. It's kind of a mystery that bears more investigation, but anyways it's better to catch bugs than let them stay dormant inside the code.