Ejemplo n.º 1
0
void ieee802frame154_dump( TiFrame * f )
{
    int8 len;
    TiIEEE802Frame154Descriptor meta;

    len = frame_length(f);
	if (len > 0)
	{   
		dbc_putchar( '>' );
	 	dbc_n8toa( len );
		 ieee802frame154_open( &meta );
        if (ieee802frame154_parse(&meta, frame_startptr(f), frame_length(f)))
        {
			dbc_putchar( ':' );
			dbc_write_n8toa( frame_startptr(f), len );
			dbc_putchar( 0xFC );
			dbc_putchar( '\r' );
			dbc_putchar( '\n' );
			}
		else{
            // if parsing failed, then we also output the data
            dbc_putchar( 0xFC );
			dbc_write_n8toa( frame_startptr(f), len );
			dbc_putchar( '\r' );
			dbc_putchar( '\n' );
			}
		}
		 else{
        // If the f doesn't contain any data, then still output some flag for indication.
        dbc_putchar( 0xFB );
        dbc_putchar( 0xFB );
    }
}
Ejemplo n.º 2
0
/**
 * Check whether there's some frame arrivaled. This function can be called anytime. 
 */
uintx aloha_recv( TiAloha * mac, TiFrame * frame, uint8 option )
{
    const uint8 HEADER_SIZE = 12, TAIL_SIZE = 2;
	uint8 count;
    char * ptr=NULL;

    // move the frame current layer to mac protocol related layer. the default layer
    // only contains the data (mac payload) rather than mac frame.

    frame_skipouter( frame, HEADER_SIZE, TAIL_SIZE );
    // assert: the skipouter must be success
	count = _aloha_tryrecv( mac, frame_startptr(frame), frame_capacity(frame), option );
	if (count > 0)
	{
        // the first byte in the frame buffer is the length byte. it represents the 
        // MPDU length. after received the frame, we first check whether this is an
        // incomplete frame or not. if it's an bad frame, then we should ignore it.
        //
        ptr = frame_startptr(frame);
        if (*ptr == count-1)
        {
            // get the pointer to the frame control field according to 802.15.4 frame format
            // we need to check whether the current frame is a DATA type frame.
			// only the DATA type frame will be transfered to upper layers. The other types, 
            // such as COMMAND, BEACON and ACK will be ignored here.
			// buf[0] is the length byte. buf[1] and buf[2] are frame control bytes.
            ptr ++;
			if (FCF_FRAMETYPE(*(ptr)) != FCF_FRAMETYPE_DATA)
			{
				count = 0;
			}
			else{
                frame_setlength( frame, count );
                frame_setcapacity( frame, count );
			}
        }
    }
    frame_moveinner( frame );

    if (count > 0)
    {
        frame_setlength( frame, count - HEADER_SIZE - TAIL_SIZE );
        frame_setcapacity( frame, count - HEADER_SIZE - TAIL_SIZE );
    }
    else{
        frame_setlength( frame, 0 );
    }

	aloha_evolve( mac, NULL );
	return count;
}
Ejemplo n.º 3
0
/* Broadcast a frame in the network. In most cases, the frame should be able to 
 * reach every node in the network, but no guarantee about this.
 */
