uiot

package
v0.0.0-...-64a008b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2020 License: GPL-3.0 Imports: 7 Imported by: 0

README

Protocols

u-iot communicates using a number of technologies. This README documents each component and the steps required for bootstrapping and sending commands, both for documentation and implementation in other languages in the future.

Protocol Buffers and gRPC

u-iot's main functionality is in uiot.proto in this directory. Described there are the RPC interfaces and messages that are sent between devices.

Bootstrapping RPCs
  • DevInfo is sent and received on startup, containing a device's IP, port, human-readable meta information, and a set of FuncDefs describing the functions it performs.

  • FuncDef describes a function a device performs. Contains an ID, human-readable name, and a list of ParamDefs, each representing a minimum and maximum value the function expects.

Triggering RPCs
  • TBD
Multicasting

gRPC communication requires knowing a remote device's IP and port number. To get that information, we send UDP multicast packets to a group that all u-iot devices are listening on. Each packet contains the port the device is using for RPC communication, encoded in big-endian.

Bootstrapping Process

When a u-iot program starts, it bootstraps itself with all other u-iot programs on the network. The steps a new program takes are as follows:

local device                           router                    remote device(s)
     |                                   |                              |
     |     send RPC port over UDP to     |  >---->---->---->---->---->  |
  1. |  >---->---->---->---->---->---->  |    forward to all devices    |
     |   multicast addr 239.0.0.0:1024   |  >---->---->---->---->---->  |
     |                                   |                              |
     |                                                                  |
     |         send Bootstrap RPC with remote device information        |
  2. |  <----<----<----<----<----<----<-----<----<----<----<----<----<  |
     |                                                                  |
     |        respond to Bootstrap with local device information        |
  3. |  >---->---->---->---->---->---->----->---->---->---->---->---->  |
     |                                                                  |
  1. All u-iot devices have a UDP server listening on 239.0.0.0:1024. When a new device starts up, it sends the port its gRPC server is using to this address, encoded in 2 network-order (big-endian) bytes. Since this IP is a multicast address, the router copies the sent packet for every other device on the network.

  2. Using the gRPC port and source IP received in step 1, all remote devices send a Bootstrap RPC with their device information to the new device. The new device saves this info to their set of known devices.

  3. The new device responds to the remote RPCs with its own device info, saving it to their sets. All existing devices know about the new device, and the new device knows about all existing devices.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterDeviceServer

func RegisterDeviceServer(s *grpc.Server, srv DeviceServer)

Types

type DevInfo

