hap

package
v0.1.0-fern-001 Latest Latest
Warning

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

Go to latest
Published: Nov 25, 2018 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package hap implements the HomeKit Accessory Protocol to pair and securily communicate with a HomeKit client. The server send data over tcp to clients (iOS devices) based on a http-like protocol.

Pairing: A client has to know the secret pin to pair with the server. After that the encryption keys are negotiated and stored on the server and client side.

Session: Before data is exchanged a new pair of keys is generated. The previously negoiated keys are verified before the new keys are generated.

Index

Constants

View Source
const (
	// MethodGET is the HTTP Get method
	MethodGET = "GET"

	// MethodPOST is the HTTP Post method
	MethodPOST = "POST"

	// MethodPUT is the HTTP Put method
	MethodPUT = "PUT"

	// MethodDEL is the HTTP Delete method
	MethodDEL = "DEL"
)
View Source
const (
	StatusSuccess                     = 0
	StatusInsufficientPrivileges      = -70401
	StatusServiceCommunicationFailure = -70402
	StatusResourceBusy                = -70403
	StatusReadOnlyCharacteristic      = -70404
	StatusWriteOnlyCharacteristic     = -70405
	StatusNotificationNotSupported    = -70406
	StatusOutOfResource               = -70407
	StatusOperationTimedOut           = -70408
	StatusResourceDoesNotExist        = -70409
	StatusInvalidValueInRequest       = -70410
)
View Source
const (
	// HTTPContentTypePairingTLV8 is the HTTP content type for pairing
	HTTPContentTypePairingTLV8 = "application/pairing+tlv8"

	// HTTPContentTypeHAPJson is the HTTP content type for json data
	HTTPContentTypeHAPJson = "application/hap+json"
)

Variables

This section is empty.

Functions

func Body

Body returns the json body for an notification response as bytes.

func FixProtocolSpecifier

func FixProtocolSpecifier(b []byte) []byte

FixProtocolSpecifier returns bytes where the http protocol specifier "HTTP/1.0" is replaced by "EVENT/1.0" in the argument bytes. This fix is necessary because http.Response ignores the Proto field value.

Related to issue: https://github.com/golang/go/issues/9304

func NewCharacteristicNotification

func NewCharacteristicNotification(a *accessory.Accessory, c *characteristic.Characteristic) (*http.Response, error)

NewCharacteristicNotification returns an notification response for a characteristic from an accessory.

func NewChunkedWriter

func NewChunkedWriter(wr io.Writer, chunk int) io.Writer

NewChunkedWriter returns a writer which writes bytes in chunkes of specified size.

func NewNotification

func NewNotification(body *bytes.Buffer) *http.Response

NewNotification returns a notification response with a specific body content.

Types

type AccessoriesHandler

type AccessoriesHandler interface {
	HandleGetAccessories(r io.Reader) (io.Reader, error)
}

A AccessoriesHandler returns a list of accessories as json.

type CharacteristicsHandler

type CharacteristicsHandler interface {
	HandleGetCharacteristics(url.Values, net.Conn) (io.Reader, error)
	HandleUpdateCharacteristics(io.Reader, net.Conn) error
}

A CharacteristicsHandler handles get and update characteristic.

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection is a connection based on HAP protocol which encrypts and decrypts the data.

For every connection, a new session is created in the context. The session uses the Cryptographer to encrypt and decrypt data. The Cryptographer is created by one of the endpoint handlers after pairing has been verified. After that the communication is encrypted.

When the connection is closed, the related session is removed from the context.

func NewConnection

func NewConnection(connection net.Conn, context Context) *Connection

NewConnection returns a hap connection.

func (*Connection) Close

func (con *Connection) Close() error

Close closes the connection and deletes the related session from the context.

func (*Connection) DecryptedRead

func (con *Connection) DecryptedRead(b []byte) (int, error)

DecryptedRead reads and decrypts bytes from the connection. The method returns the number of read bytes and an error when reading failed.

func (*Connection) EncryptedWrite

func (con *Connection) EncryptedWrite(b []byte) (int, error)

EncryptedWrite encrypts and writes bytes to the connection. The method returns the number of written bytes and an error when writing failed.

func (*Connection) LocalAddr

func (con *Connection) LocalAddr() net.Addr

LocalAddr calls LocalAddr() of the underlying connection

func (*Connection) Read

func (con *Connection) Read(b []byte) (int, error)

Read reads bytes from the connection. The read bytes are decrypted when possible.

func (*Connection) RemoteAddr

func (con *Connection) RemoteAddr() net.Addr

RemoteAddr calls RemoteAddr() of the underlying connection

func (*Connection) SetDeadline

func (con *Connection) SetDeadline(t time.Time) error

SetDeadline calls SetDeadline() of the underlying connection

func (*Connection) SetReadDeadline

func (con *Connection) SetReadDeadline(t time.Time) error

SetReadDeadline calls SetReadDeadline() of the underlying connection

func (*Connection) SetWriteDeadline

func (con *Connection) SetWriteDeadline(t time.Time) error

SetWriteDeadline calls SetWriteDeadline() of the underlying connection

func (*Connection) Write

func (con *Connection) Write(b []byte) (int, error)