uintx flood_broadcast( TiFloodNetwork * net, TiFrame * frame, uint8 option )
{
	uintx count=0;
	uintx i = 0;//todo 
	char * pc;
	
	/* This function will try to put the frame into TiFloodNetwork's internal TX buffer. 
	 * The real sending processing is in flood_evolve(). 
	 */
    i = frame_length( frame);//todo
	
	if (frame_empty(net->txque)) 
	{     
		net->txque->option = option;
		count = frame_totalcopyfrom( net->txque, frame );
        

		frame_skipouter( net->txque, 4, 0 );//todo 执行这一局后frame_length又变回0了!

		frame_setlength( net->txque,(i+4));//todo

		
		// assert( frame_skipouter must be success );
		pc = frame_startptr( net->txque );
		
		PACKET_SET_HOPCOUNT( pc,0 );
		PACKET_SET_MAX_HOPCOUNT(pc , CONFIG_FLOOD_MAX_COUNT );
		PACKET_SET_CURSEQID(pc, net->seqid );
	}

	flood_evolve( net, NULL );
	return count;
}
Ejemplo n.º 4
0
void _output_frame( TiFrame * frame, TiUartAdapter * uart )
{
    static TiIEEE802Frame154Descriptor m_desc;
    TiIEEE802Frame154Descriptor * desc;

	if (frame_totallength(frame) > 0)
	{   
		dbc_putchar( '>' );
	 	dbc_n8toa( frame_totallength(frame) );

        desc = ieee802frame154_open( &m_desc );
        // ? if (ieee802frame154_parse(desc, frame_startptr(frame), frame_length(frame)))
        if (ieee802frame154_parse(desc, frame_startptr(frame), frame_capacity(frame)))
        {
            // if the frame received is parsed successfully, then output it to the
            // computer through debugging channel

            //ieee802frame154_set_sequence( desc, seqid ++ );
		    //ieee802frame154_set_panto( desc, CONFIG_ALOHA_DEFAULT_PANID );
		    //ieee802frame154_set_shortaddrto( desc, CONFIG_ALOHA_REMOTE_ADDRESS );
		    //ieee802frame154_set_panfrom( desc, CONFIG_ALOHA_PANID);
		    //ieee802frame154_set_shortaddrfrom( desc, CONFIG_ALOHA_LOCAL_ADDRESS );

            // todo: you can output more
            // reference frame_dump() in rtl_frame.c

            dbc_n8toa( ieee802frame154_sequence(desc) );
			dbc_putchar( ':' );
			dbc_write( frame_startptr(frame), frame_capacity(frame) );
		}
		else{
	        // if the frame received is parsed failed, then output the error frame
            // to the computer through debugging channel

	        dbc_putchar( 'X' );
			dbc_putchar( ':' );
			dbc_write( frame_startptr(frame), frame_capacity(frame) );
		}
		dbc_putchar( '\r' );
		dbc_putchar( '\n' );
	}
}
Ejemplo n.º 5
0
void ieee802frame154_dump( TiFrame * f )
{
    int8 len;
    TiIEEE802Frame154Descriptor meta;

    len = frame_length(f);
	if (len > 0)
	{   
		
		dbc_putchar( 0xFA );
		dbc_putchar( 0xFA );
	    dbc_putchar( frame_curlayer(f) );
	 	dbc_putchar( len );

        // if the frame received is parsed successfully, then output it to the
        // computer through debugging channel
        //
        ieee802frame154_open( &meta );
        if (ieee802frame154_parse(&meta, frame_startptr(f), frame_length(f)))
        {
            // todo: you can output more
            // reference frame_dump() in rtl_frame.c

			dbc_putchar( 0xFB );
			dbc_write( frame_startptr(f), len );
			dbc_putchar( 0xFC );
		}
		else{
            // if parsing failed, then we also output the data
            dbc_putchar( 0xFC );
			dbc_write( frame_startptr(f), len );
		}
	}
    else{
        // If the f doesn't contain any data, then still output some flag for indication.
        dbc_putchar( 0xFB );
        dbc_putchar( 0xFB );
    }
}
Ejemplo n.º 6
0
int main(void)
{
	uint16 value, count;
	uint8 len;
	char * request;
	char * response;
    char * payload;
	char * msg = "welcome to node...";

	TiTimerAdapter * timeradapter;
	TiTimerManager * vtm;
	TiTimer * mac_timer;
	TiCc2420Adapter * cc;
	TiFrameRxTxInterface * rxtx;
	TiNioAcceptor * nac;
    TiAloha * mac;
	TiAdcAdapter * adc;
	TiLumSensor * lum;
	TiDataTreeNetwork * dtp;
	TiFrame * rxbuf;
	TiFrame * txbuf;

	target_init();

	led_open();
	led_on( LED_ALL );
	hal_delay( 500 );
	led_off( LED_ALL );

	rtl_init( (void *)dbio_open(38400), (TiFunDebugIoPutChar)dbio_putchar, (TiFunDebugIoGetChar)dbio_getchar, hal_assert_report );
	dbc_write( msg, strlen(msg) );

	timeradapter   = timer_construct( (void *)(&m_timeradapter), sizeof(m_timeradapter) );
	vtm            = vtm_construct( (void*)&m_vtm, sizeof(m_vtm) );
	cc             = cc2420_construct( (char *)(&m_cc), sizeof(TiCc2420Adapter) );
	nac            = nac_construct( &m_nacmem[0], NAC_SIZE );
	mac            = aloha_construct( (char *)(&m_aloha), sizeof(TiAloha) );
	dtp            = dtp_construct( (char *)(&m_dtp), sizeof(TiDataTreeNetwork) );
	adc            = adc_construct( (void *)&m_adc, sizeof(TiAdcAdapter) );
	lum            = lum_construct( (void *)&m_lum, sizeof(TiLumSensor) );
	txbuf          = frame_open( (char*)(&m_txbuf), FRAME_HOPESIZE(MAX_IEEE802FRAME154_SIZE), 3, 20, 0 );
	rxbuf          = frame_open( (char*)(&m_rxbuf), FRAME_HOPESIZE(MAX_IEEE802FRAME154_SIZE), 3, 20, 0 );
	// timeradapter is used by the vtm(virtual timer manager). vtm require to enable the 
	// period interrupt modal of vtm

	//timeradapter   = timer_open( timeradapter, 0, NULL, NULL, 0x01 ); 
	vtm            = vtm_open( vtm, timeradapter, CONFIG_VTM_RESOLUTION );
	cc             = cc2420_open(cc, 0, NULL, NULL, 0x00 );
	rxtx           = cc2420_interface( cc, &m_rxtx );
	mac_timer      = vtm_apply( vtm );
	mac_timer      = vti_open( mac_timer, NULL, mac_timer);
	hal_assert( rxtx != NULL );
	nac            = nac_open( nac, rxtx, CONFIG_NIOACCEPTOR_RXQUE_CAPACITY, CONFIG_NIOACCEPTOR_TXQUE_CAPACITY);
	hal_assert( nac != NULL ); 
    

	mac             = aloha_open( mac, rxtx,nac, CONFIG_NODE_CHANNEL, CONFIG_NODE_PANID, CONFIG_NODE_ADDRESS,mac_timer, NULL, NULL,0x01);

	adc            = adc_open( adc, 0, NULL, NULL, 0 );
	lum            = lum_open( lum, 0, adc );
	
	dtp            = dtp_open( dtp, mac, CONFIG_NODE_ADDRESS, NULL, NULL, 0x00 );


	//todo

	cc2420_setchannel( cc, CONFIG_NODE_CHANNEL );
	cc2420_setrxmode( cc );							            // enable RX mode
	cc2420_setpanid( cc, CONFIG_NODE_PANID  );					// network identifier, seems no use in sniffer mode
	cc2420_setshortaddress( cc, CONFIG_NODE_ADDRESS );	// in network address, seems no use in sniffer mode
	cc2420_enable_autoack( cc );

	//todo
	
	cc2420_settxpower( cc, CC2420_POWER_1);//cc2420_settxpower( cc, CC2420_POWER_2);
	cc2420_enable_autoack( cc );

	
//	ledtune        = ledtune_construct( (void*)(&m_ledtune), sizeof(m_ledtune), vti );
//	ledtune        = ledtune_open( ledtune );

	/* assert: all the above open() functions return non NULL values */

	hal_assert((timeradapter != NULL) && (cc != NULL) && (mac != NULL) && (adc != NULL) && (lum != NULL)
		&& (rxbuf != NULL) && (txbuf != NULL) && (dtp != NULL));

	hal_enable_interrupts();

    dtp->state = DTP_STATE_IDLE;//todo for testing 临时用这一句必须删掉

	//todo for testing
   
	//dtp->root = 0x01;//todo for testing
	//dtp->parent = 0x03;//todo for testing
   /*
	while ( 1)//todo for testing
	{
		
		response = frame_startptr( txbuf );

		value = lum_value( lum ); 
		payload = DTP_PAYLOAD_PTR(response);
		payload[0] = 0x13;
		payload[1] = 0x14;
		if (dtp_send_response(dtp, txbuf, 0x01) > 0)
		{ 
			led_toggle( LED_RED);//todo for testing
			
		}

        dtp_evolve( dtp, NULL );
		
		hal_delay( 2000);//todo for testing

	}

     */




	while(1)
	{
		/* Only the following two kinds of frames will be put into "rxbuf" by dtp_recv()
		 * - broadcast frames. the destination address of these frames are 0xFFFF.
		 * - destination is the current node. 
		 */
		//dbo_putchar(0x33);


		len = dtp_recv( dtp, rxbuf, 0x00 );
		if (len > 0)
		{   
            
  		    //ieee802frame154_dump( rxbuf);

			request = frame_startptr( rxbuf );

			switch (DTP_CMDTYPE(request))
			{
			/* if the frame is DTP_DATA_REQUEST, then the node will measure the data and 
			 * encapsulate the data into the txbuf, which is a TiOpenFrame and sent it back.
			 */


		

			case DTP_DATA_REQUEST:
				//payload = DTP_PAYLOAD_PTR( frame_startptr(txbuf) );
				//ledtune_write( ledtune, MAKE_WORD(payload[1], payload[0]) );

				// response frame = PHY Length 1B 
				//	+ Frame Control 2B 
				//	+ Sequence No 1B
				//	+ Destination Pan & Address 4B 
				//	+ Source Pan & Address 4B 
				//	+ DTP Section 15B

				//opf_cast( txbuf, 50, OPF_DEF_FRAMECONTROL_DATA_ACK );
				response = frame_startptr( txbuf );

				value = lum_value( lum );
				DTP_SET_MAX_HOPCOUNT( response,0x03);//todo for testing
				payload = DTP_PAYLOAD_PTR(response);

                //payload[0] = 0x17;//todo 第三个节点数据
				//payload[1] = 0x18;//todo 第三个节点数据

			    //payload[1] = 0x13;
				//payload[2] = 0x14;

				payload[1] = 0x15;//todo 另一个节点
			    payload[2] = 0x16;//todo 另一个节点

				/* call dtp_send_response() to send the data in txbuf out.
				 * 
				 * modified by zhangwei on 20091230
				 *	- Bug fix. In the past, there's no delay between two adjacent 
				 * dtp_send_response() calls. This policy is too ambitious and this
				 * node will occupy the whole time so that the other nodes will lost 
				 * chances to send, or encounter much higher frame collision probabilities. 
				 * so I add a little time delay here. 
				 *    Attention the delay time here shouldn't be too large because
				 * we don't want the hal_delay() to occupy all the CPU time. If this 
				 * occurs, it may lead to unnecessary frame lossing. 
				 */
				// try some times until the RESPONSE is successfully sent

			
               
                for (count=0; count<10; count++)
                {   
					//hal_delay( 500);
					if (dtp_send_response(dtp, txbuf, 0x03) > 0)
                    { 
                        led_toggle( LED_RED);//todo for testing
						break;
                    }
					//hal_delay( 50 );
				}
                
				break;


			default:
			    //hal_assert(false);
                break;
			}
		}
        nac_evolve( nac,NULL);//todo for tesitng
		aloha_evolve( mac,NULL);//todo for testing
		dtp_evolve( dtp, NULL );
		hal_delay( 50 );
	}
}
Ejemplo n.º 7
0
void ieee802frame154_dumpframe( TiFrame * frame )
{
	frame_movelowest(frame);
	ieee802frame154_dumpmembuf(frame_startptr(frame), frame_length(frame));
}
Ejemplo n.º 8
0
void tinymac_recvnode(void)
{
    TiCc2420Adapter * cc;
    TiFrameRxTxInterface * rxtx;;
    TiTinyMAC * mac;
	TiTimerAdapter   *timer;
	TiFrame * rxbuf;
	char * msg = "welcome to tinymac recv test...";
    int len=0;

	target_init();

    // flash the led to indicate the software is successfully running now.
    //
	led_open();
	led_on( LED_ALL );
	hal_delay( 500 );
	led_off( LED_ALL );
	led_on( LED_RED );

    // initialize the runtime library for debugging input/output and assertion
    // hal_assert_report is defined in module "hal_assert"
    //
	//dbo_open( 38400 );
    rtl_init( (void *)dbio_open(38400), (TiFunDebugIoPutChar)dbio_putchar, (TiFunDebugIoGetChar)dbio_getchar, hal_assert_report );
    dbc_putchar( 0xF0 );
    dbc_mem( msg, strlen(msg) );

	cc = cc2420_construct( (void *)(&m_cc), sizeof(TiCc2420Adapter) );
    mac = tinymac_construct((char *)(&m_tiny), sizeof(TiTinyMAC));
    timer= timer_construct((char *)(&m_timer),sizeof(TiTimerAdapter));

	#ifdef CONFIG_TSET_LISTENER
	// cc = cc2420_open( cc, 0, _aloha_listener, NULL, 0x00 );
    cc = cc2420_open( cc, 0, tinymac_evolve, mac, 0x00 );
    rxtx = cc2420_interface( cc, &m_rxtx );
	mac = tinymac_open( mac, rxtx, CONFIG_CHANNEL, CONFIG_PANID, CONFIG_LOCAL_ADDRESS, 
        timer, _tinymac_listener, NULL,0x00 );
	#endif

    #ifndef CONFIG_TSET_LISTENER
    cc = cc2420_open( cc, 0, NULL, NULL, 0x00 );
    rxtx = cc2420_interface( cc, &m_rxtx );
	mac = tinymac_open( mac, rxtx, CONFIG_CHANNEL, CONFIG_PANID, CONFIG_LOCAL_ADDRESS, NULL, NULL,0x00 );
	#endif
 
	cc2420_setchannel( cc, CONFIG_CHANNEL );
	cc2420_setrxmode( cc );							            // enable RX mode
	cc2420_setpanid( cc, CONFIG_PANID );					// network identifier, seems no use in sniffer mode
	cc2420_setshortaddress( cc, CONFIG_LOCAL_ADDRESS );	// in network address, seems no use in sniffer mode
	cc2420_enable_autoack( cc );

	#ifdef CONFIG_TEST_ADDRESSRECOGNITION
	cc2420_enable_addrdecode( cc );
	#else	
	cc2420_disable_addrdecode( cc );
	#endif

	#ifdef CONFIG_TEST_ACK
	cc2420_enable_autoack( cc );
	#endif
 
    rxbuf = frame_open( (char*)(&m_rxbufmem), FRAME_HOPESIZE(MAX_IEEE802FRAME154_SIZE), 3, 20, 0 );

    #ifdef CONFIG_TEST_ACK
    //fcf = OPF_DEF_FRAMECONTROL_DATA_ACK; 
	#else
    //fcf = OPF_DEF_FRAMECONTROL_DATA_NOACK; 
	#endif


    hal_enable_interrupts();

	/* Wait for listener action. The listener function will be called by the TiCc2420Adapter
	 * object when a frame arrives */
	#ifdef CONFIG_TEST_LISTENER	
	while (1) {}
	#endif
    
	/* Query the TiCc2420Adapter object if there's no listener */
	#ifndef CONFIG_TEST_LISTENER
	while(1) 
	{	
        frame_reset( rxbuf, 3, 20, 0 );

        len = tinymac_recv( mac, rxbuf, 0x00 );
		if (len > 0)
		{   
			dbc_putchar( 0xF3 );
            dbc_mem( frame_startptr(rxbuf), frame_length(rxbuf) );

            //frame_moveouter( rxbuf );
            //_output_frame( rxbuf, NULL );
            //frame_moveinner( rxbuf );

			led_off( LED_RED );

			/* warning: You shouldn't wait too long in the while loop, or else 
			 * you may encounter frame loss. However, the program should still 
			 * work properly even the delay time is an arbitrary value. No error 
			 * are allowed in this case. 
			 */
			//hal_delay( 500 );
			led_toggle( LED_RED );
			//hal_delay( 500 );
        }

		tinymac_evolve(mac, NULL );
	}
	#endif

    frame_close( rxbuf );
    tinymac_close( mac );
    cc2420_close( cc );
}
Ejemplo n.º 9
0
/* this function can be used as TiCc2420Adapter's listener directly. so you can get
 * to know when a new frame arrives through the event's id. however, the TiCc2420Adapter's 
 * listener is fired by ISR. so we don't suggest using aloha_evolve() as TiCc2420Adapter's
 * listener directly.
 *
 * the evolve() function also behaviors like a thread.
 */
