GXDN: Gurux Developer Network
Gurux DLMS/COSEM component
Gurux provides you with a sample code to show, how to use the component.
You can use any serial port or TCP/IP library you choose. In this example we are using Gurux Serial and Network libraries.
For further information, contact our product support.

[C# example]
using System;
using Gurux.Common;
using Gurux.Serial;
using Gurux.Net;
using Gurux.DLMS2;

namespace GuruxCOSEMSample
{
  public class GXCOSEMSample
  {
    // Device reply wait time.
    int WaitTime = 5000;

    private CGXCOSEMClass m_Cosem;
    private Gurux.Common.IGXMedia2 Media = null;

    /// 
    /// Constructor
    /// 
    /// Client ID.
    /// Served ID.
    /// Is logical name referencing used.
    public GXCOSEMSample(object clientID, object serverID, bool useLogicalNameReferencing)
    {
      m_Cosem = new CGXCOSEMClass();
      m_Cosem.ClientID = clientID;
      m_Cosem.ServerID = serverID;
      m_Cosem.UseLogicalNameReferencing = useLogicalNameReferencing;
    }

    /// 
    /// Close connection.
    /// 
    public void Close()
    {
      if (Media != null && Media.IsOpen)
      {
        this.ReadDLMSPacket(m_Cosem.DisconnectRequest());
        Media.Close();
      }
    }

    /// 
    /// Initialize serial port connection to COSEM/DLMS device.
    /// 
    /// Serial port.
    void InitSerial(string port)
    {
      GXSerial serial = new GXSerial();
      Media = serial;
      serial.Port = port;
      object reply = null;
      byte Terminator = (byte)0x0A;
      // Bitrate must be 300 when connection is initialized.
      serial.BitRate = 300;
      serial.DataBits = ByteSize.Byte7Bits;
      serial.Parity = Parity.Even;
      serial.StopBits = StopBits.One;
      serial.Open();
      //Query device information.
      if (!serial.SendSync("/?!\r\n", Gurux.Common.VariantType.String, Terminator, 0, WaitTime, false, Gurux.Common.VariantType.String, out reply))
      {
      object d = serial.GetReplyData(Gurux.Common.VariantType.HexString);
      throw new Exception("Failed to receive reply from the device in given time.");
      }
      string answer = reply.ToString();
      if (answer[0] != '/')
      {
      throw new Exception("Invalid responce.");
      }
      string manufactureID = answer.Substring(1, 3);
      char baudrate = answer[4];
      int bitrate = 0;
      switch (baudrate)
      {
      case '0':
        bitrate = 300;
      break;
      case '1':
        bitrate = 600;
      break;
      case '2':
        bitrate = 1200;
      break;
      case '3':
        bitrate = 2400;
      break;
      case '4':
        bitrate = 4800;
      break;
      case '5':
        bitrate = 9600;
      break;
      case '6':
        bitrate = 19200;
      break;
      default:
        throw new Exception("Unknown baud rate.");
      }
      //Send ACK
      //Send Protocol control character
      byte controlCharacter = (byte)'2';// "2" HDLC protocol procedure (Mode E)
      //Send Baudrate character
      //Mode control character
      byte ModeControlCharacter = (byte)'2';//"2" //(HDLC protocol procedure) (Binary mode)
      //Set mode E.
      serial.SendSync(new byte[] { 0x06, controlCharacter, (byte)baudrate, ModeControlCharacter, 13, 10 }, Gurux.Common.VariantType.None, Terminator, 0, 500, false, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, out reply);
      serial.BitRate = bitrate;
      serial.DataBits = ByteSize.Byte8Bits;
      serial.Parity = Parity.None;
      serial.StopBits = StopBits.One;

      object data;
      data = m_Cosem.SNRMRequest();
      reply = ReadDLMSPacket(data);
      //Has server accepted client.
      m_Cosem.ParseUAResponse(reply);

      //Generate AARQ request.
      data = m_Cosem.AARQRequest(null);

      //Split regusts to multible packets if needed.
      //This must be done because all data might not be fit in one packet if password is used.
      Array arr = (Array)m_Cosem.SplitDataToPackets(data);
      int len = arr.Length;
      int pos = 0;
      foreach (byte[] it in arr)
      {
        data = it;
        data = m_Cosem.Read(data, ++pos, len, ObjectType.None, 0);
        reply = ReadDLMSPacket(data);
      }
      //Parse reply.
      m_Cosem.ParseAAREResponse(reply);
    }

    /// 
    /// Initialize network connection settings.
    /// 
    /// Device address.
    /// Port number.
    public void InitNet(string hostName, int port)
    {
      GXNet net = new GXNet();
      net.HostName = hostName;
      net.HostPort = port;
      net.Protocol = NetworkType.Tcp;
      net.Connect();
      Media = net;

      object data, reply;
      data = m_Cosem.SNRMRequest();
      reply = ReadDLMSPacket(data);

      //Has server accepted client.
      m_Cosem.ParseUAResponse(reply);

      //Generate AARQ request.
      data = m_Cosem.AARQRequest(null);

      //Split regusts to multible packets if needed.
      //This must be done because all data might not be fit in one packet if password is used.
      Array arr = (Array)m_Cosem.SplitDataToPackets(data);
      int len = arr.Length;
      int pos = 0;
      foreach (byte[] it in arr)
      {
        data = it;
        data = m_Cosem.Read(data, ++pos, len, ObjectType.None, 0);
        reply = ReadDLMSPacket(data);
      }
      //Parse reply.
      m_Cosem.ParseAAREResponse(reply);
    }

    private object ReadDLMSPacket(object data)
    {
      if (data == null)
      {
        return null;
      }
      object reply = null;
      byte Terminator = 0x7E;
      if (!Media.SendSync(data, Gurux.Common.VariantType.None, null, Terminator, 5, WaitTime, true, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, out reply))
      {
        throw new Exception("Failed to receive reply from the device in given time.");
      }
      //Loop until whole m_Cosem packet is received.
      while (!m_Cosem.IsDLMSPacketComplete(reply))
      {
        if (!Media.WaitMoreReplyData(Terminator, 0, WaitTime, true, Gurux.Common.VariantType.Array | Gurux.Common.VariantType.UInt8, ref reply))
        {
          throw new Exception("Failed to receive reply from the device in given time.");
        }
      }
      Media.SendSyncComplete = true;
      return reply;
    }

    private object ReadDataBlock(object data)
    {
      object reply;
      reply = ReadDLMSPacket(data);
      object allData = null;
      m_Cosem.GetDataFromPacket(reply, ref allData);
      int maxProgress = m_Cosem.GetMaxProgressStatus(allData);
      RequestTypes moredata = m_Cosem.IsMoreDataAvailable(reply);
      bool bOnlyFrames = (moredata & RequestTypes.DataBlock) == 0;
      while (moredata != 0)
      {
        while ((moredata & RequestTypes.Frame) != 0)
        {
          data = m_Cosem.ReceiverReady(RequestTypes.Frame);
          reply = ReadDLMSPacket(data);
          m_Cosem.GetDataFromPacket(reply, ref allData);
          if ((m_Cosem.IsMoreDataAvailable(reply) & RequestTypes.Frame) == 0)
          {
            moredata &= ~RequestTypes.Frame;
            break;
          }
          if (bOnlyFrames)
          {
            Console.Write("-");
          }
        }
        if ((moredata & RequestTypes.DataBlock) != 0)
        {
            Console.Write("-");
            //Send Receiver Ready.
            data = m_Cosem.ReceiverReady(RequestTypes.DataBlock);
            reply = ReadDLMSPacket(data);
            m_Cosem.GetDataFromPacket(reply, ref allData);
            moredata = m_Cosem.IsMoreDataAvailable(reply);
        }
      }
      Console.WriteLine("");
      return allData;
    }

    /// 
    /// Returns collection of available objects.
    /// 
    /// Available objects.
    public Gurux.DLMS2.IDLMSObjectCollection GetObjects()
    {
      object data = null;
      try
      {
        data = m_Cosem.GetObjects(RegisterObjectType.AssociationView);
        data = ReadDataBlock(data);
      }
      catch (Exception Ex)
      {
        throw new Exception("DLMS AARQRequest failed. " + Ex.Message);
      }
      Gurux.DLMS2.IDLMSObjectCollection objs = m_Cosem.ParseObjects(data, ObjectType.None);
      return objs;
    }

    /// 
    /// Get value.
    /// 
    /// Logical or Short Name of the object.
    /// Interface type.
    /// Attribute order.
    /// Data type.
    /// Interface value.
    public object GetValue(object baseName, ObjectType objectType, int attributeOrder, DataType dataType)
    {
      object data = m_Cosem.Read(baseName, 1, 1, objectType, attributeOrder);
      data = ReadDataBlock(data);
      if (dataType != DataType.None)
      {
        data = m_Cosem.ChangeType(data, dataType);
      }
      else
      {
        data = m_Cosem.GetValue(data);
      }
      if (data is byte[])
      {
        data = BitConverter.ToString((byte[])data);
      }
      return data.ToString();
    }
  }
}