Write writes bytes to the connection. The written bytes are encrypted when possible.

type ContainerHandler

type ContainerHandler interface {
	Handle(util.Container) (util.Container, error)
}

A ContainerHandler abstracts request/response communication

type Context

type Context interface {
	Store

	// Returns a key to uniquely identify the connection
	GetKey(c net.Conn) interface{}

	// Returns the same key as for the underlying connection
	GetConnectionKey(r *http.Request) interface{}

	// Setter and getter for session
	SetSessionForConnection(s Session, c net.Conn)
	GetSessionForConnection(c net.Conn) Session
	GetSessionForRequest(r *http.Request) Session
	DeleteSessionForConnection(c net.Conn)

	// Returns a list of active connections
	ActiveConnections() []net.Conn

	// Setter and getter for bridge
	SetSecuredDevice(b SecuredDevice)
	GetSecuredDevice() SecuredDevice
}

Context holds objects which are shared between the different parts of the system.

func NewContextForSecuredDevice

func NewContextForSecuredDevice(b SecuredDevice) Context

NewContextForSecuredDevice returns a new Context

type Device

type Device interface {
	// Name returns the username used for pairing
	Name() string

	// PrivateKey returns the client private key used for pairing
	PrivateKey() []byte

	// PublicKey returns the client public key used for pairing
	PublicKey() []byte
}

Device is a HomeKit device with a name, private and public key.

func NewDevice

func NewDevice(name string, database db.Database) (Device, error)

NewDevice returns a client for a specific name either loaded from the database or newly created.

type IdentifyHandler

type IdentifyHandler interface {
	IdentifyAccessory()
}

IdentifyHandler calls Identify() on accessories.

type KeepAlive

type KeepAlive struct {
	// contains filtered or unexported fields
}

KeepAlive encapsulates sending notifications with no content to all connected clients. This way we can find abandoned connections and close them. Thise is also done in homebridge: https://github.com/KhaosT/HAP-NodeJS/blob/c3a8f989685b62515968278c81b86b744b968960/lib/HAPServer.js#L107

func NewKeepAlive

func NewKeepAlive(timeout time.Duration, context Context) *KeepAlive

NewKeepAlive returns a new keep alive for a specific timeout.

func (*KeepAlive) Start

func (k *KeepAlive) Start(ctx gocontext.Context)

Start starts sending keep alive messages. This method blocks until the context is canceled.

type PairVerifyHandler

type PairVerifyHandler interface {
	ContainerHandler
	SharedKey() [32]byte
}

A PairVerifyHandler is a ContainerHandler which negotations a shared key.

type SecuredDevice

type SecuredDevice interface {
	Device
	Pin() string
}

SecuredDevice is a HomeKit device with a pin.

func NewSecuredDevice

func NewSecuredDevice(name string, pin string, database db.Database) (SecuredDevice, error)

NewSecuredDevice returns a device for a specific name either loaded from the database or newly created. Additionally other device can only pair with by providing the correct pin.

type Session

type Session interface {
	// Decrypter returns decrypter for incoming data, may be nil
	Decrypter() crypto.Decrypter

	// Encrypter returns encrypter for outgoing data, may be nil
	Encrypter() crypto.Encrypter

	// SetCryptographer sets the new cryptographer used for en-/decryption
	SetCryptographer(c crypto.Cryptographer)

	// PairSetupHandler returns the pairing setup handler
	PairSetupHandler() ContainerHandler

	// SetPairSetupHandler sets the handler for pairing setup
	SetPairSetupHandler(c ContainerHandler)

	// PairVerifyHandler returns the pairing verify handler
	PairVerifyHandler() PairVerifyHandler

	// SetPairVerifyHandler sets the handler for pairing verify
	SetPairVerifyHandler(c PairVerifyHandler)

	// Connection returns the associated connection
	Connection() net.Conn
}

Session contains objects (encrypter, decrypter, pairing handler,...) used to handle the data communication.

func NewSession

func NewSession(connection net.Conn) Session

NewSession returns a session for a connection.

type Store

type Store interface {
	Set(key, val interface{})
	Get(key interface{}) interface{}
	Delete(key interface{})
}

Store provides a key-value in-memory storage.

type TCPListener

type TCPListener struct {
	*net.TCPListener
	// contains filtered or unexported fields
}

TCPListener listens for new connection and creates Connections for new connections

func NewTCPListener

func NewTCPListener(l *net.TCPListener, context Context) *TCPListener

NewTCPListener returns a new hap tcp listener.

func (*TCPListener) Accept

func (l *TCPListener) Accept() (c net.Conn, err error)

Accept creates and returns a Connection.

Directories

Path Synopsis
Package controller implements the handler interfaces to access the model.
Package controller implements the handler interfaces to access the model.
Package data provides structs to map json to objects.
Package data provides structs to map json to objects.
Package endpoint implements the HAP endpoints.
Package endpoint implements the HAP endpoints.
Package http implements a http-like hap server to handle requests and responses.
Package http implements a http-like hap server to handle requests and responses.
Package pair implements the pairing and verification protocol.
Package pair implements the pairing and verification protocol.

Jump to

Keyboard shortcuts

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