Ejemplo n.º 1
0
 async def _load_neighbors(self) -> None:
     async with self.execute(f"SELECT * FROM neighbors{DB_V}") as cursor:
         async for ieee, *fields in cursor:
             dev = self._application.get_device(ieee)
             neighbor = zdo_t.Neighbor(*fields)
             assert neighbor.is_valid
             dev.neighbors.add_neighbor(neighbor)
Ejemplo n.º 2
0
    async def _migrate_to_v4(self):
        """Schema v4 expanded the node descriptor and neighbor table columns"""
        # The `node_descriptors` table was added in v1
        if await self._table_exists("node_descriptors"):
            async with self.execute("SELECT * FROM node_descriptors") as cur:
                async for dev_ieee, value in cur:
                    node_desc, rest = zdo_t.NodeDescriptor.deserialize(value)
                    assert not rest

                    await self.execute(
                        "INSERT INTO node_descriptors_v4"
                        " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
                        (dev_ieee,) + node_desc.as_tuple(),
                    )

        # The `neighbors` table was added in v3 but the version number was not
        # incremented. It may not exist.
        if await self._table_exists("neighbors"):
            async with self.execute("SELECT * FROM neighbors") as cur:
                async for dev_ieee, epid, ieee, nwk, packed, prm, depth, lqi in cur:
                    neighbor = zdo_t.Neighbor(
                        extended_pan_id=epid,
                        ieee=ieee,
                        nwk=nwk,
                        permit_joining=prm,
                        depth=depth,
                        lqi=lqi,
                        reserved2=0b000000,
                        **zdo_t.Neighbor._parse_packed(packed),
                    )

                    await self.execute(
                        "INSERT INTO neighbors_v4 VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",
                        (dev_ieee,) + neighbor.as_tuple(),
                    )
Ejemplo n.º 3
0
def test_neighbor(device):
    """Test neighbor struct."""

    nei = zigpy.neighbor.Neighbor(
        zdo_t.Neighbor(device.ieee, device.ieee, 1, 2, 3, 4, 5), device)
    assert nei.device is device
    assert nei.neighbor.ieee == device.ieee
Ejemplo n.º 4
0
 async def _load_neighbors(self) -> None:
     async with self.execute("SELECT * FROM neighbors") as cursor:
         async for (dev_ieee, epid, ieee, nwk, packed, prm, depth,
                    lqi) in cursor:
             dev = self._application.get_device(dev_ieee)
             nei = zdo_t.Neighbor(epid, ieee, nwk, packed, prm, depth, lqi)
             dev.neighbors.add_neighbor(nei)
Ejemplo n.º 5
0
def test_neighbor_struct_relationship():
    """Test neighbor packed struct relationship."""

    for relationship in range(0, 7):
        struct = types.Neighbor()
        assert struct.relationship is None
        struct.relationship = relationship
        assert struct.relationship == relationship

    for i in range(0, 127):
        struct = types.Neighbor(packed=i)
        orig_dev_type = struct.device_type
        orig_rx = struct.rx_on_when_idle
        for relationship in range(0, 7):
            struct.relationship = relationship
            assert struct.device_type == orig_dev_type
            assert struct.rx_on_when_idle == orig_rx
            assert struct.relationship == relationship
Ejemplo n.º 6
0
def test_neighbor_struct_device_type():
    """Test neighbor packed struct device_type."""

    for dev_type in range(0, 3):
        struct = types.Neighbor()
        assert struct.device_type is None
        struct.device_type = dev_type
        assert struct.device_type == dev_type

    for i in range(0, 127):
        struct = types.Neighbor(packed=i)
        orig_rx = struct.rx_on_when_idle
        orig_rel = struct.relationship
        for dev_type in range(0, 3):
            struct.device_type = dev_type
            assert struct.rx_on_when_idle == orig_rx
            assert struct.relationship == orig_rel
            assert struct.device_type == dev_type
Ejemplo n.º 7
0
def test_neighbor_struct_rx_on_when_idle():
    """Test neighbor packed struct rx_on_when_idle."""

    for rx_on_when_idle in range(0, 3):
        struct = types.Neighbor()
        assert struct.rx_on_when_idle is None
        struct.rx_on_when_idle = rx_on_when_idle
        assert struct.rx_on_when_idle == rx_on_when_idle

    for i in range(0, 127):
        struct = types.Neighbor(**types.Neighbor._parse_packed(i))
        orig_dev_type = struct.device_type
        orig_rel = struct.relationship
        for rx_on_when_idle in range(0, 3):
            struct.rx_on_when_idle = rx_on_when_idle
            assert struct.device_type == orig_dev_type
            assert struct.relationship == orig_rel
            assert struct.rx_on_when_idle == rx_on_when_idle
