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); } } }
//***************************************************************************** // // Link to the access point and continue processing local button requests // forever. This function is called following initialization in main() and // does not return. // //***************************************************************************** static void LinkTo(void) { uint8_t pucMsg[2]; uint8_t ucMisses, ucDone; uint8_t ucNoAck; smplStatus_t eRetcode; unsigned long ulButton; UpdateStatus(false, "Linking to Access Point"); // // Keep trying to link. Flash our "LEDs" while these attempts continue. // while (SMPL_SUCCESS != SMPL_Link(&g_sLinkID)) { ToggleLED(1); ToggleLED(2); SPIN_ABOUT_A_SECOND; } // // Turn off both LEDs now that we are linked. // SetLED(1, false); SetLED(2, false); // // Tell the user all is well. // UpdateStatus(false, "Link successful"); // // Put the radio to sleep until a button is pressed. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); // // Start of the main button processing loop. // while (1) { // // Grab the button press flag and clear it. We do this since the flag // could be changed during the loop whenever function // WidgetMessageQueueProcess() is called and we don't want to miss any // button presses. // ulButton = g_ulButtonPressed; // // Has either button been pressed? // if (ulButton) { // // Clear the main button press flag. // g_ulButtonPressed = 0; // // Wake the radio up since we are about to need it. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0); /* Set TID and designate which LED to toggle */ pucMsg[1] = ++g_ucTid; pucMsg[0] = (ulButton == 1) ? 1 : 2; ucDone = 0; while (!ucDone) { // // Remember that we have yet to receive an ack from the AP. // ucNoAck = 0; // // Try sending the message MISSES_IN_A_ROW times looking for an // ack after each transmission. // for (ucMisses = 0; ucMisses < MISSES_IN_A_ROW; ucMisses++) { // // Send the message and request acknowledgement. // eRetcode=SMPL_SendOpt(g_sLinkID, pucMsg, sizeof(pucMsg), SMPL_TXOPTION_ACKREQ); // // Did we get the ack? // if (eRetcode == SMPL_SUCCESS) { // // Yes - Message acked. We're done. Toggle LED 1 to // indicate ack received. */ ToggleLED(1); break; } // // Did we send the message but fail to get an ack back? // if (SMPL_NO_ACK == eRetcode) { // // Count ack failures. Could also fail because of CCA // and we don't want to scan in this case. // ucNoAck++; } } // // Did we fail to get an ack after every transmission? // if (MISSES_IN_A_ROW == ucNoAck) { // // Tell the user what happened. // UpdateStatus(false, "Channel changed?"); // // Message not acked. Toggle LED 2. // ToggleLED(2); #ifdef FREQUENCY_AGILITY // // At this point, we assume we're on the wrong channel so // look for the correct channel by using 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(g_sLinkID)) { ucDone = 1; } #else ucDone = 1; #endif /* FREQUENCY_AGILITY */ } else { // // We got the ack so drop out of the transmit loop. // ucDone = 1; UpdateStatus(false, "Toggled AP LED %d", ulButton); } } // // Now that we are finished with it, put the radio back to sleep. // SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0); } // // Process the widget message queue. // WidgetMessageQueueProcess(); } }