protected override LLCP_PDU Exchange(LLCP_PDU send_pdu) { Trace.WriteLine("< " + send_pdu.AsString()); CAPDU capdu = new CAPDU(0xFF, 0xFE, 0x00, 0x00, send_pdu.GetBytes()); Trace.WriteLine("< " + capdu.AsString()); RAPDU rapdu = _channel.Transmit(capdu); if (rapdu == null) { return(null); } Trace.WriteLine("> " + rapdu.AsString()); if (rapdu.SW != 0x9000) { return(null); } LLCP_PDU recv_pdu = new LLCP_PDU(rapdu.data); Trace.WriteLine("> " + recv_pdu.AsString()); return(recv_pdu); }
public LLCP_Link(LLCP llcp, LLCP_Service service, LLCP_PDU recv_pdu) { _llcp = llcp; _service = service; RemotePort = recv_pdu.SSAP; LocalPort = recv_pdu.DSAP; }
private void thread_proc() { Trace.WriteLine("LLCP Initiator starting..."); while (thread_running) { LLCP_PDU send_pdu = SendPDU_POP(); if (send_pdu == null) { /* We send a SYMM PDU */ send_pdu = new LLCP_SYMM_PDU(); } LLCP_PDU recv_pdu = Exchange(send_pdu); if (recv_pdu == null) { Trace.WriteLine("Exchange failed"); break; } if ((recv_pdu.PTYPE == LLCP_PDU.PTYPE_SYMM) && (recv_pdu.DSAP == 0) && (recv_pdu.SSAP == 0)) { /* SYMM */ } if (!HandleRecvPDU(recv_pdu)) { Trace.WriteLine("Process failed"); break; } } Trace.WriteLine("LLCP Initiator exiting"); if (reset_field) { Trace.WriteLine("Reset the RF field"); _channel.Transmit(new CAPDU(0xFF, 0xFB, 0x10, 0x00)); System.Threading.Thread.Sleep(300); // _channel.Transmit(new CAPDU(0xFF, 0xFB, 0x10, 0x01)); // System.Threading.Thread.Sleep(300); reset_field = false; } if (suspend_reader) { Trace.WriteLine("Stop the reader"); _channel.Transmit(new CAPDU(0xFF, 0xF0, 0x00, 0x00, new byte[] { 0x22 })); suspend_reader = false; } Trace.WriteLine("Disconnect..."); _channel.DisconnectEject(); Trace.WriteLine("LLCP Initiator terminated"); }
protected LLCP_PDU SendPDU_POP() { LLCP_PDU r = null; if (_send_queue.Count > 0) { r = _send_queue[0]; _send_queue.RemoveAt(0); } return(r); }
public bool ProcessPDU(LLCP_PDU recv_pdu) { _answered = false; switch (recv_pdu.PTYPE) { case LLCP_PDU.PTYPE_CONNECT: case LLCP_PDU.PTYPE_CC: RemoteSequence = 0; LocalSequence = 0; break; default: break; } return(_service.ProcessPDU(this, recv_pdu)); }
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); }
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); }
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); }
public abstract bool ProcessPDU(LLCP_Link link, LLCP_PDU recv_pdu);
protected abstract LLCP_PDU Exchange(LLCP_PDU myPdu);
// public void ClientConnectToServer(LlcpClient client, LLCP_PARAMETER[] Parameters) // { /* The client wants to connect to the server -> Push a connect PDU */ // EnqueueSendPdu(new LLCP_CONNECT_PDU(client.ServerAddress(), client.LocalAddress(), Parameters)); // } public void SendPDU_PUSH(LLCP_PDU send_pdu) { _send_queue.Add(send_pdu); }
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); }
public LLCP_PAX_PDU(LLCP_PDU LLCP_PDU) : base(LLCP_PDU) { }
public LLCP_PDU(LLCP_PDU LLCP_PDU) { _bytes = LLCP_PDU.GetBytes(); }