void aloha_evolve( void * macptr, TiEvent * e )
{
	TiAloha * mac = (TiAloha *)macptr;

    mac->rxtx->evolve( mac->rxtx, NULL );

    // try sending the frame in mac->txbuf. if sending successfully, then transfer
    // to IDLE state. if failed, then still in WAITFOR_SENDING state.

    switch (mac->state)
    {
    case ALOHA_STATE_BACKOFF:
        if (vti_expired(mac->timer))
        {
            // if _aloha_trysend() returns positive value, then it means the frame
            // has been sent successfully. if it returns negative value, then it means
            // the frame has reached its maximum retry count. 
            // 
            // in the above two cases, the state should transfer to IDLE state. 
            // if the frame is failed sending and need retry, then _alohs_trysend() will 
            // return 0;
            
            // @modified by zhangwei on 2010.08.20
            // there're three cases for the result of _aloha_trysend(). if it return 
            // positive value, then it means the frame has been sent successfully. 
            // if it return 0, then means it sends nothing and you should retry the
            // sending again. if it returns negtive value, then it means this frame
            // has reached its maximum number retry count and should report sending
            // failure.
            //
            _aloha_trysend(mac, frame_startptr(mac->txbuf), frame_capacity(mac->txbuf), mac->sendoption );
        }
        break;
    
    case ALOHA_STATE_IDLE:
        break;

    case ALOHA_STATE_SLEEPING:
        /* 
        if (e->id = wakeuprequest)
        {
            phy_wakeup();
            mac->state = ADTALOHA_IDLE;
        }
        */

    default:
        break;
	}

    // attention the following process can occur in any state.
	if (e != NULL)
	{
		switch (e->id)
		{
		case EVENT_DATA_ARRIVAL:
			if (mac->listener != NULL)
			{
				mac->listener( mac->lisowner, e );
			}
            break;
        /*
        case ADTALOHA_EVENT_SHUTDOWN_REQUEST:
            // no matter what the current state is, then you can do shutdown
            vti_stop(); 
            phy_shutdown();
            mac->state = SHUTDOWN;
            break;    

        case ADTALOHA_EVENT_STARTUP_REQUEST: 
            if (mac->state == SHUTDOWN)
            {
                phy_startup();
                mac->state = IDLE;
            }
        */
		default:
			break;
		}
	}

	return;
}
Ejemplo n.º 10
0
uintx aloha_broadcast( TiAloha * mac, TiFrame * frame, uint8 option )
{
    uintx ret=0;
    TiIEEE802Frame154Descriptor * desc;

    switch (mac->state)
    {
    case ALOHA_STATE_IDLE:

        frame_totalcopyfrom( mac->txbuf, frame );

        // according to 802.15.4 specification:
        // header 12 B = 1B frame length (required by the transceiver driver currently) 
        //  + 2B frame control + 1B sequence number + 2B destination pan + 2B destination address
        //  + 2B source pan + 2B source address
        //
        frame_skipouter( mac->txbuf, 12, 2 );
        desc = ieee802frame154_format( &(mac->desc), frame_startptr(frame), frame_capacity(frame), FRAME154_DEF_FRAMECONTROL_DATA_NOACK );
        rtl_assert( desc != NULL );
        ieee802frame154_set_sequence( desc, mac->seqid );
	    ieee802frame154_set_panto( desc, mac->panto );
	    ieee802frame154_set_shortaddrto( desc, FRAME154_BROADCAST_ADDRESS );
	    ieee802frame154_set_panfrom( desc, mac->panfrom );
	    ieee802frame154_set_shortaddrfrom( desc, mac->shortaddrfrom );

        // char * fcf;
        // char * shortaddrto;

        // fcf = frame_startptr(frame);
        // shortaddrto = (char*)(frame_startptr(frame)) + 3;  // todo: according to IEEE 802.15.4 format, 加几?请参考15.4文档确认


        // for broadcasting frames, we don't need acknowledgements. so we clear the ACK 
        // REQUEST bit in the frame control field. 
        // refer to 802.15.4 protocol format
        //
        // fcf ++;
        // (*fcf) &= 0xFA; // TODO: this value should changed according to 802.15.4 format 

        // 0xFFFFFFFF the broadcast address according to 802.15.4 protocol format
        // attention: we only set the destination short address field to broadcast address.
        // the destination pan keeps unchanged.
        //
        // *shortaddrto ++ = 0xFF;
        // *shortaddrto ++ = 0xFF;

        //frame_moveinner( mac->txbuf );
        mac->sendoption = option;

        // standard aloha protocol behavior
        #ifdef CONFIG_ALOHA_STANDARD
        if (mac->rxtx->ischnclear(mac))
        {
            _aloha_trysend( mac, frame_startptr(mac->txbuf), frame_capacity(mac->txbuf), option );
        }
        else{
            mac->backoff = rand_uint8( CONFIG_ALOHA_MAX_BACKOFF );
            mac->retry = 0;
            vti_setinterval( mac->timer, mac->backoff, 0 );
            vti_start( mac->timer );
            mac->state = ALOHA_STATE_BACKOFF;
        }
        #endif

        // optimized aloha protocol behavior. it will insert a random delay before
        // sending to decrease the probability of conflictions.
        // wait for a random period before really start the transmission
        #ifdef CONFIG_ALOHA_STANDARD
        mac->backoff = rand_uint8( CONFIG_ALOHA_MAX_BACKOFF );
        mac->retry = 0;
        vti_setinterval( mac->timer, mac->backoff, 0 );
        vti_start( mac->timer );
        mac->state = ALOHA_STATE_BACKOFF;
        #endif

        ret = frame_capacity( mac->txbuf );
        aloha_evolve( mac, NULL );
        break;

    case ALOHA_STATE_BACKOFF:

        // in this state, there's already a frame pending inside the aloha object. 
        // you have no better choice but wait for this frame to be processed.
        //
        aloha_evolve( mac, NULL );
        ret = 0;
        break;

    case ALOHA_STATE_SLEEPING:

    default:
        // currently, this version implementation will ignore any frame sending request
        // if the mac component is still in sleeping state. you should wakeup it and
        // then retry aloha_send() again.
        ret = 0;
        break;
    }

    return ret;
}
Ejemplo n.º 11
0
uintx aloha_send( TiAloha * mac, TiFrame * frame, uint8 option )
{
	TiIEEE802Frame154Descriptor * desc;
    uintx ret=0;
    switch (mac->state)
    {
    case ALOHA_STATE_IDLE:

        frame_totalcopyfrom( mac->txbuf, frame );

        // according to 802.15.4 specification:
        // header 12 B = 1B frame length (required by the transceiver driver currently) 
        //  + 2B frame control + 1B sequence number + 2B destination pan + 2B destination address
        //  + 2B source pan + 2B source address
        //
        //frame_dump(mac->txbuf);
        frame_skipouter( mac->txbuf, 12, 2 );
        desc = ieee802frame154_format( &(mac->desc), frame_startptr(mac->txbuf), frame_capacity(mac->txbuf), FRAME154_DEF_FRAMECONTROL_DATA );
        rtl_assert( desc != NULL );
        ieee802frame154_set_sequence( desc, mac->seqid ); 
        ieee802frame154_set_panto( desc, mac->panto );
        ieee802frame154_set_shortaddrto( desc, mac->shortaddrto );
        ieee802frame154_set_panfrom( desc, mac->panfrom );
        ieee802frame154_set_shortaddrfrom( desc, mac->shortaddrfrom );
        
        //frame_moveinner( mac->txbuf );
        mac->sendoption = option;

        // standard aloha protocol behavior

        #ifdef CONFIG_ALOHA_STANDARD
        /*
         * @modified by XuFuzhen on 2010.09.29
         * - bug fix. should replace frame_length() here with frame_capacity()
         */
        if (mac->rxtx->ischnclear(mac))
        {
			_aloha_trysend( mac, frame_startptr(mac->txbuf), frame_capacity(mac->txbuf), option );
        }
        else{
            mac->backoff = rand_uint8( CONFIG_ALOHA_MAX_BACKOFF );
            mac->retry = 0;
            vti_setinterval( mac->timer, mac->backoff, 0 );
            vti_start( mac->timer );
            mac->state = ALOHA_STATE_BACKOFF;
        }
        #endif

        // optimized aloha protocol behavior. it will insert a random delay before
        // sending to decrease the probability of conflictions.
        // wait for a random period before really start the transmission
        #ifndef CONFIG_ALOHA_STANDARD
        mac->backoff = rand_uint8( CONFIG_ALOHA_MAX_BACKOFF );
        mac->retry = 0;
        vti_setinterval( mac->timer, mac->backoff, 0 );
        vti_start( mac->timer );
        mac->state = ALOHA_STATE_BACKOFF;
        #endif

        /* @modified by openwsn on 2010.08.30
         * - bug fix. you should place the frame_length() call before aloha_evolve() 
         * because aloha_evolve() may send mac->txbuf and clear it. this will cause
         * frame_length() returns 0 instead of the real frame length.
         * 
         * @modified by XuFuzhen on 2010.09.29
         * - bug fix. should replace frame_length() here with frame_capacity()
         */
        ret = frame_capacity( mac->txbuf );
        aloha_evolve( mac, NULL );
        break;

    case ALOHA_STATE_BACKOFF:

        // in this state, there's already a frame pending inside the aloha object. 
        // you have no better choice but wait for this frame to be processed.
        //
        aloha_evolve( mac, NULL );
        ret = 0;
        break;

    case ALOHA_STATE_SLEEPING:

    default:
        // currently, this version implementation will ignore any frame sending request
        // if the mac component is still in sleeping state. you should wakeup it and
        // then retry aloha_send() again.
        ret = 0;
        break;
    }

    return ret;
}
Ejemplo n.º 12
0
//#if (TEST_CHOICE == 1)
void recvnode1(void)
{
    TiCc2420Adapter * cc;
	char * msg = "welcome to recvnode...";
	TiFrame * rxbuf;
	uint8 len;

	target_init();
	HAL_SET_PIN_DIRECTIONS();
	wdt_disable();

	led_open();
	led_on( LED_RED );
	hal_delay( 500 );
	led_off( LED_ALL );
	rtl_init( (void *)dbio_open(38400), (TiFunDebugIoPutChar)dbio_putchar, (TiFunDebugIoGetChar)dbio_getchar, hal_assert_report );
	dbc_mem( msg, strlen(msg) );
	cc = cc2420_construct( (void *)(&g_cc), sizeof(TiCc2420Adapter) );

	cc2420_open( cc, 0, NULL, NULL, 0x00 );
	
	cc2420_setchannel( cc, DEFAULT_CHANNEL );
	cc2420_setrxmode( cc );							//Enable RX
	cc2420_enable_addrdecode( cc );					//使能地址译码
	//cc2420_disable_addrdecode(cc);
	#ifdef TEST_ACK
	cc2420_enable_autoack(cc);
	#endif

	cc2420_setpanid( cc, PANID );					//网络标识
	cc2420_setshortaddress( cc, LOCAL_ADDRESS );	//网内标识

	rxbuf = frame_open( (char*)(&m_rxbuf), FRAME_HOPESIZE(MAX_IEEE802FRAME154_SIZE), 0, 0, 0 );

	hal_enable_interrupts();	
	// when use this scan mode to receive data, interrupt should be disable; otherwise the data will be
	// read twice and in the second time there are no data actually which leads to a assert.
 	// Attention: in this scan mode, MCU always try to read and in my  test it is faster than the transmission of data. 
	// Thus, after 4 times, there no data at all, and the MCU still want to read, which lead to an assert. So we'd better
	// not use this scan mode.
    
	while(1) 
	{
		frame_reset( rxbuf,0,0,0);
		
		cc2420_evolve( cc );

		//len = cc2420_read( cc, frame_startptr( rxbuf), frame_capacity( rxbuf), 0x00 );
		len = cc2420_read( cc, frame_startptr(rxbuf), frame_capacity(rxbuf), 0x00 );
        if ( len)
        {
			frame_setlength( rxbuf,len);
			dbc_write( frame_startptr( rxbuf), len );
			led_toggle( LED_GREEN);
        }
		
		//len = cc2420_read( cc, (char*)(&buf[0]), BUF_SIZE, 0x00 );
	/*	if (len >= 5)
		{
			// output this frame to the computer through uart
			dbo_write( (char*)(&buf[0]), len );
		}*/
		
	}
}
Ejemplo n.º 13
0
/* This function receive event from other services/objects and drive the evolution 
 * of the TiFloodNetwork service. 
 * 
 * This function can also be the listener of the MAC layer, Though it's not mandatory.
 * 
 * @attention: 
 *	This function cannot run in the interrupt mode.
 */
