Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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;
                    }
                }
            }
        }
Example #4
0
        void ServerResponse(LLCP_Link link, byte response_code)
        {
            byte[] buffer = new byte[6];

            Trace.WriteLine("SNEP Server: say " + String.Format("{0:X02}", response_code));

            buffer[0] = 0x10;             /* SNEP version */
            buffer[1] = response_code;

            link.Send_I(buffer);
        }
Example #5
0
        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);
        }
Example #6
0
        private bool HandleManagementPDU(LLCP_PDU recv_pdu)
        {
            switch (recv_pdu.PTYPE)
            {
            case LLCP_PDU.PTYPE_SYMM:
                /* This is a SYMM PDU - do nothing */
                Trace.WriteLine("> SYMM");
                SymmCount++;

                /* Check whether we have clients waiting to come to life */
                if (SymmCount > StartClientsAfterSymms)
                {
                    for (int i = 0; i < _clients.Count; i++)
                    {
                        if (_clients[i].Mode == LLCP_Client.MODE_READY)
                        {
                            Trace.WriteLine("Launching client '" + _clients[i].Name + "'");

                            _clients[i].Mode = LLCP_Client.MODE_STARTING;

                            LLCP_Link link = new LLCP_Link(this, _clients[i], (byte)(0x20 + i));
                            link.Send_Connect();
                            _links.Add(link);
                            break;
                        }
                    }
                }

                /* Nothing done */
                break;

            case LLCP_PDU.PTYPE_DISC:
                /* Link deactivation */
                Trace.WriteLine("LLCP deactivation");
                return(false);

            default:
                Trace.WriteLine("BAD PTYPE with DSAP=SSAP=0\n");
                break;
            }

            return(true);
        }
Example #7
0
        public override bool OnConnect(LLCP_Link link, byte[] ConnectParams)
        {
            Fragments = false;
            Offset    = 0;
            Buffer    = null;

            Trace.WriteLine("SNEP Server: client connect");

            byte[] param_miux = LLCP.FindParameter(ConnectParams, LLCP.PARAM_MAX_INF_UNIT_EXT);
            byte[] param_rw   = LLCP.FindParameter(ConnectParams, LLCP.PARAM_RECV_WINDOW_SIZE);

            /*
             * byte[] cc_params = new byte[4];
             *
             * cc_params[0] = LLCP.PARAM_MAX_INF_UNIT_EXT;
             * cc_params[1] = 2;
             * cc_params[2] = (byte) ((SNEP.MAX_BUFFER_SIZE - 128) / 0x0100);
             * cc_params[3] = (byte) ((SNEP.MAX_BUFFER_SIZE - 128) % 0x0100);
             *
             * link.Send_CC(cc_params);
             */

            return(true);
        }
Example #8
0
        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();
        }
Example #9
0
 public override void OnDisconnect(LLCP_Link link)
 {
     Trace.WriteLine("SNEP Client: disconnected from server");
 }
Example #10
0
 public abstract bool OnConnect(LLCP_Link link, byte[] ConnectParams);
Example #11
0
 public abstract void OnAcknowledge(LLCP_Link link);
Example #12
0
 public abstract void OnDisconnect(LLCP_Link link);
Example #13
0
 public override void OnAcknowledge(LLCP_Link link)
 {
     Trace.WriteLine("SNEP Server: client aknowledge");
 }
