Exemplo n.º 1
0
void gateway_task ()
{
  uint8_t i, len;
  int8_t rssi, val;
  uint8_t *local_rx_tx_buf;
  uint16_t batt;
  nrk_time_t check_period, wait_time;
  uint16_t buf;
  int8_t fd;

  uint8_t j, cnt, level;
  nrk_sig_t tx_done_signal;
  nrk_sig_mask_t ret;
  nrk_time_t next_transmit_time;
  nrk_time_t current_time;
  nrk_time_t prev_time;
  char tmp[4];

  printf ("gateway_task PID=%d\r\n", nrk_get_pid ());

  next_transmit_time.secs 	= 0;
  next_transmit_time.nano_secs 	= 0;

  // init bmac on channel 25 
  bmac_init (26);

  // By default the RX check rate is 100ms
  // below shows how to change that
  check_period.secs=0;
  check_period.nano_secs=100*NANOS_PER_MS;
  val=bmac_set_rx_check_rate(check_period);

  // The default Clear Channel Assement RSSI threshold is -32
  // Setting this value higher means that you will only trigger
  // receive with a very strong signal.  Setting this lower means
  // bmac will try to receive fainter packets.  If the value is set
  // too high or too low performance will suffer greatly.
  // bmac_set_cca_thresh(-36); 
  
  if(val==NRK_ERROR) nrk_kprintf( PSTR("ERROR setting bmac rate\r\n" ));

  // This sets the next RX buffer.
  // This can be called at anytime before releaseing the packet
  // if you wish to do a zero-copy buffer switch
  bmac_rx_pkt_set_buffer (rx_buf, RF_MAX_PAYLOAD_SIZE);
  
  // Get and register the tx_done_signal if you want to
  // do non-blocking transmits
  tx_done_signal = bmac_get_tx_done_signal ();
  nrk_signal_register (tx_done_signal);

  nrk_time_set(0, 0);
  cnt = 0;
  // Initially clear all the data buffers
  for(i=0; i<(MAX_NODES);i++)
  {
	for(j=0; j<(WORDS_PER_NODE); j++)
	{
		data_pkt.node_specific_data[i][j] = 0;		
	}
  }
  while (1) 
  {

  	nrk_time_get(&current_time);

	// If it is time to flood the network, send the control packets
	if(current_time.secs%FLOOD_RATE == 0 && prev_time.secs != current_time.secs || cnt == 0)
   	{
			
		prev_time = current_time;

		cnt ++;
	  	SET_PACKET_COUNT(pkt_buf.pkt_type_cnt, cnt);
#if MODE==DATA_MODE
		SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_CONTROL); 
#else
		SET_PACKET_TYPE(pkt_buf.pkt_type_cnt, PKT_TYPE_DIAG_CONTROL);
#endif
		pkt_buf.hop_number 		= 0;
	  	pkt_buf.time_to_flood		= TIME_TO_FLOOD_IN_SECS;
  		pkt_buf.bmac_check_rate 	= BMAC_CHECK_RATE_IN_MS;
	  	pkt_buf.maximum_depth 		= MAXIMUM_DEPTH;
  		pkt_buf.delay_at_each_level	= DELAY_AT_EACH_LEVEL_IN_SECS;
	  	pkt_buf.next_control_time	= NEXT_CONTROL_TIME;
  		pkt_buf.data_push_rate		= 0;	
	  	for(i=0; i<(MAX_NODES);i++)
  		{
			for(j=0; j<(WORDS_PER_NODE); j++)
			{
#if MODE==DATA_MODE
				pkt_buf.node_specific_data[i][j] = SENSOR;
#else
				pkt_buf.node_specific_data[i][j] = 0;
#endif
			}
	  	}	
	
  		memcpy(tx_buf, &pkt_buf, sizeof(pkt_buf));

		// Non-blocking send
	  	nrk_led_set (BLUE_LED);
  		val = bmac_tx_pkt_nonblocking (tx_buf, sizeof(struct message_packet));
	  	nrk_kprintf (PSTR ("Tx packet enqueued\r\n"));
  		ret = nrk_event_wait (SIG(tx_done_signal));
	  	if(ret & SIG(tx_done_signal) == 0 ) 
    			nrk_kprintf (PSTR ("TX done signal error\r\n"));
	  	nrk_led_clr (BLUE_LED);
	  }
  
	  // If a new packet has been received, then update the information
	  if(bmac_rx_pkt_ready())
	  {	
    		// Wait until an RX packet is received
		nrk_led_set (ORANGE_LED);
    	
		 // Get the RX packet 
		local_rx_tx_buf = bmac_rx_pkt_get (&len, &rssi);
    
    		for (i = 0; i < len; i++)
	      	printf ("%d", rx_buf[i]);
   		printf ("\r\n");

	    	memcpy(&pkt_buf, rx_buf, sizeof(pkt_buf));
	
    		nrk_led_clr (ORANGE_LED);
   
		// Release the RX buffer so future packets can arrive 
    		bmac_rx_pkt_release ();

		// If the received packet is a data packet then update the information, gateway just ignores the control packets
		if(GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DIAG_DATA || GET_PACKET_TYPE(pkt_buf.pkt_type_cnt) == PKT_TYPE_DATA)
		{
 
  	
			printf("Type 	= %d\n\r", GET_PACKET_TYPE(pkt_buf.pkt_type_cnt));
			printf("Count 	= %d\n\r", GET_PACKET_COUNT(pkt_buf.pkt_type_cnt));
			printf("Hop #	= %d\n\r", pkt_buf.hop_number);
			printf("TTF	= %d\n\r", pkt_buf.time_to_flood);
		  	printf("BCR	= %d\n\r", pkt_buf.bmac_check_rate);
		  	printf("Nmax 	= %d\n\r", pkt_buf.maximum_depth);
		  	printf("Dlev	= %d\n\r", pkt_buf.delay_at_each_level);
		  	printf("Nxt	= %d\n\r", pkt_buf.next_control_time);
		  	printf("Prate	= %d\n\r", pkt_buf.data_push_rate);		
  	
			for(i=0; i<(MAX_NODES);i++)
		  	{
				for(j=0; j<(WORDS_PER_NODE); j++)
				{
					if(pkt_buf.node_specific_data[i][j] != 0)
					data_pkt.node_specific_data[i][j] = pkt_buf.node_specific_data[i][j];		
				}
			}
			for(i=0; i<(MAX_NODES);i++)
		  	{
				printf("Value @ Node %d is %d  (cnt is %d)", i, ((int16_t)data_pkt.node_specific_data[i][1]<<4), (data_pkt.node_specific_data[i][0]&0x3F));
				printf("\n\r");
		  	}	
		}
	  }
   }	
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	int sockfd;

	unsigned char sndbuf[128];
	unsigned char *SSI_sensor_discovery;
	int packet_len = 0;
	unsigned char SSI_request[128];
	unsigned char sndbuf_conf[128];
	unsigned char buffer[512];
	unsigned char rbuf[512];
	
	int recvbytes;
	unsigned int bytes;

	unsigned short int portn;
	
	int i = 1;

	char nRd_address[32] = "127.0.0.1";
	unsigned int nRd_port = 21870;
	unsigned char target[8];
	char argbuf[64];
	int hits = 0;

	unsigned char sensor_count = 0;
	struct sensor_description_t sensor_desc[10];
	unsigned char sensor_addr=0;

	struct pollfd pfds;
	unsigned int nfds = 1;
	int timed_out = 0;
	int full_description=0;
	int rval = 0;
	int loop = 1;
	

