FW: SMCP client multiple requests and observing

53 views
Skip to first unread message

Steven J. Ackerman

unread,
Nov 12, 2014, 12:40:47 PM11/12/14
to SMCP Developers Group Group

Robert-

 

A couple of questions…

 

First, in looking at the client code example here:

 

https://github.com/darconeous/smcp/blob/master/src/plugtest/main-client.c

 

it appears that while using uIP, and a single instance of struct smcp_state that I’m limited to a single handling a single client request/response at a time – correct ?

 

So if I have a client application that is making a request and awaiting a response no other requests can be issued until the transaction associated with the response has ‘ended’ ?

 

I guess that the ‘work-around’ is to spin up a new instance of smcp_state (and outgoing uIP port) for each new request…

 

 

Second, it’s not clear to me how the transaction has to be handled when attempting to make a client application ‘observe’ a remote resource.

 

Thanks for your continued assistance,

 

 

 

 

Robert Quattlebaum

unread,
Nov 12, 2014, 1:01:09 PM11/12/14
to Steven J. Ackerman, SMCP Developers Group Group
On Nov 12, 2014, at 9:40 AM, Steven J. Ackerman <sjack...@verizon.net> wrote:

First, in looking at the client code example here:
 
 
it appears that while using uIP, and a single instance of struct smcp_state that I’m limited to a single handling a single client request/response at a time – correct ?
 
So if I have a client application that is making a request and awaiting a response no other requests can be issued until the transaction associated with the response has ‘ended’ ?

No, concurrent requests are totally supported. You can create multiple transactions and have them execute concurrently.

Second, it’s not clear to me how the transaction has to be handled when attempting to make a client application ‘observe’ a remote resource.

I'll see if I can clarify one of the examples.

-- Robert

signature.asc

Steven Ackerman

unread,
Dec 30, 2014, 12:20:03 PM12/30/14
to smcp...@googlegroups.com, sjack...@verizon.net
Robert-

So I have the multiple requests working, using multiple transactions.  

I'm now trying to be able to handle requests that Observe. I believe that I just have to add the COAP_OPTION_OBSERVE to the outbound request and add the SMCP_TRANSACTION_OBSERVE flag when initializing the transaction.

However, I see in smcp_transaction_end( ) the TODO requirement to send a final request sans the COAP_OPTION_OBSERVE:

smcp_status_t
smcp_transaction_end
(
 smcp_t
self,
 smcp_transaction_t transaction
) {
 SMCP_EMBEDDED_SELF_HOOK
;
 DEBUG_PRINTF
("smcp_transaction_end: %p",transaction);


#if SMCP_CONF_TRANS_ENABLE_OBSERVING
 
if(transaction->flags&SMCP_TRANSACTION_OBSERVE) {
 
// If we are an observing transaction, we need to clean up
 
// first by sending one last request without an observe option.
 
// TODO: Implement this!
 
}
#endif


 
if(transaction == self->current_transaction)
 
self->current_transaction = NULL;


 
if(transaction->active) {
 transaction
->active = 0; // Maybe we should remove this line? May be hiding bad behavior.
#if SMCP_TRANSACTIONS_USE_BTREE
 bt_remove
(
 
(void**)&self->transactions,
 
(void*)transaction,
 
(bt_compare_func_t)smcp_transaction_compare,
 
(bt_delete_func_t)smcp_internal_delete_transaction_,
 
self
 
);
#else
 ll_remove
((void**)&self->transactions,(void*)transaction);
 smcp_internal_delete_transaction_
(transaction,self);
#endif
 
}
 
return 0;
}


I can clear my observing flag in the request data before calling smcp_transaction_end( ) so that a resend_request() will not add the option. Should this last request be sent from here by calling resend_request() directly or scheduled immediately via the timer as in smcp_begin_transaction() ?

Regards,

Steven J. Ackerman

Robert Quattlebaum

unread,
Jan 4, 2015, 8:21:57 PM1/4/15
to Steven Ackerman, SMCP Developers Group Group

On Dec 30, 2014, at 9:20 AM, Steven Ackerman <sjack...@verizon.net> wrote:

So I have the multiple requests working, using multiple transactions.  

Sweet!

