Code Monkey home page Code Monkey logo

gomat's Introduction

gomat

Simple matter protocol library

Go Reference go build Go Report Card

goal of project

The goal is to create golang library and supporting tools to access matter devices.

status of project

  • it can
    • commission devices
    • send commands to devices
    • read attributes from devices
    • subscribe and receive events
    • decode onboarding info (qr text, manual pair code)
    • discover commissionable devices
    • discover commissioned devices
    • open commissioning window

tested devices

general info

  • it is best to understand matter to use this, but here is most important info:
    • device access is managed using certificates
    • easiest way how to talk to device is to have signed certificate of device admin user (alternative is setup ACLs and use non-admin user)
    • certificates are signed by CA
    • during commissioning procedure root CA certificate is pushed to device together with id of device admin user
    • root CA certificate is something you need to create once and store. loosing CA keys usually means that you will have to commission devices again
    • to talk to device you have to commission it first
      • to commission device you usually need its pin/passcode and device be in state open for commisioning
      • device gets into commisioning window open state often by "factory reset"
      • when device is commissioned - connected to some fabric, it can be commissionined into other fabrics using api, where existing admin user sets device to be open for additional commissioning. During that device can be connected to additional fabric(s) - additional root CA installed and additional admin user configured

how to use test application

  • compile
git clone [email protected]:tom-code/gomat.git
cd gomat
go build -o gomat demo/main.go 
  • create directory to hold keys and certificates mkdir pem
  • generate CA key and certificate using ./gomat ca-bootstrap
  • generate controller key and certificate using ./gomat ca-createuser 100
    • 100 is example node-id of controller
  • find device IP
    • discover command can be used to discover matter devices and their ip address ./gomat discover commissionable -d
  • find device commissioning passcode/pin
    • device may show it
    • it can be extracted from QR code. use decode-qr to extract passcode from text representation of QR code ./gomat decode-qr MT:-24J0AFN00SIQ663000
    • it can be extracted from manual pairing code. use command decode-mc to extract passcode from manual pairing code ./gomat decode-mc 35792000079
  • perform commissioning of device. This authenticates using passcode, uploads CA certificate to device, signs and uploads device's own certificate and sets admin user id.
    • required for commisioning:
      • ip address of device
      • device commissioning passcode/pin
      • ca key and certificate
      • controller node key and certificate
    • example: ./gomat commission --ip 192.168.5.178 --pin 123456 --controller-id 100 --device-id 500
  • light on! ./gomat cmd on --ip 192.168.5.178 --controller-id 100 --device-id 500
  • set color hue=150 saturation=200 transition_time=10 ./gomat cmd color --ip 192.168.5.220 --controller-id 100 --device-id 500 150 200 10

how to use api

Example applications

commission device using api

create ca with root certificate, create admin user, then commission device:

package main

import (
  "net"

  "github.com/tom-code/gomat"
)


func main() {
  var fabric_id uint64 = 0x100
  var admin_user uint64 = 5
  var device_id uint64 = 10
  device_ip := "192.168.5.178"
  pin := 123456

  cm := gomat.NewFileCertManager(fabric_id)
  cm.BootstrapCa()
  cm.Load()
  cm.CreateUser(admin_user)
  fabric := gomat.NewFabric(fabric_id, cm)
  gomat.Commission(fabric, net.ParseIP(device_ip), pin, admin_user, device_id)
}

send ON command to commissioned device using api

package main

import (
  "net"

  "github.com/tom-code/gomat"
)


func main() {
  var fabric_id uint64 = 0x100
  var admin_user uint64 = 5
  var device_id uint64 = 10
  device_ip := "192.168.5.178"

  cm := gomat.NewFileCertManager(fabric_id)
  cm.Load()
  fabric := gomat.NewFabric(fabric_id, cm)

  secure_channel, err := gomat.StartSecureChannel(net.ParseIP(device_ip), 5540, 55555)
  if err != nil {
    panic(err)
  }
  defer secure_channel.Close()
  secure_channel, err = gomat.SigmaExchange(fabric, admin_user, device_id, secure_channel)
  if err != nil {
    panic(err)
  }

  on_command := gomat.EncodeInvokeCommand(1,        // endpoint
                                          6,        // api cluster (on/off)
                                          1,        // on command
                                          []byte{}, // no extra data
                                          )
  secure_channel.Send(on_command)
  resp, err := secure_channel.Receive()
  if err != nil {
    panic(err)
  }
  resp.Tlv.Dump(0)
}

