Inheritance: Techsteel.Drivers.CIP.CIPSerializer
Ejemplo n.º 1
0
        private void ThreadTask()
        {
            try
            {
                while (!m_Terminate)
                {
                    switch (m_ClientConnStates)
                    {
                    case ClientConnStates.Disconnected:
                    {
                        break;
                    }

                    case ClientConnStates.SendListServices:
                    {
                        CommandEtherNetIPHeader msgListServices = new CommandEtherNetIPHeader {
                            Command = EncapsulationCommands.ListServices
                        };
                        SendMessage(msgListServices, null);
                        m_ClientConnStates = ClientConnStates.WaitListServicesReply;
                        break;
                    }

                    case ClientConnStates.SendRegisterSession:
                    {
                        MsgRegisterSessionRequest msg    = new MsgRegisterSessionRequest();
                        CommandEtherNetIPHeader   header = new CommandEtherNetIPHeader {
                            Command = EncapsulationCommands.RegisterSession
                        };
                        msg.CommandSpecificDataRegisterSession = new CommandSpecificDataRegisterSession {
                            ProtocolVersion = 1
                        };
                        header.Length = msg.CommandSpecificDataRegisterSession.SizeOf();
                        SendMessage(header, msg);
                        m_ClientConnStates = ClientConnStates.WaitRegisterSessionReply;
                        break;
                    }

                    case ClientConnStates.SendReceive:
                    {
                        if (m_DataToSend != null)
                        {
                            CommandEtherNetIPHeader header = new CommandEtherNetIPHeader {
                                Command       = EncapsulationCommands.SendRRData,
                                SessionHandle = m_SessionHandle,
                                SenderContext = BitConverter.GetBytes(m_SenderContext)
                            };
                            MsgUnconnectedSendRequest msg = new MsgUnconnectedSendRequest {
                                CommandSpecificDataSendRRData = new CommandSpecificDataSendRRData {
                                    InterfaceHandle = 0,
                                    Timeout         = 0,
                                    ItemCount       = 2,
                                    List            = new CommandSpecificDataSendRRDataItem[] {
                                        new CommandSpecificDataSendRRDataItem {
                                            TypeID = 0,
                                            Length = 0
                                        },
                                        new CommandSpecificDataSendRRDataItem {
                                            TypeID = CommonPacketItemID.UnconnectedMessage,
                                            Length = 0
                                        }
                                    }
                                },
                                CommonIndustrialProtocolRequest = new CommonIndustrialProtocolRequest {
                                    Service         = 0x52, // Unconnected Send Service ID
                                    RequestPathSize = 2,
                                    PathSegmentList = new List <PathSegment> {
                                        new LogicalPathSegment8bits {
                                            PathSegmentType = 0x20,
                                            LogicalValue    = 0x06  // Connection Manager Class ID
                                        },
                                        new LogicalPathSegment8bits {
                                            PathSegmentType = 0x24,
                                            LogicalValue    = 0x01  // Connection Manager Instance ID
                                        }
                                    }
                                },
                                CIPConnectionManagerUnconnSnd = new CIPConnectionManagerUnconnSnd {
                                    PriorityAndPickTime             = 0x07,
                                    TimeOutTicks                    = 233,
                                    MessageRequestSize              = 0,
                                    CommonIndustrialProtocolRequest = new CommonIndustrialProtocolRequest {
                                        Service         = 0x4d, // CIP Write Data Service
                                        RequestPathSize = 0,
                                    },
                                    CIPClassGeneric = new CIPClassGeneric {
                                        DataType         = m_DataTypeToSend,
                                        SpecificDataSize = (ushort)(m_DataToSend.Length / CIPClassGeneric.GetDataTypeSize(m_DataTypeToSend)),
                                        CIPClassGenericCmdSpecificData = m_DataToSend,
                                    },
                                    Pad           = null,
                                    RoutePathSize = 0,
                                    Reserved      = 0,
                                    RoutePath     = new List <PathSegment> {
                                        new PortPathSegment {
                                            PathSegmentType                = 0x01,
                                            OptionalLinkAddressSize        = null,
                                            OptionalExtendedPortIdentifier = null,
                                            LinkAddress = new byte[] { m_LinkAddress },
                                            Pad         = null
                                        }
                                    }
                                }
                            };

                            msg.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.PathSegmentList = new List <PathSegment>();
                            string[] segs = m_Symbol.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string seg in segs)
                            {
                                msg.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.PathSegmentList.Add(
                                    new DataPathSegmentANSISymb {
                                        PathSegmentType = 0x91,
                                        DataSize        = (byte)seg.Length,
                                        ANSISymbol      = Encoding.ASCII.GetBytes(seg.Length % 2 == 0 ? seg : seg + "\0")
                                    });
                            }

                            msg.CIPConnectionManagerUnconnSnd.Pad           = (msg.CIPConnectionManagerUnconnSnd.SizeOf() % 2) == 0 ? null : (byte?)0;
                            msg.CIPConnectionManagerUnconnSnd.RoutePathSize = (byte)(msg.CIPConnectionManagerUnconnSnd.RoutePath.Sum(a => a.SizeOf()) / 2);
                            msg.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.RequestPathSize = (byte)(msg.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.PathSegmentList.Sum(a => a.SizeOf()) / 2);
                            msg.CIPConnectionManagerUnconnSnd.MessageRequestSize = (ushort)(msg.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.SizeOf() + msg.CIPConnectionManagerUnconnSnd.CIPClassGeneric.SizeOf());
                            msg.CommandSpecificDataSendRRData.List[1].Length     = (ushort)(msg.CommonIndustrialProtocolRequest.SizeOf() + msg.CIPConnectionManagerUnconnSnd.SizeOf());
                            header.Length = msg.SizeOf();
                            SendMessage(header, msg);
                        }
                        else
                        {
                            CommandEtherNetIPHeader msgListServices = new CommandEtherNetIPHeader {
                                Command = EncapsulationCommands.NOP
                            };
                            SendMessage(msgListServices, null);
                        }
                        break;
                    }
                    }
                    if (!m_Terminate)
                    {
                        m_ThreadResetEvent.WaitOne(2000);
                    }
                }
            }
            catch (Exception exc)
            {
                Trace(EventType.Error, string.Format("{0} - Thread exception: {1}", LOG_TAG, exc.Message));
                Trace(exc);
            }
        }
