←  APIs and Utilities

ComputerCraft | Programmable Computers for Minecraft

»

RedMesh & HyperCoro - A Mesh Networkin...

Treyzania's Photo Treyzania 18 Feb 2015

RedMesh & HyperCoro


So I was always thinking that "It'd be really easy to make it so that you just relay messages along with some routers!" when talking about the wireless modems in this mod. Nobody ever did it to any major degree, so I did it myself.

RedMesh (v1.0)
This API is a vague analogue to 802.11s, as in it's a set of computers running similar software that relay messages to each other dynamically. It encodes packets in a table structure, serializes it, then sends it over the "redmesh" protocol. Packets are identified by a unique SHA-1 signature, and the message (and protocol) are stored in base64. Its supports routing packets over both wired and wireless connections.

HyperCoro (v1.1)
When working on this I knew that I'd need to have a coroutine running in the background, as I couldn't use the Parallel API. I had some of it working, but after a little research I realized that you couldn't do much in a coroutine without a manager as, due to the way they work, you can't use events (os.pullEvent) directly. This is a supporting API that I created to allow for better use of events in coroutines. This went through a few revisions over the course of development.

Installer (v1.0): pastebin get SLrpfsyz RMI-10

The installed includes the RedMesh core API, the HyperCoro API, a base64 library, a SHA-1 library, as well as the DediRouter utility.

Tutorial - Dedicated Router
Setting up a router is more or less seamless. Get up to a high point (Example tower from reddit a few days ago: http://redd.it/2vvyuu), and place a computer with a wireless modem on it. Run the installer. Then here comes the tricky part... for the startup program, put this code:
shell.run("DediRouter <IDENTITY> -M<SIDE>")

Where "<IDENTITY>" is replaced with the "identity" you want to give your computer, and <SIDE> is the side of the modem. The identity of the computer is probably different than its label. Semantically, you should name it in an "abbreviated namespace tree pattern thing", separated with periods. For example, if I were to have a master router at my home, I would give it it "tz.main". At the lower level of my secondary mine I would have one called "tz.mine2.lower". If New York City had one in its city hall, it would be identified as "us.nyc.hall.main", or something. The side is pretty self-explanatory, and you can specify as many modems as you want. Here's an example of a more practical statement:
shell.run("DediRouter tz.main -Mtop -Mright")

As you might see in the album from the reddit post, there's a display next to the tower. It can display packet transfers. That is specified by using the -D flag. You can only specify one of these. These also support using peripheral cables:
shell.run("DediRouter us.nyc.hall.main -Mtop -Mleft -Dmonitor_4")

And that's all there is to it! It's important to note that you can't run anything else on the computer. I'm working on that. If you try to terminate the program, the computer shuts down. I'm working on that too.

Tutorial - Basic API use
Before doing anything, you must call `redmesh.init`. It begins the background code and allows it to properly work. Here's an example:
os.loadAPI("redmesh")
redmesh.init("tz.mine2.lower")
Other than this, it's pretty similar to the rednet API (`redmesh.send`, `redmesh.broadcast`), however you need to specify the name (from above) of the computer being sent to, instead of the ID. You also must specify a protocol, due to limitations of the API's (ab)use of Lua. As for using `rednet.receive`, it should work. If it doesn't, file a bug report in the replies, posting your code.

Tutorial - Advanced API use
You can register a handler using the `redmesh.registerHandler` function, returning the index in its cache of handlers. This is a little difficult to explain, but it keeps a table of all the handlers, and it calls it every time it decides that the computer should know about a packet passing through it. The handlers are passes a table of the packet's data. You can look at the source code for DediRouter for a better explanation. Here's a modified version of the code that makes the data (body) table for the packet, which is run on the sender of the packet:
local body = {}
local t = os.day() + (os.time() / 24)

body["dest"] = dest -- "*" for broadcasts.
body["sender"] = ident
body["sender_id"] = os.getComputerID() -- Of sender
body["signature"] = msgSig(message, t) -- SHA-1
body["time"] = t
body["type"] = mType -- "p2p" or "broadcast"
body["protocol"] = base64.to_base64(proto)
body["message"] = base64.to_base64(message)

I am not ready to make tutorials on the HyperCoro API, as I do not fully understand how to completely use them. However, you are welcome to view how RedMesh uses it if you are an advanced user and would like to learn.

Limitations...
Due to the fact that this project is not a mature development stage, there are some problems in the code. There are also some problems that arise in some situations.

One of the most major of these is `os.sleep` does not seem to work properly. I have a vague idea of why this is, but I am still trying to figure out why this exactly is happening. This problem is also on anything that uses that function, such as `textutils.slowWrite` and `textutils.slowPrint`.

Pictures
Here's an overhead shot of a concept design tower I built a few days ago for /r/feedthebeast. The computer at the base is another router. This is explained in the album in more detail.
Posted Image
And the rest of the album: http://imgur.com/a/m2OsF

To do
  • Fix the bugs with `os.sleep` and such.
  • Make everything more robust.
  • Override `rednet.send` and `rednet.broadcast`.
  • Make a tutorial for HyperCoro
  • Upload a video tutorial.

If you would like to support this project, go ahead and fork the GitHub project.


Edited by Treyzania, 18 February 2015 - 06:13 PM.
Quote