Пример #1
0
        /// <summary>
        /// Reads the specified table from the meter.
        /// </summary>
        /// <param name="usTableID">The table ID for the table to read.</param>
        /// <param name="MeterTables">The tables object to read the table into.</param>
        /// <returns>PSEMResponse code.</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 10/19/06 RCG	7.40.00			Created
        // 01/11/07 RCG 8.00.05         Removed code that would do a full read since
        //                              the meter no longer supports full reads of 64

        protected PSEMResponse ReadTable(ushort usTableID, ref CentronTables MeterTables)
        {
            MemoryStream PSEMDataStream;
            PSEMResponse PSEMResult = PSEMResponse.Ok;

            byte[] byaData;
            int    iReadAttempt = 0;
            bool   bRetry       = true;

            while (bRetry)
            {
                switch (usTableID)
                {
                case 64:
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = ReadTable64(ref MeterTables);
                    }

                    break;
                }

                case 2152:
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = ReadTable2152(ref MeterTables);
                    }

                    break;
                }

                default:
                {
                    if (0x0800 == usTableID)
                    {
                        PSEMResult = PSEMResponse.Ok;
                    }

                    PSEMResult = m_PSEM.FullRead(usTableID, out byaData);

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMDataStream = new MemoryStream(byaData);
                        MeterTables.SavePSEMStream(usTableID, PSEMDataStream);
                    }

                    break;
                }
                }

                iReadAttempt++;

                if (iReadAttempt < 3 && (PSEMResult == PSEMResponse.Bsy || PSEMResult == PSEMResponse.Dnr))
                {
                    bRetry = true;
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    bRetry = false;
                }
            }

            return(PSEMResult);
        }
Пример #2
0
        /// <summary>
        /// Reads Table 2152
        /// </summary>
        /// <param name="MeterTables">The tables for the meter.</param>
        /// <returns>The PSEM response for communications.</returns>
        //  Revision History
        //  MM/DD/YY who Version Issue# Description
        //  -------- --- ------- ------ -------------------------------------------
        //  05/15/08 RCG 1.50.24 N/A    Created

        protected PSEMResponse ReadTable2152(ref CentronTables MeterTables)
        {
            PSEMResponse PSEMResult = PSEMResponse.Ok;
            MemoryStream PSEMDataStream;

            byte[] byaData;

            CentronTables TempTables = new CentronTables();
            uint          uiMaxOffsetReadBytes;
            uint          uiReadMemorySize;
            uint          uiNumberOfReads;
            uint          uiBytesToRead;
            uint          uiCurrentOffset;
            uint          uiBlockOffset;
            uint          uiBlockLength;
            uint          uiMaxBlocksToRead;
            uint          uiMaxBytesToRead;
            ushort        usValidBlocks;
            ushort        usNumberIntervals;

            ushort usNewValidBlocks;
            ushort usNewNumberIntervals;
            ushort usNewLastBlock;
            int    iBlockToRead;

            // This must be initialized to false or you will break the retry logic.
            bool   bBlocksReRead = false;
            object objData;

            // Since Voltage Monitoring Data can be very large (144k) it may not be able
            // to be read completely when doing a full read so we need to break
            // it up into multiple offset reads. Table 2149 must be read prior to this.

            if (MeterTables.IsCached((long)CentronTblEnum.MFGTBL101_MEMORY_LEN, null) == true)
            {
                uiMaxOffsetReadBytes = (m_PSEM.PacketSize - PACKET_OVERHEAD_SIZE) * PACKETS_PER_READ;

                // Because offset reads can be only up to ushort.MaxValue, limit to that if needed.
                if (uiMaxOffsetReadBytes > ushort.MaxValue)
                {
                    uiMaxOffsetReadBytes = ushort.MaxValue;
                }

                MeterTables.GetValue(CentronTblEnum.MFGTBL103_NBR_VALID_BLOCKS, null, out objData);
                usValidBlocks = (ushort)objData;

                MeterTables.GetValue(CentronTblEnum.MFGTBL103_NBR_VALID_INT, null, out objData);
                usNumberIntervals = (ushort)objData;

                // Determine the size of a Voltage monitoring data block
                MeterTables.GetFieldOffset((long)CentronTblEnum.MFGTBL104_VM_DATA, new int[] { 0 },
                                           out uiBlockOffset, out uiBlockLength);

                // Determine how many blocks can be read in an offset read
                uiMaxBlocksToRead = uiMaxOffsetReadBytes / uiBlockLength;
                uiMaxBytesToRead  = uiMaxBlocksToRead * uiBlockLength;

                // Determine total amount to read
                uiReadMemorySize = usValidBlocks * uiBlockLength;

                // Determine how many reads need to be done
                uiNumberOfReads = usValidBlocks / uiMaxBlocksToRead;

                // Add in a read for any remaining data
                if (usValidBlocks % uiMaxBlocksToRead > 0)
                {
                    uiNumberOfReads++;
                }

                uiCurrentOffset = 0;

                for (uint iIndex = 0; iIndex < uiNumberOfReads && PSEMResult == PSEMResponse.Ok; iIndex++)
                {
                    uiBytesToRead = uiReadMemorySize - uiCurrentOffset;

                    if (uiBytesToRead > uiMaxBytesToRead)
                    {
                        uiBytesToRead = uiMaxBytesToRead;
                    }

                    PSEMResult = m_PSEM.OffsetRead(2152, (int)uiCurrentOffset, (ushort)uiBytesToRead, out byaData);

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMDataStream = new MemoryStream(byaData);
                        MeterTables.SavePSEMStream(2152, PSEMDataStream, uiCurrentOffset);
                        uiCurrentOffset += uiBytesToRead;
                    }

                    OnStepProgress(new ProgressEventArgs());
                }

                // Reread table 63 and make sure no new intervals have occurred while reading
                CentronTables.CopyTable(0, MeterTables, TempTables);
                CentronTables.CopyTable(1, MeterTables, TempTables);
                CentronTables.CopyTable(2148, MeterTables, TempTables);
                CentronTables.CopyTable(2149, MeterTables, TempTables);
                CentronTables.CopyTable(2150, MeterTables, TempTables);

                do
                {
                    ReadTable(2151, ref TempTables);

                    TempTables.GetValue(CentronTblEnum.MFGTBL103_NBR_VALID_BLOCKS, null, out objData);
                    usNewValidBlocks = (ushort)objData;

                    TempTables.GetValue(CentronTblEnum.MFGTBL103_NBR_VALID_INT, null, out objData);
                    usNewNumberIntervals = (ushort)objData;

                    if (usNewNumberIntervals != usNumberIntervals || usNewValidBlocks != usValidBlocks)
                    {
                        // This will limit us to only two tries at this. (if it is already true it will be set
                        // to false which means we won't try this again.)
                        bBlocksReRead = !bBlocksReRead;

                        // A new interval has occurred so we need to reread atleast one block
                        CentronTables.CopyTable(2151, TempTables, MeterTables);

                        MeterTables.GetValue(CentronTblEnum.MFGTBL103_LAST_BLOCK_ELEMENT, null, out objData);
                        usNewLastBlock = (ushort)objData;

                        // Determine the offset of the block
                        iBlockToRead = (int)usNewLastBlock;
                        MeterTables.GetFieldOffset((long)CentronTblEnum.MFGTBL104_VM_DATA, new int[] { iBlockToRead },
                                                   out uiBlockOffset, out uiBlockLength);

                        PSEMResult = m_PSEM.OffsetRead(2152, (int)uiBlockOffset, (ushort)uiBlockLength, out byaData);

                        if (PSEMResult == PSEMResponse.Ok)
                        {
                            PSEMDataStream = new MemoryStream(byaData);
                            MeterTables.SavePSEMStream(2152, PSEMDataStream, uiBlockOffset);

                            // Now if there was also a new block we need to reread the previous block as well.
                            if (usNewValidBlocks != usValidBlocks)
                            {
                                if (usNewLastBlock - 1 < 0)
                                {
                                    iBlockToRead = usNewValidBlocks - 1;
                                }
                                else
                                {
                                    iBlockToRead = usNewLastBlock - 1;
                                }

                                // Determine the offset of the block
                                MeterTables.GetFieldOffset((long)CentronTblEnum.MFGTBL104_VM_DATA, new int[] { iBlockToRead },
                                                           out uiBlockOffset, out uiBlockLength);

                                PSEMResult = m_PSEM.OffsetRead(2152, (int)uiBlockOffset, (ushort)uiBlockLength, out byaData);

                                if (PSEMResult == PSEMResponse.Ok)
                                {
                                    PSEMDataStream = new MemoryStream(byaData);
                                    MeterTables.SavePSEMStream(2152, PSEMDataStream, uiBlockOffset);
                                }
                            }
                        }

                        // Make sure that we save the new data to the old.
                        usValidBlocks     = usNewValidBlocks;
                        usNumberIntervals = usNewNumberIntervals;
                    }
                    else // No new interval occurred
                    {
                        bBlocksReRead = false;
                    }
                } while (bBlocksReRead == true);
            }
            else
            {
                throw new Exception("Table 2149 must be read prior to Table 2152.");
            }

            return(PSEMResult);
        }