Example #14
0
        public override void OnInformation(LLCP_Link link, byte[] ServiceDataUnit)
        {
            if (Fragments)
            {
                /* Is the length acceptable ? */
                if (Offset + ServiceDataUnit.Length > Buffer.Length)
                {
                    /* Overflow */
                    Trace.WriteLine("SNEP Server: bad request");
                    ServerResponse(link, SNEP.RSP_BAD_REQUEST);
                    return;
                }

                /* Get the NFC_DATA */
                for (int i = 0; i < ServiceDataUnit.Length; i++)
                {
                    Buffer[Offset++] = ServiceDataUnit[i];
                }

                /* Is the message complete ? */
                if (Offset >= Buffer.Length)
                {
                    /* Yes ! Process the message */
                    Trace.WriteLine("SNEP Server: got last fragment (" + ServiceDataUnit.Length + "B)");
                    Fragments = false;
                }
                else
                {
                    /* Do nothing */
                    Trace.WriteLine("SNEP Server: got a fragment (" + ServiceDataUnit.Length + "B), more to come");
                    link.Send_RR();
                    return;
                }
            }
            else
            {
                if (ServiceDataUnit.Length < 6)
                {
                    /* Frame is too short to have the REQUEST header */
                    Trace.WriteLine("SNEP Server: bad request");
                    ServerResponse(link, SNEP.RSP_BAD_REQUEST);
                    return;
                }

                /* Get version */
                byte version = ServiceDataUnit[0];
                if ((version < 0x10) || (version >= 0x20))
                {
                    /* Version not supported */
                    Trace.WriteLine("SNEP Server: unsupported version");
                    ServerResponse(link, SNEP.RSP_UNSUPPORTED_VERSION);
                    return;
                }

                /* Request code */
                byte request = ServiceDataUnit[1];
                if (request != SNEP.REQ_PUT)
                {
                    /* Only PUT REQUEST implemented */
                    Trace.WriteLine("SNEP Server: not implemented");
                    ServerResponse(link, SNEP.RSP_NOT_IMPLEMENTED);
                    return;
                }

                /* Message length */
                uint total_length;
                total_length  = ServiceDataUnit[2]; total_length <<= 8;
                total_length |= ServiceDataUnit[3]; total_length <<= 8;
                total_length |= ServiceDataUnit[4]; total_length <<= 8;
                total_length |= ServiceDataUnit[5];

                /* Is the length acceptable ? */
                if (total_length > SNEP.MAX_BUFFER_SIZE)
                {
                    /* Overflow */
                    Trace.WriteLine("SNEP Server: reject");
                    ServerResponse(link, SNEP.RSP_REJECT);
                    return;
                }

                /* Allocate the buffer */
                Buffer = new byte[total_length];
                Offset = 0;

                /* Get the NFC_DATA */
                for (int i = 6; i < ServiceDataUnit.Length; i++)
                {
                    Buffer[Offset++] = ServiceDataUnit[i];
                }

                /* Is the message complete ? */
                if (Offset >= Buffer.Length)
                {
                    /* Yes ! Process the message */
                    Trace.WriteLine("SNEP Server: got single fragment (" + ServiceDataUnit.Length + "B)");
                }
                else
                {
                    /* No ! The client may continue */
                    Fragments = true;
                    Trace.WriteLine("SNEP Server: got first fragment (" + ServiceDataUnit.Length + "B), more to come");
                    Trace.WriteLine("SNEP Server: continue");
                    ServerResponse(link, SNEP.RSP_CONTINUE);
                    return;
                }
            }

            /* Say thank you */
            Trace.WriteLine("SNEP Server: thank you");
            ServerResponse(link, SNEP.RSP_SUCCESS);

            /* Process the message */
            if (OnMessageReceived != null)
            {
                OnMessageReceived(Buffer);
            }
        }
Example #15
0
 public override void OnDisconnect(LLCP_Link link)
 {
     Trace.WriteLine("SNEP Server: client disconnect");
 }
Example #16
0
 public abstract void OnInformation(LLCP_Link link, byte[] ServiceDataUnit);
