the data packet is then assigned a unique sequence number (with respect to the
node).
Next, the MAC checks it's backoff timer. If the backoff timer is not currently counting
down, then the node checks if the channel (medium) is idle, and if so the node will
begin to defer. The node checks this using the function is_idle(). As per the 802.11
specs, the node will defer a difs time plus a randomly chosen amount of time in the
interval [0, cw_), where cw_ is the current congestion window. If the node is
already waiting on it's defer timer, it will just continue waiting (not resetting the
timer). If the medium is detected to be busy, then the node starts it's backoff timer.
As of this point, the send() function has finished and control will resume when one
of the timers expires, calling either deferHandler() or backoffHandler().
sendDATA() - This function builds the MAC header for the data packet. This involves
increasing the size of the packet, setting the type as data, and subtype as data. The
packet should now have a complete MAC header attached to it. The function then
stores the txtime of the packet, which is computed by the txtime() function. By
txtime, we basically mean the size of the packet multiplied by the Data rate. You'll
notice (in 2.28 at least), that this calculation is done twice – this first time is just a
waste. It's calculated again because a different value for the data rate is used if the
packet happens to be a broadcast packet. Also, if the packet is not a broadcast
packet, the duration field in the MAC header is computed. By duration, we mean the
amount of time this communication still needs the channel after the data packet has
been transmitted. For the case of a data packet, this corresponds to the amount of
time to transmit an ACK plus a short inter-frame spacing. If the packet happens to
be broadcast, this field is set to zero (no ACKs for broadcast packets). Now, the MAC
has finished building the MAC header for the packet and finally assigns the internal
variable pktTx_ to point to the packet we've been working on. This is essentially a
way of storing the packet to be transmitted in a local buffer in the MAC. Now, the
code returns to the send() function.
sendRTS() – This function is in charge of creating an RTS packet with the specified
destination in conjunction with the data packet the MAC is trying to send. The first
thing it does is check the size of the packet against the RTSThreshold. If the packet
is smaller (or is broadcast) then no RTS is sent before the data is transmitted (the
RTS/CTS mechanism is not used). In this case, the function simply returns control
back to the send() function. Otherwise, a brand new packet is created (actually
done in the first line of the function) and it's fields are set appropriately, i.e. the type
is set as a MAC packet. A rts_frame structure is used to fill in the rest of the packet
header and the appropriate values are put in the rts fields. The destination field is
filled in with the parameter passed to the function and the rf_ta (source?) is filled in
with the MAC's address. The duration field is also calculated as the time to transmit
a CTS, the data packet (pktTx_) and an ACK (plus 3 sifs). After the RTS has been
constructed, the internal state variable pktRTS_ is assigned a pointer to the new
RTS. After this, control is returned to the send() function.