Skip to content
Marvin edited this page Aug 13, 2013 · 21 revisions

Network Protocol Specification

This document specifies the network protocol used by our product. The protocol is divided into two parts: UDP multicast for host discovery and TCP unicast for direct communication.

Common characteristics

All communication is based on JSON which is sent in UTF-8. Each JSON object that is sent must have a string value of name type which identifies the message type. Messages which are not JSON objects or which do not have the type field should be discarded.

All Messages have UUID in a field called uuid. This is used for Responses.

Response Messages

If a message needs a positve/negative response the appropriate responses are specified below the message. A message ending on Ack always is a positive response and a message ending on Nak is always a negative one. Ack/Nak messages may contain additional data.

Responses contain an additional field sourceuuid that contains the UUID of the Message they are a response to.

UDP multicast

The UDP multicast used is very simple as it consists of a single message type:

{
    "type": "beacon",
    "uuid": "12345678-9abc-def0-1234-56789abcdef0",
    "addresses":
    [
        {
            "address": "192.168.0.42",
            "port": 5000
        },
        {
            "address": "foo.lan",
            "port": 3621
        }
    ]
}
  • type: The type to use is beacon
  • uuid: The UUID of the module that sent the beacon
  • addresses: An array containing addresses which may be used to contact the module. The address have two properties:
    • address: Either a numerical IPv4 or IPv6 address or a hostname
    • port: The port number

For UDP multicast each message has to be sent in its own datagram packet. These packets may not contain other data. No Responses are sent for multicast messages.

TCP unicast

TCP unicast is used for direct communication between two computers. The message format is the same as for UDP multicast (JSON objects with type field) except that they are now prepended by a length field that is an unsigned integer of 4 bytes sent in most significant byte order. The length field does not include the 4 bytes added by the length field itself.

If a new connection is made, both sides have to send a HelloMessage. Afterwards the module with the lower UUID decides if the connection is kept or closed because it is redundant. The module with the lower UUID either sends a ConnectionEstablishedMessage or ConnectionClosedMessage to inform the other participant whether or not the connection can be used. The moduler with the higher UUID has to respond to a ConnectionEstablishedMessage with another ConnectionEstablishedMessage to fully establish the connection.

For all Messages a Response is sent. This can either be a DefaultResponse or a response specific for the Message. All Messages called Ack or Nak are Responses.

HelloMessage

{
    "type": "hello",
    "uuid": "12345678-9abc-def0-1234-56789abcdef0",
    "framesize": 65536,
}
  • type: The type to use is hello
  • uuid: The UUID of the module sending the message
  • framesize: The maximum size for a message that this module can receive

ConnectionEstablishedMessage

{
    "type": "connection established"
}
  • type: The type to use is connection established

ConnectionClosedMessage

{
    "type": "connection closed"
}
  • type: The type to use is connection closed

JoinApplicationMessage

{
    "type": "join application",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "name": "foo"
}

Informs a module that it should start an ApplicationAgent for the given application.

  • type: The type to use is join application
  • appId: The UUID of the application
  • name: The name of the application

JoinApplicationAck

{
    "type": "join application ack",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "name": "foo"
}

JoinApplicationNak

{
    "type": "join application nak",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "name": "foo"
}

Sent in response to an JoinApplicationMessage. Ack is send on success, nak on failure.

  • type: The type to use is join application ack or join application nak
  • appId: The UUID of the application that this module joined
  • name: The name of the application

BlockMessage

{
    "type": "block",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "scheduleToId": -1,
    "className": "TheNameOfTheClass"
    "block": "<base64 data>"
}

Informs a module that it should execute a given FunctionBlock, once the StartApplication Message arrives.

  • type: The type to use is start block
  • appId: The UUID of the application the block belongs to
  • scheduleToId: which concrete opening on the allowed blocks list to use.
  • className: Class this block is of. Must not be a superclass.
  • block: Base64 encoded (Java-)serialised FunctionBlock

BlockAck

{
    "type": "block ack",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "className": "TheNameOfTheClass"
}
  • type: The type to use is start block
  • appId: The UUID of the application the block belongs to
  • className: Class this block is of. Must not be a superclass.

BlockNak

{
    "type": "block nak",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "className": "TheNameOfTheClass"
}
  • type: The type to use is start block
  • appId: The UUID of the application the block belongs to
  • className: Class this block is of. Must not be a superclass.

StartApplicationMessage

{
    "type": "start application",
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}

Informs an ApplicationAgent that all blocks belonging to the application should be started.

  • type: The type to use is start application
  • appId: The UUID of the application