/*	First check the command line parameters and parse them. */
	if(argc < 2 || argc > 4 || strncmp(argv[1], "--help", 6) == 0)
	{
		usage();
		return(-1);
	}

	while(i < argc)
	{
		sscanf(argv[i], "%s ", argbuf);
		if(strncmp(argbuf, "-S", 2) == 0)
		{
			i++;
			hits = sscanf(argv[i], "%[^:]:%d", nRd_address, &nRd_port);
			if(hits == 2)
				printf("Trying to connect nRouted at %s port %d\n", nRd_address, nRd_port);

			bzero(argbuf, 64);
		}
		else if (strncmp(argbuf, "-l", 2) == 0)
		{
			printf("Loop mode.\n");
			loop = 10;
		}
		else
		{
			hits = sscanf(argv[i], "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &(target[0]), &(target[1]), &(target[2]), &(target[3]), &(target[4]), &(target[5]), &(target[6]), &(target[7]));

			printf("Requesting SSI data from: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", target[0], target[1], target[2], target[3], target[4], target[5], target[6], target[7]);
		}
		
		bzero(argbuf, 64);
		i++;
	}

	printf("Trying to connect nRouted at %s port %d\n", nRd_address, nRd_port);

/*	Copying the Target address to the end of the nRouted Configuration packet, discovery packet and SSI request packet. */
	for(i=0;i<8;i++)
	{
		sndbuf_conf[i+12] = target[i];
		sndbuf[i+18] = target[i];
		SSI_request[i+12] = target[i];
	}

//	if((rval=libnrp_create_conf_pkt(sndbuf_conf, PROTO_UNDEFINED, target, NULL, ADDR_UNDEFINED, NULL, PORT_UNDEFINED)) < 0)
	if((rval=libnrp_create_conf_pkt(sndbuf_conf, PROTO_6LOWPAN, NULL, NULL, ADDR_UNDEFINED, NULL, PORT_UNDEFINED)) < 0)
	{
		printf("Failed to create an nRouted configuration packet.\n");
		return(-1);
	}
	
	if((sockfd = libnrp_snd_conf(sndbuf_conf, rval, nRd_address, nRd_port)) < 0)
	{
		printf("Failed to send the configuration packet to nRouted.\n");
		return(-1);
	}
	else
	{
		printf("nRouted configuration successful.\n");
	}




/*	Create the SSI sensor discovery packet using the wildcard address */
	SSI_sensor_discovery = libSSI_sensor_discovery(NULL);
	printf("SSI_sensor_discovery:0x%hhx 0x%hhx\n", SSI_sensor_discovery[0], SSI_sensor_discovery[1]);


/*	Create the SSI sensor query packet inside a nRP data packet. */
	portn = 122;
	packet_len = libnrp_create_data_pkt_hdr(sndbuf, SSI_sensor_discovery, 2, PROTO_6LOWPAN, NULL, target, ADDR_IEEE_802_15_4_DEV_LONG, &portn, 40, NULL);



/*	Here we send the SSI discovery packet to the sensor device. */
	write(sockfd, sndbuf, packet_len);

	pfds.fd = (int)(sockfd);
	pfds.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;

/*	We try to read the answer and then process it. */
	i=0;
	timed_out = 0;
	while(!timed_out && full_description != 1)
	{
		if((rval = poll(&pfds, nfds, 1000)) == 0)
		{
			printf("Timed out SSI discovery reply.\n");
			timed_out = -1;
		}
		else
		{
			recvbytes = read(sockfd, rbuf, 512);
			if(recvbytes>0)
			{
				printf("Received %d bytes ", recvbytes);

				libnrp_get_data(rbuf, recvbytes, buffer, &bytes);

				if(GET_PACKET_TYPE(buffer) == SSI_DISC_REPLY)
				{
					printf("Got an SSI sensor discovery reply - good.\n");
					
					libSSI_parse_disc_reply(buffer, &sensor_addr, bytes, &sensor_count, sensor_desc);

					printf("Got %u sensor descriptions.\n", sensor_count);
					
					if(buffer[bytes-2] == 0xff && buffer[bytes-1] == 0xff)
					{
						full_description = 1;
						printf("Got full set of sensor descriptions.\n");
					}
				}
				else
				{
					printf("Wrong type: 0x%hhx\n", (unsigned char)GET_PACKET_TYPE(buffer));
				}
			}
		}
	}
	
	if(full_description == 0)
	{
		printf("Some sensor descriptions were left missing as I timed out.\n");
	}
	

	usleep(100000);

	if(sensor_count > 0)
	{
		int k;
		uint16_t sensor_id_list[12];

		for(k=0;k<sensor_count;k++)
		{
			memcpy(&(sensor_id_list[k]), &(sensor_desc[k].sensor_id), 2);
		}

		bytes = libSSI_data_request(SSI_request, &sensor_addr, sensor_id_list, &sensor_count);

		packet_len = libnrp_create_data_pkt_hdr(sndbuf, SSI_request, bytes, PROTO_6LOWPAN, NULL, target, ADDR_IEEE_802_15_4_DEV_LONG, &portn, 40, NULL);

		printf("Write %d bytes\n", packet_len);
		write(sockfd, sndbuf, packet_len);

		timed_out = 0;
		while(!timed_out )
		{
			if((rval = poll(&pfds, nfds, 2000)) == 0)
			{
				printf("Timed out SSI discovery reply.\n");
				timed_out = -1;
			}
			else
			{
				printf("Read\n");
				recvbytes = read(sockfd, buffer, 512);
		
				libnrp_get_data(buffer, recvbytes, rbuf, &bytes);
		
				if(GET_PACKET_TYPE(rbuf) == SSI_DATA_REPLY)
				{
					if(bytes>0)
					{
						uint16_t sensor_ids[32];
						uint32_t sensor_values[32];
		
						printf("Received SSI_DATA_REPLY (%d bytes).\n", bytes);
						i=0;
		
						i = libSSI_parse_data_response(rbuf, NULL, sensor_ids, sensor_values, bytes);
		
		
						for(k=0;k<i;k++)
						{
							int j;
							for(j=0;j<i;j++)
							{
								if(sensor_ids[k] == sensor_desc[j].sensor_id)
								{
									if(sensor_desc[j].type == 0x00)
										printf("%s:%lf %s\n", sensor_desc[j].description, (double)sensor_values[k],  sensor_desc[j].unit);
									else if(sensor_desc[j].type == 0x01)
										printf("%s:%d %s\n", sensor_desc[j].description, (int)sensor_values[k],  sensor_desc[j].unit);
								}
							}
						}
					}
				}
				timed_out = -1;
			}
		}
	}
	else
	{
		printf("No sensors found.\n");
		close(sockfd);
		return(-1);
	}
	
	close(sockfd);

	return(1);
}
Exemplo n.º 3
0
static PVRSRV_ERROR
DoTLStreamReserve(IMG_HANDLE hStream,
				IMG_UINT8 **ppui8Data, 
				IMG_UINT32 ui32ReqSize,
                IMG_UINT32 ui32ReqSizeMin,
				PVRSRVTL_PACKETTYPE ePacketType,
				IMG_UINT32* pui32AvSpace)
{
	PTL_STREAM psTmp;
	IMG_UINT32 *ui32Buf, ui32LRead, ui32LWrite, ui32LPending, lReqSizeAligned, lReqSizeActual;
	IMG_INT pad, iFreeSpace;

	PVR_DPF_ENTERED;
	if (pui32AvSpace) *pui32AvSpace = 0;

	if (( IMG_NULL == hStream ))
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS);
	}
	psTmp = (PTL_STREAM)hStream;

	/* Assert used as the packet type parameter is currently only provided
	 * by the TL APIs, not the calling client */
	PVR_ASSERT((PVRSRVTL_PACKETTYPE_UNDEF < ePacketType) && (PVRSRVTL_PACKETTYPE_LAST >= ePacketType));

	/* The buffer is only used in "rounded" (aligned) chunks */
	lReqSizeAligned = PVRSRVTL_ALIGN(ui32ReqSize);

	/* Get a local copy of the stream buffer parameters */
	ui32LRead  = psTmp->ui32Read ;
	ui32LWrite = psTmp->ui32Write ;
	ui32LPending = psTmp->ui32Pending ;

	/*  Multiple pending reserves are not supported. */
	if ( NOTHING_PENDING != ui32LPending )
	{
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_READY);
	}

	if ( IMG_UINT16_MAX < lReqSizeAligned )
	{
		psTmp->ui32Pending = NOTHING_PENDING;
		if (pui32AvSpace)
		{
			*pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin);
		}
		PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_FULL);
	}

	/* Prevent other threads from entering this region before we are done.
	 * Not exactly a lock... */
	psTmp->ui32Pending = 0;

	/* If there is enough contiguous space following the current Write
	 * position then no padding is required */
	if (  psTmp->ui32Size
		< ui32LWrite + lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) )
	{
		pad = psTmp->ui32Size - ui32LWrite;
	}
	else
	{
		pad = 0 ;
	}

	lReqSizeActual = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) + pad ;
	/* If this is a blocking reserve and there is not enough space then wait. */
	if( psTmp->bBlock )
	{
		if( psTmp->ui32Size < lReqSizeActual )
		{
			psTmp->ui32Pending = NOTHING_PENDING;
			PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
		}
		while ( ( cbSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size)
		         <(IMG_INT) lReqSizeActual ) )
		{
			OSEventObjectWait(psTmp->hProducerEvent);
			// update local copies.
			ui32LRead  = psTmp->ui32Read ;
			ui32LWrite = psTmp->ui32Write ;
		}
	}

	/* The easy case: buffer has enough space to hold the requested packet (data + header) 
	 */
	iFreeSpace = cbSpaceLeft(ui32LRead, ui32LWrite, psTmp->ui32Size);
	if (  iFreeSpace >=(IMG_INT) lReqSizeActual )
	{
		if ( pad ) 
		{ 
			/* Inserting padding packet. */
			ui32Buf = (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite];
			*ui32Buf = PVRSRVTL_SET_PACKET_PADDING(pad-sizeof(PVRSRVTL_PACKETHDR)) ;

			/* CAUTION: the used pad value should always result in a properly 
			 *          aligned ui32LWrite pointer, which in this case is 0 */
			ui32LWrite = (ui32LWrite + pad) % psTmp->ui32Size;
			/* Detect unaligned pad value */
			PVR_ASSERT( ui32LWrite == 0);
		}
		/* Insert size-stamped packet header */
		ui32Buf = (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite];

		*ui32Buf = PVRSRVTL_SET_PACKET_HDR(ui32ReqSize, ePacketType);

		/* return the next position in the buffer to the user */
		*ppui8Data =  &psTmp->pbyBuffer[ ui32LWrite+sizeof(PVRSRVTL_PACKETHDR) ] ;

		/* update pending offset: size stamp + data  */
		ui32LPending = lReqSizeAligned + sizeof(PVRSRVTL_PACKETHDR) ;
	}
	/* The not so easy case: not enough space, decide how to handle data */
	else
	{

#if defined(DEBUG)
		/* Sanity check that the user is not trying to add more data than the
		 * buffer size. Conditionally compile it out to ensure this check has
		 * no impact to release performance */
		if ( lReqSizeAligned+sizeof(PVRSRVTL_PACKETHDR) > psTmp->ui32Size )
		{
			psTmp->ui32Pending = NOTHING_PENDING;
			PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_MISUSE);
		}
