} // SendUnencryptedOTA /// <summary>Sends a Request to given cluster and returns any data that /// comes back. This method is usually used for a table read.</summary> /// <param name="TargetAddress">Short address of device to send the message to</param> /// <param name="Msg"></param> /// <returns></returns> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 01/31/08 mcm 1.0.x Initial Release // 09/15/08 AF Replaced ItronC177 with ItronEZSP because // the interface names changed in the new version // of the EZSP dlls. // 10/26/12 PGH Replaced EZSP with C177App // 09/17/15 jrf 4.21.04 616082 Added in a monitor in order to synchronize communication // with the beacon timer. public override ZigbeeResult SendDataRequest(ushort TargetAddress, byte[] Msg) { ZigbeeResult Result = ZigbeeResult.SUCCESS; PauseIntermittentBeacons(); Monitor.Enter(C177App); try { if (null != Msg) { m_Logger.WriteLine(Logger.LoggingLevel.Protocol, "Sending data request to address " + TargetAddress.ToString("X4", CultureInfo.InvariantCulture)); try { C177App.SendDataRequest(Msg); } catch (Exception e) { m_Logger.WriteException(this, e); Result = ZigbeeResult.ERROR; } } } finally { Monitor.Exit(C177App); } ResumeIntermittentBeacons(); return(Result); } // SendDataRequest
} // FindNeworks /// <summary>Sends a Request to given cluster and returns any data that /// comes back. This method is usually used for a table read.</summary> /// <param name="TargetAddress">Short address of device to send the message to</param> /// <param name="Msg"></param> /// <param name="Response"></param> /// <returns></returns> /// <remarks> ///Revision History ///MM/DD/YY who Version Issue# Description ///-------- --- ------- ------ --------------------------------------- ///01/31/08 mcm 1.0.x Initial Release ///</remarks> public override ZigbeeResult SendUnencryptedOTA(ushort TargetAddress, byte[] Msg, out byte[] Response) { ZigbeeResult Result = ZigbeeResult.SUCCESS; Response = null; //Add in Monitor if implement this method. See Send Data Request. return(Result); } // SendUnencryptedOTA
/// <summary> /// Scan for devices using a USB Belt Clip Radio /// </summary> /// <param name="iChannel">The channel to scan.</param> // Revision History // MM/DD/YY Who Version Issue# Description // -------- --- ------- ------ ------------------------------------------- // 02/25/08 RCG 1.50.10 Created // 04/09/09 AF 2.20.00 Added code to distinguish between an Itron ZBCR // and a Telegesis dongle // 09/18/15 jrf 4.21.04 616082 Modified to send a beacon burst and encapsulated storing found networks // in a new method. private void ScanUsingUSBBeltClipRadio(int iChannel) { Radio BeltClipRadio = new BeltClipRadio(); ZigbeeNetwork[] ZigBeeNetworks = null; ZigbeeResult Result = ZigbeeResult.ERROR; if (m_ScanningRadio != null && iChannel == SCAN_CHANNELS[0]) { if (ZigBeeRadioToken.ZigBeeRadioType.USBRadio == m_ScanningRadio.RadioType) { ((BeltClipRadio)BeltClipRadio).RadioManufacturer = Itron.Metering.Zigbee.BeltClipRadio.RadioMfg.ItronZBCR; } else { ((BeltClipRadio)BeltClipRadio).RadioManufacturer = Itron.Metering.Zigbee.BeltClipRadio.RadioMfg.TelegesisDongle; } BeltClipRadio.OpenPort(m_ScanningRadio.RadioIdentifier); if (BeltClipRadio.IsOpen == true) { uint BeaconChannels = 0; WriteLog(Logger.LoggingLevel.Minimal, "\tBeacon Channels: "); for (int iIndex = 0; iIndex < SCAN_CHANNELS.Length; iIndex++) { BeaconChannels |= (uint)(0x1 << SCAN_CHANNELS[iIndex]); WriteLog(Logger.LoggingLevel.Minimal, "\t\t Channel " + (SCAN_CHANNELS[iIndex]).ToString(CultureInfo.InvariantCulture)); } ZigBeeNetworks = BeltClipRadio.SendBeaconBurst(BeaconChannels); //Store off networks found during burst. StoreZigBeeNetworks(ZigBeeNetworks); for (int iIndex = 0; iIndex < SCAN_CHANNELS.Length; iIndex++) { Result = BeltClipRadio.FindNetworks(BeaconChannels, out ZigBeeNetworks, true); if (Result == ZigbeeResult.SUCCESS) { StoreZigBeeNetworks(ZigBeeNetworks); } } } BeltClipRadio.ClosePort(); } }
} // Stop /// <summary> /// Find the Networks around the radio /// </summary> /// <param name="ScanChannels">Packed bits representing the channels /// to search. Only channels 15-26 are valid, so only bits 15 (0x800) /// through bit 26 (0x4000000). Note that bits are 0 indexed, so /// channel 0 = 0x01.</param> /// <param name="Networks">Returned array of found networks</param> /// <param name="Fast">Indicates whether or not the duration period /// used during scan should be set to a small number.</param> /// <returns>ZigbeeResult indicating success of search</returns> /// // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 01/31/08 mcm 1.0.x Initial Release // 09/08/08 AF Increased the Sleep() to give the scan // enough time to complete. In HH-Pro we // weren't getting many channel 25 networks // 08/24/09 AF 2.21.03 138987 Replaced the Sleep() with a WaitEvent() // so that we will wait only as long as necessary // // 10/17/12 PGH 2.70.36 Replaced EZSP with C177App // 09/17/15 jrf 4.21.04 616082 Added a fast parameter to cause scan duration to // be set to a lower number of periods (speeds scan up) // and also added in a monitor in order to synchronize // communication with the beacon timer. // 11/03/15 jrf 4.22.00 629782 Adding null referenced checks for m_NetworkList public override ZigbeeResult FindNetworks(uint ScanChannels, out ZigbeeNetwork[] Networks, bool Fast = false) { ZigbeeResult Result = ZigbeeResult.SUCCESS; EZSPScanDuration ScanDuration = EZSPScanDuration.ScanPeriodX33; PauseIntermittentBeacons(); Monitor.Enter(C177App); try { if (Fast) { ScanDuration = EZSPScanDuration.ScanPeriodX2; } Networks = new ZigbeeNetwork[0]; m_Logger.WriteDetail(this, "Searching for Zigbee Networks"); if (null != m_NetworkList) { m_NetworkList.Clear(); } try { m_NetworkList = C177App.ScanForDevices((ZigBeeChannels)ScanChannels, ScanDuration); if (null != m_NetworkList) { m_NetworkList.Sort(); Networks = m_NetworkList.ToArray(); } } catch (Exception e) { m_Logger.WriteException(this, e); Result = ZigbeeResult.ERROR; } } finally { Monitor.Exit(C177App); } ResumeIntermittentBeacons(); return(Result); } // FindNeworks
/// <summary>Starts the Radio. Returns a bool indicating success. /// </summary> /// <param name="MAC">MAC address for the radio</param> /// <param name="LogicalType">The type of device to configure. When /// joined to a cell relay, this should be a router, otherwise this /// should be a coordinator</param> /// <param name="ScanChannels">Packed bits representing the channels /// to search. Only channels 15-26 are valid, so only bits 15 (0x800) /// through bit 26 (0x4000000). Note that bits are 0 indexed, so /// bit 0 = 0x01.</param> /// <param name="ExPanID">The 8 byte extended Pan ID you want to start /// with. This value can be 0, which will cause the radio to either /// assign one at random or join the first suitable network it finds /// depending on the LogicalType.</param> /// <returns>True if the radio exists and was successfully started</returns> /// // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 01/31/08 mcm 1.0.x Initial Release // 06/17/08 AF 1.50.37 Changed to read the link key from the registry // 09/15/08 AF Replaced C177 with EZSP because // the interface names changed in the new version // of the EZSP dlls. // 10/07/08 AF 121097 Modified the filter on channel. We should allow // any valid channel // 01/26/11 AF 2.45.26 158436 Integration of new ezsp library to support secure rejoin. // // 10/17/12 PGH 2.70.36 Replaced EZSP with C177App // 09/17/15 jrf 4.21.04 616082 Sending a burst of beacons before joining and // starting intermittent beacons if method is successful. public override ZigbeeResult Start(ulong MAC, ulong ExPanID, ZigbeeLogicalType LogicalType, uint ScanChannels) { ZigbeeResult Result = ZigbeeResult.SUCCESS; if (!m_bConnected) { Result = ZigbeeResult.NOT_CONNECTED; } else { try { if (C177App.IsJoined) { C177App.LeaveNetwork(); } byte[] NetworkKey = GetSecurityKey(false); //Need to wake up troublesome devices before we attempt to join. SendBeaconBurst((uint)(0x1 << (int)ScanChannels)); C177App.Rejoin(ConvertLogicalTypeToEmberType(LogicalType), ExPanID, (byte)ScanChannels, NetworkKey); if (!C177App.IsJoined) { Result = ZigbeeResult.ERROR; } } catch (Exception e) { m_Logger.WriteDetail(this, "BeltClipRadio.Start exception"); m_Logger.WriteException(this, e); Result = ZigbeeResult.ERROR; throw e; } } if (ZigbeeResult.SUCCESS == Result) { //This will keep troublesome devices communicative. StartIntermittentBeacons(); } return(Result); } // Start
/// <summary> /// Sends a series of find network commands (beacons) in quick succession. /// This helps some devices with communication issues to become /// responsive. /// </summary> /// <param name="Channels">Packed bits representing the channels /// to search. Only channels 15-26 are valid, so only bits 15 (0x800) /// through bit 26 (0x4000000). Note that bits are 0 indexed, so /// bit 0 = 0x01.</param> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 09/16/15 jrf 4.21.04 616082 Created. public virtual ZigbeeNetwork[] SendBeaconBurst(uint Channels) { ZigbeeNetwork[] ZigBeeNetworks = null; ZigbeeResult Result = ZigbeeResult.ERROR; List <ZigbeeNetwork> AccumulatedZigBeeNetworks = new List <ZigbeeNetwork>(); for (int i = 0; i < NUMBER_OF_BEACONS; i++) { Result = FindNetworks(Channels, out ZigBeeNetworks, true); if (null != ZigBeeNetworks) { AccumulatedZigBeeNetworks.AddRange(ZigBeeNetworks); } } return(AccumulatedZigBeeNetworks.ToArray()); }
/// <summary> /// Connects to the meter using ZigBee /// </summary> // Revision History // MM/DD/YY Who Version Issue# Description // -------- --- ------- ------ ------------------------------------------- // 09/17/09 RCG 2.30.00 Created // 10/31/14 jrf 4.00.82 WR 542694 Added support for identifying Bridge meter with signed authorizaion. // 01/27/15 jrf 4.01.01 WR 557786 Adding ability for test to logon to meter using signed authorization. // 02/10/17 jrf 4.72.00 WR 645582 Adding try/catch around final logoff and close port. private bool LogonViaZigBee(ZigBeeRadioToken radioToken) { Radio ZigBeeRadio = CreateZigBeeRadio(radioToken); CPSEM ZigBeePSEM = null; CENTRON_AMI ZigBeeDevice = null; bool bCouldLogon = false; PSEMResponse Response; if (ZigBeeRadio != null) { ZigbeeResult ZBResult = ZigbeeResult.NOT_CONNECTED; ZigBeeRadio.OpenPort(radioToken.RadioIdentifier); if (ZigBeeRadio.IsOpen) { int counter = 0; while ((ZigbeeResult.SUCCESS != ZBResult) && (counter < 4)) { try { ZBResult = ZigBeeRadio.Start(Radio.C177_HANDHELD_PROGRAMMER_MAC, m_ulMACAddress, ZigbeeLogicalType.ENDDEVICE, m_byChannel); } catch { Thread.Sleep(5000); } counter++; } } if (!ZigBeeRadio.IsOpen || ZBResult != ZigbeeResult.SUCCESS) { // Make sure the radio is disconnected. ZigBeeRadio.ClosePort(); ZigBeeRadio = null; } else { try { // Logon to the meter ZigBeePSEM = new CPSEM(ZigBeeRadio); Response = ZigBeePSEM.Identify(); if (Response != PSEMResponse.Ok) { // Retry the identify in case the meter is in a bad state Response = ZigBeePSEM.Identify(); } if (Response == PSEMResponse.Ok) { Response = ZigBeePSEM.Negotiate(CPSEM.DEFAULT_MAX_PACKET_LEGNTH, CPSEM.DEFAULT_MAX_NUMBER_OF_PACKETS, (uint)9600); } if (Response == PSEMResponse.Ok) { Response = ZigBeePSEM.Logon("", CPSEM.DEFAULT_HH_PRO_USER_ID); } if (Response == PSEMResponse.Ok) { ZigBeeDevice = CreateDevice(ZigBeePSEM, m_AuthorizationKey); if (m_AuthorizationKey != null && m_AuthorizationKey.IsValid && ZigBeeDevice.SignedAuthorizationState != null && ZigBeeDevice.SignedAuthorizationState.Value != FeatureState.Disabled) { // We should use signed authorization to log on to the meter. ZigBeeDevice.Authenticate(m_AuthorizationKey); } else { ZigBeeDevice.Security(GetPasswords()); } if (ZigBeeDevice.HANMACAddress == m_ulMACAddress) { bCouldLogon = true; } else { bCouldLogon = false; } } } catch (Exception) { } finally { try { ZigBeeDevice.Logoff(); } catch { } } } if (ZigBeeRadio != null) { try { ZigBeeRadio.ClosePort(); } catch { } } } return(bCouldLogon); }