async def form_network(self, channel=15, pan_id=None, extended_pan_id=None): channel = t.uint8_t(channel) if pan_id is None: pan_id = t.uint16_t.from_bytes(os.urandom(2), 'little') pan_id = t.uint16_t(pan_id) if extended_pan_id is None: extended_pan_id = t.fixed_list(8, t.uint8_t)([t.uint8_t(0)] * 8) initial_security_state = bellows.zigbee.util.zha_security( controller=True) v = await self._ezsp.setInitialSecurityState(initial_security_state) assert v[0] == t.EmberStatus.SUCCESS # TODO: Better check parameters = t.EmberNetworkParameters() parameters.panId = pan_id parameters.extendedPanId = extended_pan_id parameters.radioTxPower = t.uint8_t(8) parameters.radioChannel = channel parameters.joinMethod = t.EmberJoinMethod.USE_MAC_ASSOCIATION parameters.nwkManagerId = t.EmberNodeId(0) parameters.nwkUpdateId = t.uint8_t(0) parameters.channels = t.uint32_t(0) await self._ezsp.formNetwork(parameters) await self._ezsp.setValue(t.EzspValueId.VALUE_STACK_TOKEN_WRITING, 1)
async def _restore(ezsp, backup_data, force, update_eui64_token=False, upg_tc_link_key=False): """Restore backup.""" (status, ) = await ezsp.networkInit() LOGGER.debug("Network init status: %s", status) assert status in (t.EmberStatus.SUCCESS, t.EmberStatus.NOT_JOINED) if status == t.EmberStatus.SUCCESS: if not force: click.echo("Network is up, not forcing restore") return try: (status, ) = await ezsp.leaveNetwork() if status != t.EmberStatus.NETWORK_DOWN: LOGGER.error("Couldn't leave network") return except asyncio.TimeoutError: LOGGER.error("Didn't not receive stack changed status callback") return if update_eui64_token: ncp_eui64 = t.EmberEUI64(backup_data[ATTR_NODE_EUI64]).serialize() (status, ) = await ezsp.setMfgToken(t.EzspMfgTokenId.MFG_CUSTOM_EUI_64, ncp_eui64) sec_bitmask = (t.EmberInitialSecurityBitmask.HAVE_PRECONFIGURED_KEY | t.EmberInitialSecurityBitmask.REQUIRE_ENCRYPTED_KEY | t.EmberInitialSecurityBitmask.TRUST_CENTER_GLOBAL_LINK_KEY | t.EmberInitialSecurityBitmask.HAVE_NETWORK_KEY | t.EmberInitialSecurityBitmask.NO_FRAME_COUNTER_RESET) if not is_well_known_key(backup_data[ATTR_KEY_GLOBAL][ATTR_KEY]): sec_bitmask |= t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY init_sec_state = t.EmberInitialSecurityState( bitmask=sec_bitmask, preconfiguredKey=backup_data[ATTR_KEY_GLOBAL][ATTR_KEY], networkKey=backup_data[ATTR_KEY_NWK][ATTR_KEY], networkKeySequenceNumber=backup_data[ATTR_KEY_NWK][ATTR_KEY_SEQ], preconfiguredTrustCenterEui64=[0x00] * 8, ) if (upg_tc_link_key and t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY not in sec_bitmask): init_sec_state.bitmask |= ( t.EmberInitialSecurityBitmask.TRUST_CENTER_USES_HASHED_LINK_KEY) init_sec_state.preconfiguredKey = t.EmberKeyData(os.urandom(16)) (status, ) = await ezsp.setInitialSecurityState(init_sec_state) LOGGER.debug("Set initial security state: %s", status) assert status == t.EmberStatus.SUCCESS if backup_data[ATTR_KEY_TABLE]: await _restore_keys(ezsp, backup_data[ATTR_KEY_TABLE]) network_key = backup_data[ATTR_KEY_NWK] (status, ) = await ezsp.setValue( ezsp.types.EzspValueId.VALUE_NWK_FRAME_COUNTER, t.uint32_t(network_key[ATTR_KEY_FRAME_COUNTER_OUT]).serialize(), ) LOGGER.debug("Set network frame counter: %s", status) assert status == t.EmberStatus.SUCCESS tc_key = backup_data[ATTR_KEY_GLOBAL] (status, ) = await ezsp.setValue( ezsp.types.EzspValueId.VALUE_APS_FRAME_COUNTER, t.uint32_t(tc_key[ATTR_KEY_FRAME_COUNTER_OUT]).serialize(), ) LOGGER.debug("Set network frame counter: %s", status) assert status == t.EmberStatus.SUCCESS await _form_network(ezsp, backup_data) await asyncio.sleep(2)
def join(ctx, channels, pan_id, extended_pan_id): """Join an existing ZigBee network as an end device""" def cb(fut, frame_name, response): if frame_name == 'stackStatusHandler': fut.set_result(response) s = yield from util.setup(ctx.obj['device'], ctx.obj['baudrate']) channel = None if len(channels) != 1: if pan_id or extended_pan_id: raise click.BadOptionUsage( "Specify exactly one channel to join a specific network") else: channel = t.uint8_t(channels[0]) if not (pan_id or extended_pan_id): scan_type = t.EzspNetworkScanType.ACTIVE_SCAN channel_mask = util.channel_mask(channels) click.echo("PAN not provided, scanning channels %s..." % (' '.join(map(str, channels)), )) v = yield from s.startScan(scan_type, channel_mask, 3) networks = [n[0] for n in v if n[0].allowingJoin] if len(networks) == 0: click.echo("No joinable networks found") return 1 if len(networks) > 1: click.echo("Multiple joinable networks found. Refusing to pick.") return 1 network = networks[0] pan_id = network.panId extended_pan_id = network.extendedPanId channel = network.channel click.echo("Found network %s %s on channel %s" % ( pan_id, extended_pan_id, channel, )) if pan_id is None: pan_id = t.uint16_t(0) else: pan_id = t.uint16_t(pan_id) if isinstance(extended_pan_id, str): extended_pan_id = util.parse_epan(extended_pan_id) if extended_pan_id is None: extended_pan_id = t.fixed_list(8, t.uint8_t)([t.uint8_t(0)] * 8) v = yield from util.network_init(s) if v[0] == t.EmberStatus.SUCCESS: LOGGER.debug("Network was up, leaving...") v = yield from s.leaveNetwork() util.check(v[0], "Failure leaving network: %s" % (v[0], )) yield from asyncio.sleep(1) # TODO initial_security_state = zutil.zha_security() v = yield from s.setInitialSecurityState(initial_security_state) util.check(v[0], "Setting security state failed: %s" % (v[0], )) parameters = t.EmberNetworkParameters() parameters.extendedPanId = extended_pan_id parameters.panId = pan_id parameters.radioTxPower = t.uint8_t(8) parameters.radioChannel = t.uint8_t(channel) parameters.joinMethod = t.EmberJoinMethod.USE_MAC_ASSOCIATION parameters.nwkManagerId = t.EmberNodeId(0) parameters.nwkUpdateId = t.uint8_t(0) parameters.channels = t.uint32_t(0) click.echo(parameters) fut = asyncio.Future() cbid = s.add_callback(functools.partial(cb, fut)) v = yield from s.joinNetwork(t.EmberNodeType.END_DEVICE, parameters) util.check(v[0], "Joining network failed: %s" % (v[0], )) v = yield from fut click.echo(v) s.remove_callback(cbid) s.close()
def form(ctx, channel, pan_id, extended_pan_id): """Create a new ZigBee network""" s = yield from util.setup(ctx.obj['device'], util.print_cb) v = yield from util.networkInit(s) if v[0] == t.EmberStatus.SUCCESS: LOGGER.debug("Network was up, leaving...") v = yield from s.leaveNetwork() util.check(v[0], "Failure leaving network: %s" % (v[0], )) yield from asyncio.sleep(1) # TODO initial_security_state = util.zha_security(controller=True) v = yield from s.setInitialSecurityState(initial_security_state) util.check(v[0], "Setting security state failed: %s" % (v[0], )) yield from util.basic_tc_permits(s) if channel: channel = t.uint8_t(channel) else: channel = t.uint8_t(17) if extended_pan_id: extended_pan_id = util.parse_epan(extended_pan_id) else: extended_pan_id = t.fixed_list(8, t.uint8_t)([t.uint8_t(0)] * 8) if pan_id: pan_id = t.uint16_t(pan_id) else: pan_id = t.uint16_t.from_bytes(os.urandom(2), 'little') parameters = t.EmberNetworkParameters() parameters.panId = pan_id parameters.extendedPanId = extended_pan_id parameters.radioTxPower = t.uint8_t(8) parameters.radioChannel = channel parameters.joinMethod = t.EmberJoinMethod.USE_MAC_ASSOCIATION parameters.nwkManagerId = t.EmberNodeId(0) parameters.nwkUpdateId = t.uint8_t(0) parameters.channels = t.uint32_t(0) click.echo(parameters) LOGGER.info("Forming network ...") fut = asyncio.Future() def cb(fut, frame_name, response): if frame_name == 'stackStatusHandler': fut.set_result(response) s.add_callback(functools.partial(cb, fut)) v = yield from s.formNetwork(parameters) util.check(v[0], "Failed to form network: %s" % (v[0], )) v = yield from fut util.check( v[0], "Network didn't come up after form", t.EmberStatus.NETWORK_UP, ) yield from s.setValue(t.EzspValueId.VALUE_STACK_TOKEN_WRITING, 1) yield from asyncio.sleep(0.1) s.close()