Ejemplo n.º 8
0
def test_bitstruct_complex():
    data = (b"\x11\x00\xff\xee\xdd\xcc\xbb\xaa\x08\x07\x06"
            b"\x05\x04\x03\x02\x01\x00\x00\x24\x02\x00\x7c")

    neighbor, rest = zdo_t.Neighbor.deserialize(data + b"asd")
    assert rest == b"asd"

    neighbor2 = zdo_t.Neighbor(
        extended_pan_id=t.ExtendedPanId.convert("aa:bb:cc:dd:ee:ff:00:11"),
        ieee=t.EUI64.convert("01:02:03:04:05:06:07:08"),
        nwk=0x0000,
        device_type=zdo_t.Neighbor.DeviceType.Coordinator,
        rx_on_when_idle=zdo_t.Neighbor.RxOnWhenIdle.On,
        relationship=zdo_t.Neighbor.RelationShip.Sibling,
        reserved1=0b0,
        permit_joining=zdo_t.Neighbor.PermitJoins.Unknown,
        reserved2=0b000000,
        depth=0,
        lqi=124,
    )

    assert neighbor == neighbor2
    assert neighbor2.serialize() == data
Ejemplo n.º 9
0
async def test_migration_from_3_to_4(open_twice, test_db):
    test_db_v3 = test_db("simple_v3.sql")

    with sqlite3.connect(test_db_v3) as conn:
        cur = conn.cursor()

        neighbors_before = list(cur.execute("SELECT * FROM neighbors"))
        assert len(neighbors_before) == 2
        assert all([len(row) == 8 for row in neighbors_before])

        node_descs_before = list(cur.execute("SELECT * FROM node_descriptors"))
        assert len(node_descs_before) == 2
        assert all([len(row) == 2 for row in node_descs_before])

    # Ensure migration works on first run, and after shutdown
    if open_twice:
        app = await make_app(test_db_v3)
        await app.pre_shutdown()

    app = await make_app(test_db_v3)

    dev1 = app.get_device(nwk=0xBD4D)
    assert dev1.node_desc == zdo_t.NodeDescriptor(
        logical_type=zdo_t.LogicalType.Router,
        complex_descriptor_available=0,
        user_descriptor_available=0,
        reserved=0,
        aps_flags=0,
        frequency_band=zdo_t.NodeDescriptor.FrequencyBand.Freq2400MHz,
        mac_capability_flags=142,
        manufacturer_code=4476,
        maximum_buffer_size=82,
        maximum_incoming_transfer_size=82,
        server_mask=11264,
        maximum_outgoing_transfer_size=82,
        descriptor_capability_field=0,
    )
    assert len(dev1.neighbors) == 1
    assert dev1.neighbors[0].neighbor == zdo_t.Neighbor(
        extended_pan_id=t.ExtendedPanId.convert("81:b1:12:dc:9f:bd:f4:b6"),
        ieee=t.EUI64.convert("ec:1b:bd:ff:fe:54:4f:40"),
        nwk=0x6D1C,
        reserved1=0,
        device_type=zdo_t.Neighbor.DeviceType.Router,
        rx_on_when_idle=1,
        relationship=zdo_t.Neighbor.RelationShip.Sibling,
        reserved2=0,
        permit_joining=2,
        depth=15,
        lqi=130,
    )

    dev2 = app.get_device(nwk=0x6D1C)
    assert dev2.node_desc == dev1.node_desc.replace(manufacturer_code=4456)
    assert len(dev2.neighbors) == 1
    assert dev2.neighbors[0].neighbor == zdo_t.Neighbor(
        extended_pan_id=t.ExtendedPanId.convert("81:b1:12:dc:9f:bd:f4:b6"),
        ieee=t.EUI64.convert("00:0d:6f:ff:fe:a6:11:7a"),
        nwk=0xBD4D,
        reserved1=0,
        device_type=zdo_t.Neighbor.DeviceType.Router,
        rx_on_when_idle=1,
        relationship=zdo_t.Neighbor.RelationShip.Sibling,
        reserved2=0,
        permit_joining=2,
        depth=15,
        lqi=132,
    )

    await app.pre_shutdown()

    with sqlite3.connect(test_db_v3) as conn:
        cur = conn.cursor()

        # Old tables are untouched
        assert neighbors_before == list(cur.execute("SELECT * FROM neighbors"))
        assert node_descs_before == list(
            cur.execute("SELECT * FROM node_descriptors"))

        # New tables exist
        neighbors_after = list(cur.execute("SELECT * FROM neighbors_v4"))
        assert len(neighbors_after) == 2
        assert all([len(row) == 12 for row in neighbors_after])

        node_descs_after = list(
            cur.execute("SELECT * FROM node_descriptors_v4"))
        assert len(node_descs_after) == 2
        assert all([len(row) == 14 for row in node_descs_after])
