unsigned char random_u8(unsigned int seed) { rand_t *r; int rv; unsigned char rand; r = rand_open(); if (r == NULL) return -1; rv = rand_set(r,&seed,4); if (r == NULL) return -1; rand = rand_uint8(r); r = rand_close(r); return rand; }
/** * try send a frame out through the transceiver. the frame should be already placed * inside buffer. * * this function is shared by aloha_send() and aloha_broadcast(). * * @return * > 0 success * 0 failed. no byte has been sent successfully. need call this function to retry. * - 1: retry reach maximum count. failed the whole sending */ uintx _aloha_trysend( TiAloha * mac, char * buf, uint8 len, uint8 option ) { uintx count=0; // while (!csma_ischannelclear(mac->rxtx)) // continue; // attention whether the sending process will wait for ACK or not depends on // "option" parameter. count = mac->rxtx->send( mac->rxtx->provider, buf, len, option ); if (count > 0) { mac->seqid ++; mac->retry = 0; mac->state = ALOHA_STATE_IDLE; } else{ if (mac->retry >= CONFIG_ALOHA_MAX_RETRY) { mac->retry = 0; mac->state = ALOHA_STATE_IDLE; mac->sendfailed ++; } else{ mac->retry++; mac->backoff = CONFIG_ALOHA_MIN_BACKOFF + rand_uint8( mac->backoff << 1 ); if (mac->backoff > CONFIG_ALOHA_MAX_BACKOFF) mac->backoff = CONFIG_ALOHA_MAX_BACKOFF; vti_restart( mac->timer, mac->backoff, 0 ); mac->state = ALOHA_STATE_BACKOFF; } } return count; }
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; }
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; }