Ejemplo n.º 1
0
// 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
}
func TestPutCharacteristic(t *testing.T) {
	info := accessory.Info{
		Name:         "My Switch",
		SerialNumber: "001",
		Manufacturer: "Google",
		Model:        "Bridge",
	}

	a := accessory.NewSwitch(info)
	a.Switch.On.SetValue(false)

	m := accessory.NewContainer()
	m.AddAccessory(a.Accessory)

	// find on characteristic with type TypeOn
	var cid int64
	for _, s := range a.Accessory.Services {
		for _, c := range s.Characteristics {
			if c.Type == characteristic.TypeOn {
				cid = c.ID
			}
		}
	}

	if cid == 0 {
		t.Fatal("characteristic not found")
	}

	char := data.Characteristic{AccessoryID: 1, CharacteristicID: cid, Value: true}
	var slice []data.Characteristic
	slice = append(slice, char)

	chars := data.Characteristics{Characteristics: slice}
	b, err := json.Marshal(chars)

	if err != nil {
		t.Fatal(err)
	}

	var buffer bytes.Buffer
	buffer.Write(b)

	controller := NewCharacteristicController(m)
	err = controller.HandleUpdateCharacteristics(&buffer, characteristic.TestConn)

	if err != nil {
		t.Fatal(err)
	}

	if is, want := a.Switch.On.GetValue(), true; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}
Ejemplo n.º 3
0
func TestCharacteristicNotification(t *testing.T) {
	a := accessory.New(info, accessory.TypeOther)
	c := accessory.NewContainer()
	c.AddAccessory(a)

	buffer, err := Body(a, a.Info.Name.Characteristic)
	if err != nil {
		t.Fatal(err)
	}

	bytes, err := ioutil.ReadAll(buffer)

	if err != nil {
		t.Fatal(err)
	}
	if is, want := string(bytes), `{"characteristics":[{"aid":1,"iid":5,"value":"My Bridge"}]}`; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}
func TestGetCharacteristic(t *testing.T) {
	info := accessory.Info{
		Name:         "My Bridge",
		SerialNumber: "001",
		Manufacturer: "Google",
		Model:        "Bridge",
	}

	a := accessory.New(info, accessory.TypeBridge)

	m := accessory.NewContainer()
	m.AddAccessory(a)

	aid := a.GetID()
	cid := a.Info.Name.GetID()
	values := idsString(aid, cid)
	controller := NewCharacteristicController(m)
	res, err := controller.HandleGetCharacteristics(values)

	if err != nil {
		t.Fatal(err)
	}

	b, err := ioutil.ReadAll(res)

	if err != nil {
		t.Fatal(err)
	}

	var chars data.Characteristics
	err = json.Unmarshal(b, &chars)

	if err != nil {
		t.Fatal(err)
	}

	if is, want := len(chars.Characteristics), 1; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
	if x := chars.Characteristics[0].Value; x != "My Bridge" {
		t.Fatal(x)
	}
}