discover IP address of previously commissioned device using api

Device exposes its info using mdns under identifier [compressed-fabric-id]-[device-id]. For this reason to discover commissioned device fabric info is required.

package main

import (
  "encoding/hex"
  "fmt"
  "strings"

  "github.com/tom-code/gomat"
  "github.com/tom-code/gomat/discover"
)



func main() {
  var fabric_id uint64 = 0x100
  var device_id uint64 = 10


  cm := gomat.NewFileCertManager(fabric_id)
  cm.Load()
  fabric := gomat.NewFabric(fabric_id, cm)

  identifier := fmt.Sprintf("%s-%016X", hex.EncodeToString(fabric.CompressedFabric()), device_id)
  identifier = strings.ToUpper(identifier)
  identifier = identifier + "._matter._tcp.local."
  fmt.Printf("%s\n", identifier)
  devices := discover.DiscoverComissioned("", true, identifier)
  for _, d := range devices {
    fmt.Printf("host:%s ip:%v\n", d.Host, d.Addrs)
  }
}

extract pairing passcode from QR code and manual pairing code

Following example shows how to extract passcode from textual representation of QR code or from manual pairing code. Manual pairing code can have dash characters at any position(they are discarded)

package main

import (
	"fmt"

	"github.com/tom-code/gomat/onboarding_payload"
)


func main() {
	setup_qr_code := "MT:-24J0AFN00SIQ663000"
	qr_decoded := onboarding_payload.DecodeQrText(setup_qr_code)
	fmt.Printf("passcode: %d\n", qr_decoded.Passcode)


	manual_pair_code := "357-920-000-79"
	code_decoded := onboarding_payload.DecodeManualPairingCode(manual_pair_code)
	fmt.Printf("passcode: %d\n", code_decoded.Passcode)
}

Set color of light to specific hue color

package main

import (
	"fmt"
	"net"

	"github.com/tom-code/gomat"
	"github.com/tom-code/gomat/mattertlv"
)


func main() {
	var fabric_id uint64 = 0x100
	var admin_user uint64 = 5
	var device_id uint64 = 10
	device_ip := "192.168.5.178"

	cm := gomat.NewFileCertManager(fabric_id)
	cm.Load()
	fabric := gomat.NewFabric(fabric_id, cm)


	secure_channel, err := gomat.StartSecureChannel(net.ParseIP(device_ip), 5540, 55555)
	if err != nil {
		panic(err)
	}
	defer secure_channel.Close()
	secure_channel, err = gomat.SigmaExchange(fabric, admin_user, device_id, secure_channel)
	if err != nil {
		panic(err)
	}

	var tlv mattertlv.TLVBuffer
	tlv.WriteUInt8(0, byte(hue))        // hue
	tlv.WriteUInt8(1, byte(saturation)) // saturation
	tlv.WriteUInt8(2, byte(time))       // time
	to_send := gomat.EncodeInvokeCommand(1, 0x300, 6, tlv.Bytes())
	secure_channel.Send(to_send)

	resp, err := secure_channel.Receive()
	if err != nil {
		panic(err)
	}
	status, err := resp.Tlv.GetIntRec([]int{1,0,1,1,0})
	if err != nil {
		panic(err)
	}
	fmt.Printf("result status: %d\n", status)
}

certificate manager

NewFabric function accepts certificate manager object as input parameter. Certificate manager must implement interface CertificateManager and user can supply own implementation. Supplied CertManager created by NewFileCertManager is very simple and stores all data in .pem files under pem directory.

notes

consider move to https://pkg.go.dev/filippo.io/nistec

gomat's People

Contributors

tom-code avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

ihidchaos

gomat's Issues

Reuse of secure channel for multiple commands?

Hi,

Thanks for putting this library together.

Have noticed that the SigmaExchange appears to take 1.5 seconds for the device I'm using - mainly spent waiting on UDP response.

Is it possible to re-use the secure channel so that the overhead of the SigmaExchange can be paid once?

Calling Send on it multiple times doesn't appear to work at the moment.

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.