/// <summary> /// Creates the communications object for the radio /// </summary> /// <param name="radioToken">The radio token to use.</param> /// <returns>The communications object.</returns> // Revision History // MM/DD/YY Who Version Issue# Description // -------- --- ------- ------ ------------------------------------------- // 09/17/09 RCG 2.30.00 Created private Radio CreateZigBeeRadio(ZigBeeRadioToken radioToken) { Radio ZigBeeRadio = null; switch (radioToken.RadioType) { case ZigBeeRadioToken.ZigBeeRadioType.USBRadio: { ZigBeeRadio = new BeltClipRadio(); ((BeltClipRadio)ZigBeeRadio).RadioManufacturer = BeltClipRadio.RadioMfg.ItronZBCR; break; } case ZigBeeRadioToken.ZigBeeRadioType.TelegesisRadio: { ZigBeeRadio = new BeltClipRadio(); ((BeltClipRadio)ZigBeeRadio).RadioManufacturer = BeltClipRadio.RadioMfg.TelegesisDongle; break; } } return(ZigBeeRadio); }
/// <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); }
/// <summary> /// Tests the ZigBee Connection /// </summary> // Revision History // MM/DD/YY Who Version ID Number Description // -------- --- ------- -- ------ ------------------------------------------- // 09/17/09 RCG 2.30.00 Created // 09/19/14 jrf 4.00.63 WR 534158 Modified way test details are set // 10/03/14 jrf 4.00.67 WR 536944 Corrected expect logon success check. It doesn't // require joining to be enabled. // 02/10/17 jrf 4.72.00 WR 645582 Reworking to try all available zigbee radios from service // and to retry zigbee logon on if the first attempt fails. private void TestZigBeeConnection() { ZigBeeRadioCallBack ServiceCallback = new ZigBeeRadioCallBack(); ZigBeeRadioChannel ServiceChannel = new ZigBeeRadioChannel(ServiceCallback); ZigBeeRadioToken CurrentRadioToken = null; bool bLoggedOn = false; bool bRadioTested = false; bool bExpectLogOnSuccess = false; Random RandomNumGen = new Random(); DateTime StartTime; string Details = ""; try { // In order to prevent a possible case where multiple threads try to get radios at the same // time and possibly cause one of them to lock up we need to wait a random amount of time Thread.Sleep(RandomNumGen.Next(2000, 3000)); StartTime = DateTime.Now; while (bRadioTested == false && (DateTime.Now - StartTime < MAX_WAIT_TIME) && IsAborted == false && null != ServiceChannel) { List <ZigBeeRadioToken> AllRadios = ServiceChannel.GetRadioInformation(); if (null != AllRadios && AllRadios.Count > 0) { // Only attempt to run the test if there are no radios currently in use. if (AllRadios.Where(r => r.Status == ZigBeeRadioToken.ZigBeeRadioStatus.InUse).Count() == 0) { List <ZigBeeRadioToken> RadioTokens = new List <ZigBeeRadioToken>(); CurrentRadioToken = ServiceChannel.RequestZigBeeRadio(); while (null != CurrentRadioToken && false == bLoggedOn) { RadioTokens.Add(CurrentRadioToken); bRadioTested = true; try { bLoggedOn = LogonViaZigBee(CurrentRadioToken); if (false == bLoggedOn) { bLoggedOn = LogonViaZigBee(CurrentRadioToken); } } catch { bLoggedOn = false; } if (false == bLoggedOn) { CurrentRadioToken = ServiceChannel.RequestZigBeeRadio(); } } if (true == bRadioTested) { bExpectLogOnSuccess = m_bC1218OverZigBeeEnabled && m_bZigBeeEnabled && m_bPrivateProfileEnabled; Details = ConvertYesOrNo(bLoggedOn); if (bLoggedOn != bExpectLogOnSuccess) { Details += ", " + TestResources.InconsistentWithHANSetup; } AddTestDetail(TestResources.AllowedANSIC1218Connection, GetResultString(bLoggedOn == bExpectLogOnSuccess), Details); } //Release all radios requested foreach (ZigBeeRadioToken item in RadioTokens) { ServiceChannel.ReleaseZigBeeRadio(item); } RadioTokens.Clear(); } else { // Wait a random amount of time between 1s and 3s Thread.Sleep(RandomNumGen.Next(1000, 3000)); } } else { m_bTestSkipped = true; bRadioTested = true; m_TestResults.Reason = TestResources.NoRadiosAvailable; AddTestDetail(TestResources.AllowedANSIC1218Connection, GetResultString(true, false), m_TestResults.Reason); } } if (m_bTestSkipped == false && bRadioTested == false) { m_bTestSkipped = true; m_TestResults.Reason = TestResources.AllAvailableRadiosInUse; AddTestDetail(TestResources.AllowedANSIC1218Connection, GetResultString(true, false), m_TestResults.Reason); } } catch (Exception e) { m_bTestSkipped = true; m_TestResults.Reason = e.Message; } }