#endif

		/* No data overwriting, insert write_failed flag and return */
		if (psTmp->bDrop) 
		{
			/* Caller should not try to use ppui8Data,
			 * NULLify to give user a chance of avoiding memory corruption */
			ppui8Data = IMG_NULL;

			/* This flag should not be inserted two consecutive times, so 
			 * check the last ui32 in case it was a packet drop packet. */
			ui32Buf =  ui32LWrite 
					  ? 
					    (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite - sizeof(PVRSRVTL_PACKETHDR)]
					   : // Previous four bytes are not guaranteed to be a packet header...
					    (IMG_UINT32*)&psTmp->pbyBuffer[psTmp->ui32Size - PVRSRVTL_PACKET_ALIGNMENT];

			if ( PVRSRVTL_PACKETTYPE_MOST_RECENT_WRITE_FAILED
				 != 
				 GET_PACKET_TYPE( (PVRSRVTL_PACKETHDR*)ui32Buf ) )
			{
				/* Insert size-stamped packet header */
				ui32Buf = (IMG_UINT32*)&psTmp->pbyBuffer[ui32LWrite];
				*ui32Buf = PVRSRVTL_SET_PACKET_WRITE_FAILED ;
				ui32LWrite += sizeof(PVRSRVTL_PACKETHDR);
				iFreeSpace -= sizeof(PVRSRVTL_PACKETHDR);
			}

			psTmp->ui32Write = ui32LWrite;
			psTmp->ui32Pending = NOTHING_PENDING;
			if (pui32AvSpace)
			{
				*pui32AvSpace = suggestAllocSize(ui32LRead, ui32LWrite, psTmp->ui32Size, ui32ReqSizeMin);
			}
			PVR_DPF_RETURN_RC(PVRSRV_ERROR_STREAM_FULL);
		} 
	}
	/* Update stream. */
	psTmp->ui32Write = ui32LWrite ;
	psTmp->ui32Pending = ui32LPending ;

	PVR_DPF_RETURN_OK;
}