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; } } } }
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); }
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); }
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 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); }
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(); }
public abstract void OnAcknowledge(LLCP_Link link);
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); } }
public override void OnAcknowledge(LLCP_Link link) { Trace.WriteLine("SNEP Server: client aknowledge"); }
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 override void OnDisconnect(LLCP_Link link) { Trace.WriteLine("SNEP Server: client disconnect"); }
public abstract bool ProcessPDU(LLCP_Link link, LLCP_PDU recv_pdu);
public override void OnDisconnect(LLCP_Link link) { Trace.WriteLine("SNEP Client: disconnected from server"); }
public abstract bool OnConnect(LLCP_Link link, byte[] ConnectParams);
public abstract void OnDisconnect(LLCP_Link link);
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 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 abstract void OnInformation(LLCP_Link link, byte[] ServiceDataUnit);