| 50 | The {{{frame_transmit()}}} needs to do a lot. It is safe to say that the function is certainly the most complex part of the DCF and, perhaps, even the entire 802.11 Reference Design. In no particular order, the function needs to: |
| 51 | |
| 52 | * draw a random backoff according to the binary exponential backoff |
| 53 | * use the [wiki:802.11/MAC/Support_HW MAC Support Core] to transmit a frame that defers to the medium |
| 54 | * if needed, send an RTS instead of the data itself to reserve the medium |
| 55 | * if needed, look out for a response frame (i.e. a CTS from a transmitted RTS or an ACK from a transmitted data frame) |
| 56 | * if needed, handle a timeout and implement the complex [wiki:802.11/MAC/Lower/Retransmissions retransmission behavior] |
| 57 | |
52 | | * If it is a unicast frame and an acknowledgment for that frame has been received |
53 | | * If it is a unicast frame and all retransmission attempts have failed |
54 | | * If it is a multicast frame, an MPDU transmission is done as soon as the PHY transmission is complete since no acknowledgment is required. |
| 60 | * a unicast frame that is acknowledged |
| 61 | * a unicast frame whose every retransmission attempt has failed |
| 62 | * any multicast frame has been transmitted (since multicast frames are, by definition, successful since they cannot be acknowledged) |
| 63 | |
| 64 | Pseudocode: |
| 65 | {{{ |
| 66 | continue_retries = 1 |
| 67 | while( continue_retries ) |
| 68 | if( mpdu is long ) |
| 69 | load MAC support core with RTS |
| 70 | else |
| 71 | load MAC support core with MPDU |
| 72 | |
| 73 | draw a random backoff and set MAC support core (will only be used if medium is busy) |
| 74 | |
| 75 | start MAC support core Tx state machine |
| 76 | |
| 77 | do |
| 78 | if( MAC support core is done ) |
| 79 | switch( MAC support core result ) |
| 80 | case immediate success (e.g., multicast): |
| 81 | reset contention windows and counters |
| 82 | start backoff |
| 83 | continue_retries = 0 |
| 84 | |
| 85 | case Rx has started: |
| 86 | call frame_receive() and check return value |
| 87 | if( Rx was ACK and we were waiting for ACK ) |
| 88 | reset contention windows and counters |
| 89 | start backoff |
| 90 | continue_retries = 1 |
| 91 | |
| 92 | if ( Rx was CTS and we were waiting on CTS ) |
| 93 | frame_receive handled the MPDU Tx, so we should set |
| 94 | the MAC support core status variable to pending explicitly |
| 95 | so we do not fall out of the do-while |
| 96 | |
| 97 | if ( other Rx ) |
| 98 | increment counters and contention window |
| 99 | continue_retries = 1 |
| 100 | |
| 101 | case Timeout has occurred: |
| 102 | increment counters and contention window |
| 103 | continue_retries = 1 |
| 104 | |
| 105 | while( MAC support core is pending ) |
| 106 | |
| 107 | |
| 108 | }}} |
| 109 | |
| 110 | |