LoadClassMessage

{
    "type": "load class",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "className": "NameOfClass",
    "classByteCode": "<base64 data>"
}

Sends a class.

  • type: The type to use is load class
  • appId: The UUID of the application that requested the class
  • className: The name of the class being sent
  • classByteCode: Base64 encoded class file

LoadClassAck

{
    "type": "load class ack",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "className": "NameOfClass"
}

Sends a class.

  • type: The type to use is load class ack
  • appId: The UUID of the application that requested the class
  • className: The name of the class that was sent sent

LoadClassNak

{
    "type": "load class nak",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "className": "NameOfClass"
}

Sends a class.

  • type: The type to use is load class nak
  • appId: The UUID of the application that requested the class
  • className: The name of the class that was sent sent

KillAppMessage

{
    "type": "kill",
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}

Informs a module that a given application should be killed.

  • type: The type to use is kill
  • appId: The UUID of the application that should be killed

KillAppNak

{
    "type": "kill nak",
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}
  • type: The type to use is kill nak
  • appId: The UUID of the application that should be killed

KillAppAck

{
    "type": "kill ack",
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}
  • type: The type to use is kill ack
  • appId: The UUID of the application that should be killed

RequestApplicationInfoMessage

{
    "type": "request application info"
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}

Requests an ApplicationInfoMessage with information about an application running on the module.

  • type: The type to use is request application info

ApplicationInfoMessage

{
    "type": "application info"
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "appName": "name of app"
}
  • type: The type to use is application info
  • appId: The Id of the app
  • appName: The name of the app

RequestModuleInfoMessage

{
    "type": "request module info"
}

Requests an ModuleInfoMessage with information about the module receiving this message.

  • type: The type to use is request module info

ModuleInfoMessage

{
    "type": "module info"
    "moduleInformation":
    {
        "uuid": "123-456",
        "name": "NameOfModule",
        "location": "locationOfModule",
        "holder":
        {
            "amount": 9,
            "children":
            [
                {
                    "type": "testblock1",
                    "amount": 3
                },
                {
                    "amount": 7
                    "children":
                    [
                        {
                            "type": "testsubblock1",
                            "amount": 4
                        },
                        {
                            "type": "testsubblock2",
                            "amount": 4
                        },
                    ]
                }
            ]
        }
    }
}
  • type: The type to use is module info
  • allowedblocks: a tree of block types that can be run on this module. Each element consists of:
    • amount: Optional. How many of the given type respectively of the subtypes under this node can be run. If not specified or negative the amount is not limited.
    • One of:
      • type: the type of function block.
      • children: the subtypes of this node. Behavior if a type is listed under multiple parents is undefined.

ValueMessage

{
    "type": "value",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "blockId": "98765678-9abc-def0-1234-56789abcdef0",
    "input": "name",
    "value": "<base64 data>"
}

Informs an ApplicationAgent that it should update an input of a FunctionBlock.

  • type: The type to use is value
  • appId: The UUID of the application
  • blockId: The UUID of the FunctionBlock
  • input: The name of the input that should be updated
  • value: The new value as a Base64 encoded (Java-)serialized object

ValueAck

{
    "type": "value ack",
    "appId": "12345678-9abc-def0-1234-56789abcdef0"
}
  • type: The type to use is value ack
  • appId: The UUID of the application

ValueNak

{
    "type": "value nak",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "blockId": "98765678-9abc-def0-1234-56789abcdef0",
    "input": "name",
    "errorType": "OTHER",

}
  • type: The type to use is value nak
  • appId: The UUID of the application
  • blockId: BlockId field from the valueMessage
  • input: input field from the valueMessage
  • errorType: Reason for failure. One of "WRONG_MODULE", "INVALID_INPUT" & "OTHER"

WhoHasBlockMessage

{
    "type": "who has block",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "blockId": "98765678-9abc-def0-1234-56789abcdef0",
}

Requests the moduleID, which currently executes the given blockID. See BlockFoundMessage.

  • type: The type to use is who has block
  • appId: The UUID of the application
  • blockId: The UUID of the Block being searched for

BlockFoundMessage

{
    "type": "block found",
    "appId": "12345678-9abc-def0-1234-56789abcdef0",
    "blockId": "98765678-9abc-def0-1234-56789abcdef0",
    "moduleId": "29999999-9abc-def0-1234-56789abcdef0"
}

Specifies that the given module currently executes the given block.

  • type: The type to use is block found
  • appId: The UUID of the application
  • blockId: The UUID of the FunctionBlock being searched for
  • moduleId: The UUID of the Module executing said blockId