| 53 | Finally, we need to include the Channel Switch Announcement inside our beacon transmissions and actually hop to a different center frequency at the appropriate time. We can accomplish both of these actions with modifications to the existing {{{beacon_transmit()}}} function. First, we need to define a few new variables at the top of the function: |
| 54 | |
| 55 | {{{ |
| 56 | #!c |
| 57 | |
| 58 | mgmt_tag_template* mgmt_tag_ptr; |
| 59 | |
| 60 | static u8 channel_switch_count = HOP_INTERVAL_NUM_TBTT; |
| 61 | static u8 next_chan = 1; |
| 62 | |
| 63 | }}} |
| 64 | |
| 65 | The {{{static}}} keyword prior to the declaration of a variable means that the variable will keep its value between invocations of the function. Next, find the part of {{{beacon_transmit()}}} that calls {{{wlan_create_beacon_frame()}}}. This function creates a beacon frame and includes some mandatory tagged parameters. In addition to these tags, we want our beacons to contain a Channel Switch Announcement if {{{HOP_MODE = 1}}}. Add the following snippet of code after the call to {{{wlan_create_beacon_frame()}}}: |
| 66 | |
| 67 | {{{ |
| 68 | #!c |
| 69 | |
| 70 | if(HOP_MODE == 1){ |
| 71 | |
| 72 | if(channel_switch_count == HOP_INTERVAL_NUM_TBTT){ |
| 73 | mac_param_chan = next_chan; |
| 74 | my_bss_info->chan = mac_param_chan; |
| 75 | wlan_mac_high_set_channel( mac_param_chan ); |
| 76 | |
| 77 | next_chan = (rand()%11)+1; // Valid channels are in the range [1, 11] |
| 78 | } |
| 79 | |
| 80 | mgmt_tag_ptr = (mgmt_tag_template*) ( ((u8*)(curr_tx_queue_buffer->frame)) + (tx_length - WLAN_PHY_FCS_NBYTES) ); |
| 81 | mgmt_tag_ptr->header.tag_element_id = MGMT_TAG_CHANNEL_SWITCH_ANNOUNCEMENT; |
| 82 | mgmt_tag_ptr->header.tag_length = 3; |
| 83 | |
| 84 | mgmt_tag_ptr->data[0] = 0; //Channel Switch Mode - 0: No restrictions on Tx, 1: Stations should wait until switch |
| 85 | mgmt_tag_ptr->data[1] = next_chan; //New Channel Number |
| 86 | mgmt_tag_ptr->data[2] = channel_switch_count; //Channel Switch Count |
| 87 | |
| 88 | mgmt_tag_ptr = (void*)mgmt_tag_ptr + ( mgmt_tag_ptr->header.tag_length + sizeof(mgmt_tag_header) ); //Advance tag template forward |
| 89 | |
| 90 | tx_length = ((u8*)mgmt_tag_ptr - (u8*)((curr_tx_queue_buffer->frame))) + WLAN_PHY_FCS_NBYTES; |
| 91 | |
| 92 | if(channel_switch_count > 1){ |
| 93 | channel_switch_count--; |
| 94 | } else { |
| 95 | channel_switch_count = HOP_INTERVAL_NUM_TBTT; |
| 96 | } |
| 97 | |
| 98 | } |
| 99 | |
| 100 | }}} |
| 101 | |
| 102 | This short chunk of code does everything we need. It will tune to a new channel on every "lap" of {{{HOP_INTERVAL_NUM_TBTT}}} beacon intervals. It will also include the {{{next_chan}}} inside every beacon along with the {{{channel_switch_count}}} to let each STA know where and when it should retune. |
| 103 | |
| 104 | ---- |