⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sendvirtualizerp.nc

📁 tinyos2.0版本驱动
💻 NC
字号:
// $Id: SendVirtualizerP.nc,v 1.2 2007/09/13 23:10:18 scipio Exp $/** "Copyright (c) 2005 Stanford University. All rights reserved.** Permission to use, copy, modify, and distribute this software and* its documentation for any purpose, without fee, and without written* agreement is hereby granted, provided that the above copyright* notice, the following two paragraphs and the author appear in all* copies of this software.* * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN* IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH* DAMAGE.* * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE* PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY* HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,* ENHANCEMENTS, OR MODIFICATIONS."*//** * A Send queue that provides a Service Instance pattern for formatted * packets and calls an underlying Send in a round-robin fashion. Used * to share L3 bandwidth between different communication clients. * * @author Philip Levis * @date   April 6 2007 */ #include "AM.h"generic module SendVirtualizerP(int numClients) {    provides interface Send[uint8_t client];    uses {       interface Send as SubSend;      interface Packet;    }}implementation {    typedef struct {        message_t* msg;    } queue_entry_t;      uint8_t current = numClients; // mark as empty    queue_entry_t queue[numClients];    uint8_t cancelMask[numClients/8 + 1];    void tryToSend();        void nextPacket() {        uint8_t i;        current = (current + 1) % numClients;        for(i = 0; i < numClients; i++) {            if((queue[current].msg == NULL) ||               (cancelMask[current/8] & (1 << current%8)))            {                current = (current + 1) % numClients;            }            else {                break;            }        }        if(i >= numClients) current = numClients;    }    /**     * Accepts a properly formatted AM packet for later sending.     * Assumes that someone has filled in the AM packet fields     * (destination, AM type).     *     * @param msg - the message to send     * @param len - the length of the payload     *     */    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;        }        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;            current = clientId;                        err = call SubSend.send(msg, len);            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;    }    task void CancelTask() {      uint8_t i,j,mask,last;      message_t *msg;      for(i = 0; i < numClients/8 + 1; i++) {	if(cancelMask[i]) {	  for(mask = 1, j = 0; j < 8; j++) {	    if(cancelMask[i] & mask) {	      last = i*8 + j;	      msg = queue[last].msg;		queue[last].msg = NULL;		cancelMask[i] &= ~mask;		signal Send.sendDone[last](msg, ECANCEL);	    }	    mask <<= 1;	  }	}      }    }        command error_t Send.cancel[uint8_t clientId](message_t* msg) {      if (clientId >= numClients ||         // Not a valid client    	  queue[clientId].msg == NULL ||    // No packet pending	  queue[clientId].msg != msg) {     // Not the right packet	return FAIL;      }      if(current == clientId) {	error_t err = call SubSend.cancel(msg);	return err;      }      else {	cancelMask[clientId/8] |= 1 << clientId % 8;	post CancelTask();	return SUCCESS;      }    }    void sendDone(uint8_t last, message_t *msg, error_t err) {      queue[last].msg = NULL;      tryToSend();      signal Send.sendDone[last](msg, err);    }    task void errorTask() {      sendDone(current, queue[current].msg, FAIL);    }        // NOTE: Increments current!    void tryToSend() {      nextPacket();      if (current < numClients) { // queue not empty	error_t nextErr;	message_t* nextMsg = queue[current].msg;	uint8_t len = call Packet.payloadLength(nextMsg);	nextErr = call SubSend.send(nextMsg, len);	if(nextErr != SUCCESS) {	  post errorTask();	}      }    }        event void SubSend.sendDone(message_t* msg, error_t err) {      if(queue[current].msg == msg) {	sendDone(current, msg, err);      }      else {	dbg("PointerBug", "%s received send done for %p, signaling for %p.\n",	    __FUNCTION__, msg, queue[current].msg);      }    }        command uint8_t Send.maxPayloadLength[uint8_t id]() {        return call SubSend.maxPayloadLength();    }    command void* Send.getPayload[uint8_t id](message_t* m, uint8_t len) {      return call SubSend.getPayload(m, len);    }    default event void Send.sendDone[uint8_t id](message_t* msg, error_t err) {        // Do nothing    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -