void main (void) { init_cc(); BSP_Init(); /* If an on-the-fly device address is generated it must be done before the * call to SMPL_Init(). If the address is set here the ROM value will not * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call * will not take effect. One shot only. The IOCTL call below is conformal. */ #ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE { addr_t lAddr; createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); } #endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */ /* This call will fail because the join will fail since there is no Access Point * in this scenario. But we don't care -- just use the default link token later. * We supply a callback pointer to handle the message returned by the peer. */ SMPL_Init(sRxCallback); /* turn on LEDs. */ if (!BSP_LED2_IS_ON()) { toggleLED(2); } if (!BSP_LED1_IS_ON()) { toggleLED(1); } /* wait for a button press... */ do { if (BSP_BUTTON1() || BSP_BUTTON2()) { break; } } while (1); /* never coming back... */ linkTo(); /* but in case we do... */ while (1) ; }
static void linkTo() { uint8_t msg[2]; uint8_t button, misses, done; /* Keep trying to link... */ while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) { toggleLED(1); toggleLED(2); SPIN_ABOUT_A_SECOND; } /* Turn off LEDs. */ if (BSP_LED2_IS_ON()) { toggleLED(2); } if (BSP_LED1_IS_ON()) { toggleLED(1); } /* sleep until button press... */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); while (1) { button = 0; /* Send a message when either button pressed */ if (BSP_BUTTON1()) { SPIN_ABOUT_A_QUARTER_SECOND; /* debounce... */ /* Message to toggle LED 1. */ button = 1; } else if (BSP_BUTTON2()) { SPIN_ABOUT_A_QUARTER_SECOND; /* debounce... */ /* Message to toggle LED 2. */ button = 2; } if (button) { uint8_t noAck; smplStatus_t rc; /* get radio ready...awakens in idle state */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); /* Set TID and designate which LED to toggle */ msg[1] = ++sTid; msg[0] = (button == 1) ? 1 : 2; done = 0; while (!done) { noAck = 0; /* Try sending message MISSES_IN_A_ROW times looking for ack */ for (misses=0; misses < MISSES_IN_A_ROW; ++misses) { if (SMPL_SUCCESS == (rc=SMPL_SendOpt(sLinkID1, msg, sizeof(msg), SMPL_TXOPTION_ACKREQ))) { /* Message acked. We're done. Toggle LED 1 to indicate ack received. */ toggleLED(1); break; } if (SMPL_NO_ACK == rc) { /* Count ack failures. Could also fail becuase of CCA and * we don't want to scan in this case. */ noAck++; } } if (MISSES_IN_A_ROW == noAck) { /* Message not acked. Toggle LED 2. */ toggleLED(2); #ifdef FREQUENCY_AGILITY /* Assume we're on the wrong channel so look for channel by * using the Ping to initiate a scan when it gets no reply. With * a successful ping try sending the message again. Otherwise, * for any error we get we will wait until the next button * press to try again. */ if (SMPL_SUCCESS != SMPL_Ping(sLinkID1)) { done = 1; } #else done = 1; #endif /* FREQUENCY_AGILITY */ } else { /* Got the ack or we don't care. We're done. */ done = 1; } } /* radio back to sleep */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); } } }
static void linkTo() { uint8_t msg[2]; uint8_t button, misses, done; /* Keep trying to link... */ while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) { toggleLED(1); toggleLED(2); SPIN_ABOUT_A_SECOND; } /* Turn off LEDs. */ if (BSP_LED2_IS_ON()) { toggleLED(2); } if (BSP_LED1_IS_ON()) { toggleLED(1); } /* sleep until button press... */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); while (1) { button = 0; /* Send a message when either button pressed */ if (BSP_BUTTON1()) { SPIN_ABOUT_A_QUARTER_SECOND; /* debounce... */ /* Message to toggle LED 1. */ button = 1; } else if (BSP_BUTTON2()) { SPIN_ABOUT_A_QUARTER_SECOND; /* debounce... */ /* Message to toggle LED 2. */ button = 2; } if (button) { /* get radio ready...awakens in idle state */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); /* Set TID and designate which LED to toggle */ msg[1] = ++sTid; msg[0] = (button == 1) ? 1 : 2; done = 0; while (!done) { for (misses=0; misses < MISSES_IN_A_ROW; ++misses) { if (SMPL_SUCCESS == SMPL_Send(sLinkID1, msg, sizeof(msg))) { #if defined( FREQUENCY_AGILITY ) /* If macro is defined we're supporting Frequency Agility. In this case * the peer will acknowledge the message sent. It is the only way we can * tell if we are on the right channel. Wait for ack. */ { bspIState_t intState; SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); NWK_REPLY_DELAY(); SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0); if (!sPeerFrameSem) { /* Try again if we havn't received anything. */ continue; } else { uint8_t len; BSP_ENTER_CRITICAL_SECTION(intState); sPeerFrameSem--; BSP_EXIT_CRITICAL_SECTION(intState); /* We got something. Go get it. */ SMPL_Receive(sLinkID1, msg, &len); if (len && (*msg & NWK_APP_REPLY_BIT)) { toggleLED(*msg & ~NWK_APP_REPLY_BIT); break; } } } #else /* Not supporting Frequency agility. Just break out since there * will be no ack. */ break; #endif } } if (misses == MISSES_IN_A_ROW) { /* This can only happen if we are supporting Frequency Agility and we * appear not to have received an acknowledge. Do a scan. */ ioctlScanChan_t scan; freqEntry_t freq[NWK_FREQ_TBL_SIZE]; scan.freq = freq; SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SCAN, &scan); /* If we now know the channel (number == 1) change to it. In any case * try it all again. If we changed channels we should get an ack now. */ if (1 == scan.numChan) { SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, freq); } } else { /* Got the ack. We're done. */ done = 1; } } /* radio back to sleep */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); } } }
static void monitorForBadNews() { uint8_t i, msg[1], len; /* Turn off LEDs. Check for bad news will toggle one LED. * The other LED will toggle when bad news message is sent. */ toggleLED(2); toggleLED(1); /* frequency hopping doesn't support sleeping just yet */ #ifndef FREQUENCY_HOPPING /* start the radio off sleeping */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); #endif while (1) { /* spoof MCU sleeping... */ for (i=0; i<CHECK_RATE; ++i) { SPIN_ABOUT_A_SECOND; /* manages FHSS implicitly */ } toggleLED(1); /* check "sensor" to see if we need to send an alert */ if (BSP_BUTTON1() || BSP_BUTTON2()) { /* sensor activated. start babbling. */ start2Babble(); } /* frequency hopping doesn't support sleeping just yet */ #ifndef FREQUENCY_HOPPING /* wake up radio. we need it to listen for others babbling. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); #endif /* stay on "long enough" to see if someone else is babbling */ SPIN_ABOUT_A_QUARTER_SECOND; /* frequency hopping doesn't support sleeping just yet */ #ifndef FREQUENCY_HOPPING /* we're done with radio. shut it down */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); #endif /* got message? */ if (SMPL_SUCCESS == SMPL_Receive(SMPL_LINKID_USER_UUD, msg, &len)) { /* got something. is it bad news? */ if (len && (msg[0] == BAD_NEWS)) { /* Yep. start babbling. If there is a filtering token make * sure the token matches the expected value. */ start2Babble(); } } } }