Example #17
0
        public override bool ProcessPDU(LLCP_Link link, LLCP_PDU recv_pdu)
        {
            switch (recv_pdu.PTYPE)
            {
            case LLCP_PDU.PTYPE_CC:
                Trace.WriteLine("> CC");

                if (link.State == LLCP_Link.StateOpening)
                {
                    /* Connection accepted */
                    link.State = LLCP_Link.StateActive;
                    OnConnect(link, recv_pdu.Payload);
                }
                break;

            case LLCP_PDU.PTYPE_DM:
                Trace.WriteLine("> DM");

                /* Disconnect OK */
                if (link.State == LLCP_Link.StateActive)
                {
                    /* Peer is disconnecting */
                    link.State = LLCP_Link.StateClosed;
                    OnDisconnect(link);
                }
                else
                {
                    /* We were disconnecting - no need to invoke the callback */
                    link.State = LLCP_Link.StateClosed;
                }
                /* Drop the link */
                return(false);

            case LLCP_PDU.PTYPE_I:
                Trace.WriteLine("> I");

                /* The server is talking to us */
                if (link.State == LLCP_Link.StateActive)
                {
                    byte nr = (byte)(recv_pdu.Sequence & 0x0F);
                    byte ns = (byte)((recv_pdu.Sequence >> 4) & 0x0F);

                    OnInformation(link, recv_pdu.Payload);
                }
                break;

            case LLCP_PDU.PTYPE_RR:
                Trace.WriteLine("> RR");
                /* Acknowledge */
                if (link.State == LLCP_Link.StateActive)
                {
                    byte nr = (byte)(recv_pdu.Sequence & 0x0F);

                    OnAcknowledge(link);
                }
                break;

            case LLCP_PDU.PTYPE_RNR:
                Trace.WriteLine("> RNR");
                break;

            default:
                Trace.WriteLine("Unsupported LLCP frame server->client");
                link.Send_FRMR(0x80, recv_pdu.PTYPE, 0x00);
                /* Drop the link */
                return(false);
            }

            /* Keep the link ON */
            return(true);
        }
Example #18
0
 public abstract bool ProcessPDU(LLCP_Link link, LLCP_PDU recv_pdu);
Example #19
0
        public override bool ProcessPDU(LLCP_Link link, LLCP_PDU recv_pdu)
        {
            /* Server action */
            /* ------------- */

            link.RemotePort = recv_pdu.SSAP;
            link.LocalPort  = (byte)(_server_port & 0x3F);

            switch (recv_pdu.PTYPE)
            {
            case LLCP_PDU.PTYPE_CONNECT:
                Trace.WriteLine("> CONNECT");

                /* The client wants to connect us */
                link.State = LLCP_Link.StateActive;

                if (!OnConnect(link, recv_pdu.Payload))
                {
                    /* Failed */
                    link.Send_DM(LLCP_DM_PDU.REASON_REJECTED);                             /* 03 */
                    /* Drop the link */
                    return(false);
                }
                else
                if (!link.Answered)
                {
                    /* Confirm we agree (CC) */
                    link.Send_CC();
                }
                break;

            case LLCP_PDU.PTYPE_DISC:
                Trace.WriteLine("> DISC");

                /* The client is leaving us */
                if (link.State == LLCP_Link.StateActive)
                {
                    OnDisconnect(link);
                    link.Send_DM(LLCP_DM_PDU.REASON_DISC_OK);                             /* 00 */
                }
                else
                {
                    link.Send_DM(LLCP_DM_PDU.REASON_NO_CONNECTION);                             /* 01 */
                }
                /* Drop the link */
                return(false);

            case LLCP_PDU.PTYPE_I:
                Trace.WriteLine("> I");

                /* The client is talking to us */
                if (link.State == LLCP_Link.StateActive)
                {
                    byte nr = (byte)(recv_pdu.Sequence & 0x0F);
                    byte ns = (byte)((recv_pdu.Sequence >> 4) & 0x0F);

                    link.SetRemoteSequence((byte)((ns + 1) & 0x0F));

                    OnInformation(link, recv_pdu.Payload);

                    if (!link.Answered)
                    {
                        /* No frame -> ACK */
                        link.Send_RR();
                    }
                }
                else
                {
                    link.Send_DM(LLCP_DM_PDU.REASON_NO_CONNECTION);                             /* 01 */
                }
                break;

            case LLCP_PDU.PTYPE_RR:
                Trace.WriteLine("> RR");

                /* The client is acknowledging */
                if (link.State == LLCP_Link.StateActive)
                {
                    byte nr = (byte)(recv_pdu.Sequence & 0x0F);

                    OnAcknowledge(link);
                }
                else
                {
                    link.Send_DM(LLCP_DM_PDU.REASON_NO_CONNECTION);                             /* 01 */
                }
                break;

            default:
                Trace.WriteLine("Unsupported LLCP frame client->server");
                link.Send_FRMR(0x80, recv_pdu.PTYPE, 0x00);
                /* Drop the link */
                return(false);
            }

            /* Keep the link OK */
            return(true);
        }