Пример #3
0
        /// <summary>
        /// Gets the device information from the meter.
        /// </summary>
        //  Revision History
        //  MM/DD/YY Who Version ID Number Description
        //  -------- --- ------- -- ------ -------------------------------------------
        //  08/28/09 RCG 2.30.00           Created
        //  09/19/14 jrf 4.00.63 WR 534158 Modified to use the CANSIDevice.CreateDevice()
        //                                 method to instantiate the correct device and switched
        //                                 to store the name of the meter instead of device class.
        //  10/31/14 jrf 4.00.82  WR 542694 Added support for identifying Bridge meter with signed authorizaion.
        private TestRun GetDeviceInfo()
        {
            CXMLOpenWaySystemSettings SystemSettings = new CXMLOpenWaySystemSettings("");
            CPSEM        PSEM       = new CPSEM(m_Comm);
            PSEMResponse Response   = PSEMResponse.Ok;
            string       strModel   = null;
            TestRun      NewTestRun = new TestRun();
            string       MeterType  = "";

            Response = PSEM.Identify();

            if (Response == PSEMResponse.Ok)
            {
                Response = PSEM.Negotiate(CPSEM.DEFAULT_MAX_PACKET_LEGNTH,
                                          CPSEM.DEFAULT_MAX_NUMBER_OF_PACKETS, m_uiBaudRate);
            }

            if (Response == PSEMResponse.Ok)
            {
                Response = PSEM.Logon("", CPSEM.DEFAULT_HH_PRO_USER_ID);
            }

            if (Response == PSEMResponse.Ok)
            {
                CTable00 Table0 = new CTable00(PSEM);
                CTable01 Table1 = new CTable01(PSEM, Table0.StdVersion);
                strModel = Table1.Model;

                if (strModel == AMI_CENT)
                {
                    CANSIDevice ANSIDevice = CANSIDevice.CreateDevice(m_Comm, PSEM, Settings.Default.AuthenticationKey);
                    CENTRON_AMI AMIDevice  = ANSIDevice as CENTRON_AMI;

                    if (null != AMIDevice)
                    {
                        if (SystemSettings.UseSignedAuthorization && AMIDevice.SignedAuthorizationState != null &&
                            AMIDevice.SignedAuthorizationState.Value != FeatureState.Disabled &&
                            Settings.Default.AuthenticationKey != null)
                        {
                            // Use Signed Authenticaiton
                            AMIDevice.Authenticate(Settings.Default.AuthenticationKey);
                        }
                        else
                        {
                            // Use standard security
                            AMIDevice.Security(GetPasswords());
                        }

                        MeterType = AMIDevice.MeterName;

                        if (AMIDevice.CommModule != null)
                        {
                            m_strMeterID = AMIDevice.CommModule.ElectronicSerialNumber;
                        }
                    }
                }
            }

            try
            {
                PSEM.Logoff();
                PSEM.Terminate();
            }
            catch (Exception)
            {
                // Make sure we log off.
            }

            // Handle any errors that may have occurred
            if (Response != PSEMResponse.Ok)
            {
                throw new PSEMException(PSEMException.PSEMCommands.PSEM_READ, Response, Resources.ErrorRetrievingDeviceIdentification);
            }
            else if (strModel != AMI_CENT)
            {
                throw new InvalidOperationException(Resources.MeterTypeNotSupported);
            }

            // Set up the TestRun results
            NewTestRun.MeterType   = MeterType;
            NewTestRun.MeterID     = m_strMeterID;
            NewTestRun.TestDate    = DateTime.Now;
            NewTestRun.ProgramName = m_strProgramFile;
            NewTestRun.SWVersion   = Application.ProductVersion;

            return(NewTestRun);
        }
Пример #4
0
        /// <summary>
        /// Runs the test.
        /// </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 Using new method to set test result string.
        //  10/02/14 jrf 4.00.66 WR 431248 Making sure if logon is called and exception occurs then a logoff is
        //                                 attempted so other tests may continue if possible.
        //  10/13/14 jrf 4.00.72 WR 537980 Skipping test on sealed canadian meter.
        public override Test RunTest()
        {
            CXMLOpenWayUserAccessPolicy UserAccess = new CXMLOpenWayUserAccessPolicy();
            bool         bIsUserAllowed            = UserAccess.CheckUserAccess(CXMLOpenWayUserAccessPolicy.FunctionalCapability.ResetActivityStatus);
            PSEMResponse Response = PSEMResponse.Ok;

            m_TestResults      = new Test();
            m_TestResults.Name = TestName;

            m_bTestPassed = true;

            try
            {
                Response = LogonToDevice();

                if (true == m_AmiDevice.IsSealedCanadian)
                {
                    m_bTestSkipped       = true;
                    m_TestResults.Reason = TestResources.ReasonActivityStatusSealedCanadian;
                }
                else if (false == bIsUserAllowed)
                {
                    m_bTestSkipped       = true;
                    m_TestResults.Reason = TestResources.ReasonActivityStatusPermissions;
                }
                else if (Response == PSEMResponse.Ok)
                {
                    ClearDemandResetCount();
                    ClearOutageCount();
                    ClearProgrammedCount();
                    ClearInversionTampers();
                    ClearRemovalTampers();
                    ClearSiteScanDiagCounts();
                    ClearEventLogs();

                    Thread.Sleep(1000);
                    ShowCounters();
                }
                else
                {
                    m_TestResults.Reason = TestResources.ReasonLogonFailed;
                    m_bTestPassed        = false;
                }
            }
            catch (Exception e)
            {
                throw (e);
            }
            finally
            {
                if (m_AmiDevice != null)
                {
                    m_AmiDevice.Logoff();
                }
            }

            // Set the final result.
            m_TestResults.Result = GetTestResultString(m_bTestSkipped, m_bTestPassed);

            return(m_TestResults);
        }
Пример #5
0
        /// <summary>
        /// Reads the table from the meter.
        /// </summary>
        /// <returns>The result of the read request.</returns>
        //  Revision History
        //  MM/DD/YY who Version Issue# Description
        //  -------- --- ------- ------ -------------------------------------------
        //  06/17/09 MMD         N/A    Created

        public override PSEMResponse Read()
        {
            m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "OpenWayMFGTable2170.Read");

            PSEMResponse Result = base.Read();

            //Populate the member variables that represent the table
            if (PSEMResponse.Ok == Result)
            {
                m_DataStream.Position = 0;

                try
                {
                    m_usPulseWeightNormal = m_Reader.ReadUInt16();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_usPulseWeightNormal = 0;
                }

                try
                {
                    m_uiPulseQuantityNormal = m_Reader.ReadUInt32();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_uiPulseQuantityNormal = 0;
                }

                try
                {
                    m_usPulseWeightAlt = m_Reader.ReadUInt16();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_usPulseWeightAlt = 0;
                }
                try
                {
                    m_uiPulseQuantityAlt = m_Reader.ReadUInt32();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_uiPulseQuantityAlt = 0;
                }

                try
                {
                    m_usPulseWeightTest = m_Reader.ReadUInt16();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_usPulseWeightTest = 0;
                }

                try
                {
                    m_uiPulseQuantityTest = m_Reader.ReadUInt32();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_uiPulseQuantityTest = 0;
                }

                try
                {
                    m_usPulseWeightTestAlt = m_Reader.ReadUInt16();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_usPulseWeightTestAlt = 0;
                }

                try
                {
                    m_uiPulseQuantityTestAlt = m_Reader.ReadUInt32();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_uiPulseQuantityTestAlt = 0;
                }

                try
                {
                    m_byappPowerCalcMethod = m_Reader.ReadByte();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_byappPowerCalcMethod = 0;
                }

                try
                {
                    m_byDummy = m_Reader.ReadByte();
                }
                catch (Exception)
                {
                    // If an exception occurs populate the default value
                    m_byDummy = 0;
                }
            }

            return(Result);
        }