void flood_evolve( void * netptr, TiEvent * e )
{
	TiFloodNetwork * net = (TiFloodNetwork *)netptr;
	uint8 len, count, cur_hopcount, max_hopcount;
	bool done = true, cont= false;
	char * pc;

	aloha_evolve( net->mac,e );

	// This event is sent from MAC layer. 
	//
	// @todo
	// Currently, all the frames from MAC layer will submitted the listener function.
	// Actually, this isn't necessary. Only those to this node should submitted to 
	// the listener.
	//
	if (e->id == EVENT_DATA_ARRIVAL)
	{
		if (net->listener != NULL)
		{
			net->listener( net->lisowner, e );
			return;
		}
	}

	do{ 
		
		switch (net->state)
		{
		// IDLE is the initial and default state of this state machine. 
		case FLOOD_STATE_IDLE:

			
			// Check if the TX queue is empty. If not then try to send the frame.
			if (!frame_empty(net->txque))
			{   
				
				len = aloha_broadcast( net->mac, net->txque, net->txque->option );
				
				if (len > 0)
				{
					frame_bufferclear( net->txque );
				}

				// @attention
				// @todo: if the aloha_send() is non-blocked operation, then you should
				// transfer to FLOOD_STATE_WAITFOR_TXREPLY state to wait. You should empty
				// the buffer only when this service receives the reply from MAC layer.
				
				 //net->state = FLOOD_STATE_WAIT_TXREPLY
				 done = true;
			}
		
			// Check if the RX queue is empty, then try to receive one from MAC layer
          	if ((frame_empty(net->rxbuf)) && frame_empty(net->rxque))
			{   
				cont = true;
				count = aloha_recv( net->mac, net->rxbuf, 0x00 );
				
				if (count <= 0)
					cont = false;

				// Check: whether the same frame has already been received. This
				// is by searching it in the cache. If it cannot find it in the 
				// cache, then put the frame in the cache.
				//
				// @modified by zhangwei on 2011.03.14
				// - we use the first 4 bytes in the frame (which is essentially 
				// the header of flood protocol as the key to visit the cache.
				//
	            if (cont)
				{   
					if (flood_cache_visit( net->cache, (char*)frame_startptr(net->rxbuf) ))//todo 我将CONFIG_FLOOD_CACHE_CAPACITY改成了1原先为8,不改的话不再接收新的帧.
					{   
						
						frame_bufferclear( net->rxbuf );
						cont = false;
					}
				}

				if (cont)
				{     
					frame_totalcopyto( net->rxbuf, net->rxque );
                  
					// Check whether this frame has reaches its maximum hopcount. 
					// Discard this frame if this is true.
					
					char * pc;
					pc = frame_startptr( net->rxbuf);

					cur_hopcount = PACKET_CUR_HOPCOUNT( pc );
					max_hopcount = PACKET_MAX_HOPCOUNT( pc);
					cur_hopcount ++;
					if (cur_hopcount > max_hopcount)
						frame_bufferclear( net->rxbuf );
					else
						PACKET_SET_HOPCOUNT( pc, cur_hopcount );
				}
				
				done = true;
			}

			// Check whether there's frame pending for forwarding
			if ((!frame_empty(net->rxbuf)) && frame_empty(net->txque))
			{   
				pc = frame_startptr( net->txque);
				// move the frame from rxbuf to txque. For efficiency reasons, this is implmented
				// by switching the two pointers.				 
				_switch_ptr( &(net->rxbuf), &(net->txque) );
				
				// @attention
				// generally, you should change the frame in "txque" with the PAN id
                // and BROADCAST_ADDRESS configured in this flood component. However,
				// here we assume the low level medium access protocol helps us to do so.

				cur_hopcount = PACKET_CUR_HOPCOUNT( pc );
				PACKET_SET_HOPCOUNT( pc, cur_hopcount++ );
				done = false;
			}	
			break;


		// This's the state waiting for MAC layer's reply. The sending process of the 
		// MAC layer may last for quite a long time due to re-transmission. Only at the
		// end of the transmission, the MAC layer does possible to notify the NET layer 
		// the transmission results of the sending request.
		//
		/*case FLOOD_STATE_WAITFOR_TXREPLY:
			 ioresult = aloha_ioresult(net->mac);
			 if ioresult == IDLE|TXDONE
			 {
					opf_clear( net->txque );
					net->state = FLOOD_STATE_IDLE;
			 }
			// if ioresult indicate there's error or failure
			//	report to the master program by call net->listener
			net->state = FLOOD_STATE_IDLE;
			break;*/

		default:
			net->state = FLOOD_STATE_IDLE;
		}
	}while (!done);

	return;
}