hap

package
v0.0.0-...-c3ad350 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2024 License: MIT Imports: 25 Imported by: 0

README

Home Accessory Protocol

PS. Character = Characteristic

Device - HomeKit end device (swith, camera, etc)

  • mDNS name: MyCamera._hap._tcp.local.
  • DeviceID - mac-like: 0E:AA:CE:2B:35:71
  • HomeKit device is described by:
    • one or more Accessories - has AID and Services
    • Services - has IID, Type and Characters
    • Characters - has IID, Type, Format and Value

Client - HomeKit client (iPhone, iPad, MacBook or opensource library)

  • ClientID - static random UUID
  • ClientPublic/ClientPrivate - static random 32 byte keypair
  • can pair with Device (exchange ClientID/ClientPublic, ServerID/ServerPublic using Pin)
  • can auth to Device using ClientPrivate
  • holding persistant Secure connection to device
  • can read device Accessories
  • can read and write device Characters
  • can subscribe on device Characters change (Event)

Server - HomeKit server (soft on end device or opensource library)

  • ServerID - same as DeviceID (using for Client auth)
  • ServerPublic/ServerPrivate - static random 32 byte keypair

AAC ELD

Requires ffmpeg built with --enable-libfdk-aac

-acodec libfdk_aac -aprofile aac_eld 
SampleRate RTPTime constantDuration objectType
8000 60 =8000/1000*60=480 39 (AAC ELD)
16000 30 =16000/1000*30=480 39 (AAC ELD)
24000 20 =24000/1000*20=480 39 (AAC ELD)
16000 60 =16000/1000*60=960 23 (AAC LD)
24000 40 =24000/1000*40=960 23 (AAC LD)

Documentation

Index

Constants

View Source
const (
	FormatString = "string"
	FormatBool   = "bool"
	FormatFloat  = "float"
	FormatUInt8  = "uint8"
	FormatUInt16 = "uint16"
	FormatUInt32 = "uint32"
	FormatInt32  = "int32"
	FormatUInt64 = "uint64"
	FormatData   = "data"
	FormatTLV8   = "tlv8"

	UnitPercentage = "percentage"
)
View Source
const (
	ConnDialTimeout = time.Second * 3
	ConnDeadline    = time.Second * 3
)
View Source
const (
	MimeTLV8 = "application/pairing+tlv8"
	MimeJSON = "application/hap+json"

	PathPairSetup       = "/pair-setup"
	PathPairVerify      = "/pair-verify"
	PathPairings        = "/pairings"
	PathAccessories     = "/accessories"
	PathCharacteristics = "/characteristics"
	PathResource        = "/resource"
)
View Source
const (
	TXTConfigNumber = "c#" // Current configuration number (ex. 1, 2, 3)
	TXTDeviceID     = "id" // Device ID of the accessory (ex. 77:75:87:A0:7D:F4)
	TXTModel        = "md" // Model name of the accessory (ex. MJCTD02YL)
	TXTProtoVersion = "pv" // Protocol version string (ex. 1.1)
	TXTStateNumber  = "s#" // Current state number (ex. 1)
	TXTCategory     = "ci" // Accessory Category Identifier (ex. 2, 5, 17)
	TXTSetupHash    = "sh" // Setup hash (ex. Y9w9hQ==)

	// TXTFeatureFlags
	//  - 0001b - Supports Apple Authentication Coprocessor
	//  - 0010b - Supports Software Authentication
	TXTFeatureFlags = "ff" // Pairing Feature flags (ex. 0, 1, 2)

	// TXTStatusFlags
	//  - 0001b - Accessory has not been paired with any controllers
	//  - 0100b - A problem has been detected on the accessory
	TXTStatusFlags = "sf" // Status flags (ex. 0, 1)

	StatusPaired    = "0"
	StatusNotPaired = "1"

	CategoryBridge   = "2"
	CategoryCamera   = "17"
	CategoryDoorbell = "18"

	StateM1 = 1
	StateM2 = 2
	StateM3 = 3
	StateM4 = 4
	StateM5 = 5
	StateM6 = 6

	MethodPair          = 0
	MethodPairMFi       = 1 // if device has MFI cert
	MethodVerifyPair    = 2
	MethodAddPairing    = 3
	MethodDeletePairing = 4
	MethodListPairings  = 5

	PermissionUser  = 0
	PermissionAdmin = 1
)
View Source
const (
	PairMethodSetup = iota
	PairMethodSetupWithAuth
	PairMethodVerify
	PairMethodAdd
	PairMethodRemove
	PairMethodList
)
View Source
const DeviceAID = 1 // TODO: fix someday
View Source
const ProtoEvent = "EVENT/1.0"

Variables

View Source
var EVPR = []string{"ev", "pr"}
View Source
var EVPRPW = []string{"ev", "pr", "pw"}
View Source
var PR = []string{"pr"}
View Source
var PRPW = []string{"pr", "pw"}
View Source
var PW = []string{"pw"}

Functions

func Append

func Append(items ...any) (b []byte)

func DecodeKey

func DecodeKey(s string) []byte

func GenerateKey

func GenerateKey() []byte

func GenerateUUID

func GenerateUUID() string

func ReadResponse

func ReadResponse(r *bufio.Reader, req *http.Request) (*http.Response, error)

func SanitizePin

func SanitizePin(pin string) (string, error)

func Unpair

func Unpair(rawURL string) error

func WriteResponse

func WriteResponse(w *bufio.Writer, statusCode int, contentType string, body []byte) error

Types

type Accessory

type Accessory struct {
	AID      uint8      `json:"aid"` // 150 unique accessories per bridge
	Services []*Service `json:"services"`
}