Ejemplo n.º 10
0
async def test_neighbors(tmpdir):
    """Test neighbor loading."""

    ext_pid = t.EUI64.convert("aa:bb:cc:dd:ee:ff:01:02")
    ieee_1 = make_ieee(1)
    nwk_1 = 0x1111
    nei_1 = zdo_t.Neighbor(ext_pid, ieee_1, nwk_1, 2, 1, 1, 0, 0, 0, 15, 250)

    ieee_2 = make_ieee(2)
    nwk_2 = 0x2222
    nei_2 = zdo_t.Neighbor(ext_pid, ieee_2, nwk_2, 1, 1, 2, 0, 0, 0, 15, 250)

    ieee_3 = make_ieee(3)
    nwk_3 = 0x3333
    nei_3 = zdo_t.Neighbor(ext_pid, ieee_3, nwk_3, 1, 1, 2, 0, 0, 0, 15, 250)

    db = os.path.join(str(tmpdir), "test.db")
    app = await make_app(db)
    app.handle_join(nwk_1, ieee_1, 0)

    dev_1 = app.get_device(ieee_1)
    dev_1.node_desc = zdo_t.NodeDescriptor(2, 64, 128, 4174, 82, 82, 0, 82, 0)
    ep1 = dev_1.add_endpoint(1)
    ep1.status = zigpy.endpoint.Status.ZDO_INIT
    ep1.profile_id = 260
    ep1.device_type = 0x1234
    app.device_initialized(dev_1)

    # 2nd device
    app.handle_join(nwk_2, ieee_2, 0)
    dev_2 = app.get_device(ieee_2)
    dev_2.node_desc = zdo_t.NodeDescriptor(1, 64, 142, 4476, 82, 82, 0, 82, 0)
    ep2 = dev_2.add_endpoint(1)
    ep2.status = zigpy.endpoint.Status.ZDO_INIT
    ep2.profile_id = 260
    ep2.device_type = 0x1234
    app.device_initialized(dev_2)

    neighbors = zdo_t.Neighbors(2, 0, [nei_2, nei_3])
    p1 = patch.object(
        dev_1.zdo,
        "request",
        new=AsyncMock(return_value=(zdo_t.Status.SUCCESS, neighbors)),
    )
    with p1:
        res = await dev_1.neighbors.scan()
        assert res

    neighbors = zdo_t.Neighbors(2, 0, [nei_1, nei_3])
    p1 = patch.object(
        dev_2.zdo,
        "request",
        new=AsyncMock(return_value=(zdo_t.Status.SUCCESS, neighbors)),
    )
    with p1:
        res = await dev_2.neighbors.scan()
        assert res

    await app.pre_shutdown()
    del dev_1, dev_2

    # Everything should've been saved - check that it re-loads
    app2 = await make_app(db)
    dev_1 = app2.get_device(ieee_1)
    dev_2 = app2.get_device(ieee_2)

    assert len(dev_1.neighbors) == 2
    assert dev_1.neighbors[0].device is dev_2
    assert dev_1.neighbors[1].device is None
    assert dev_1.neighbors[1].neighbor.ieee == ieee_3

    assert len(dev_2.neighbors.neighbors) == 2
    assert dev_2.neighbors[0].device is dev_1
    assert dev_2.neighbors[1].device is None
    assert dev_2.neighbors[1].neighbor.ieee == ieee_3
    await app2.pre_shutdown()
    os.unlink(db)
Ejemplo n.º 11
0
 async def _load_neighbors(self):
     for (dev_ieee, epid, ieee, nwk, packed, prm, depth,
          lqi) in self._scan("neighbors"):
         dev = self._application.get_device(dev_ieee)
         nei = zdo_t.Neighbor(epid, ieee, nwk, packed, prm, depth, lqi)
         dev.neighbors.add_neighbor(nei)