Пример #6
0
        /// <summary>
        /// Downloads the firmware file to the meter and activates it.
        /// On download failure, the pending table is cleared.  The activation
        /// will cause the meter to drop the psem task so meter log off must
        /// follow this function call
        /// </summary>
        /// <param name="path">Complete file path of the firmware file</param>
        /// <returns>Itron.Metering.Device.FWDownloadResult</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 08/28/06 AF  7.35.00  N/A   Created
        // 09/15/06 AF  7.35.00  N/A   Added Catch for TimeOutException
        // 10/18/06 AF  7.40.00  N/A   Removed wait within the main loop
        // 05/13/08 AF  1.50.24        Removed IFirmwareDownload from the method name
        // 04/19/10 AF  2.40.39        Added M2 Gateway support
        // 08/18/11 AF  2.52.05        Added support for authentication using a hash code
        // 08/26/11 AF  2.52.08        Added support for Cisco f/w
        // 09/22/11 AF  2.52.21  N/A   Added support for Cisco config file f/w d/l - TODO remove when no longer needed
        // 10/12/11 AF  2.53.00        Changed the Cisco Comm fw enum name
        // 03/22/12 JJJ 2.60.xx        Added support for ChoiceConnect FW
        // 05/10/12 JJJ 2.60.xx        Tweaked FW Type passed to AuthenticateFWDL if ChoiceConnect, make RFLAN
        //
        public FWDownloadResult DownloadFW(string path)
        {
            FWDownloadResult     Result           = FWDownloadResult.UNKNOWN_DRIVER_ERROR;
            ProcedureResultCodes ProcResult       = ProcedureResultCodes.INVALID_PARAM;
            PSEMResponse         ProtocolResponse = PSEMResponse.Ok;
            byte   byEventNumber  = 0;
            ushort idTable        = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
            ushort usNumberChunks = 0;
            ushort intIndex;

            System.IO.FileStream   streamFile;
            System.IO.MemoryStream streamHeader = new System.IO.MemoryStream();
            System.IO.MemoryStream streamPSEM   = new System.IO.MemoryStream();

            try
            {
                // Tell the meter to enter firmware download mode
                Result = EnterFirmwareDownloadMode(path);

                if (FWDownloadResult.SUCCESS != Result)
                {
                    m_Logger.WriteLine(Logger.LoggingLevel.Detailed,
                                       "Initiate F/W Download procedure failed with result = "
                                       + Result);
                }
                else
                {
                    // Meter is ready to receive the firmware file
                    streamFile = new System.IO.FileStream(path, System.IO.FileMode.Open, FileAccess.Read);
                    byte[] bybuffer = new byte[streamFile.Length];

                    streamFile.Read(bybuffer, 0, (int)streamFile.Length);
                    streamFile.Position = 0;

                    switch (bybuffer[9])
                    {
                    case (byte)FirmwareType.RegisterFW:
                    case (byte)FirmwareType.M2GTWY:
                    case (byte)FirmwareType.DisplayFW:
                    {
                        byEventNumber = REGISTER_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.ZigbeeFW:
                    {
                        byEventNumber = ZIGBEE_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.HANModuleFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.RFLANFW:
                    case (byte)FirmwareType.PLANFW:
                    case (byte)FirmwareType.CiscoCommFW:
                    case (byte)FirmwareType.CiscoCfgFW:
                    case (byte)FirmwareType.ChoiceConnectFW:
                    {
                        byEventNumber = COMM_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.CommModuleFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.HANDevFW:
                    {
                        byEventNumber = HAN_DEV_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.HANDeviceFWTbl | PENDING_BIT;
                        break;
                    }

                    default:
                    {
                        throw new NotImplementedException("Table not supported");
                    }
                    }

                    BuildPendingHeader(ref streamHeader, false, false,
                                       byEventNumber, PendingEventRecord.PendingEventCode.NonTimeTrigger);

                    usNumberChunks = (ushort)(streamFile.Length / BLOCK_SIZE);

                    if (streamFile.Length != BLOCK_SIZE * usNumberChunks)
                    {
                        usNumberChunks++;
                    }

                    OnShowProgress(new ShowProgressEventArgs(1, usNumberChunks + 1,
                                                             "Firmware Download",
                                                             "Downloading..."));

                    ushort usSendSize = BLOCK_SIZE;

                    for (intIndex = 0;
                         (intIndex < usNumberChunks) && (PSEMResponse.Ok == ProtocolResponse);
                         intIndex++)
                    {
                        // The last chunk could be smaller
                        if (usNumberChunks - 1 == intIndex)
                        {
                            usSendSize = (ushort)(streamFile.Length % BLOCK_SIZE);
                            // If no remainder then it is a full packet
                            if (0 == usSendSize)
                            {
                                usSendSize = BLOCK_SIZE;
                            }
                        }

                        streamHeader.Position = 0;
                        streamPSEM.Position   = 0;
                        streamPSEM.SetLength(0);
                        streamHeader.WriteTo(streamPSEM);
                        streamPSEM.Write(bybuffer, intIndex * BLOCK_SIZE, usSendSize);

                        ProtocolResponse = m_PSEM.OffsetWrite((ushort)idTable,
                                                              intIndex * BLOCK_SIZE,
                                                              streamPSEM.ToArray());
                        OnStepProgress(new ProgressEventArgs());
                    }

                    // Translate Protocol result
                    Result = TranslateProtocolResult(ProtocolResponse);

                    streamFile.Close();

                    //Check on success and then activate the table
                    if (PSEMResponse.Ok == ProtocolResponse)
                    {
                        if (FWDLLogSupported)
                        {
                            //Construct the hash code and call the procedure to authenticate
                            CENTRON_AMI_FW_File FWFile = new CENTRON_AMI_FW_File(path);
                            byte[] FWHashCode          = FWFile.HashCode;

                            // if MSM ChoiceConnect meter and ChoiceConnect FWDL request, spoof RFLAN FWDL
                            CENTRON_AMI AmiDevice = this as CENTRON_AMI;
                            if (AmiDevice != null &&
                                bybuffer[9] == (byte)FirmwareType.ChoiceConnectFW &&
                                AmiDevice.IsChoiceConnectMsmMeter)
                            {
                                bybuffer[9] = (byte)FirmwareType.RFLANFW;
                            }

                            ProcResult = AuthenticateFWDL(idTable, bybuffer[9], FWHashCode);
                        }
                        else
                        {
                            ProcResult = ProcedureResultCodes.COMPLETED;
                        }

                        if (ProcResult == ProcedureResultCodes.COMPLETED)
                        {
                            // Activate the pending table
                            ProcResult = ActivatePendingTable(false, false, byEventNumber,
                                                              PendingEventRecord.PendingEventCode.NonTimeTrigger);

                            Result = TranslateProcedureResult(ProcResult);
                        }
                        else
                        {
                            //We couldn't authenticate using the hash code so activation will fail
                            ProcResult = ClearPendingTable(false, false, byEventNumber,
                                                           PendingEventRecord.PendingEventCode.NonTimeTrigger);

                            //TODO - not sure this is the correct error
                            Result = FWDownloadResult.SECURITY_ERROR;
                        }

                        OnStepProgress(new ProgressEventArgs());
                    }
                    else
                    {
                        // Write failed, so clear the pending table
                        ProcResult = ClearPendingTable(false, false, byEventNumber,
                                                       PendingEventRecord.PendingEventCode.NonTimeTrigger);

                        Result = FWDownloadResult.WRITE_ERROR;
                    }
                    OnHideProgress(new EventArgs());
                }
            }

            catch (Exception e)
            {
                // Log it and pass it up
                OnHideProgress(new EventArgs());
                m_Logger.WriteException(this, e);
                throw e;
            }

            return(Result);
        }
Пример #7
0
        public ConfigurationError Logon(ushort usUserID, String strUserName, string strPassword, string strSerialPort, uint uiBaudRate)
        {
            PSEMResponse PSEMResult = new PSEMResponse();

            // Set up the serial port
            if (!m_SerialPort.IsOpen)
            {
                try
                {
                    // Open the Serial Port
                    m_SerialPort.OpenPort(strSerialPort);
                }
                #region SerialPort Open catch statements
                catch (InvalidOperationException)
                {
                    // The port is already open
                    return(ConfigurationError.UNABLE_TO_OPEN_PORT);
                }
                catch (ArgumentException)
                {
                    // The port name is invalid
                    return(ConfigurationError.UNABLE_TO_OPEN_PORT);
                }
                catch (IOException)
                {
                    // The port is in an invalid state
                    return(ConfigurationError.UNABLE_TO_OPEN_PORT);
                }
                catch (UnauthorizedAccessException)
                {
                    // Port access was denied
                    return(ConfigurationError.UNABLE_TO_OPEN_PORT);
                }
                #endregion

                // Log on to the meter
                try
                {
                    PSEMResult = m_PSEM.Identify();

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_PSEM.Negotiate(512, 254, uiBaudRate);
                    }

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_PSEM.Logon(strUserName, usUserID);
                    }

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_PSEM.Security(strPassword);
                    }

                    if (PSEMResult != PSEMResponse.Ok)
                    {
                        // TODO: Add additional error translations
                        // Translate the PSEM error code
                        return(AMIConfigureDevice.InterpretPSEMResult(PSEMResult));
                    }
                }
                catch (TimeOutException)
                {
                    // The meter has timed out so return an error
                    m_SerialPort.ClosePort();
                    return(ConfigurationError.TIMEOUT);
                }
            }
            else
            {
                // The serial port is already open so we can not continue logging on
                return(ConfigurationError.UNABLE_TO_OPEN_PORT);
            }

            return(ConfigurationError.SUCCESS);
        }
