Example #1
0
boolean MySensor::sendRoute(MyMessage &message) {
	// Make sure to process any incoming messages before sending (could this end up in recursive loop?)
	// process();
	bool isInternal = mGetCommand(message) == C_INTERNAL;

	// If we still don't have any node id, re-request and skip this message.
	if (nc.nodeId == AUTO && !(isInternal && message.type == I_ID_REQUEST)) {
		requestNodeId();
		return false;
	}

	if (repeaterMode) {
		uint8_t dest = message.destination;
		uint8_t route = getChildRoute(dest);
		if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) {
			// --- debug(PSTR("route %d.\n"), route);
			// Message destination is not gateway and is in routing table for this node.
			// Send it downstream
			return sendWrite(route, message);
		} else if (isInternal && message.type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) {
			// Node has not yet received any id. We need to send it
			// by doing a broadcast sending,
			return sendWrite(BROADCAST_ADDRESS, message, true);
		}
	}

	if (!isGateway) {
		// --- debug(PSTR("route parent\n"));
		// Should be routed back to gateway.
		bool ok = sendWrite(nc.parentNodeId, message);

		if (!ok) {
			// Failure when sending to parent node. The parent node might be down and we
			// need to find another route to gateway.
			if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
				findParentNode();
			}
			failedTransmissions++;
		} else {
			failedTransmissions = 0;
		}
		return ok;
	}
	return false;
}
Example #2
0
//Send a block of data to the FPGA, raise the execution signal, wait for the execution
// signal to be lowered, then read back up to values of results
// startAddress: local address on FPGA input buffer to begin writing at
// length: # of bytes to write
// inData: data to be sent to FPGA
// maxWaitTime: # of seconds to wait until execution timeout
// outData: readback data buffer (if function returns successfully)
// maxOutLength: maximum length of outData buffer provided
// outputLength: number of bytes actually returned (if function returns successfully)
// Returns true if entire process is successful.
// If function fails for any reason, returns false.
//  Check error code with getLastError().
//  error == FAILCAPACITY: The output was larger than provided buffer.  Rather than the number of
//			bytes actually returned, the outputLength variable will contain the TOTAL number bytes the
//			function wanted to return (the number of bytes actually returned will be maxOutLength).
//			If this occurs, user should read back bytes {maxOutLength, outputLength - 1} manually
//			with a subsequent sendRead command.
//  error == FAILREADACK: The write and execution phases completed correctly, but we retried
//			the readback phase too many times.  In this case, like the FAILCAPICITY error, outputLength
//			will contain the TOTAL number bytes the	function wanted to return.  The state of outData is unknown,
//			but some data has been partially written.  The user could try calling sendRead
//			from {0, outputLength-1} manually if re-calling sendWriteAndRun is not easy
//			(for example, if inData and outData overlapped).
//  error == anything else: see normal error list
BOOL PICO_SIRC::sendWriteAndRun(uint32_t startAddress, uint32_t inLength, uint8_t *inData, 
							  uint32_t maxWaitTimeInMsec, uint8_t *outData, uint32_t maxOutLength, 
							  uint32_t *outputLength)
{
	setLastError( 0);

	//Check the input parameters
	if(!inData){
		setLastError( INVALIDBUFFER);
		return false;
	}
	if(startAddress > OUTPUT_OFFSET){
		setLastError( INVALIDADDRESS);
		return false;
	}
	if(inLength == 0 || startAddress + inLength > OUTPUT_OFFSET){
		setLastError( INVALIDLENGTH);
		return false;
	}

	//Check the output parameters
	if(!outData){
		setLastError( INVALIDBUFFER);
		return false;
	}
	if(maxOutLength == 0 || maxOutLength > OUTPUT_OFFSET){
		setLastError( INVALIDLENGTH);
		return false;
	}

	//Send the data to the FPGA
    if (!sendWrite(startAddress,inLength,inData)){
        return false;
    }

    //Send the run cmd
    if (!sendRun()){
        return false;
    }

    //Wait till done
    if (!waitDone( maxWaitTimeInMsec)){
        return false;
    }

    //Read back data
    //BUGBUG what about partial results??
    if (!sendRead(0,maxOutLength,outData)){
        return false;
    }
    *outputLength = maxOutLength;

    //and done
    return true;
}
Example #3
0
/*****************************************************************************
	DISCRIPTION	: コマンドスレッドメイン1
	ARGUMENT	: argc
				  argv
	RETURN		: 0		= 正常終了
				  0以外	= 異常終了
	NOTE		: -
	UPDATED		: 2014-06-22
*****************************************************************************/
int command_main(int argc, char** argv)
{
    char*	pcBuf;
    int		iSize;
    uint32	ulAddr = 0x00003034;

    sendUse(SERIAL_DEFAULT_DEV);

    while(1) {
        sendWrite("cmd> ");

        /* コンソールからの受信文字列を受け取る */
        kzRecv(MSGBOX_ID_CONS_INPUT, &iSize, &pcBuf);
        pcBuf[iSize] = '\0';

        if(strncmp(pcBuf, "echo", 4) == TRUE) {
            sendWrite(&pcBuf[4]);
            sendWrite("\n");
        }
#if 1
        else if(strncmp(pcBuf, "usb", 3) == TRUE) {
            usb_main(0,NULL);
        }
#endif
        else if(pcBuf[0] == '\0') {
            /* 何もしない */
        }
        else if(strcmp(pcBuf, "0000") == TRUE) {
            //pFuncEntry = (int (*)(int argc, char** argv))ppcOsEntryFp;
            //pFuncEntry(1, ppcOsEntryFp);

            ((void (*)())ulAddr)();
        }
        else {
            sendWrite("unknown.\n");
        }

        kzMfree(pcBuf);
    }

    return 0;
}
Example #4
0
void MySensor::findParentNode() {
	failedTransmissions = 0;

	// Set distance to max
	nc.distance = 255;

	// Send ping message to BROADCAST_ADDRESS (to which all relaying nodes and gateway listens and should reply to)
	build(msg, nc.nodeId, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT, false).set("");
	sendWrite(BROADCAST_ADDRESS, msg, true);

	// Wait for ping response.
	waitForReply();
}
Example #5
0
static bool sendAndWait(uint8_t reqType, uint8_t resType) {
	outMsg.type = reqType;
	// outer loop, retries
	for (uint8_t i = 0; i < MAX_RESEND; i++) {
		sendWrite(outMsg);
		// loop 20 times, wait time 0.1s if no/wrong data => 2s
		for (uint8_t j = 0; j < 20; j++) {
			// loop 100 times, wait 1ms if no/wrong data => 0.1s
			for (uint8_t k = 0; k < 100; k++) {
				watchdogReset();
				// Tx FIFO data available? (we don't care about the pipe here)
				if (available(NULL)) {
					// read message from FIFO, skip if size = 0
					if (readMessage(inMsg.array) > 0) {
						// protocol compatible? if not ignore msg
						if ((mGetVersion(inMsg) != PROTOCOL_VERSION)) {
							continue;
						}
						// msg for us?
						if (inMsg.destination == nc.nodeId) {
							// internal command: find parent
							if ((mGetCommand(inMsg) == C_INTERNAL) && (inMsg.type == I_FIND_PARENT_RESPONSE)) {
								// static parent found?
								if (configuredParentID == inMsg.sender) {
									configuredParentFound = true;
								}
								if ( ((inMsg.bValue < nc.distance - 1) && ( !configuredParentFound) ) || (configuredParentID == inMsg.sender)) {
									// got new routing info, update settings
									nc.distance = inMsg.bValue + 1;
									nc.parentNodeId = inMsg.sender;
								}
							}
							// did we receive expected reply?
							if ((mGetCommand(inMsg) == mGetCommand(outMsg)) && (inMsg.type == resType)) {
								return true;
							}
						
						}
					}
				} else { 
					// wait 1ms if no data available
					_delay_ms(1);
				}
				
			}
		}
	}
	return false;
}
Example #6
0
boolean MySensor::process() {
	uint8_t pipe;
	boolean available = RF24::available(&pipe);

	if (!available || pipe>6)
		return false;

	uint8_t len = RF24::getDynamicPayloadSize();
	RF24::read(&msg, len);
	RF24::writeAckPayload(pipe,&pipe, 1 );

	// Add string termination, good if we later would want to print it.
	msg.data[mGetLength(msg)] = '\0';
	debug(PSTR("read: %d-%d-%d s=%d,c=%d,t=%d,pt=%d,l=%d:%s\n"),
				msg.sender, msg.last, msg.destination,  msg.sensor, mGetCommand(msg), msg.type, mGetPayloadType(msg), mGetLength(msg), msg.getString(convBuf));

	if(!(mGetVersion(msg) == PROTOCOL_VERSION)) {
		debug(PSTR("version mismatch\n"));
		return false;
	}

	uint8_t command = mGetCommand(msg);
	uint8_t type = msg.type;
	uint8_t sender = msg.sender;
	uint8_t last = msg.last;
	uint8_t destination = msg.destination;

	if (repeaterMode && command == C_INTERNAL && type == I_FIND_PARENT) {
		// Relaying nodes should always answer ping messages
		// Wait a random delay of 0-2 seconds to minimize collision
		// between ping ack messages from other relaying nodes
		delay(millis() & 0x3ff);
		sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance), true);
		return false;
	} else if (destination == nc.nodeId) {
		// Check if sender requests an ack back.
		if (mGetRequestAck(msg)) {
			// Copy message
			ack = msg;
			mSetRequestAck(ack,false); // Reply without ack flag (otherwise we would end up in an eternal loop)
			mSetAck(ack,true);
			ack.sender = nc.nodeId;
			ack.destination = msg.sender;
			sendRoute(ack);
		}

		// This message is addressed to this node
		if (repeaterMode && last != nc.parentNodeId) {
			// Message is from one of the child nodes. Add it to routing table.
			addChildRoute(sender, last);
		}

		if (command == C_INTERNAL) {
			if (type == I_FIND_PARENT_RESPONSE && !isGateway) {
				// We've received a reply to a FIND_PARENT message. Check if the distance is
				// shorter than we already have.
				uint8_t distance = msg.getByte();
				if (distance<nc.distance-1) {
					// Found a neighbor closer to GW than previously found
					nc.distance = distance + 1;
					nc.parentNodeId = msg.sender;
					eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, nc.parentNodeId);
					eeprom_write_byte((uint8_t*)EEPROM_DISTANCE_ADDRESS, nc.distance);
					debug(PSTR("new parent=%d, d=%d\n"), nc.parentNodeId, nc.distance);
				}
				return false;
			} else if (sender == GATEWAY_ADDRESS) {
				bool isMetric;

				if (type == I_REBOOT) {
					wdt_enable(WDTO_15MS);
					for (;;);
				} else if (type == I_ID_RESPONSE) {
					if (nc.nodeId == AUTO) {
						nc.nodeId = msg.getByte();
						// Write id to EEPROM
						if (nc.nodeId == AUTO) {
							// sensor net gateway will return max id if all sensor id are taken
							debug(PSTR("full\n"));
							while (1); // Wait here. Nothing else we can do...
						} else {
							RF24::openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(nc.nodeId));
							eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, nc.nodeId);
						}
						debug(PSTR("id=%d\n"), nc.nodeId);
					}
				} else if (type == I_CONFIG) {
					// Pick up configuration from controller (currently only metric/imperial)
					// and store it in eeprom if changed
					isMetric = msg.getByte() == 'M' ;
					if (cc.isMetric != isMetric) {
						cc.isMetric = isMetric;
						eeprom_write_byte((uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, isMetric);
						//eeprom_write_block((const void*)&cc, (uint8_t*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(ControllerConfig));
					}
				} else if (type == I_CHILDREN) {
					if (repeaterMode && msg.getByte() == 'C') {
						// Clears child relay data for this node
						debug(PSTR("rd=clear\n"));
						for (uint8_t i=0;i< sizeof(childNodeTable); i++) {
							removeChildRoute(i);
						}
						sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_CHILDREN,false).set(""));
					}
				} else if (type == I_TIME) {
					if (timeCallback != NULL) {
						// Deliver time to callback
						timeCallback(msg.getULong());
					}
				}
				return false;
			}
		}
		// Call incoming message callback if available
		if (msgCallback != NULL) {
			msgCallback(msg);
		}
		// Return true if message was addressed for this node...
		return true;
	} else if (repeaterMode && pipe == CURRENT_NODE_PIPE) {
		// We should try to relay this message to another node

		uint8_t route = getChildRoute(msg.destination);
		if (route>0 && route<255) {
			// This message should be forwarded to a child node. If we send message
			// to this nodes pipe then all children will receive it because the are
			// all listening to this nodes pipe.
			//
			//    +----B
			//  -A
			//    +----C------D
			//
			//  We're node C, Message comes from A and has destination D
			//
			// lookup route in table and send message there
			sendWrite(route, msg);
		} else  {
			// A message comes from a child node and we have no
			// route for it.
			//
			//    +----B
			//  -A
			//    +----C------D    <-- Message comes from D
			//
			//     We're node C
			//
			// Message should be passed to node A (this nodes relay)

			// This message should be routed back towards sensor net gateway
			sendWrite(nc.parentNodeId, msg);
			// Add this child to our "routing table" if it not already exist
			addChildRoute(sender, last);
		}
	}
	return false;
}
void FtpServer::sendCatWrite( const char * s )
{
  sendCat( s );
  sendWrite();
}
void FtpServer::sendWrite( const char * s )
{
  sendBegin( s );
  sendWrite();
}
Example #9
0
void SMPCache::doWrite(MemRequest *mreq)
{
  PAddr addr = mreq->getPAddr();
  Line *l = cache->writeLine(addr);

//LINE exists in cache
 #ifdef TLS
  	if (l && !l->isLocked()) {
	  	if (mreq->isDataReq()==true){
		  	//Check for Epoch match
		 	//If Epoch mismatch -read miss, invalidate line
		 	if (l->getEpoch()!=mreq->getEpoch())
		 	{
		 		l=0;
		 		 if(!l && mreq->getMemOperation() == MemWrite) {
					    mreq->mutateWriteToRead();
  				}
		 		if (!mutExclBuffer->issue(addr)) {
				   mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq),
							          sendReadCB::create(this, mreq));
				return;
		 		}
		 		invalidateLineTLS(mreq);
		 		mutExclBuffer->retire(addr);
		 		epochMissW.inc();
		 	}
		 	//WRITE HIT-----------------------
		  	else
		  	{
			  	//Broadcast write hit on bus- if If others exposed is set
			  	 if (l->getCacheFlags()->getOE())
			  	 {
					  (l->getCacheFlags())->setWordWM(getOffsetInLine(addr));
					    if(mreq->getMemOperation() == MemWrite) {
							    mreq->mutateWriteToRead();
	  					}
					  writeHitProp.inc();//write hit but broadcast
					  writeHit.inc();//Propagated hits still counted
					  if (!mutExclBuffer->issue(addr)) {
					    mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq),
					      			          sendWriteCB::create(this, mreq));
					    return;
					  }
					 sendWrite(mreq);
					 return;
		  	     }
			  	//Dont broadcast
			  	else
			  	{
			  	    writeHit.inc();
				    outsReq->retire(addr);
				  	(l->getCacheFlags())->setWordWM(getOffsetInLine(addr));
				  	mreq->goUp(hitDelay);
				  	return;
			  	}
			} 
	  	} 
	  	else{
	  		writeHit.inc();
		    outsReq->retire(addr);
		    mreq->goUp(hitDelay);  
		    return;
	  	}
  	}	
	#else
     if (l && l->canBeWritten()) {
	    writeHit.inc();
	    outsReq->retire(addr);
	    mreq->goUp(hitDelay);  
	    return;
     }
   #endif

//LINE LOCKED RETRY
  if (l && l->isLocked()) {
	    writeRetry.inc();
	    doWriteCB::scheduleAbs(nextSlot(), this, mreq);
	    return;
  }
  GI(l, !l->isLocked());

  // this should never happen unless this is highest level because L2
  // is inclusive; there is only one case in which this could happen when 
  // SMPCache is used as an L2:
  // 1) line is written in L1 and scheduled to go down to L2
  // 2) line is invalidated in both L1 and L2
  // 3) doWrite in L2 is executed after line is invalidated

  if(!l && mreq->getMemOperation() == MemWrite) {
    mreq->mutateWriteToRead();
  }

  writeMiss.inc();

  if (!mutExclBuffer->issue(addr)) {
    mutExclBuffer->addEntry(addr, sendWriteCB::create(this, mreq),
			          sendWriteCB::create(this, mreq));
    return;
  }

  sendWrite(mreq);
}