private void ClientNEXT(LLCP_Link link, SNEP_ClientInstanceData instance)
        {
            if (SnepDataToSend == null)
            {
                return;
            }

            int length = SnepDataToSend.Length - instance.Offset;

            if (length <= 0)
            {
                return;
            }

            if (length > instance.FragmentSize)
            {
                length = instance.FragmentSize;
            }

            byte[] buffer = new byte[length];
            for (int i = 0; i < length; i++)
            {
                buffer[i] = SnepDataToSend[instance.Offset++];
            }

            if (instance.Offset >= SnepDataToSend.Length)
            {
                instance.MayContinue = false;
            }

            Trace.WriteLine("SNEP Client: sending (" + instance.Offset + "/" + SnepDataToSend.Length + "): " + (new CardBuffer(buffer)).AsString());
            instance.SomethingSent = true;
            link.Send_I(buffer);
        }
        private void ClientPUT(LLCP_Link link, SNEP_ClientInstanceData instance)
        {
            int length = 6 + SnepDataToSend.Length;

            if (length > instance.FragmentSize)
            {
                instance.Offset = instance.FragmentSize - 6;
                length          = instance.FragmentSize;
            }
            else
            {
                instance.Offset = length - 6;
            }

            byte[] buffer = new byte[length];

            buffer[0] = 0x10;             /* SNEP version */
            buffer[1] = SNEP.REQ_PUT;
            buffer[4] = (byte)(SnepDataToSend.Length / 0x0100);
            buffer[5] = (byte)(SnepDataToSend.Length % 0x0100);

            for (int i = 0; i < instance.Offset; i++)
            {
                buffer[i + 6] = SnepDataToSend[i];
            }

            Trace.WriteLine("SNEP Client: sending (" + instance.Offset + "/" + SnepDataToSend.Length + "): " + (new CardBuffer(buffer)).AsString());
            instance.SomethingSent = true;
            link.Send_I(buffer);
        }
        public override void OnAcknowledge(LLCP_Link link)
        {
            SNEP_ClientInstanceData instance = (SNEP_ClientInstanceData)link.InstanceData;

            if (instance.MayContinue)
            {
                Trace.WriteLine("SNEP Client: RR -> Next I");
                ClientNEXT(link, instance);
            }
            else if (instance.SomethingSent)
            {
                Trace.WriteLine("SNEP Client: RR (thank you)");
                instance.SomethingSent = false;
            }
            else
            {
                Trace.WriteLine("SNEP Client: RR unexpected");
                if (MessageSentCallbackOnAcknowledge)
                {
                    if ((OnMessageSent != null) && (!instance.MessageSentSent))
                    {
                        OnMessageSent();
                        instance.MessageSentSent = true;
                    }
                }
            }
        }
        public override void OnConnect(LLCP_Link link, byte[] payload)
        {
            Trace.WriteLine("SNEP Client: connected to server");

            if (SnepDataToSend == null)
            {
                return;
            }

            SNEP_ClientInstanceData instance = new SNEP_ClientInstanceData();

            link.InstanceData     = instance;
            instance.FragmentSize = link.MaxPayload;

            ClientPUT(link, instance);
        }
        public override void OnInformation(LLCP_Link link, byte[] ServiceDataUnit)
        {
            SNEP_ClientInstanceData instance = (SNEP_ClientInstanceData)link.InstanceData;

            Trace.WriteLine("SNEP Client: I...");
            instance.SomethingSent = false;

            if (ServiceDataUnit.Length < 2)
            {
                /* Frame is too short to have the RESPONSE header */
                Trace.WriteLine("SNEP Client: I.Bad length");
                goto close;
            }

            /* Get version */
            byte version = ServiceDataUnit[0];

            if ((version < 0x10) || (version >= 0x20))
            {
                /* Version not supported */
                Trace.WriteLine("SNEP Client: I.Bad version");
                goto close;
            }

            /* Response code */
            byte response = ServiceDataUnit[1];

            switch (response)
            {
            case SNEP.RSP_CONTINUE:
                /* Message successfully transmited, let's continue */
                instance.MayContinue = true;
                Trace.WriteLine("SNEP Client: I.Continue -> send RR, then second I");
                link.Send_RR();
                ClientNEXT(link, instance);
                break;

            case SNEP.RSP_SUCCESS:
                /* Message successfully transmited, let's disconnect */
                Trace.WriteLine("SNEP Client: I.Success -> send RR");
                /* Acknowledge */
                link.Send_RR();
                if ((OnMessageSent != null) && (!instance.MessageSentSent))
                {
                    OnMessageSent();
                    instance.MessageSentSent = true;
                }
                break;

            default:
                /* An error has occured */
                Trace.WriteLine("SNEP Client: I.Bad Opcode");
                goto close;
            }

            /*  */
            return;

close:

            Trace.WriteLine("SNEP Client: Force exit");
            link.Send_Disc();
        }