802.11 Implementation Project
This project was implemented by Professor Brad Richards of Vassar University. I have reproduced his notes and work here as a reference project.
This project involves implementing a simplified version of the 802.11 MAC layer on the Cybiko. You will extend the services of the RF physical layer, and implement a set of services to be provided to the layer above. We will make the following simplifying assumptions:
- No base station or distribution system
- All machines are within range of all others
- No fragmentation or reassembly
- No power management mechanisms
- WEP will not be supported
Each of you will work individually, and your implementations will be expected to interoperate. You will all implement an indentical interface to the layer above, as well, so that a common test application can be used atop any of your implementation projects.
void MAC_Init(struct module_t *main, char *name)
This routine must be called before any of the other MAC routines are used. It is passed a pointer to the application's main module, and the application's name.
The layer above is expected to call this function frequently. It gives you an opportunity to service the RF layer, and perform any other regular tasks.
bool MAC_Handler(struct Message *ptr_message)
The layer above must pass events to this function so that the MAC layer has an opportunity to process any messages of interest. It returns TRUE if the event was handled by the MAC layer. Note that the RF layer may be interested in some of the messages passed to the MAC handler.
int MAC_Send(MACaddr dest, char *data, int size)
This function takes data from the layer above and sends it to the specified host using the CSMA/CA mechanism. The arguments include a pointer to a data buffer, and an integer specifying the number of bytes to be sent, and the function returns the number of bytes queued for transmission.
int MAC_Recv(MACaddr *source, MACaddr *dest, char *data, int bufSize)
This function presents data from the MAC layer to the layer above. The source and destination addresses are filled in as a result of the call. The caller is expected to set bufSize to the size of the buffer pointed to by data. The function returns the number of bytes written into the buffer. If the buffer is too small to hold the entire contents of the waiting transmission, the rest should be discarded. If there is no data waiting to be delivered, the function returns zero, and none of the other parameters are inspected or set.
The MAC layer signals the layer above upon the arrival of data via a MSG_MAC_ARRIVAL message. This message will not contain any data, though its cyid_from field should describe the source of the data that has arrived.
Our frame format is much simpler than that used in the actual 802.11 MAC. Since we don't have to worry about delivering data outside of our BSS, we only need address information for the transmitting and receiving machines. And, since one can determine the sending machine via the Message_get_sender_id call, only the destination address must be transmitted as part of the frame. Our checksum field precedes the data, which is necessary on the Cybiko if we ever intend to transmit an odd number of data bytes. Note that the Cybiko RF routines automatically perform a checksum, and only present data that arrives undamaged. Thus our CRC is unnecessary in practice, but will still be implemented. The two bytes of control information shown in the frame format above are also simplified. The 16 bits are divided into the following fields:
These three bits describe the frame's type, though currently only the last two of the bits are used. They specify the following frame types:
00 Data 01 ACK 10 CTS 11 RTS
This bit is set if the frame is a retransmission.
The remaining 12 bits constitute a sequence number so that receiving stations can distinguish between and properly order frames.