Ejemplo n.º 2
0
        private void MessageFactory(CommandEtherNetIPHeader header, byte[] bodyBytes)
        {
            try
            {
                Trace(EventType.Full, string.Format("{0} - Receive msg. '{1}'", LOG_TAG, header.Command));
                long headerSize = Marshal.SizeOf(typeof(CommandEtherNetIPHeader));
                switch (header.Command)
                {
                case EncapsulationCommands.ListServices:
                {
                    if (bodyBytes.Length == 0)
                    {
                        MsgListServiceReply msg = new MsgListServiceReply();
                        msg.CommandSpecificDataListServices           = new CommandSpecificDataListServices();
                        msg.CommandSpecificDataListServices.ItemCount = 1;
                        msg.CommandSpecificDataListServices.Items     = new CommandSpecificDataListServicesItem[1];
                        msg.CommandSpecificDataListServices.Items[0]  = new CommandSpecificDataListServicesItem
                        {
                            TypeCode        = CommonPacketItemID.ListServicesResponse,
                            Version         = 1,
                            CapabilityFlags = Convert.ToUInt16("100100000", 2),
                            ServiceName     = Encoding.ASCII.GetBytes("Communications\0\0")
                        };
                        header.Length = msg.SizeOf();
                        msg.CommandSpecificDataListServices.Items[0].Length =
                            (ushort)(msg.CommandSpecificDataListServices.Items[0].SizeOf() - 2 - 2);
                        SendMessage(header, msg);
                    }
                    break;
                }

                case EncapsulationCommands.RegisterSession:
                {
                    int pointer = 0;
                    CommandSpecificDataRegisterSession cmdSpecData =
                        (CommandSpecificDataRegisterSession)CommandSpecificDataRegisterSession.Deserialize(
                            typeof(CommandSpecificDataRegisterSession), bodyBytes, ref pointer);
                    MsgRegisterSessionReply msg = new MsgRegisterSessionReply();
                    // TODO: check the protocol version to accept the registration
                    msg.CommandSpecificDataRegisterSession = cmdSpecData;
                    m_SessionHandle      = (uint)((DateTime.Now.Ticks / 10) & 0xFFFFFFFF);
                    header.SessionHandle = m_SessionHandle;
                    header.Length        = msg.SizeOf();
                    SendMessage(header, msg);
                    Trace(EventType.Info, string.Format("{0} - Registration session number: {1}", LOG_TAG, header.SessionHandle));
                    break;
                }

                case EncapsulationCommands.SendRRData:
                {
                    if (header.SessionHandle != m_SessionHandle)
                    {
                        throw new Exception(string.Format("Received invalid session handle (unregistred) in SendRRData message: ", header.SessionHandle));
                    }
                    int pointer = 0;
                    MsgUnconnectedSendRequest unconnSndReq = (MsgUnconnectedSendRequest)MsgUnconnectedSendRequest.Deserialize(
                        typeof(MsgUnconnectedSendRequest), bodyBytes, ref pointer);
                    string             symbol   = Encoding.ASCII.GetString(((DataPathSegmentANSISymb)unconnSndReq.CIPConnectionManagerUnconnSnd.CommonIndustrialProtocolRequest.PathSegmentList[0]).ANSISymbol);
                    ElementaryDataType dataType = unconnSndReq.CIPConnectionManagerUnconnSnd.CIPClassGeneric.DataType;
                    OnReceiveData?.Invoke(m_ScktConn.RemoteEndPoint, symbol.Replace("\0", ""), dataType, unconnSndReq.CIPConnectionManagerUnconnSnd.CIPClassGeneric.CIPClassGenericCmdSpecificData);
                    MsgUnconnectedSendReply msg = new MsgUnconnectedSendReply();
                    msg.CommandSpecificDataSendRRData = unconnSndReq.CommandSpecificDataSendRRData;
                    CommandSpecificDataSendRRDataItem item = msg.CommandSpecificDataSendRRData.List.First(
                        a => a.TypeID == CommonPacketItemID.UnconnectedMessage);
                    msg.CommonIndustrialProtocolReply = new CommonIndustrialProtocolReply {
                        Service              = 0xcd,
                        Reserved             = 0x0,
                        GeneralStatus        = 0x0, // <- success
                        AdditionalStatusSize = 0x0,
                        AdditionalStatus     = new ushort[0]
                    };
                    item.Length   = msg.CommonIndustrialProtocolReply.SizeOf();
                    header.Length = msg.SizeOf();
                    SendMessage(header, msg);
                    break;
                }

                case EncapsulationCommands.UnRegisterSession:
                {
                    break;
                }

                default:
                {
                    Trace(EventType.Error, string.Format("{0} - Command {1} not implemented", LOG_TAG, header.Command));
                    break;
                }
                }
            }
            catch (Exception e)
            {
                Trace(e);
            }
        }