I'm now trying to be able to handle requests that Observe. I believe that I just have to add the COAP_OPTION_OBSERVE to the outbound request and add the SMCP_TRANSACTION_OBSERVE flag when initializing the transaction.

Adding SMCP_TRANSACTION_OBSERVE is all you need to do. SMCP will handle adding the COAP_OPTION_OBSERVE to the header automatically. Subtitles like that are handled automatically. I've tried to make the act of observing relatively insulated from the nitty-gritty of how observing works over-the-wire. You don't have to add any special options or do anything special other than adding the SMCP_TRANSACTION_OBSERVE flag. 

Unlike normal transactions, an observing transaction is intended to live for as long as you are observing a resource. It will make multiple successful calls into the responseHandler. However, any error received will mark the end the transaction. In other words, once you get a callback with a negative status code (indicating error), you won't get any other calls to responseHandler for this transaction (unless, of course, you've got SMCP_TRANSACTION_ALWAYS_INVALIDATE set, in which case you will get one last call).

Using the transaction flag SMCP_TRANSACTION_ALWAYS_INVALIDATE can help make it more clear exactly when the transaction is being torn down. (I may end up just making that flag set by default at some point)

I've been meaning to re-write how the transaction system is implemented to have a more clearly defined state machine. As it stands, it's rather complex and hard to follow. Finding the time for such things is becoming increasingly difficult.
The TODO above is for when the observing transaction is manually closed. When the observing transaction is closed, we should really tell the observer that we aren't interested anymore. This is supposed to be performed by sending a request without the observe option, but I am being a little naughty and skipping that step(for reasons I'll describe below). The observed instance will eventually catch on when we start automatically sending RESET responses to updates. So while it is less than optimal that we don't explicitly cancel the observation with the remote device, it isn't really a big deal in practice.

The reason I haven't implemented this already is because, at the point indicated above, the transaction is already doomed: we can't use it to send any more packets.  To do it right SMCP needs to actually spawn a new "cleanup" transaction and set up in such a way that the responseHandler finally gets called (with SMCP_STATUS_INVALIDATE) after the "cleanup" transaction is finished. This isn't really hard to do, but it requires some dynamic allocation of transactions. I deferred implementing it because it's absence doesn't change anything functionally or from an API perspective, and I also wasn't yet convinced that there wasn't a better way.

In any case, this shouldn't have an effect on the functionality of observing. The final message is really just a curtesy to the device you are observing, so leaving it out shouldn't be a big deal as long as the observed device is implemented properly. Observing should just work regardless on if SMCP is being polite when we are no longer observing a resource.

I really need to write up a good example for this case. Sorry about that.

-- Robert

Steven J. Ackerman

unread,
Jan 5, 2015, 2:58:25 PM1/5/15
to Robert Quattlebaum, SMCP Developers Group Group

Robert-

 

First, thank you for your detailed reply. I greatly appreciate your continued support.

 

I removed the un-necessary COAP_OPTION_OBSERVE from the outbound request and it still appears to work.

 

And, when I am no longer interested in the observation I end the transaction and SMCP responds to the remote server with a RST – which does stop the server from sending further observations.

 

For some reason my end is issuing multiple observe requests which results in multiple observations being received – still have to track this down:

 

 

 

image001.png

Robert Quattlebaum

unread,
Jan 5, 2015, 3:09:03 PM1/5/15
to Steven J. Ackerman, SMCP Developers Group Group
Hmm... That is kinda weird. The subsequent requests shouldn't have caused more responses. And there shouldn't have been more than one request if it got a response.

There is probably a bug in my logic somewhere.

Mind attaching that wireshark trace so I can have a closer look?

On Jan 5, 2015, at 11:58 AM, Steven J. Ackerman <sjack...@verizon.net> wrote:

Robert-

 

First, thank you for your detailed reply. I greatly appreciate your continued support.

 

I removed the un-necessary COAP_OPTION_OBSERVE from the outbound request and it still appears to work.

 

And, when I am no longer interested in the observation I end the transaction and SMCP responds to the remote server with a RST – which does stop the server from sending further observations.

 

For some reason my end is issuing multiple observe requests which results in multiple observations being received – still have to track this down:

 

<image001.png>

Reply all
Reply to author
Forward
0 new messages