Пример #8
0
        /// <summary>
        /// Reads Table 2524 (mfg 476)
        /// </summary>
        /// <param name="MeterTables">The meter tables object</param>
        /// <returns>The result of the read</returns>
        //  Revision History
        //  MM/DD/YY Who Version Issue# Description
        //  -------- --- ------- ------ -------------------------------------------
        //  06/27/13 AF  2.80.44 TR7648 Created
        //  07/16/13 AF  2.80.53 WR417522 Adjusted the size of the offset reads to make sure that each
        //                                reads an even multiple of entries.
        //  06/19/15 AF  4.20.14 591427 Calculate the table size instead of retrieving from the CE dlls
        //  07/23/15 AF  4.20.18 597509 The number of entries from table 2521 might not be correct so read from 2524
        //
        public PSEMResponse ReadTable2524(ref CentronTables MeterTables)
        {
            PSEMResponse PSEMResult = PSEMResponse.Ok;
            MemoryStream PSEMDataStream;

            byte[] PSEMData;

            uint TableSize     = 0;
            uint CurrentOffset = 0;

            uint   NumberUnreadEntriesOffset;
            uint   NumberUnreadEntriesLength;
            ushort NumberICSEntries = 0;
            uint   HeaderSize;
            object objData;
            uint   SizeOfEntry        = ICS_LOG_RCD_BASIC;
            bool   blnEventNumberFlag = false;

            if (MeterTables.IsCached((long)CentronTblEnum.MFGTBL473_EVENT_NUMBER_FLAG, null))
            {
                MeterTables.GetValue((long)CentronTblEnum.MFGTBL473_EVENT_NUMBER_FLAG, null, out objData);
                blnEventNumberFlag = (bool)objData;
            }

            if (MeterTables.IsCached((long)CentronTblEnum.MFGTBL473_ICS_DATA_LENGTH, null))
            {
                MeterTables.GetValue((long)CentronTblEnum.MFGTBL473_ICS_DATA_LENGTH, null, out objData);
                SizeOfEntry += (byte)objData;
            }

            if (blnEventNumberFlag)
            {
                SizeOfEntry += sizeof(UInt16);
            }

            MeterTables.GetFieldOffset((long)CentronTblEnum.MFGTBL476_NBR_UNREAD_ENTRIES, null, out NumberUnreadEntriesOffset, out NumberUnreadEntriesLength);

            HeaderSize = NumberUnreadEntriesOffset + NumberUnreadEntriesLength;

            // Read the header
            PSEMResult = m_PSEM.OffsetRead(2524, 0, (ushort)HeaderSize, out PSEMData);

            if (PSEMResult == PSEMResponse.Ok)
            {
                PSEMDataStream = new MemoryStream(PSEMData);
                MeterTables.SavePSEMStream(2524, PSEMDataStream, 0);

                CurrentOffset += HeaderSize;
                ushort BytesToRead;

                if (MeterTables.IsCached((long)CentronTblEnum.MFGTBL476_NBR_VALID_ENTRIES, null))
                {
                    MeterTables.GetValue((long)CentronTblEnum.MFGTBL476_NBR_VALID_ENTRIES, null, out objData);
                    NumberICSEntries = (ushort)objData;
                }

                TableSize = HeaderSize + (SizeOfEntry * NumberICSEntries);

                // Read the entries
                while (CurrentOffset < TableSize)
                {
                    if ((TableSize - CurrentOffset) < MAX_ENTRIES_IN_ONE_READ * SizeOfEntry)
                    {
                        BytesToRead = (ushort)(TableSize - CurrentOffset);
                    }
                    else
                    {
                        BytesToRead = (ushort)(MAX_ENTRIES_IN_ONE_READ * SizeOfEntry);
                    }

                    PSEMResult = m_PSEM.OffsetRead(2524, (int)CurrentOffset, BytesToRead, out PSEMData);

                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMDataStream = new MemoryStream(PSEMData);
                        MeterTables.SavePSEMStream(2524, PSEMDataStream, CurrentOffset);

                        CurrentOffset += BytesToRead;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(PSEMResult);
        }
        /// <summary>
        /// Downloads the firmware file to the meter and activates it.
        /// The activation will cause the meter to drop the psem task so meter log off must
        /// follow this function call on success.  This method supports resuming
        /// a previous failed FWDL.
        /// </summary>
        /// <param name="path">Complete file path of the firmware file</param>
        /// <param name="usBlockIndex">Dual purpose parameter. The passed in value indicates
        /// which block to begin downloading. The passed out parameter indicates which block to
        /// resume downloading in case there was a failure. This can then passed in again to
        /// restart the download at the point where it left off.</param>
        /// <param name="blnRetry">Whether or not to leave the FWDL in a state
        /// to permit subsequent retries at point of faliure. If false the pending table
        /// will be cleared on failure.</param>
        /// <param name="blnActivate">Whether or not to activate the firmware.</param>
        /// <returns>Itron.Metering.Device.FWDownloadResult</returns>
        // Revision History
        // MM/DD/YY who Version ID Number Description
        // -------- --- ------- -- ------ ---------------------------------------
        // 11/15/13 AF  3.50.03	            Class re-architecture - Cloned from CENTRON_AMI
        //
        public FWDownloadResult DownloadFW(string path, ref ushort usBlockIndex, bool blnRetry = false, bool blnActivate = true)
        {
            FWDownloadResult     Result           = FWDownloadResult.UNKNOWN_DRIVER_ERROR;
            ProcedureResultCodes ProcResult       = ProcedureResultCodes.INVALID_PARAM;
            PSEMResponse         ProtocolResponse = PSEMResponse.Ok;
            byte   byEventNumber  = 0;
            ushort idTable        = (ushort)FWDLTableIds.CommModuleFWTbl | PENDING_BIT;
            ushort usNumberChunks = 0;
            //A non-zero starting block means we are need to pick up were we left off.
            bool blnResumeFWDL = (0 != usBlockIndex);

            System.IO.FileStream   streamFile;
            System.IO.MemoryStream streamHeader = new System.IO.MemoryStream();
            System.IO.MemoryStream streamPSEM   = new System.IO.MemoryStream();

            try
            {
                if (true == blnResumeFWDL)
                {
                    Result = FWDownloadResult.SUCCESS;
                }
                else
                {
                    // Tell the meter to enter firmware download mode
                    Result = EnterFirmwareDownloadMode(path);
                }

                if (FWDownloadResult.SUCCESS != Result)
                {
                    m_Logger.WriteLine(Logger.LoggingLevel.Detailed,
                                       "Initiate F/W Download procedure failed with result = "
                                       + Result);
                }
                else
                {
                    // Meter is ready to receive the firmware file
                    streamFile = new System.IO.FileStream(path, System.IO.FileMode.Open, FileAccess.Read);
                    byte[] bybuffer = new byte[streamFile.Length];

                    streamFile.Read(bybuffer, 0, (int)streamFile.Length);
                    streamFile.Position = 0;

                    switch (bybuffer[9])
                    {
                    case (byte)FirmwareType.ICSFW:
                    {
                        byEventNumber = COMM_EVENT_NUMBER;
                        idTable       = (ushort)FWDLTableIds.CommModuleFWTbl | PENDING_BIT;
                        break;
                    }

                    default:
                    {
                        throw new NotImplementedException("Table not supported");
                    }
                    }

                    BuildPendingHeader(ref streamHeader, false, false,
                                       byEventNumber, PendingEventRecord.PendingEventCode.NonTimeTrigger);

                    usNumberChunks = (ushort)(streamFile.Length / BLOCK_SIZE);

                    if (streamFile.Length != BLOCK_SIZE * usNumberChunks)
                    {
                        usNumberChunks++;
                    }

                    OnShowProgress(new ShowProgressEventArgs(1, usNumberChunks + 1,
                                                             "Firmware Download",
                                                             "Downloading..."));

                    ushort usSendSize = BLOCK_SIZE;

                    for (;
                         (usBlockIndex < usNumberChunks) && (PSEMResponse.Ok == ProtocolResponse);
                         usBlockIndex++)
                    {
                        // The last chunk could be smaller
                        if (usNumberChunks - 1 == usBlockIndex)
                        {
                            usSendSize = (ushort)(streamFile.Length % BLOCK_SIZE);
                            // If no remainder then it is a full packet
                            if (0 == usSendSize)
                            {
                                usSendSize = BLOCK_SIZE;
                            }
                        }

                        streamHeader.Position = 0;
                        streamPSEM.Position   = 0;
                        streamPSEM.SetLength(0);
                        streamHeader.WriteTo(streamPSEM);
                        streamPSEM.Write(bybuffer, usBlockIndex * BLOCK_SIZE, usSendSize);

                        ProtocolResponse = m_PSEM.OffsetWrite((ushort)idTable,
                                                              usBlockIndex * BLOCK_SIZE,
                                                              streamPSEM.ToArray());
                        OnStepProgress(new ProgressEventArgs());
                    }

                    // Translate Protocol result
                    Result = TranslateProtocolResult(ProtocolResponse);

                    streamFile.Close();

                    //Check on success and then activate the table
                    if (PSEMResponse.Ok == ProtocolResponse)
                    {
                        ProcResult = ProcedureResultCodes.COMPLETED;

                        if (ProcResult == ProcedureResultCodes.COMPLETED)
                        {
                            if (true == blnActivate)
                            {
                                // Activate the pending table using mfg proc 69
                                ProcResult = ActivateFWDLTable(idTable, (byte)FirmwareType.ICSFW, bybuffer[5], bybuffer[6], bybuffer[7]);

                                Result = TranslateProcedureResult(ProcResult);
                            }
                        }
                        else
                        {
                            //TODO - not sure this is the correct error
                            Result = FWDownloadResult.SECURITY_ERROR;
                        }

                        OnStepProgress(new ProgressEventArgs());
                    }
                    else //PSEMResponse.Ok != ProtocolResponse
                    {
                        //Decrement the block index so we make sure we restart on the block that we failed on.
                        usBlockIndex--;

                        Result = FWDownloadResult.WRITE_ERROR;
                    }
                    OnHideProgress(new EventArgs());
                }
            }

            catch (Exception e)
            {
                if (false == blnRetry)
                {
                    // Log it and pass it up
                    OnHideProgress(new EventArgs());
                    m_Logger.WriteException(this, e);
                    throw e;
                }
                else
                {
                    Result = FWDownloadResult.WRITE_ERROR;
                }
            }

            return(Result);
        }
Пример #10
0
        /// <summary>
        /// This method updates the IO configuration in the meter.
        /// </summary>
        /// <param name="IOConfig">KYZ configuration data object.</param>
        /// <returns>The result of the configuration.</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 04/22/09 jrf 2.20.02 n/a	   Created
        // 04/19/10 AF  2.40.39        Made virtual for M2 Gateway override
        // 07/08/10 jrf 2.42.02 157552 Setting the CPC reset bit on close config to fix
        //                             LED lock issue.
        //
        public virtual ItronDeviceResult ConfigureIO(KYZData IOConfig)
        {
            byte[] ProcParam = new byte[0];
            byte[] ProcResponse;
            ProcedureResultCodes ProcResult =
                ProcedureResultCodes.INVALID_PARAM;
            PSEMResponse Result = PSEMResponse.Err;

            ItronDeviceResult    ConfigResult = ItronDeviceResult.ERROR;
            CTable2048_OpenWay   OW2048       = Table2048 as CTable2048_OpenWay;
            CENTRON_AMI_IOConfig IOTable      = OW2048.IOConfig as CENTRON_AMI_IOConfig;

            // Open the Config
            ProcResult = ExecuteProcedure(Procedures.OPEN_CONFIG_FILE, ProcParam, out ProcResponse);

            // Execute Write of IO Table in 2048
            if (ProcedureResultCodes.COMPLETED == ProcResult)
            {
                IOTable.IOData = IOConfig;
                Result         = IOTable.Write();
            }
            else if (ProcedureResultCodes.NO_AUTHORIZATION == ProcResult)
            {
                Result = PSEMResponse.Isc;
            }
            else
            {
                m_Logger.WriteLine(Logger.LoggingLevel.Detailed,
                                   "Open config procedure failed with result = " +
                                   ProcResult);
                Result = PSEMResponse.Err;
            }

            if (Result == PSEMResponse.Ok)
            {
                // Close the Config
                // Data reset bits - we don't want to reset any data, so
                // just initialize them to 0
                ProcParam = new byte[4];
                ProcParam.Initialize();

                // Okay we do want to reset data if we are a HW2.0 Poly.  Need to do this to
                // prevent the worm on the display from freezing.
                if (0 == VersionChecker.CompareTo(HWRevisionFiltered, HW_VERSION_2_5) ||
                    0 == VersionChecker.CompareTo(HWRevisionFiltered, HW_VERSION_2_6))
                {
                    //We need to reset CPC
                    MemoryStream ParamStream = new MemoryStream(ProcParam);
                    BinaryWriter BinWriter   = new BinaryWriter(ParamStream);

                    BinWriter.Write((uint)CloseConfigOptions.CPC);
                }

                ProcResult = ExecuteProcedure(Procedures.CLOSE_CONFIG_FILE, ProcParam, out ProcResponse);

                if (ProcedureResultCodes.COMPLETED != ProcResult)
                {
                    ConfigResult = ItronDeviceResult.ERROR;
                }
                else
                {
                    ConfigResult = ItronDeviceResult.SUCCESS;
                }
            }
            else
            {
                if (Result == PSEMResponse.Isc)
                {
                    ConfigResult = ItronDeviceResult.SECURITY_ERROR;
                }
                else
                {
                    ConfigResult = ItronDeviceResult.ERROR;
                }
            }

            return(ConfigResult);
        }
Пример #11
0
        /// <summary>
        /// Runs the test.
        /// </summary>
        //  Revision History
        //  MM/DD/YY Who Version ID Number Description
        //  -------- --- ------- -- ------ -------------------------------------------
        //  09/17/09 RCG 2.30.00        Created
        //  12/09/09 jrf 2.30.26        Removing upper nibble of hardware version before
        //                              displaying for PrismLite devices.
        //  02/19/13 AF  2.70.69 322427 Show InterPAN Mode only for pre-Lithium meters
        //  09/19/14 jrf 4.00.63 WR 534158 Using new method to set test result string and
        //                                 modified way test details are set.
        //  10/02/14 jrf 4.00.66 WR 431248 Making sure if logon is called and exception occurs then a logoff is
        //                                 attempted so other tests may continue if possible.
        public override Test RunTest()
        {
            PSEMResponse Response = PSEMResponse.Ok;
            string       strValue = "";

            m_TestResults      = new Test();
            m_TestResults.Name = TestName;


            m_bTestPassed = true;

            try
            {
                Response = LogonToDevice();

                if (Response == PSEMResponse.Ok)
                {
                    if (IsAborted == false)
                    {
                        AddTestDetail(TestResources.MeterID, TestResources.OK, m_AmiDevice.UnitID);
                        AddTestDetail(TestResources.SerialNumber, TestResources.OK, m_AmiDevice.SerialNumber);
                        AddTestDetail(TestResources.MFGSerialNumber, TestResources.OK, m_AmiDevice.MFGSerialNumber);


                        if (m_AmiDevice.CommModule != null)
                        {
                            strValue = m_AmiDevice.CommModule.ElectronicSerialNumber;
                        }
                        else
                        {
                            strValue = TestResources.NotAvailable;
                        }

                        AddTestDetail(TestResources.ElectronicSerialNumber, TestResources.OK, strValue);
                    }

                    if (IsAborted == false)
                    {
                        CheckRegisterFWVersion();
                        CheckRFLANFWVersion();
                        CheckZigBeeFWVersion();
                        CheckDisplayFWVersion();

                        float fltHWRev = m_AmiDevice.HWRevision;

                        // If this is a PrismLite device we need to ignore the upper nibble of the hardware version
                        if (((byte)(fltHWRev) & PRISM_LITE_HW_MASK) == PRISM_LITE_HW_MASK)
                        {
                            fltHWRev -= (float)PRISM_LITE_HW_MASK;
                        }

                        AddTestDetail(TestResources.HardwareVersion, TestResources.OK, fltHWRev.ToString("F3", CultureInfo.CurrentCulture));
                    }

                    if (IsAborted == false)
                    {
                        AddTestDetail(TestResources.TimeZone, TestResources.OK, m_AmiDevice.TimeZoneOffset.Hours + ":00");
                        AddTestDetail(TestResources.DeviceTime, TestResources.OK, m_AmiDevice.DeviceTime.ToString("G", CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.TOUEnabled, TestResources.OK, m_AmiDevice.TOUEnabled.ToString(CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.DSTEnabled, TestResources.OK, m_AmiDevice.DSTEnabled.ToString(CultureInfo.CurrentCulture));


                        for (int iIndex = 0; iIndex < m_AmiDevice.DST.Count; iIndex++)
                        {
                            AddTestDetail(TestResources.DSTFromDate + (iIndex + 1).ToString(CultureInfo.CurrentCulture),
                                          TestResources.OK, m_AmiDevice.DST[iIndex].FromDate.ToString("G", CultureInfo.CurrentCulture));
                            AddTestDetail(TestResources.DSTToDate + (iIndex + 1).ToString(CultureInfo.CurrentCulture),
                                          TestResources.OK, m_AmiDevice.DST[iIndex].ToDate.ToString("G", CultureInfo.CurrentCulture));
                        }
                    }

                    if (IsAborted == false)
                    {
                        AddTestDetail(TestResources.MinutesOnBattery, TestResources.OK, m_AmiDevice.NumberOfMinutesOnBattery.ToString(CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.DateLastProgrammed, TestResources.OK, m_AmiDevice.DateProgrammed.ToString("G", CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.DateOfLastDemandReset, TestResources.OK, m_AmiDevice.DateLastDemandReset.ToString("G", CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.DateOfLastOutage, TestResources.OK, m_AmiDevice.DateLastOutage.ToString("G", CultureInfo.CurrentCulture));
                        AddTestDetail(TestResources.DateOfLastTest, TestResources.OK, m_AmiDevice.DateLastTestMode.ToString("G", CultureInfo.CurrentCulture));


                        if ((m_AmiDevice is OpenWayBasicPoly == true) || (m_AmiDevice is OpenWayAdvPoly == true))
                        {
                            AddTestDetail(TestResources.NormalKh, TestResources.OK, (m_AmiDevice.NormalKh / 40.0).ToString("F3", CultureInfo.CurrentCulture));
                        }
                        else
                        {
                            AddTestDetail(TestResources.NormalKh, TestResources.OK, (m_AmiDevice.NormalKh / 10.0).ToString("F3", CultureInfo.CurrentCulture));
                        }
                    }

                    if (IsAborted == false)
                    {
                        CheckLPRunning();

                        CheckDeviceErrors();

                        GetRFLANMac();

                        if (m_AmiDevice.CommModule != null)
                        {
                            RFLANCommModule RFLANModule = m_AmiDevice.CommModule as RFLANCommModule;

                            if (RFLANModule != null)
                            {
                                strValue = RFLANModule.CommModuleLevel;
                            }
                            else
                            {
                                strValue = TestResources.NotAvailable;
                            }
                        }
                        else
                        {
                            strValue = TestResources.NotAvailable;
                        }

                        AddTestDetail(TestResources.RFLANSynchLevel, TestResources.OK, strValue);
                    }

                    if (IsAborted == false)
                    {
                        AddTestDetail(TestResources.HANMACAddress, TestResources.OK, m_AmiDevice.HANServerMACAddr);
                        AddTestDetail(TestResources.HANSecurityProfile, TestResources.OK, m_AmiDevice.HANSecurityProfile);

                        if (VersionChecker.CompareTo(m_AmiDevice.FWRevision, CENTRON_AMI.VERSION_3_12_LITHIUM) < 0)
                        {
                            AddTestDetail(TestResources.InterPANMode, TestResources.OK, m_AmiDevice.InterPANMode);
                        }

                        AddTestDetail(TestResources.ZigBeeEnabled, TestResources.OK, ConvertYesOrNo(m_AmiDevice.IsZigBeeEnabled));
                        AddTestDetail(TestResources.ANSIC1218OverZigBeeEnabled, TestResources.OK, ConvertYesOrNo(m_AmiDevice.IsC1218OverZigBeeEnabled));
                        AddTestDetail(TestResources.ZigBeePrivateProfileEnabled, TestResources.OK, ConvertYesOrNo(m_AmiDevice.IsZigBeePrivateProfileEnabled));

                        AddTestDetail(TestResources.EnhancedBlurtsEnabled, TestResources.OK, ConvertYesOrNo(m_AmiDevice.MeterKey_EnhancedBlurtsSupported));
                        AddTestDetail(TestResources.AdvancedPolyMeter, TestResources.OK, ConvertYesOrNo(m_AmiDevice.MeterKey_AdvancedPolySupported));
                    }
                }
                else
                {
                    m_TestResults.Reason = TestResources.ReasonLogonFailed;
                    m_bTestPassed        = false;
                }
            }
            catch (Exception e)
            {
                throw (e);
            }
            finally
            {
                if (m_AmiDevice != null)
                {
                    m_AmiDevice.Logoff();
                }
            }

            // Set the final result.
            m_TestResults.Result = GetTestResultString(m_bTestSkipped, m_bTestPassed);

            return(m_TestResults);
        }
Пример #12
0
        /// <summary>
        /// Runs the test.
        /// </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 Using new method to set test result string and
        //                                 modified way test details are set.
        //  10/02/14 jrf 4.00.66 WR 431248 Making sure if logon is called and exception occurs then a logoff is
        //                                 attempted so other tests may continue if possible.
        public override Test RunTest()
        {
            PSEMResponse Response = PSEMResponse.Ok;

            m_TestResults      = new Test();
            m_TestResults.Name = TestName;

            m_bTestPassed             = true;
            m_ulMACAddress            = 0;
            m_byChannel               = 0;
            m_bC1218OverZigBeeEnabled = false;

            try
            {
                // First we need to log on and get the HAN MAC address, channel, and ZigBee state optically
                Response = LogonToDevice();

                if (Response == PSEMResponse.Ok)
                {
                    try
                    {
                        m_ulMACAddress = m_AmiDevice.HANMACAddress;
                        AddTestDetail(TestResources.HANMACAddress, TestResources.OK, m_ulMACAddress.ToString("X16", CultureInfo.InvariantCulture));

                        m_byChannel = m_AmiDevice.HANChannel;
                        AddTestDetail(TestResources.HANChannel, TestResources.OK, m_byChannel.ToString(CultureInfo.InvariantCulture));

                        m_bJoiningEnabled = m_AmiDevice.IsHANJoiningEnabled;
                        AddTestDetail(TestResources.HANJoiningEnabled, TestResources.OK, ConvertYesOrNo(m_bJoiningEnabled));

                        m_bC1218OverZigBeeEnabled = m_AmiDevice.IsC1218OverZigBeeEnabled;
                        AddTestDetail(TestResources.SupportsANSIC1218OverZigBee, TestResources.OK, ConvertYesOrNo(m_bC1218OverZigBeeEnabled));

                        m_bZigBeeEnabled = m_AmiDevice.IsZigBeeEnabled;
                        AddTestDetail(TestResources.ZigBeeEnabled, TestResources.OK, ConvertYesOrNo(m_bZigBeeEnabled));

                        m_bPrivateProfileEnabled = m_AmiDevice.IsZigBeePrivateProfileEnabled;
                        AddTestDetail(TestResources.ZigBeePrivateProfileEnabled, TestResources.OK, ConvertYesOrNo(m_bPrivateProfileEnabled));
                    }
                    catch (Exception)
                    {
                        m_TestResults.Reason = TestResources.ReasonFailedToGetHANInfo;
                        m_bTestPassed        = false;
                    }
                }
                else
                {
                    m_TestResults.Reason = TestResources.ReasonLogonFailed;
                    m_bTestPassed        = false;
                }
            }
            catch (Exception e)
            {
                throw (e);
            }
            finally
            {
                if (m_AmiDevice != null)
                {
                    m_AmiDevice.Logoff();
                }
            }

            if (true == m_bTestPassed)
            {
                // Try to log on via ZigBee.
                TestZigBeeConnection();
            }
            else
            {
                AddTestDetail(TestResources.AllowedANSIC1218Connection, GetResultString(true, false), m_TestResults.Reason);
            }

            // Set the final result.
            m_TestResults.Result = GetTestResultString(m_bTestSkipped, m_bTestPassed);

            // This test like to cause communications problems with tests that follow
            // Giving the meter a little time to recover should help.
            Thread.Sleep(10000);

            return(m_TestResults);
        }
Пример #13
0
        /// <summary>
        /// Implements the ICustomSchedule interface.  Reconfigures the Custom Schedule
        /// based on the provided schedule.
        /// </summary>
        /// <param name="sPathName"></param>
        /// <param name="sScheduleName"></param>
        /// <param name="bWriteUserData2"></param>
        /// <returns>CSReconfigResult</returns>
        /// Revision History
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------------
        /// 05/31/06 mrj 7.30.00 N/A    Created
        ///
        CSReconfigResult ICustomSchedule.Reconfigure(string sPathName, string sScheduleName, bool bWriteUserData2)
        {
            ProcedureResultCodes ProcResult = ProcedureResultCodes.INVALID_PARAM;
            CSReconfigResult     Result     = CSReconfigResult.ERROR;

            byte[]       ProcParam;
            byte[]       ProcResponse;
            PSEMResponse PSEMResult = PSEMResponse.Ok;

            try
            {
                m_Logger.WriteLine(Logger.LoggingLevel.Functional, "Starting Custom Schedule Reconfigure");


                //Check to make sure the meter is configured correctly before performing
                //the reconfigure
                if (((ICustomSchedule)this).CustomScheduleConfigured)
                {
                    if (!((ICustomSchedule)this).MultipleCustomScheduleConfigured)
                    {
                        //Schedule is valid write the custom schedule dates to the
                        //billing schedule (custom schedule) config block of table 2048
                        Result = WriteCustomSchedule(sPathName, sScheduleName);

                        if (CSReconfigResult.SUCCESS == Result ||
                            CSReconfigResult.SUCCESS_SCHEDULE_TRUNCATED == Result)
                        {
                            //Set the schedule name to user data 2 (Sentinel only)
                            if (bWriteUserData2 &&
                                !Table2048.BillingSchedConfig.ScheduleNameSupported)
                            {
                                //Write schedule name to user data 2 if the System Manager option
                                //is set and the meter is a SENTINEL (schedule name is not supported
                                //in CS config block)
                                Table2048.ConstantsConfig.UserData2 = sScheduleName;
                            }


                            //Send the MFG procedure to open the config file (2048)
                            ProcParam  = new byte[0];
                            ProcResult = ExecuteProcedure(Procedures.OPEN_CONFIG_FILE, ProcParam, out ProcResponse);

                            if (ProcedureResultCodes.NO_AUTHORIZATION == ProcResult)
                            {
                                //Return ISC
                                PSEMResult = PSEMResponse.Isc;
                            }
                            else if (ProcedureResultCodes.COMPLETED != ProcResult)
                            {
                                //We had a problem with this procedure
                                PSEMResult = PSEMResponse.Err;
                            }


                            //NOTE: 2048 must be written in sequential order

                            //Write the User Data 2, custom schedule name, to the meter
                            if (bWriteUserData2 &&
                                !Table2048.BillingSchedConfig.ScheduleNameSupported &&
                                PSEMResponse.Ok == PSEMResult)
                            {
                                //Write schedule name to user data 2 if the System Manager option
                                //is set and the meter is a SENTINEL
                                PSEMResult = Table2048.ConstantsConfig.Write();
                            }


                            //Write the billing schedule (custom schedule) config block to the
                            //meter
                            if (PSEMResponse.Ok == PSEMResult)
                            {
                                PSEMResult = Table2048.BillingSchedConfig.Write();
                            }


                            //Send the MFG procedure to close the config file (2048), which tell the meter to
                            //do the reconfigure
                            if (PSEMResponse.Ok == PSEMResult)
                            {
                                ProcParam = new byte[4];
                                ProcParam.Initialize();                                                 //No reset bits needed

                                ProcResult = ExecuteProcedure(Procedures.CLOSE_CONFIG_FILE, ProcParam, out ProcResponse);

                                if (ProcedureResultCodes.INVALID_PARAM == ProcResult)
                                {
                                    //The procedure finished but there was an invalid parameter
                                    //error.  Most likely because the user is at level 3
                                    if (4 == ProcResponse.Length)
                                    {
                                        //Read the result data
                                        MemoryStream TempStream   = new MemoryStream(ProcResponse);
                                        BinaryReader TempBReader  = new BinaryReader(TempStream);
                                        uint         uiResultData = TempBReader.ReadUInt32();

                                        if (CLOSE_CONFIG_CONST_ERROR_MASK == (uint)(uiResultData & CLOSE_CONFIG_CONST_ERROR_MASK) ||
                                            CLOSE_CONFIG_BILL_ERROR_MASK == (uint)(uiResultData & CLOSE_CONFIG_BILL_ERROR_MASK))
                                        {
                                            //The user is level 3, which does not support reconfiguring
                                            //the custom schedule, return security error
                                            Result = CSReconfigResult.SECURITY_ERROR;
                                        }
                                        else
                                        {
                                            //The reconfigure failed
                                            Result = CSReconfigResult.ERROR;
                                        }
                                    }
                                    else
                                    {
                                        //The reconfigure failed
                                        Result = CSReconfigResult.ERROR;
                                    }
                                }
                                else if (ProcedureResultCodes.COMPLETED != ProcResult)
                                {
                                    //The reconfigure failed
                                    Result = CSReconfigResult.ERROR;
                                }

                                m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Reconfig Custom Schedule Result = " + ProcResult);
                            }
                            else if (PSEMResponse.Isc == PSEMResult)
                            {
                                //Return security error
                                Result = CSReconfigResult.SECURITY_ERROR;
                            }
                            else
                            {
                                //The reconfigure failed
                                Result = CSReconfigResult.ERROR;
                            }
                        }
                    }
                    else
                    {
                        //Multiple Custom Schedules is configured so return an error.  This
                        //should never happen since HH-Pro will not call this method when
                        //MCS is enabled.
                        Result = CSReconfigResult.ERROR_MCS_ENALBED;
                    }
                }
                else
                {
                    //This should never happen since HH-Pro will not call unless configured
                    Result = CSReconfigResult.ERROR;
                }
            }
            catch (Exception e)
            {
                // Log it and pass it up
                m_Logger.WriteException(this, e);
                throw (e);
            }

            return(Result);
        }
Пример #14
0
        /// <summary>
        /// Creates an EDL file with the specified sections.
        /// </summary>
        /// <param name="FileName">Path to the file where the EDL file will be written.</param>
        /// <param name="IncludedSections">The sections to include in the EDL file.</param>
        /// <returns>CreateEDLResult Code.</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 04/25/08 RCG	1.50.19			Created
        // 07/06/10 AF  2.42.02         Made virtual for use in the M2 Gateway

        public override CreateEDLResult CreateEDLFromMeter(string FileName, EDLSections IncludedSections)
        {
            CentronTables   MeterTables = new CentronTables();
            List <ushort>   TablesToRead;
            int             iFileNameStart;
            string          strDirectory;
            CreateEDLResult Result     = CreateEDLResult.SUCCESS;
            PSEMResponse    PSEMResult = PSEMResponse.Ok;

            // First check to make sure we can create the file
            iFileNameStart = FileName.LastIndexOf(@"\", StringComparison.Ordinal);

            if (iFileNameStart > 0)
            {
                strDirectory = FileName.Substring(0, iFileNameStart);

                if (Directory.Exists(strDirectory) == false)
                {
                    Result = CreateEDLResult.INVALID_PATH;
                }
            }

            // Make sure we will be able to write to the file
            if (Result == CreateEDLResult.SUCCESS && File.Exists(FileName) == true)
            {
                FileInfo OutputFile = new FileInfo(FileName);

                if ((OutputFile.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                {
                    Result = CreateEDLResult.INVALID_PATH;
                }
            }

            if (Result == CreateEDLResult.SUCCESS)
            {
                // Read the data from the meter
                TablesToRead = GetTablesToRead(IncludedSections);

                OnShowProgress(new ShowProgressEventArgs(1, TablesToRead.Count, "Creating EDL file...", "Creating EDL file..."));

                foreach (ushort TableID in TablesToRead)
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        // Read the table if it exists
                        if ((Table00.IsTableUsed(TableID) == true))
                        {
                            if (MeterTables.GetTableDependencies(TableID).Contains(TableID) || MeterTables.GetTableLength(TableID) > 0)
                            {
                                PSEMResult = ReadTable(TableID, ref MeterTables);

                                if (PSEMResult == PSEMResponse.Bsy ||
                                    PSEMResult == PSEMResponse.Dnr ||
                                    PSEMResult == PSEMResponse.Iar ||
                                    PSEMResult == PSEMResponse.Onp ||
                                    PSEMResult == PSEMResponse.Err)
                                {
                                    // We can't read the table but we should be able to continue we just need to
                                    // clear out anything that is there.
                                    MeterTables.ClearTable(TableID);
                                    PSEMResult = PSEMResponse.Ok;
                                }
                            }
                        }

                        OnStepProgress(new ProgressEventArgs());
                    }
                }

                if (PSEMResult == PSEMResponse.Isc)
                {
                    Result = CreateEDLResult.SECURITY_ERROR;
                }
                else if (PSEMResult != PSEMResponse.Ok)
                {
                    Result = CreateEDLResult.PROTOCOL_ERROR;
                }
            }

#if (WindowsCE)
            //The saving of the EDL file on the handheld can take over 6 seconds so we need
            //to send a wait before.
            m_PSEM.Wait(CPSEM.MAX_WAIT_TIME);
#endif

            // Generate the EDL file
            if (Result == CreateEDLResult.SUCCESS)
            {
                XmlWriterSettings WriterSettings = new XmlWriterSettings();
                WriterSettings.Encoding        = Encoding.ASCII;
                WriterSettings.Indent          = true;
                WriterSettings.CheckCharacters = false;

                XmlWriter EDLWriter = XmlWriter.Create(FileName, WriterSettings);

                MeterTables.SaveEDLFile(EDLWriter, null, AllowTableExport, AllowFieldExport);
                System.Threading.Thread.Sleep(2000);
            }

            OnHideProgress(new EventArgs());

            return(Result);
        }
Пример #15
0
        /// <summary>
        /// Downloads the firmware file to the device but does NOT
        /// activate.  On download failure, the pending table is cleared.
        /// </summary>
        /// <param name="path">Complete path to the firmware file</param>
        /// <returns>FWDownloadResult</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 10/05/06 AF  7.35.00  N/A   Created
        // 10/18/06 AF  7.40.00  N/A   Removed wait within the main loop
        // 05/13/08 AF  1.50.24        Removed IFirmwareDownload from the method name
        // 04/19/10 AF  2.40.39        Added M2 Gateway support
        // 03/21/12 JJJ 2.60.xx        Added support for ChoiceConnect FW
        // 08/17/12 AF  2.60.55        Added support for RF Mesh FW and RF Mesh Config
        //
        public FWDownloadResult DownloadFWNoActivate(string path)
        {
            FWDownloadResult     Result           = FWDownloadResult.UNKNOWN_DRIVER_ERROR;
            ProcedureResultCodes ProcResult       = ProcedureResultCodes.INVALID_PARAM;
            PSEMResponse         ProtocolResponse = PSEMResponse.Ok;
            byte   byEventNumber  = 0;
            ushort idTable        = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
            ushort usNumberChunks = 0;
            ushort intIndex;

            System.IO.FileStream   streamFile;
            System.IO.MemoryStream streamHeader = new System.IO.MemoryStream();
            System.IO.MemoryStream streamPSEM   = new System.IO.MemoryStream();

            try
            {
                Result = EnterFirmwareDownloadMode(path);

                if (FWDownloadResult.SUCCESS != Result)
                {
                    m_Logger.WriteLine(Logger.LoggingLevel.Detailed,
                                       "Initiate F/W Download procedure failed with result = "
                                       + Result);
                }
                else
                {
                    // Meter is ready to receive the firmware file
                    streamFile = new System.IO.FileStream(path, System.IO.FileMode.Open, FileAccess.Read);
                    byte[] bybuffer = new byte[streamFile.Length];

                    streamFile.Read(bybuffer, 0, (int)streamFile.Length);
                    streamFile.Position = 0;

                    switch (bybuffer[9])
                    {
                    case (byte)FirmwareType.RegisterFW:
                    case (byte)FirmwareType.M2GTWY:
                    case (byte)FirmwareType.DisplayFW:
                    {
                        byEventNumber = REGISTER_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.ZigbeeFW:
                    {
                        byEventNumber = ZIGBEE_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.HANModuleFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.RFLANFW:
                    case (byte)FirmwareType.PLANFW:
                    case (byte)FirmwareType.CiscoCommFW:
                    case (byte)FirmwareType.CiscoCfgFW:
                    case (byte)FirmwareType.ChoiceConnectFW:
                    {
                        byEventNumber = COMM_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.CommModuleFWTbl | PENDING_BIT;
                        break;
                    }

                    case (byte)FirmwareType.HANDevFW:
                    {
                        byEventNumber = HAN_DEV_EVENT_NUMBER;
                        idTable       = (ushort)PendingTableIds.HANDeviceFWTbl | PENDING_BIT;
                        break;
                    }

                    default:
                    {
                        throw new NotImplementedException("Table not yet supported");
                    }
                    }

                    BuildPendingHeader(ref streamHeader, false, false,
                                       byEventNumber, PendingEventRecord.PendingEventCode.NonTimeTrigger);

                    usNumberChunks = (ushort)(streamFile.Length / BLOCK_SIZE);

                    if (streamFile.Length != BLOCK_SIZE * usNumberChunks)
                    {
                        usNumberChunks++;
                    }

                    OnShowProgress(new ShowProgressEventArgs(1, usNumberChunks + 1,
                                                             "Firmware Download",
                                                             "Downloading..."));

                    ushort usSendSize = BLOCK_SIZE;

                    for (intIndex = 0;
                         (intIndex < usNumberChunks) && (PSEMResponse.Ok == ProtocolResponse);
                         intIndex++)
                    {
                        // The last chunk could be smaller
                        if (usNumberChunks - 1 == intIndex)
                        {
                            usSendSize = (ushort)(streamFile.Length % BLOCK_SIZE);
                            // If no remainder then it is a full packet
                            if (0 == usSendSize)
                            {
                                usSendSize = BLOCK_SIZE;
                            }
                        }

                        streamHeader.Position = 0;
                        streamPSEM.Position   = 0;
                        streamPSEM.SetLength(0);
                        streamHeader.WriteTo(streamPSEM);
                        streamPSEM.Write(bybuffer, intIndex * BLOCK_SIZE, usSendSize);

                        ProtocolResponse = m_PSEM.OffsetWrite((ushort)idTable,
                                                              intIndex * BLOCK_SIZE,
                                                              streamPSEM.ToArray());
                        OnStepProgress(new ProgressEventArgs());
                    }

                    // Translate Protocol result
                    Result = TranslateProtocolResult(ProtocolResponse);

                    streamFile.Close();

                    // If any write failed, give up and clear the pending table
                    if (PSEMResponse.Ok != ProtocolResponse)
                    {
                        // Write failed, so clear the pending table
                        ProcResult = ClearPendingTable(false, false, byEventNumber,
                                                       PendingEventRecord.PendingEventCode.NonTimeTrigger);

                        Result = FWDownloadResult.WRITE_ERROR;
                    }
                    OnHideProgress(new EventArgs());
                }
            }

            catch (Exception e)
            {
                // Log it and pass it up
                OnHideProgress(new EventArgs());
                m_Logger.WriteException(this, e);
                throw e;
            }

            return(Result);
        }
Пример #16
0
        /// <summary>
        /// Reads the specified table from the meter.
        /// </summary>
        /// <param name="usTableID">The table ID for the table to read.</param>
        /// <param name="MeterTables">The tables object to read the table into.</param>
        /// <returns>PSEMResponse code.</returns>
        //  Revision History
        //  MM/DD/YY Who Version Issue#   Description
        //  -------- --- ------- -------- -------------------------------------------
        //  11/21/13 DLG 3.50.07 No WR    Overriding to handle ICS related tables
        //  05/08/14 AF  3.50.91 WR503773 Added a case for table 2242
        //  05/09/14 AF  3.50.91 WR503773 Removed the case for table 2242. We should be consistent with
        //                                CENTRON_AMI which also does not have a case for 2242.
        //  06/11/14 AF  4.00.25 WR442864 Added back the case for table 2242, due to test failures
        //  07/23/15 jrf 4.20.18 598314   Removing code that is duplicated from base class and
        //                                calling base.ReadTable(...) in default case to handle those cases.
        public override PSEMResponse ReadTable(ushort usTableID, ref CentronTables MeterTables)
        {
            PSEMResponse PSEMResult   = PSEMResponse.Ok;
            int          iReadAttempt = 0;
            bool         bRetry       = true;

            while (bRetry)
            {
                switch (usTableID)
                {
                case 2508:
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_ICSTableReader.ReadTable2508(ref MeterTables);
                    }

                    break;
                }

                case 2511:
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_ICSTableReader.ReadTable2511(ref MeterTables);
                    }

                    break;
                }

                case 2524:
                {
                    if (PSEMResult == PSEMResponse.Ok)
                    {
                        PSEMResult = m_ICSTableReader.ReadTable2524(ref MeterTables);
                    }

                    break;
                }

                default:
                {
                    PSEMResult   = base.ReadTable(usTableID, ref MeterTables);
                    iReadAttempt = 3;     //Skipping retries since they will be handled in base class

                    break;
                }
                }

                iReadAttempt++;

                if (iReadAttempt < 3 && (PSEMResult == PSEMResponse.Bsy || PSEMResult == PSEMResponse.Dnr))
                {
                    bRetry = true;
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    bRetry = false;
                }
            }

            return(PSEMResult);
        }
Пример #17
0
        /// <summary>
        /// This method just downloads the firmware file blocks to the device for a
        /// given range of blocks.  Use 1-based indexing for blocks.
        /// </summary>
        /// <param name="path">Complete path to the firmware file</param>
        /// <param name="usStartBlock">The first block to download.</param>
        /// <param name="usEndBlock">The last block to download.</param>
        /// <returns>FWDownloadResult</returns>
        // Revision History
        // MM/DD/YY who Version Issue# Description
        // -------- --- ------- ------ ---------------------------------------
        // 01/20/10 jrf 2.40.08  N/A    Created
        // 03/22/12 JJJ 2.60.xx        Added support for ChoiceConnect FW
        //
        public FWDownloadResult DownloadFWBlocks(string path, ushort usStartBlock, ushort usEndBlock)
        {
            FWDownloadResult Result           = FWDownloadResult.SUCCESS;
            PSEMResponse     ProtocolResponse = PSEMResponse.Ok;
            byte             byEventNumber    = 0;
            ushort           idTable          = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
            ushort           usNumberChunks   = 0;
            ushort           usIndex;

            System.IO.FileStream   streamFile;
            System.IO.MemoryStream streamHeader = new System.IO.MemoryStream();
            System.IO.MemoryStream streamPSEM   = new System.IO.MemoryStream();

            try
            {
                streamFile = new System.IO.FileStream(path, System.IO.FileMode.Open, FileAccess.Read);
                byte[] bybuffer = new byte[streamFile.Length];

                streamFile.Read(bybuffer, 0, (int)streamFile.Length);
                streamFile.Position = 0;

                switch (bybuffer[9])
                {
                case (byte)FirmwareType.RegisterFW:
                {
                    byEventNumber = REGISTER_EVENT_NUMBER;
                    idTable       = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
                    break;
                }

                case (byte)FirmwareType.ZigbeeFW:
                {
                    byEventNumber = ZIGBEE_EVENT_NUMBER;
                    idTable       = (ushort)PendingTableIds.HANModuleFWTbl | PENDING_BIT;
                    break;
                }

                case (byte)FirmwareType.RFLANFW:
                case (byte)FirmwareType.PLANFW:
                case (byte)FirmwareType.ChoiceConnectFW:
                {
                    byEventNumber = COMM_EVENT_NUMBER;
                    idTable       = (ushort)PendingTableIds.CommModuleFWTbl | PENDING_BIT;
                    break;
                }

                case (byte)FirmwareType.DisplayFW:
                {
                    //TODO - Firmware wants to use the same event number.  Need to test
                    //that it works
                    byEventNumber = REGISTER_EVENT_NUMBER;
                    idTable       = (ushort)PendingTableIds.RegisterFWTbl | PENDING_BIT;
                    break;
                }

                case (byte)FirmwareType.HANDevFW:
                {
                    byEventNumber = HAN_DEV_EVENT_NUMBER;
                    idTable       = (ushort)PendingTableIds.HANDeviceFWTbl | PENDING_BIT;
                    break;
                }

                default:
                {
                    throw new NotImplementedException("Table not yet supported");
                }
                }

                BuildPendingHeader(ref streamHeader, false, false,
                                   byEventNumber, PendingEventRecord.PendingEventCode.NonTimeTrigger);

                usNumberChunks = (ushort)(streamFile.Length / BLOCK_SIZE);

                if (streamFile.Length != BLOCK_SIZE * usNumberChunks)
                {
                    usNumberChunks++;
                }

                OnShowProgress(new ShowProgressEventArgs(1, usNumberChunks + 1,
                                                         "Firmware Download",
                                                         "Downloading..."));

                ushort usSendSize = BLOCK_SIZE;

                //Make sure the start block is not less than 1
                if (usStartBlock < 1)
                {
                    usStartBlock = 1;
                }
                //Make sure the end block is not greater than the actual number of FW blocks.
                if (usEndBlock > usNumberChunks)
                {
                    usEndBlock = usNumberChunks;
                }

                for (usIndex = (ushort)(usStartBlock - 1);
                     (usIndex < usEndBlock) && (PSEMResponse.Ok == ProtocolResponse);
                     usIndex++)
                {
                    // The last chunk could be smaller
                    if (usNumberChunks - 1 == usIndex)
                    {
                        usSendSize = (ushort)(streamFile.Length % BLOCK_SIZE);
                        // If no remainder then it is a full packet
                        if (0 == usSendSize)
                        {
                            usSendSize = BLOCK_SIZE;
                        }
                    }

                    streamHeader.Position = 0;
                    streamPSEM.Position   = 0;
                    streamPSEM.SetLength(0);
                    streamHeader.WriteTo(streamPSEM);
                    streamPSEM.Write(bybuffer, usIndex * BLOCK_SIZE, usSendSize);

                    ProtocolResponse = m_PSEM.OffsetWrite((ushort)idTable,
                                                          usIndex * BLOCK_SIZE,
                                                          streamPSEM.ToArray());
                    OnStepProgress(new ProgressEventArgs());
                }

                // Translate Protocol result
                Result = TranslateProtocolResult(ProtocolResponse);

                streamFile.Close();


                OnHideProgress(new EventArgs());
            }

            catch (Exception e)
            {
                // Log it and pass it up
                OnHideProgress(new EventArgs());
                m_Logger.WriteException(this, e);
                throw e;
            }

            return(Result);
        }
Пример #18
0
        /// <summary>
        /// Runs the test.
        /// </summary>
        //  Revision History
        //  MM/DD/YY Who Version ID Number Description
        //  -------- --- ------- -- ------ -------------------------------------------
        //  09/17/09 RCG 2.30.00           Created
        //  08/15/12 MAH 2.60.54 WR 201902 Added more time between switch operations to allow the meter to recharge its capacitor
        //  09/19/14 jrf 4.00.63 WR 534158 Using new method to set test result string and also checking user permissions.
        //  10/02/14 jrf 4.00.66 WR 431248 Making sure if logon is called and exception occurs then a logoff is
        //                                 attempted so other tests may continue if possible.
        //  04/27/15 jrf 4.20.03 WR 574470 Increased wait between disconnect/connect to allow capacitor more time to charge
        //                                 for hw 2.0 meter.
        public override Test RunTest()
        {
            PSEMResponse Response = PSEMResponse.Ok;
            CXMLOpenWayUserAccessPolicy UserAccess = new CXMLOpenWayUserAccessPolicy();
            bool bIsUserAllowed = UserAccess.CheckUserAccess(CXMLOpenWayUserAccessPolicy.FunctionalCapability.MeterSwitchOperations);

            m_TestResults      = new Test();
            m_TestResults.Name = TestName;

            m_bTestPassed = true;

            try
            {
                Response = LogonToDevice();

                if (false == bIsUserAllowed)
                {
                    m_bTestSkipped       = true;
                    m_TestResults.Reason = TestResources.ReasonSwitchOperationPermissions;
                }
                else if (Response == PSEMResponse.Ok)
                {
                    // First make sure the meter supports connect disconnect.
                    if (m_AmiDevice.IsServiceLimitingTablePresent &&
                        m_AmiDevice.DisconnectHardwareExists &&
                        m_AmiDevice.IsDisconnectHardwareFunctioning)
                    {
                        DisconnectMeter();

                        if (IsAborted == false)
                        {
                            m_AmiDevice.SendWait();
                            // Thread.Sleep(2000);
                            // MAH - 8/15/12 - Increased the time between switch operations to allow the capacitor to recharge
                            //Thread.Sleep(12500);
                            // jrf - 4/27/15 - Increased the time between switch operations slightly more to allow the capacitor
                            //                 to recharge for HW 2.0 meter.
                            Thread.Sleep(15000);
                        }

                        CheckStatus(false);

                        ConnectMeter();

                        if (IsAborted == false)
                        {
                            m_AmiDevice.SendWait();
                            Thread.Sleep(2000);
                        }

                        CheckStatus(true);
                    }
                    else
                    {
                        // Disconnect is not supported
                        m_bTestSkipped       = true;
                        m_TestResults.Reason = TestResources.ReasonDisconnectNotSupported;
                    }
                }
                else
                {
                    m_TestResults.Reason = TestResources.ReasonLogonFailed;
                    m_bTestPassed        = false;
                }
            }
            catch (Exception e)
            {
                throw (e);
            }
            finally
            {
                if (m_AmiDevice != null)
                {
                    m_AmiDevice.Logoff();
                }
            }


            // Set the final result.
            m_TestResults.Result = GetTestResultString(m_bTestSkipped, m_bTestPassed);

            return(m_TestResults);
        }
Пример #19
0
        /// <summary>
        /// Performs a full read of this table.  The table will be marked as
        /// Loaded if the read succeeds.
        /// </summary>
        /// <overloads>Read(ushort Offset, ushort Count)</overloads>
        /// <returns>protocol response</returns>
        ///
        // Revision History
        // MM/DD/YY who Version ID Number Description
        // -------- --- ------- -- ------ ---------------------------------------
        // 06/08/06 mcm 7.30.00    N/A	  Created
        // 03/05/08 KRC 1.50.00           Adding Exception if PSEM is not valid
        // 11/15/11 RCG 2.53.06           Adding code to display a message if we get a data size mismatch
        // 11/07/12 jrf 2.70.36 WR 240583 Adding ability to ignore a table size mismatch under special circumstances.
        // 06/12/13 AF  2.80.37           Corrected spelling error in logger entry
        // 07/18/13 jrf 2.80.54 WR 417794 Modifying to only resize table when sizes differ.
        //
        public virtual PSEMResponse Read()
        {
            PSEMResponse Result       = PSEMResponse.Iar;
            int          iReadAttempt = 0;
            bool         bRetry       = true;

            while (bRetry)
            {
                if (m_PSEM != null)
                {
                    byte[] Data;
                    Result = m_PSEM.FullRead(m_TableID, out Data);

                    if (PSEMResponse.Ok == Result)
                    {
                        if (true == m_blnAllowAutomaticTableResizing && 0 < Data.Length && m_Data.Length != Data.Length)
                        {
                            m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Resizing Table " + m_TableID.ToString(CultureInfo.InvariantCulture)
                                               + " based on data received. Original Length: " + m_Size.ToString(CultureInfo.InvariantCulture)
                                               + " New Length: " + Data.Length.ToString(CultureInfo.InvariantCulture));
                            //Special case where table size is not known in advance and determination
                            //of this knowledge proves to be more complex and time consuming than worth while.
                            //Tables that allow this need to take care to only read as much data as retrieved.
                            ChangeTableSize((uint)Data.Length);
                        }

                        if (m_Data.Length == Data.Length)
                        {
                            Array.Copy(Data, 0, m_Data, 0, m_Data.Length);
                            m_TableState = TableState.Loaded;
                            m_ExpirationTimer.Change(m_iTimeout, 0);

                            // mcm 3/9/2007 - SCR 2553: reposition stream for cases
                            // where the table might be read mulitple times.
                            m_DataStream.Position = 0;
                        }
                        else
                        {
                            Result = PSEMResponse.Err;
                            m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Data size mismatch. Expected Length: " + m_Size.ToString(CultureInfo.InvariantCulture)
                                               + " Received Length: " + Data.Length.ToString(CultureInfo.InvariantCulture));
                        }
                    }
                }
                else
                {
                    throw (new NotImplementedException("This Operation is not supported with a file"));
                }

                iReadAttempt++;

                if (iReadAttempt < 3 && (Result == PSEMResponse.Bsy || Result == PSEMResponse.Dnr))
                {
                    bRetry = true;
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    bRetry = false;
                }
            }

            return(Result);
        }