/** * Utility function to join an existing network as a Router * * @param networkParameters the required {@link EmberNetworkParameters} * @param linkKey the {@link ZigBeeKey} with the initial link key. This cannot be set to all 00 or all FF. */ public void JoinNetwork(EmberNetworkParameters networkParameters, ZigBeeKey linkKey) { Log.Debug("Joining Ember network with configuration {Parameters}", networkParameters); // Leave the current network so we can initialise a new network EmberNcp ncp = new EmberNcp(_protocolHandler); if (CheckNetworkJoined()) { ncp.LeaveNetwork(); } ncp.ClearKeyTable(); // Initialise security - no network key as we'll get that from the coordinator SetSecurityState(linkKey, null); DoJoinNetwork(networkParameters); }
/** * Performs an energy scan and returns the quietest channel * * @param ncp {@link EmberNcp} * @param scanDuration duration of the scan on each channel * @return the quietest channel, or null on error */ private int?DoEnergyScan(EmberNcp ncp, int scanDuration) { List <EzspEnergyScanResultHandler> channels = ncp.DoEnergyScan(ZigBeeChannelMask.CHANNEL_MASK_2GHZ, scanDuration); if (channels == null) { Log.Debug("Error during energy scan: {Status}", ncp.GetLastStatus()); return(null); } int lowestRSSI = 999; int lowestChannel = 11; foreach (EzspEnergyScanResultHandler channel in channels) { if (channel.GetMaxRssiValue() < lowestRSSI) { lowestRSSI = channel.GetMaxRssiValue(); lowestChannel = channel.GetChannel(); } } return(lowestChannel); }
/** * Constructor to set the {@link EmberNcp} * * @param ncp the {@link EmberNcp} used to communicate with the NCP */ public EmberStackConfiguration(EmberNcp ncp) { this._ncp = ncp; }
/** * This utility function uses emberStartScan, emberStopScan, emberScanCompleteHandler, emberEnergyScanResultHandler, * and emberNetworkFoundHandler to discover other networks or determine the background noise level. It then uses * emberFormNetwork to create a new network with a unique PAN-ID on a channel with low background noise. * <p> * Setting the PAN-ID or Extended PAN-ID to 0 will set these values to a random value. * <p> * If channel is set to 0, the quietest channel will be used. * * @param networkParameters the required {@link EmberNetworkParameters} * @param linkKey the {@link ZigBeeKey} with the link key. This can not be set to all 00 or all FF. * @param networkKey the {@link ZigBeeKey} with the network key. This can not be set to all 00 or all FF. */ public void FormNetwork(EmberNetworkParameters networkParameters, ZigBeeKey linkKey, ZigBeeKey networkKey) { if (networkParameters.GetExtendedPanId() == null) { networkParameters.SetExtendedPanId(new ExtendedPanId()); } Log.Debug("Initialising Ember network with configuration {NetworkParameters}", networkParameters); EmberNcp ncp = new EmberNcp(_protocolHandler); // Leave the current network so we can initialise a new network if (CheckNetworkJoined()) { ncp.LeaveNetwork(); } ncp.ClearKeyTable(); // Perform an energy scan to find a clear channel int?quietestChannel = DoEnergyScan(ncp, _scanDuration); Log.Debug("Energy scan reports quietest channel is {QuietestChannel}", quietestChannel); // Check if any current networks were found and avoid those channels, PAN ID and especially Extended PAN ID ncp.DoActiveScan(ZigBeeChannelMask.CHANNEL_MASK_2GHZ, _scanDuration); // Read the current network parameters GetNetworkParameters(); // Create a random PAN ID and Extended PAN ID if (networkParameters.GetPanId() == 0 || networkParameters.GetExtendedPanId().Equals(new ExtendedPanId())) { Random random = new Random(); int panId = random.Next(65535); networkParameters.SetPanId(panId); Log.Debug("Created random PAN ID: {PanId}", panId); byte[] extendedPanIdBytes = new byte[8]; random.NextBytes(extendedPanIdBytes); ExtendedPanId extendedPanId = new ExtendedPanId(extendedPanIdBytes); networkParameters.SetExtendedPanId(extendedPanId); Log.Debug("Created random Extended PAN ID: {ExtendedPanId}", extendedPanId.ToString()); } if (networkParameters.GetRadioChannel() == 0 && quietestChannel.HasValue) { networkParameters.SetRadioChannel(quietestChannel.Value); } // If the channel set is empty, use the single channel defined above if (networkParameters.GetChannels() == 0) { networkParameters.SetChannels(1 << networkParameters.GetRadioChannel()); } // Initialise security SetSecurityState(linkKey, networkKey); // And now form the network DoFormNetwork(networkParameters); }
/** * Sets the initial security state * * @param linkKey the initial {@link ZigBeeKey} * @param networkKey the initial {@link ZigBeeKey} * @return true if the security state was set successfully */ private bool SetSecurityState(ZigBeeKey linkKey, ZigBeeKey networkKey) { EzspSetInitialSecurityStateRequest securityState = new EzspSetInitialSecurityStateRequest(); EmberInitialSecurityState state = new EmberInitialSecurityState(); state.AddBitmask(EmberInitialSecurityBitmask.EMBER_TRUST_CENTER_GLOBAL_LINK_KEY); EmberKeyData networkKeyData = new EmberKeyData(); if (networkKey != null) { networkKeyData.SetContents(Array.ConvertAll(networkKey.Key, c => (int)c)); state.AddBitmask(EmberInitialSecurityBitmask.EMBER_HAVE_NETWORK_KEY); if (networkKey.SequenceNumber.HasValue) { state.SetNetworkKeySequenceNumber(networkKey.SequenceNumber.Value); } } state.SetNetworkKey(networkKeyData); EmberKeyData linkKeyData = new EmberKeyData(); if (linkKey != null) { linkKeyData.SetContents(Array.ConvertAll(linkKey.Key, c => (int)c)); state.AddBitmask(EmberInitialSecurityBitmask.EMBER_HAVE_PRECONFIGURED_KEY); state.AddBitmask(EmberInitialSecurityBitmask.EMBER_REQUIRE_ENCRYPTED_KEY); } state.SetPreconfiguredKey(linkKeyData); state.SetPreconfiguredTrustCenterEui64(new IeeeAddress()); securityState.SetState(state); EzspSingleResponseTransaction transaction = new EzspSingleResponseTransaction(securityState, typeof(EzspSetInitialSecurityStateResponse)); _protocolHandler.SendEzspTransaction(transaction); EzspSetInitialSecurityStateResponse securityStateResponse = (EzspSetInitialSecurityStateResponse)transaction.GetResponse(); Log.Debug(securityStateResponse.ToString()); if (securityStateResponse.GetStatus() != EmberStatus.EMBER_SUCCESS) { Log.Debug("Error during retrieval of network parameters: {Response}", securityStateResponse); return(false); } EmberNcp ncp = new EmberNcp(_protocolHandler); if (networkKey != null && networkKey.OutgoingFrameCounter.HasValue) { EzspSerializer serializer = new EzspSerializer(); serializer.SerializeUInt32(networkKey.OutgoingFrameCounter.Value); if (ncp.SetValue(EzspValueId.EZSP_VALUE_NWK_FRAME_COUNTER, serializer.GetPayload()) != EzspStatus.EZSP_SUCCESS) { return(false); } } if (linkKey != null && linkKey.OutgoingFrameCounter.HasValue) { EzspSerializer serializer = new EzspSerializer(); serializer.SerializeUInt32(linkKey.OutgoingFrameCounter.Value); if (ncp.SetValue(EzspValueId.EZSP_VALUE_APS_FRAME_COUNTER, serializer.GetPayload()) != EzspStatus.EZSP_SUCCESS) { return(false); } } return(true); }