This is a tutorial on how to write small modules which run on the device. Modules are bits of regular 'Arduino' code that can send and receive packets to other nodes/apps/PCs using our mesh.
All modules should be subclasses of MeshModule. By inheriting from this class and creating an instance of your new module your module will be automatically registered to receive packets.
Messages are sent to particular port numbers (similar to UDP networking). Your new module should eventually pick its own port number (see below), but at first you can simply use PRIVATE_APP (which is the default).
- [MeshModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/mesh/MeshModule.h) (in src/mesh/MeshModule.h) - you probably don't want to use this baseclass directly
- [SinglePortModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/mesh/SinglePortModule.h) (in src/mesh/SinglePortModule.h) - for modules that send/receive from a single port number (the normal case)
- [ProtobufModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/mesh/ProtobufModule.h) (in src/mesh/ProtobufModule.h) - for modules that send/receive a single particular Protobuf type. Inherit from this if you are using protocol buffers in your module.
You will typically want to inherit from either SinglePortModule (if you are just sending/receiving raw bytes) or ProtobufModule (if you are sending/receiving protobufs). You'll implement your own handleReceived/handleReceivedProtobuf - probably based on the example code.
A number of [key services](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules) are implemented using the module API, these modules are as follows:
- [TextMessageModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/TextMessageModule.h) - receives text messages and displays them on the LCD screen/stores them in the local DB
- [NodeInfoModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/NodeInfoModule.h) - receives/sends User information to other nodes so that usernames are available in the databases
- [RemoteHardwareModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/RemoteHardwareModule.h) - a module that provides easy remote access to device hardware (for things like turning GPIOs on or off). Intended to be a more extensive example and provide a useful feature of its own.
- [ReplyModule](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/ReplyModule.h) - a simple module that just replies to any packet it receives (provides a 'ping' service).
- Copy [src/modules/ReplyModule.\*](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/ReplyModule.cpp) into src/modules/YourModule.*. Then change the port number from *PortNum_REPLY_APP* to *PortNum_PRIVATE_APP\*.
- Edit moduless/Moduless.cpp:setupModules() to add a call to create an instance of your module (see comment at head of that function)
- Use the [meshtastic commandline tool](https://github.com/meshtastic/Meshtastic-python) to send a packet to your board, for example `meshtastic --dest 1234 --sendping`, where _1234_ is another mesh node to send the ping to.
We use a crude/basic cooperative threading system to allow this on any of our supported platforms. Simply inherit from OSThread and implement runOnce(). See the OSThread [documentation](http://github.com/meshtastic/meshtastic-device/tree/master/src/concurrency/OSThread.h) for more details.
If you would like to proactively send messages (rather than just responding to them), just call service.sendToMesh(). For an example of this see [NodeInfoModule::sendOurNodeInfo(...)](http://github.com/meshtastic/meshtastic-device/tree/master/src/modules/NodeInfoModule.cpp).
For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a unique 'portnum' for their application.
If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to [the master list](https://github.com/meshtastic/Meshtastic-protobufs/blob/master/portnums.proto). PortNums should be assigned in the following range:
- **0-63** Core Meshtastic use; do not use for third party apps
- **64-127** Registered 3rd party apps. Send in a pull request that adds a new entry to portnums.proto to register your application
- Run "bin/regen-protos.sh" to regenerate the C code for accessing the protocol buffers. If you don't have the required nanopb tool, follow the instructions printed by the script to get it.
- Done! You can now use your new protobuf just like any of the existing protobufs in meshtastic.