NFC P2P - SNEP Client / Server - server

As i wrote in another post ("Symmetry Procedure" in NFC P2P LLCP) i'm currently trying to implement the LLCP & SNEP protocol on a PN532 chip.
The question i had in the other post was about the Symmetry Procedure as defined in LLCP which allows
to actually bypass the original Initiator / Target roles (command / response) i.e. gives each peer device
the change to send a message at any time.
If i got it right, the SNEP-protocol defines a Client / Server approach. The role is actually defined at
the LLCP-level when one device (client) sends a CONN-PDU to the peer device (server).
Afterwards the client can send NDEF-messages to the server by using a "PUT Request" as defined in SNEP.
Let's assume now, the client has sent it's NDEF message to the server and - depending on the application -
the peer device which currently acts as a server wants to send a new (not a response) NDEF message back to the
current client.
My assumption is that the current server would send a new CONN-PDU to the current client and in case this succeeds,
both both devices change their initial roles i.e. the initial client becomes now the server etc.
What happens to the initially established connection ? Will it be closed or can still exist in parallel to the new one ?
In addition (if my assumption from above is correct), is it also necessary on the NFC MAC level that the Client / Server change
mandates also a change of the Initiator / Target roles or can both devices stay in their initial (MAC) modes ?
Thanks a lot !

If i got it right, the SNEP-protocol defines a Client / Server
approach. The role is actually defined at the LLCP-level when one
device (client) sends a CONN-PDU to the peer device (server).
No, that's not how it works. The role is not defined that way. It is not obvious from the specification, but each peer usually is a client and a server at the same time.
Note that the spec section 6.1 "Functional Description" defines the following default behavior:
The default server SHALL NOT accept Get requests.
That means, that a client is in general not allowed to request NDEF messages. The client is supposed to push it's own message if available.
The usual message flow in SNEP looks like this:
Initial state: LLCP link is down. Each peer has a SNEP server registered and waiting for connections.
On LLCP connect: Each peer that wants to send a message tries to connect to the opposing SNEP server using it's own SNEP client.
On SNEP connect the SNEP server will: wait for a SNEP PUT command. It can then either accept the message or reject it:
On SNEP connect the SNEP client will: send out a PUT command along with it's NDEF data.
Once each side has transmitted it's message (if they wanted to) they just leave the SNEP connections open. There is no proper way to close this connection anyway and there is also no cost associated with it. Each client can - at any time - always send an additional PUT request if they want to. This can be useful to esablish an bidirectional data-flow over SNEP.
Android won't allow this bidirectinal data-flow because they somewhat dumbed down SNEP a bit and don't allow a second message to be sent, but they will happily accept additional messages passed to it.

Related

How to check whether user already authenticated via UDP

Suppose that I have to write a UDP server which should receive authentication token for each client in the first message and then receive different data after some period of time. This UDP server should obviously check whether certain client authenticated previously or not. How should I do it? Should I store "authenticated" flag for each (IP addr, port) pair? Is it ok? If so, what will happen if several clients will have the same IP address (for example, they share it from the same internet provider)?
I think you can't. You'll need to have the token in each message. Multiple requests can come from the same IP, such as a client connecting from behind a NAT.
This a rare case where you might want to use multiple UDP sockets at the server and connect() each of them to one authenticated client, so that you can only receive further messages on each one from each authenticated client. You'll have to send the first reply via hat socket,a denture client will have to be written to adjust its destination accordingly after receiving the first reply.

xmpp messages are lost when client connection lost suddently