func (*Accessory) GetCharacter

func (a *Accessory) GetCharacter(charType string) *Character

func (*Accessory) GetCharacterByID

func (a *Accessory) GetCharacterByID(iid uint64) *Character

func (*Accessory) GetService

func (a *Accessory) GetService(servType string) *Service

func (*Accessory) InitIID

func (a *Accessory) InitIID()

type Character

type Character struct {
	Desc string `json:"description,omitempty"`

	IID    uint64   `json:"iid"`
	Type   string   `json:"type"`
	Format string   `json:"format"`
	Value  any      `json:"value,omitempty"`
	Perms  []string `json:"perms"`
	// contains filtered or unexported fields
}

Character - Aqara props order Value should be omit for PW Value may be empty for PR

func (*Character) AddListener

func (c *Character) AddListener(w io.Writer)

func (*Character) GenerateEvent

func (c *Character) GenerateEvent() (data []byte, err error)

GenerateEvent with raw HTTP headers

func (*Character) NotifyListeners

func (c *Character) NotifyListeners(ignore io.Writer) error

func (*Character) ReadBool

func (c *Character) ReadBool() bool

func (*Character) ReadTLV8

func (c *Character) ReadTLV8(v any) (err error)

ReadTLV8 value to right struct

func (*Character) RemoveListener

func (c *Character) RemoveListener(w io.Writer)

func (*Character) Set

func (c *Character) Set(v any) (err error)

Set new value and NotifyListeners

func (*Character) String

func (c *Character) String() string

func (*Character) Write

func (c *Character) Write(v any) (err error)

Write new value with right format

type Client

type Client struct {
	DeviceAddress string // including port
	DeviceID      string // aka. Accessory
	DevicePublic  []byte
	ClientID      string // aka. Controller
	ClientPrivate []byte

	OnEvent func(res *http.Response)

	Conn net.Conn
	// contains filtered or unexported fields
}

Client for HomeKit. DevicePublic can be null.

func NewClient

func NewClient(rawURL string) (*Client, error)

func Pair

func Pair(rawURL string) (*Client, error)

Pair homekit

func (*Client) ClientPublic

func (c *Client) ClientPublic() []byte

func (*Client) Close

func (c *Client) Close() error

func (*Client) DeletePairing

func (c *Client) DeletePairing(id string) error

func (*Client) DeviceHost

func (c *Client) DeviceHost() string

func (*Client) Dial

func (c *Client) Dial() (err error)

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) Get

func (c *Client) Get(path string) (*http.Response, error)

func (*Client) GetAccessories

func (c *Client) GetAccessories() ([]*Accessory, error)

func (*Client) GetCharacter

func (c *Client) GetCharacter(char *Character) error

func (*Client) GetCharacters

func (c *Client) GetCharacters(query string) ([]JSONCharacter, error)

func (*Client) GetFirstAccessory

func (c *Client) GetFirstAccessory() (*Accessory, error)

func (*Client) GetImage

func (c *Client) GetImage(width, height int) ([]byte, error)

func (*Client) ListPairings

func (c *Client) ListPairings() error

func (*Client) LocalIP

func (c *Client) LocalIP() string

func (*Client) Pair

func (c *Client) Pair(feature, pin string) (err error)

func (*Client) PairingsAdd

func (c *Client) PairingsAdd(clientID string, clientPublic []byte, admin bool) error

func (*Client) Post

func (c *Client) Post(path, contentType string, body io.Reader) (*http.Response, error)

func (*Client) Put

func (c *Client) Put(path, contentType string, body io.Reader) (*http.Response, error)

func (*Client) PutCharacters

func (c *Client) PutCharacters(characters ...*Character) error

func (*Client) Request

func (c *Client) Request(method, path, contentType string, body io.Reader) (*http.Response, error)

func (*Client) URL

func (c *Client) URL() string

type HandlerFunc

type HandlerFunc func(net.Conn) error

type JSONAccessories

type JSONAccessories struct {
	Value []*Accessory `json:"accessories"`
}

type JSONCharacter

type JSONCharacter struct {
	AID   uint8  `json:"aid"`
	IID   uint64 `json:"iid"`
	Value any    `json:"value,omitempty"`
	Event any    `json:"ev,omitempty"`
}

type JSONCharacters

type JSONCharacters struct {
	Value []JSONCharacter `json:"characteristics"`
}

type Server

type Server struct {
	Pin           string
	DeviceID      string
	DevicePrivate []byte

	GetPair func(conn net.Conn, id string) []byte
	AddPair func(conn net.Conn, id string, public []byte, permissions byte)

	Handler HandlerFunc
}

func (*Server) PairSetup

func (s *Server) PairSetup(req *http.Request, rw *bufio.ReadWriter, conn net.Conn) error

func (*Server) PairVerify

func (s *Server) PairVerify(req *http.Request, rw *bufio.ReadWriter, conn net.Conn) error

func (*Server) ServerPublic

func (s *Server) ServerPublic() []byte

func (*Server) SetupHash

func (s *Server) SetupHash() string

type Service

type Service struct {
	Desc string `json:"description,omitempty"`

	Type       string       `json:"type"`
	IID        uint64       `json:"iid"`
	Primary    bool         `json:"primary,omitempty"`
	Characters []*Character `json:"characteristics"`
	Linked     []int        `json:"linked,omitempty"`
}

func ServiceAccessoryInformation

func ServiceAccessoryInformation(manuf, model, name, serial, firmware string) *Service

func ServiceHAPProtocolInformation

func ServiceHAPProtocolInformation() *Service

func (*Service) GetCharacter

func (s *Service) GetCharacter(charType string) *Character

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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