private bool IsTableRead(object sender, GXPacket packet)
		{
			if ((sender as GXIEC62056Table).ReadMode == 6)
			{
                GXIEC62056Table table = (GXIEC62056Table)sender;
                object[][] rows = Parser.IEC62056Parser.ParseTableData(packet.ExtractPacket(), ref Columns, ref Status, ref Time, ref Add, table.Data);
                System.Diagnostics.Debug.WriteLine("Mikko " + rows.Length);
                table.AddRows(table.RowCount, new List<object[]>(rows), false);                
            }            
            return (byte) packet.Eop != 0x4;
		}
        internal void Send(GXPacket packet)
        {
            lock (m_SendPackets.SyncRoot)
            {
				if (packet.Sender == null)
				{
					throw new Exception(Resources.InvalidSender);
				}
                packet.Id = ++m_PacketIdCounter;
                //If packet is send asyncronously.
                if (packet.ResendCount == -1)
                {
                    byte[] buff = packet.ExtractPacket();
                    packet.Sender.NotifyVerbose(packet.Sender, TraceTypes.Sent, buff);
                    Media.Send(buff, packet.SenderInfo);
                }
                else
                {
                    m_SendPackets.Add(packet);
                    m_SendPacketsAdded.Set();
                }
            }
        }
 void AAREReply(object sender, GXPacket packet)
 {
     GXDLMSDevice device = sender as GXDLMSDevice;
     byte[] data = packet.ExtractPacket();
     parser.ParseAAREResponse(data);            
     //parser.Objects.Add
     // Show limits as parameters.    
     /*
     if (parser.UseLogicalNameReferencing)
     {
         UpdateParameter(device.Parameters, "Attribute0SetReferencing", parser.LNSettings.Attribute0SetReferencing);
         UpdateParameter(device.Parameters, "PriorityManagement", parser.LNSettings.PriorityManagement);
         UpdateParameter(device.Parameters, "Attribute0GetReferencing", parser.LNSettings.Attribute0GetReferencing);
         UpdateParameter(device.Parameters, "GetBlockTransfer", parser.LNSettings.GetBlockTransfer);
         UpdateParameter(device.Parameters, "SetBlockTransfer", parser.LNSettings.SetBlockTransfer);
         UpdateParameter(device.Parameters, "ActionBlockTransfer", parser.LNSettings.ActionBlockTransfer);
         UpdateParameter(device.Parameters, "MultibleReferences", parser.LNSettings.MultibleReferences);
         UpdateParameter(device.Parameters, "Get", parser.LNSettings.Get);
         UpdateParameter(device.Parameters, "Set", parser.LNSettings.Set);
         UpdateParameter(device.Parameters, "Action", parser.LNSettings.Action);
         UpdateParameter(device.Parameters, "EventNotification", parser.LNSettings.EventNotification);
         UpdateParameter(device.Parameters, "SelectiveAccess", parser.LNSettings.SelectiveAccess);
     }
     else
     {
         UpdateParameter(device.Parameters, "SNReadSupported", parser.SNSettings.Read);
         UpdateParameter(device.Parameters, "SNWriteSupported", parser.SNSettings.Write);
         UpdateParameter(device.Parameters, "SNUnConfirmedWriteSupported", parser.SNSettings.UnconfirmedWrite);
         UpdateParameter(device.Parameters, "SNInformationReportSupported", parser.SNSettings.InformationReport);
         UpdateParameter(device.Parameters, "MultibleReferencesSupported", parser.SNSettings.MultibleReferences);
         UpdateParameter(device.Parameters, "ParametrizedAccessSupported", parser.SNSettings.ParametrizedAccess);
         UpdateParameter(device.Parameters, "ServerMaxPDUsize", parser.MaxReceivePDUSize);
         UpdateParameter(device.Parameters, "ValueOfQualityOfService", parser.ValueOfQualityOfService);
         UpdateParameter(device.Parameters, "ServerDLMSVersionNumber", parser.DLMSVersion);
         UpdateParameter(device.Parameters, "NumberOfUnusedBits", parser.NumberOfUnusedBits);
     }     
      * */
 }
 public bool IsTransactionComplete(object sender, string command, GXPacket packet)
 {
     if (command == "IsAARQSend")
     {                
         bool complete = AARQRequest.Length == AARQRequestPos;
         return complete;
     }
     else if (command == "IsAllDataReceived")//Is all data read.
     {
         byte[] data = packet.ExtractPacket();
         CheckErrors(data, false);
         RequestTypes tmp = parser.GetDataFromPacket(data, ref ReceivedData);
         if (tmp == RequestTypes.None && IsMoreDataAvailable != RequestTypes.None)
         {
             if ((IsMoreDataAvailable & RequestTypes.Frame) != 0)
             {
                 IsMoreDataAvailable &= ~RequestTypes.Frame;
             }
             else
             {
                 IsMoreDataAvailable &= ~RequestTypes.DataBlock;
             }
         }
         else
         {
             IsMoreDataAvailable |= tmp;
         }
         return IsMoreDataAvailable == Gurux.DLMS.RequestTypes.None;
     }
     else if (command == "IsAllTableInfoReceived")//Is all data read.
     {
         byte[] data = packet.ExtractPacket();
         CheckErrors(data, true);
         RequestTypes tmp = parser.GetDataFromPacket(data, ref ReceivedData);
         if (tmp == RequestTypes.None && IsMoreDataAvailable != RequestTypes.None)
         {
             if ((IsMoreDataAvailable & RequestTypes.Frame) != 0)
             {
                 IsMoreDataAvailable &= ~RequestTypes.Frame;
             }
             else
             {
                 IsMoreDataAvailable &= ~RequestTypes.DataBlock;
             }
         }
         else
         {
             IsMoreDataAvailable |= tmp;
         }
         if (IsMoreDataAvailable != Gurux.DLMS.RequestTypes.None)
         {                    
             return true;
         }
         ExtraInfo[ExtraInfo.Keys.ElementAt(ExtraInfoPos)] = parser.GetValue(ReceivedData);
         ReceivedData = null;
         //Read next item.
         if (++ExtraInfoPos < ExtraInfo.Count)
         {
             return false;                    
         }                
         return true;                
     }                
     else if (command == "IsAllTableDataReceived")//Are all columns read.
     {                
         Gurux.Device.GXTable table = sender as Gurux.Device.GXTable;
         Gurux.Device.GXDevice device = table.Device;
         int progress = 0;                
         byte[] data = packet.ExtractPacket();
         CheckErrors(data, true);
         //Clear packet so we are not saved it for later use.
         packet.Clear();
         RequestTypes tmp = parser.GetDataFromPacket(data, ref ReceivedData);
         if (tmp == RequestTypes.None && IsMoreDataAvailable != RequestTypes.None)
         {
             if ((IsMoreDataAvailable & RequestTypes.Frame) != 0)
             {
                 IsMoreDataAvailable &= ~RequestTypes.Frame;
             }
             else
             {
                 IsMoreDataAvailable &= ~RequestTypes.DataBlock;
             }
         }
         else
         {
             IsMoreDataAvailable |= tmp;
         }
         bool complete = IsMoreDataAvailable == Gurux.DLMS.RequestTypes.None;
         //Notify only percent to increase traffic.
         int maxValue = parser.GetMaxProgressStatus(ReceivedData);
         //Notify progess.
         if (maxValue == 0)
         {
             progress = 0;
         }
         else
         {
             double val = parser.GetCurrentProgressStatus(ReceivedData);                    
             progress = (int)(val / maxValue * 100);
         }
         if (LastNotifiedTransactionProgress != progress)
         {
             if (complete)
             {
                 device.NotifyTransactionProgress(this, new Gurux.Device.GXTransactionProgressEventArgs(sender, 100, 100, Gurux.Device.DeviceStates.ReadEnd));
             }
             else
             {
                 device.NotifyTransactionProgress(this, new Gurux.Device.GXTransactionProgressEventArgs(sender, progress, 100, Gurux.Device.DeviceStates.ReadStart));                        
             }
             LastNotifiedTransactionProgress = progress;
         }
         //Try Parse DLMS objexts.
         if (TryParse)
         {
             GXDLMSTable table2 = sender as GXDLMSTable;
             if (this.ReceivedRows == 0)
             {
                 table2.ClearRows();                        
             }                    
             Array reply = (Array)parser.TryGetValue(ReceivedData);
             // If there is data.
             if (reply != null && reply.Length != 0)
             {
                 int count = pg.Buffer.Count;
                 pg.SetValue(2, reply);                        
                 List<object> receivedData = new List<object>(pg.Buffer.ToArray());
                 //Remove old rows. We must keep latest because some meters returns null as date time.
                 if (count != 0)
                 {                            
                     receivedData.RemoveRange(0, count);
                     pg.Buffer.RemoveRange(0, count - 1);
                 }
                 List<object[]> rows = new List<object[]>(receivedData.Count);
                 bool updated = false;
                 if (Extension != null)
                 {
                     updated = Extension.UpdateTableData(TableColumns, table2, reply, rows);
                 }
                 if (!updated)
                 {
                     foreach (object row in receivedData)
                     {
                         List<object> cols = new List<object>();
                         foreach (int it in ColumnIndexs)
                         {
                             cols.Add(((object[])row)[it]);
                         }
                         rows.Add(cols.ToArray());
                     }
                 }
                 table2.AddRows(-1, rows, false);
                 //Save latest read time. Note we must add Capture Period or we will read last values again.
                 Gurux.Device.Editor.IGXPartialRead partialRead = table as Gurux.Device.Editor.IGXPartialRead;
                 if (partialRead.Type == Gurux.Device.Editor.PartialReadType.New && rows[rows.Count - 1][0] is GXDateTime)
                 {                            
                     DateTime tm = (rows[rows.Count - 1][0] as GXDateTime).Value;
                     partialRead.Start = tm.AddSeconds(pg.CapturePeriod);
                 }
                 ReceivedRows += reply.Length;
             }                  
         }
         return complete;
     }
     else
     {
         throw new NotImplementedException();
     }
 }
 // Confirm that the secondary received and acted on an SNRM or DISC command.
 void UAReply(object sender, GXPacket GXPacket)
 {                        
     byte[] data = GXPacket.ExtractPacket();
     parser.ParseUAResponse(data);                                    
 }