I am using ejabberd server and ios xmppframework.
there are two clients, A and B.
When A and B are online, A can send message to B successfully.
If B is offline, B can receive the message when B is online again.
But when B is suddenly/unexpectedly lost connection, such as manually close wi-fi, the message sent by A is lost. B will never
receive this message.
I guess the reason is that B lost connection suddenly and the server still think B is online. Thus the offline message does work under this condition.
So my question is how to ensure the message that sent by A will be received by B? To ensure there is no messages lost.
I've spent the last week trying to track down missing messages in my XMPPFramework and eJabberd messaging app. Here are the full steps I went through to guarantee message delivery and what the effects of each step are.
Mod_offline
In the ejabberd.yml config file ensure that you have this in the access rules:
max_user_offline_messages:
admin: 5000
all: 100
and this in the modules section:
mod_offline:
access_max_user_messages: max_user_offline_messages
When the server knows the recipient of a message is offline they will store it and deliver it when they re-connect.
Ping (XEP-199)
xmppPing = XMPPPing()
xmppPing.respondsToQueries = true
xmppPing.activate(xmppStream)
xmppAutoPing = XMPPAutoPing()
xmppAutoPing.pingInterval = 2 * 60
xmppAutoPing.pingTimeout = 10.0
xmppAutoPing.activate(xmppStream)
Ping acts like a heartbeat so the server knows when the user is offline but didn't disconnect normally. It's a good idea to not rely on this by disconnecting on applicationDidEnterBackground but when the client looses connectivity or the stream disconnects for unknown reasons there is a window of time where a client is offline but the server doesn't know it yet because the ping wasn't expected until sometime in the future. In this scenario the message isn't delivered and isn't stored for offline delivery.
Stream Management (XEP-198)
xmppStreamManagement = XMPPStreamManagement(storage: XMPPStreamManagementMemoryStorage(), dispatchQueue: dispatch_get_main_queue())
xmppStreamManagement.autoResume = true
xmppStreamManagement.addDelegate(self, delegateQueue: dispatch_get_main_queue())
xmppStreamManagement.activate(xmppStream)
and then in xmppStreamDidAuthenticate
xmppStreamManagement.enableStreamManagementWithResumption(true, maxTimeout: 100)
Nearly there. The final step is to go back to the ejabberd.yml and add this line to the listening ports section underneath access: c2s:
resend_on_timeout: true
Stream Management adds req/akn handshakes after each message delivery. On it's own it won't have any effect on the server side unless that resend_on_timeout is set (which it isn't by default on eJabberd).
There is a final edge case which needs to be considered when the acknowledgement of a received message doesn't get to the server and it decides to hold it for offline delivery. The next time the client logs in they are likely to get a duplicate message. To handle this we set that delegate for the XMPPStreamManager. Implement the xmppStreamManagement getIsHandled: and if the message has a chat body set the isHandledPtr to false. When you construct an outbound message add an xmppElement with a unique id:
let xmppMessage = XMPPMessage(type: "chat", to: partnerJID)
let xmppElement = DDXMLElement(name: "message")
xmppElement.addAttributeWithName("id", stringValue: xmppStream.generateUUID())
xmppElement.addAttributeWithName("type", stringValue: "chat")
xmppElement.addAttributeWithName("to", stringValue: partnerJID.bare())
xmppMessage.addBody(message)
xmppMessage.addChild(xmppElement)
xmppMessage.addReceiptRequest()
xmppStream.sendElement(xmppMessage)
Then when you receive a message, inform the stream manager that the message has been handled with xmppStreamManager.markHandledStanzaId(message.from().resource)
The purpose of this final step is to establish a unique identifier that you can add to the XMPPMessageArchivingCoreDataStorage and check for duplicates before displaying.
I guess the reason is that B lost connection suddenly and the server
still think B is online. Thus the offline message does work under this
condition
Yes you are absolutely correct,this is well known limitation of TCP connections.
There are two approaches to your problem
1 Server side
As I can see you are using ejabbed as XMPP server you can implement
mod_ping , Enabling this module will enables server side
heartbeat[ping] ,in case of broken connection to server[ejabbed] will
try to send heartbeat to connection and will detect connection is lost
between server and client. Use of this approach has one
drawback,module mod_ping has property called ping_interval which
states how often to send heartbeat to connected clients, here lower
limit is 32 seconds any value below 32 is ignored by ejabbed,means
you have 32 seconds black window in which messages can be lost if user
is sowing as online
2 Client side
From client side you can implement Message Delivery Receipts
mechanism .With each Chat message send a receipt to receiver user of
as soon as receiver user receives message send back this receipt
id. This way you can detect that your message is actually delivered to
receiver. If you don't receive such acknowledgement between certain
time interval you can show user as offline locally(on mobile
phone),store any further messages to this user as offline message
locally[in SQLLight database ],and wait for offline presence stanza for that user
,as soon as you receive offline presence stanza it means that server
has finally detected connection to that user is lost and makes user
status as offline ,now you can send all messages to that user ,which
will be again stored as offline messages on server.This is best
approach to avoid black-window.
Conclusion
You can either use Approach 2 and design you client such way ,you can also use Approach 1 along with approach 2 to minimize server broken connection detraction time.
If B goes offline suddenly then user A have to check if B is online/offline while sending message to user B. If user B is offline then user A have to upload that message on Server using Web service. And user B have to call web service on below function.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
So user B will get that all offline message which was lost due to connection Lost.
At last, I use Ping together with Stream Management:
http://xmpp.org/extensions/xep-0198.html
This problem is solved.

Determine TLS support BEFORE sending email

We have a system that can send emails using TLS. However, we only want to send full email w/attachments if the destination supports TLS. IF it does not support TLS, we send a different message without attachments.
We used to just try sending with TLS and waiting for the receiver to "fail" back to us, then send the backup message. Recently, we switched to relaying through Frontbridge for all of our outgoing messages. However, Frontbridge will send a message using TLS if it can, or without if it can't. We've lost the ability to customize our message based on TLS support.
The question is this: in a .NET C# web app, how can I tell if a destination supports TLS BEFORE sending anything? That way we can customize the message BEFORE relaying it through Frontbridge.
I need to be able to do this programmatically, but I don't want to have to add a whole library to our solution (like Minimalistic Telnet), because we don't need full telnet functionality... I just need to ping to server and ask it what it supports!
Can that be done simply using the System.Net.Sockets stuff??
Thanks,
Kevin
Yes, you need to write part of SMTP protocol.
For explicit TLS mode: You connect, receive and send data, then send STARTTLS command and see if the response is 220. Then you should close connection.
For implicit TLS you would need to emulate or use an SSL/TLS client: send initial request, check the response and disconnect.
As you don't want to use external libraries, I can't recommend you our SecureBlackbox, whose SMTP component lets you do what you need in a dozen of lines of code.

Detecting other clients using the same account in XMPP

XMPP allows users to connect to the server from multiple clients simultaneously, using the same account. I built an application that does this but if the desktop client is enabled, I do not want the users to be able to connect using a mobile client. This is for a game and being connected to both causes problems.
So what I'm wondering is:
Is it possible to detect if there are other clients connected using the same account. If I can check for other clients, I can auto logout the user.
#Flow was on the right track. If all of your client instances use the same resource, in most servers, the later-connecting client will replace the older session. The older session will get a conflict stream error, and be disconnected. You MUST be careful not to auto-reconnect with the older client, or you will have written the "dueling resources" bug.
If you had control over your server, you have a chance at configuring it to allow a maximum of one resource for a given user, in which case the newer connection will fail with a conflict error, but you'll have worse user interface problems if you head down that path; there will be no way to get the second client logged in, even if you wanted to.
Finally, all resources for a given user are subscribed to that user's presence. As long as your client sends presence in:
<presence/>
you will receive presence from each of your other devices:
<presence to='user#example.com/resource1' from='user#example.com/resource2'/>
<presence to='user#example.com/resource1' from='user#example.com/resource3'/>
<presence to='user#example.com/resource1' from='user#example.com/resource4'/>
You could use this to decide which client is current, perhaps by adding an extension to the presence like XEP-0115.
Give the desktop and mobile client a fixed but different resource string. If the mobile client logs in, it can detect the presence of the desktop client by looking up the presence/availability of the resource of the desktop client and vice versa.
Then you only need to implement an custom XMPP ad-hoc command (XEP-0050) that tells the conflicting resource to log out.
It would be the servers responsibility: to reject a login from a client that is not accepted. I don't know if servers are able to blacklist xmpp clients but, in case you use openfire, you should be able to write an extension.

Push mechanism of Exchange Activesync

I've a question regarding the over all design of push email and specifically the approach taken by Exchange ActiveSync.
As I understand there are two basic ways to get push email with the following architecture
Device <---> Push Email Server <---> Actual Email server
Keep a constant socket connection between Push email server and device. Push email server will inform device over the connection.
Related technology - IMAP IDLE
No sms gateway required
The Push email server will send a message (wap push, sms etc) to ask device to download new email.
Related technology- OMA-ENM
Needs a SMS gateway at Push email server
Considering this, what type of push email service does Exchange Activesync actually offer?
(AFAIK, white label push solution from Emoze/Synchronica uses the 1st approach - constant connection over something like IMAP-IDLE).
Exchange ActiveSync uses Direct Push. The client (phone, whatever) syncs with the Exchange server and then makes a very long-running HTTP POST request (called a "PING", but it's not an ICMP ping or anything like that). When the client issues the request they specify how long it should run for (typically it's on the order of many minutes).
That HTTP POST request will sit there idle on the Exchange server's side until either a change occurs in the mailbox or the time period requested by the client had simply passed with nothing of interest happening.
In the case of the former - where something changed in the mailbox - the return value of the POST call indicates to the client that it needs to re-sync with the mailbox to pull down the latest changes.
In the case of the latter - where nothing changed at all - the return value specifies this and the client simply re-sends another long-running PING to the server, repeating the whole process again.
So it's your #1, really. For more information, this Microsoft link goes into more detail.
I think Exchange ActiveSync offers something similar to IMAP-IDLE, see below...
http://technet.microsoft.com/en-us/library/aa997252.aspx
If you've come to a different conclusion please post. Thanks!