Example #20
0
        protected bool HandleRecvPDU(LLCP_PDU recv_pdu)
        {
            LLCP_Link link;

            if ((recv_pdu.DSAP == 0) && (recv_pdu.SSAP == 0))
            {
                /* Management PDUs */
                /* --------------- */

                return(HandleManagementPDU(recv_pdu));
            }

            SymmCount = 0;

            if (recv_pdu.PTYPE == LLCP_PDU.PTYPE_CONNECT)
            {
                /* Handle CONNECT */
                /* -------------- */

                Trace.WriteLine("> CONNECT");

                /* Name server is listening on address 01 */
                if (recv_pdu.DSAP == ADDR_NAME_SERVER)
                {
                    /* Using name server */
                    string server_name = FindParameterStr(recv_pdu.Payload, LLCP.PARAM_SERVICE_NAME);

                    if (server_name != null)
                    {
                        Trace.WriteLine("Looking for server '" + server_name + "'");

                        /* Looking for a server by its name */
                        for (int i = 0; i < _servers.Count; i++)
                        {
                            if (_servers[i].ServerName == server_name)
                            {
                                link           = new LLCP_Link(this, _servers[i], recv_pdu);
                                link.LocalPort = _servers[i].ServerPort;

                                if (link.ProcessPDU(recv_pdu))
                                {
                                    _links.Add(link);
                                }

                                return(true);
                            }
                        }
                    }
                }
                else
                {
                    /* Using server address */

                    Trace.WriteLine("Looking for server " + recv_pdu.DSAP);

                    for (int i = 0; i < _servers.Count; i++)
                    {
                        if (_servers[i].ServerPort == recv_pdu.DSAP)
                        {
                            link = new LLCP_Link(this, _servers[i], recv_pdu);

                            if (link.ProcessPDU(recv_pdu))
                            {
                                _links.Add(link);
                            }

                            return(true);
                        }
                    }
                }
            }

            /* Looking for an already-connected Server, or already instancied Client */
            /* --------------------------------------------------------------------- */

            for (int i = 0; i < _links.Count; i++)
            {
                if (_links[i].LocalPort == recv_pdu.DSAP)
                {
                    if (!_links[i].ProcessPDU(recv_pdu))
                    {
                        /* Drop the link */
                        _links.RemoveAt(i);
                    }

                    return(true);
                }
            }

            /* No client, no server, and DSAP or SSAP != 0 */
            link = new LLCP_Link(this, null, recv_pdu);

            switch (recv_pdu.PTYPE)
            {
            case LLCP_PDU.PTYPE_CONNECT:
                /* Peer is trying to connect to a non-existing service */
                Trace.WriteLine("CONNECT to non existing server");
                link.Send_DM(LLCP_DM_PDU.REASON_NO_SERVICE);
                break;

            case LLCP_PDU.PTYPE_RR:
            case LLCP_PDU.PTYPE_I:
                Trace.WriteLine("I or RR to non active service");
                link.Send_DM(LLCP_DM_PDU.REASON_NO_CONNECTION);                         /* 01 */
                break;

            default:
                Trace.WriteLine("No client, no server, bad PTYPE");
                break;
            }

            return(true);
        }