[Tinyos-help] CTP: CtpForwardingEngineP component error

Dongyu Yang yangdy.nwpu at gmail.com
Mon Nov 1 18:46:46 PDT 2010


Hello!

    The return value is EBUSY. The AM layer do not promise signal
AMSend.sendDone
event, if the return value is not SUCCESS when call AMSend.send().
     Because in the component AMQueueImplP, when call Send.send() it may
return
EBUSY in two place, as show below:

generic module AMQueueImplP(int numClients) @safe() {
      provides interface Send[uint8_t client];
      uses{
            interface AMSend[am_id_t id];
            interface AMPacket;
            interface Packet;
      }
}implementation {
      ......
      command error_t Send.send[uint8_t clientId](message_t* msg, uint8_t
len) {
            if (clientId >= numClients) {
                  return FAIL;
            }
            if (queue[clientId].msg != NULL) {
                    return EBUSY; //
.................................................................................(1)
            }
            dbg("AMQueue", "AMQueue: request to send from %hhu (%p): passed
checks\n", clientId, msg);

            queue[clientId].msg = msg;
            call Packet.setPayloadLength(msg, len);

            if (current >= numClients) { // queue empty
                  error_t err;
                  am_id_t amId = call AMPacket.type(msg);
                  am_addr_t dest = call AMPacket.destination(msg);

                  dbg("AMQueue", "%s: request to send from %hhu (%p): queue
empty\n", __FUNCTION__, clientId, msg);
                  current = clientId;

                  err = call AMSend.send[amId](dest, msg,
len);//.....................................(2)
                  if (err != SUCCESS) {
                        dbg("AMQueue", "%s: underlying send failed.\n",
__FUNCTION__);
                        current = numClients;
                        queue[clientId].msg = NULL;

                  }
                  return err;
            }
            else {
                  dbg("AMQueue", "AMQueue: request to send from %hhu (%p):
queue not empty\n", clientId, msg);
            }
            return SUCCESS;
      }
     ......
}

     If the EBUSY is returned from (1), it is OK, and the Send.sendDone
event will be
signaled for the client who call it later; but if the EBUSY is returned from
(2), the
problem arise, it do not signal the Send.sendDone event for the client who
call it, but
it will only signal the Send.sendDone event for another client whose AM ID
is different
from the current client later.
    I find this phenomenon arises when the EBUSY value return from (2). So
it may be
the component AMQueueImplP have some problem, it can not guarantee the same
semantic for the EBUSY.


    Best regards!



2010/10/30 Omprakash Gnawali <gnawali at cs.stanford.edu>

> On Sat, Oct 23, 2010 at 12:25 AM, Dongyu Yang <yangdy.nwpu at gmail.com>
> wrote:
> >  I have tested this: when one Node (A) happened this phenomenon, I reduce
> > the dissemination rate
> > to once ever 10 seconds, and stop the other Nodes, this phenomenon exist
> > still, the Node (A) can
> > only receive the dissemination command, but can never send out data!
> > I think it is not cased by the channel capacity, but because in
> Send.send()
> > the
> > clientPtrs[client]  be set NULL;
> >
> > command error_t Send.send[uint8_t client](message_t* msg, uint8_t len) {
> > ......
> >       if (call SendQueue.enqueue(qe) == SUCCESS) {
> >             if (radioOn && !call RetxmitTimer.isRunning()) {
> >                   post sendTask();
> >             }
> >             clientPtrs[client] = NULL;
> >             return SUCCESS;
> >       }
> > ......
> > }
> > if it do not deal with the EBUSY and FAIL state in the else condition, it
> > will remain NULL. So the
> > next when call Send.send() it return EBUSY, because the
> "clientPtrs[client]"
> > only be reseted
> > in the "void packetComplete()" function  which be called in the "event
> void
> > SubSend.sendDone()"
> > as below:
> >
> > command error_t Send.send[uint8_t client](message_t* msg, uint8_t len) {
> >
> >       ......
> >
> >       if (clientPtrs[client] == NULL) {
> >             dbg("Forwarder", "%s: send failed as client is busy.\n",
> > __FUNCTION__);
> >             return EBUSY;
> >       }
> >       ......
> > }
> >
> >
> > void packetComplete(fe_queue_entry_t* qe, message_t* msg, bool success) {
> >     ....
> >     if (qe->client < CLIENT_COUNT) {
> >         clientPtrs[qe->client] = qe;
> >
> >         ....
> >    }
> >     ....
> > }
> > because the command SubSend.send() return not SUCCESS, so the  event
> > SubSend.sendDone() will not signal, so the "clientPtrs[client]" remain
> NULL.
>
> The return value is either FAIL or EBUSY in that else block.
> If it is FAIL, we should wait until the condition that resulted in
> FAIL is repaired. If it is EBUSY, that means we should wait
> until sendDone.
>
> I think we are handing the EBUSY case properly.
>
> There is a possibility that we are not handing all the possible cases
> that can result in FAIL.
>
> I understand posting sendTask solved your problem but I want to
> understand why it works and if there is any FAIL condition that we do
> not handle properly before committing the fix. Do you know what return
> value you were getting when this bug is triggered? If it is FAIL, what
> caused that FAIL return value?
>
> - om_p
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://www.millennium.berkeley.edu/pipermail/tinyos-help/attachments/20101102/1115af51/attachment.htm 


More information about the Tinyos-help mailing list