type DevInfo struct {
	Port                 uint32   `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"`
	Addr                 string   `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
	Meta                 *Meta    `protobuf:"bytes,3,opt,name=meta,proto3" json:"meta,omitempty"`
	Funcs                []*Func  `protobuf:"bytes,4,rep,name=funcs,proto3" json:"funcs,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

DevInfo message are sent when a new device is connecting to the network. Contains a device's identifying information and all of the functions it performs.

func (*DevInfo) Descriptor

func (*DevInfo) Descriptor() ([]byte, []int)

func (*DevInfo) GetAddr

func (m *DevInfo) GetAddr() string

func (*DevInfo) GetFuncs

func (m *DevInfo) GetFuncs() []*Func

func (*DevInfo) GetMeta

func (m *DevInfo) GetMeta() *Meta

func (*DevInfo) GetPort

func (m *DevInfo) GetPort() uint32

func (*DevInfo) ProtoMessage

func (*DevInfo) ProtoMessage()

func (*DevInfo) Reset

func (m *DevInfo) Reset()

func (*DevInfo) String

func (m *DevInfo) String() string

func (*DevInfo) XXX_DiscardUnknown

func (m *DevInfo) XXX_DiscardUnknown()

func (*DevInfo) XXX_Marshal

func (m *DevInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*DevInfo) XXX_Merge

func (m *DevInfo) XXX_Merge(src proto.Message)

func (*DevInfo) XXX_Size

func (m *DevInfo) XXX_Size() int

func (*DevInfo) XXX_Unmarshal

func (m *DevInfo) XXX_Unmarshal(b []byte) error

type DeviceClient

type DeviceClient interface {
	// Send our information to a remote device, and get theirs in return
	Bootstrap(ctx context.Context, in *DevInfo, opts ...grpc.CallOption) (*DevInfo, error)
	// call a function on a remote device
	CallFunc(ctx context.Context, in *FuncCall, opts ...grpc.CallOption) (*FuncRet, error)
	// tell a remote device that we are quitting, and to remove us from their network
	Quit(ctx context.Context, in *DevInfo, opts ...grpc.CallOption) (*Nothing, error)
}

DeviceClient is the client API for Device service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.

func NewDeviceClient

func NewDeviceClient(cc grpc.ClientConnInterface) DeviceClient

type DeviceServer

type DeviceServer interface {
	// Send our information to a remote device, and get theirs in return
	Bootstrap(context.Context, *DevInfo) (*DevInfo, error)
	// call a function on a remote device
	CallFunc(context.Context, *FuncCall) (*FuncRet, error)
	// tell a remote device that we are quitting, and to remove us from their network
	Quit(context.Context, *DevInfo) (*Nothing, error)
}

DeviceServer is the server API for Device service.

type Func

type Func struct {
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Params               []*Param `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

Func messages represent individual functions a device can perform. Contains an ID, human-readable name, and list of parameters.

func (*Func) Descriptor

func (*Func) Descriptor() ([]byte, []int)

func (*Func) GetName

func (m *Func) GetName() string

func (*Func) GetParams

func (m *Func) GetParams() []*Param

func (*Func) ProtoMessage

func (*Func) ProtoMessage()

func (*Func) Reset

func (m *Func) Reset()

func (*Func) String

func (m *Func) String() string

func (*Func) XXX_DiscardUnknown

func (m *Func) XXX_DiscardUnknown()

func (*Func) XXX_Marshal

func (m *Func) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Func) XXX_Merge

func (m *Func) XXX_Merge(src proto.Message)

func (*Func) XXX_Size

func (m *Func) XXX_Size() int

func (*Func) XXX_Unmarshal

func (m *Func) XXX_Unmarshal(b []byte) error

type FuncCall

type FuncCall struct {
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Params               []uint32 `protobuf:"varint,2,rep,packed,name=params,proto3" json:"params,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

FuncCall is used when calling functions on a remote device. Provides the name and parameter values, set by the caller.

func (*FuncCall) Descriptor

func (*FuncCall) Descriptor() ([]byte, []int)

func (*FuncCall) GetName

func (m *FuncCall) GetName() string

func (*FuncCall) GetParams

func (m *FuncCall) GetParams() []uint32

func (*FuncCall) ProtoMessage

func (*FuncCall) ProtoMessage()

func (*FuncCall) Reset

func (m *FuncCall) Reset()

func (*FuncCall) String

func (m *FuncCall) String() string

func (*FuncCall) XXX_DiscardUnknown

func (m *FuncCall) XXX_DiscardUnknown()

func (*FuncCall) XXX_Marshal

func (m *FuncCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*FuncCall) XXX_Merge

func (m *FuncCall) XXX_Merge(src proto.Message)

func (*FuncCall) XXX_Size

func (m *FuncCall) XXX_Size() int

func (*FuncCall) XXX_Unmarshal

func (m *FuncCall) XXX_Unmarshal(b []byte) error

type FuncRet

type FuncRet struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

FuncRet represents function return values. Empty for now, allowing the ability to expand in the future

func (*FuncRet) Descriptor

func (*FuncRet) Descriptor() ([]byte, []int)

func (*FuncRet) ProtoMessage

func (*FuncRet) ProtoMessage()

func (*FuncRet) Reset

func (m *FuncRet) Reset()

func (*FuncRet) String

func (m *FuncRet) String() string

func (*FuncRet) XXX_DiscardUnknown

func (m *FuncRet) XXX_DiscardUnknown()

func (*FuncRet) XXX_Marshal

func (m *FuncRet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*FuncRet) XXX_Merge

func (m *FuncRet) XXX_Merge(src proto.Message)

func (*FuncRet) XXX_Size

func (m *FuncRet) XXX_Size() int

func (*FuncRet) XXX_Unmarshal

func (m *FuncRet) XXX_Unmarshal(b []byte) error

type Meta

type Meta struct {
	Type                 uint32   `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"`
	Room                 uint32   `protobuf:"varint,2,opt,name=room,proto3" json:"room,omitempty"`
	Name                 string   `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

Meta contains human-readable information about a device. Name, type of device, and room it is located in

func (*Meta) Descriptor

func (*Meta) Descriptor() ([]byte, []int)

func (*Meta) GetName

func (m *Meta) GetName() string

func (*Meta) GetRoom

func (m *Meta) GetRoom() uint32

func (*Meta) GetType

func (m *Meta) GetType() uint32

func (*Meta) ProtoMessage

func (*Meta) ProtoMessage()

func (*Meta) Reset

func (m *Meta) Reset()

func (*Meta) String

func (m *Meta) String() string

func (*Meta) XXX_DiscardUnknown

func (m *Meta) XXX_DiscardUnknown()

func (*Meta) XXX_Marshal

func (m *Meta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Meta) XXX_Merge

func (m *Meta) XXX_Merge(src proto.Message)

func (*Meta) XXX_Size

func (m *Meta) XXX_Size() int

func (*Meta) XXX_Unmarshal

func (m *Meta) XXX_Unmarshal(b []byte) error

type Nothing

type Nothing struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

Nothing represents nothing

func (*Nothing) Descriptor

func (*Nothing) Descriptor() ([]byte, []int)

func (*Nothing) ProtoMessage

func (*Nothing) ProtoMessage()

func (*Nothing) Reset

func (m *Nothing) Reset()

func (*Nothing) String

func (m *Nothing) String() string

func (*Nothing) XXX_DiscardUnknown

func (m *Nothing) XXX_DiscardUnknown()

func (*Nothing) XXX_Marshal

func (m *Nothing) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Nothing) XXX_Merge

func (m *Nothing) XXX_Merge(src proto.Message)

func (*Nothing) XXX_Size

func (m *Nothing) XXX_Size() int

func (*Nothing) XXX_Unmarshal

func (m *Nothing) XXX_Unmarshal(b []byte) error

type Param

type Param struct {
	Min                  uint32   `protobuf:"varint,1,opt,name=min,proto3" json:"min,omitempty"`
	Max                  uint32   `protobuf:"varint,2,opt,name=max,proto3" json:"max,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

Param messages represent valid parameters for a given function. Contains mininum and maximum values the parameter can take.

func (*Param) Descriptor

func (*Param) Descriptor() ([]byte, []int)

func (*Param) GetMax

func (m *Param) GetMax() uint32

func (*Param) GetMin

func (m *Param) GetMin() uint32

func (*Param) ProtoMessage

func (*Param) ProtoMessage()

func (*Param) Reset

func (m *Param) Reset()

func (*Param) String

func (m *Param) String() string

func (*Param) XXX_DiscardUnknown

func (m *Param) XXX_DiscardUnknown()

func (*Param) XXX_Marshal

func (m *Param) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Param) XXX_Merge

func (m *Param) XXX_Merge(src proto.Message)

func (*Param) XXX_Size

func (m *Param) XXX_Size() int

func (*Param) XXX_Unmarshal

func (m *Param) XXX_Unmarshal(b []byte) error

type UnimplementedDeviceServer

type UnimplementedDeviceServer struct {
}

UnimplementedDeviceServer can be embedded to have forward compatible implementations.

func (*UnimplementedDeviceServer) Bootstrap

func (*UnimplementedDeviceServer) Bootstrap(ctx context.Context, req *DevInfo) (*DevInfo, error)

func (*UnimplementedDeviceServer) CallFunc

func (*UnimplementedDeviceServer) Quit

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL