// NewIPTransport creates a transport to provide accessories over IP. // // The IP transports stores the crypto keys inside a database, which // is by default inside a folder at the current working directory. // The folder is named exactly as the accessory name. // // The transports can contain more than one accessory. If this is the // case, the first accessory acts as the HomeKit bridge. // // *Important:* Changing the name of the accessory, or letting multiple // transports store the data inside the same database lead to // unexpected behavior – don't do that. // // The transport is secured with an 8-digit pin, which must be entered // by an iOS client to successfully pair with the accessory. If the // provided transport config does not specify any pin, 00102003 is used. func NewIPTransport(config Config, a *accessory.Accessory, as ...*accessory.Accessory) (Transport, error) { // Find transport name which is visible in mDNS name := a.Info.Name.GetValue() if len(name) == 0 { log.Info.Panic("Invalid empty name for first accessory") } cfg := defaultConfig(name) cfg.merge(config) storage, err := util.NewFileStorage(cfg.StoragePath) if err != nil { return nil, err } database := db.NewDatabaseWithStorage(storage) hap_pin, err := NewPin(cfg.Pin) if err != nil { return nil, err } cfg.load(storage) device, err := hap.NewSecuredDevice(cfg.id, hap_pin, database) t := &ipTransport{ storage: storage, database: database, device: device, config: cfg, container: accessory.NewContainer(), mutex: &sync.Mutex{}, context: hap.NewContextForSecuredDevice(device), emitter: event.NewEmitter(), } t.addAccessory(a) for _, a := range as { t.addAccessory(a) } // Users can only pair discoverable accessories if t.isPaired() { cfg.discoverable = false } cfg.categoryId = int(t.container.AccessoryType()) cfg.updateConfigHash(t.container.ContentHash()) cfg.save(storage) // Listen for events to update mDNS txt records t.emitter.AddListener(t) return t, err }
// NewIPTransport creates a transport to provide accessories over IP. // The pairing is secured using a 8-numbers pin. // If more than one accessory is provided, the first becomes a bridge in HomeKit. // It's fine when the bridge has no explicit services. // // All accessory specific data (crypto keys, ids) is stored in a folder named after the first accessory. // So changing the order of the accessories or renaming the first accessory makes the stored // data inaccessible to the tranport. In this case new crypto keys are created and the accessory // appears as a new one to clients. func NewIPTransport(pin string, pth string, a *accessory.Accessory, as ...*accessory.Accessory) (Transport, error) { // Find transport name which is visible in mDNS name := a.Name() if len(name) == 0 { log.Fatal("Invalid empty name for first accessory") } hapPin, err := NewPin(pin) if err != nil { return nil, err } storage, err := util.NewFileStorage(path.Join(pth, name)) if err != nil { return nil, err } // Find transport uuid which appears as "id" txt record in mDNS and // must be unique and stay the same over time uuid := transportUUIDInStorage(storage) database := db.NewDatabaseWithStorage(storage) device, err := netio.NewSecuredDevice(uuid, hapPin, database) t := &ipTransport{ database: database, name: name, device: device, container: container.NewContainer(), mutex: &sync.Mutex{}, context: netio.NewContextForSecuredDevice(device), emitter: event.NewEmitter(), } t.addAccessory(a) for _, a := range as { t.addAccessory(a) } t.emitter.AddListener(t) return t, err }
// NewIPTransport creates a transport to provide accessories over IP. // // The IP transports stores the crypto keys inside a database, which // is by default inside a folder at the current working directory. // The folder is named exactly as the accessory name. // // The transports can contain more than one accessory. If this is the // case, the first accessory acts as the HomeKit bridge. // // *Important:* Changing the name of the accessory, or letting multiple // transports store the data inside the same database lead to // unexpected behavior – don't do that. // // The transport is secured with an 8-digit pin, which must be entered // by an iOS client to successfully pair with the accessory. If the // provided transport config does not specify any pin, 00102003 is used. func NewIPTransport(config Config, a *accessory.Accessory, as ...*accessory.Accessory) (Transport, error) { // Find transport name which is visible in mDNS name := a.Name() if len(name) == 0 { log.Fatal("Invalid empty name for first accessory") } default_config := Config{ StoragePath: name, Pin: "00102003", Port: "", } if dir := config.StoragePath; len(dir) > 0 { default_config.StoragePath = dir } if pin := config.Pin; len(pin) > 0 { default_config.Pin = pin } if port := config.Port; len(port) > 0 { default_config.Port = ":" + port } storage, err := util.NewFileStorage(default_config.StoragePath) if err != nil { return nil, err } // Find transport uuid which appears as "id" txt record in mDNS and // must be unique and stay the same over time uuid := transportUUIDInStorage(storage) database := db.NewDatabaseWithStorage(storage) hap_pin, err := NewPin(default_config.Pin) if err != nil { return nil, err } device, err := netio.NewSecuredDevice(uuid, hap_pin, database) t := &ipTransport{ database: database, name: name, device: device, config: default_config, container: container.NewContainer(), mutex: &sync.Mutex{}, context: netio.NewContextForSecuredDevice(device), emitter: event.NewEmitter(), } t.addAccessory(a) for _, a := range as { t.addAccessory(a) } t.emitter.AddListener(t) return t, err }