= Description = The WANMAC is a TDM MAC that serves as a framework for all '''Scheduled Access''' MACs. In this scheme, their is one Base Station '''(BS)''' and many Subscriber Stations '''(SS)''' forming a Star Topology. The BS broadcasts downlink and uplink maps periodically which tells a SS when would be its turn to send and receive data, as is done in 802.16 or Wimax. For the first implementation we have assumed the system to be in equilbrium i.e. no new SS`s are added to the system. Their is no notion of an ACK here and no contention issues. == == == == [[Image(P2MP.png, align=centre, 600)]] == == This behavioral description of both BS and SS can be transformed to state-machines, which in turn can be transformed to C-code. A few typical transitions through states are numbered. For the Base Station, we have the following states: [[Image(BS.JPG, align=left, 600)]] == == == == == == == == == == == == 1) '''Process Map''' : The BS decides the allocation of slots for the uplink and the downlink to the various SS. Each slot consists of the number of burst units allowed. For our TDM system we have assumed a equal slots for all the subscribers. Also, new Connection ID`s are allocated during this stage. 2) '''Send Map''' : The Base Station broadcasts the map created in the above stage, using a special '''Connection ID''' 0, meant for all the Subscriber nodes already in the system. 3)'''DL Burst''' : The BS emits on the downlink as specified by Map transmitted in the previous stage. To distinguish between each of the SS it uses a Connection ID, which corresponds to its own queues. This can be heard by all the nodes and they too distinguish it by their Connection ID. 4) '''Contention Time''' : This stage is for future reserve. Any new SS wishing to join the system and already synchronized with BS would send in a Request during this stage. For the time being we make the BS and the SS sleep during this period. 5) '''UL Burst''' : The BS receives on the uplink as specified by Map transmitted in the previous stage. Again it distinguishes between various SS`s by the use of Connection ID. 6) '''Map Sending''' : If the BS does not receive from any SS for a long time, it enters this special stage. After coming to this state, the BS emits MAPS Periodically and simply waits for the rest of the frame. == == == == == == == == == == For the Subscriber Station, the states look like the following: == == [[Image(SS.JPG, align=right, 600)]] 1) '''Map Wait''' : A Subscriber Station begins by waiting for a good map broadcast. This is like polling for reception of a Map. The SS state machine cannot proceed any further untill it receives any further 2) '''Read Map''' : This basically involves processing of the map read and extracting the uplink time, downlink time and the waiting period for a subscriber. 3)'''Wait DL Burst''' : This is the waiting stage after which a SS can receive downlink bursts from the base station. 4) '''Rx DownLink''' : As the receive process is asynchronous, this invloves setting timer and receiving packets before timeout, meant for that node from the BS. It simply fills up its queues or hands up to the application layer. 5) '''Contention Period''' : As of now this stage simple involves waiting for the desired time, but can be used to exchange messages with the BS for increasing decreasing its slot size as per its demand. 6) '''Wait UL Burst''' : This is the waiting stage afer which a SS can transmit uplink downlink bursts from the base station. 7) '''Tx Uplink''' : The SS reads from it Tx Queue and transmits to the BS. Before starting to transmit it sets a timer which would tell it when to stop transmitting. After transmitting it simply waits for another map. The behavior described above is a small subset of that which is implemented in the attached code. Here, we bridge that state machine to a source and a sink (ethernet and OFDM physical layer respectively for a transmitter, and vice versa for a receiver). In that way, we have a project that creates a virtual wire between three WARP node, one BS and two SS. Any ethernet and higher layer traffic will be forwarded across the wireless medium. == == == == == == == == == == = Code = Latest Revision C File : [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c basestation.c] and [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c substation.c] Latest Revision Header File : [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h basestation.h] and [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.h substation.h] Hardware Related Base Station Header File : [source:/ResearchApps/MAC/WANMAC/Basestation/hardware.h hardware.h] Hardware Related Subscriber Station Header File : [source:/ResearchApps/MAC/WANMAC/Subscriber/hardware.h hardware.h] Note: This code relies on many external dependencies and will not compile on traditional architectures. == == == == == == = Documentation = When the MAC program is executed, it sets up the external devices that must be used ([source:/ResearchApps/MAC/ACKMAC/src/ackmac.c@211#L890 Ethernet], [source:/ResearchApps/MAC/ACKMAC/src/ackmac.c@211#L1128 Radio and PHY], and [source:/ResearchApps/MAC/ACKMAC/src/ackmac.c@211#L1297 Automatic Gain Control]). == == == == == Typedefs == This section contains all the data structures used in the protocol with their explaination. '''Common''' [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L46 pduStruct] The pduStruct type is the internal representation of what information is included in the frame sent to the PHY. There is a one to one conversion between this struct and array of bytes interpreted by the PHY. This allows us to abstract away from this array structure, making our MAC's behavior independent of the header format. Each packet contains a CID, which indicates the subscriber ID. The CID sof zero is for broadcasting purposes. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L58 pduQueueStruct] The pduQueueStruct is a structure containing an array of frameStructs and a few control bytes to keep track of indices, flags and the length of the queue. This queue can serve two purposes. The first use is during the receive phase of the MAC. When the MAC receives a packet from another node, it needs to put the payload somewhere. Because the specification of the connection between our MAC and higher networking layers is still in the process of being defined, we need a method of abstracting our layer away from this future glue layer. An acceptable solution is to simply copy packets from the PHY's memory space into a queue. It is assumed that another in the xilkernel will be taking these packets and giving them to higher layers. The other use of this queue is on the transmit side of the MAC. Again, the connection to the higher layer is still being defined, so we need a way of getting packets to send in the meantime. You can think of the transmit queue as analogous to the receive queue, in that some process somewhere gives us packets to send. This could be the [wiki:"Video Board" Video Board], or eventually the ethernet controller. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L74 MAPEntryStruct] The MAPEntryStruct is a single entry/slot of an uplink or a downlink MAP data structure. It contains the start time and the end time for that entry, which denote the number of bursts allocated in a given slot. [[Image(Maps.JPG, align=centre, 700)]] [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L79 MAPStruct] This is the data structure depicting the MAP. It contains the number of entries of the MAP along with the start time for that MAP. Also it has the pointer to the actual entries array. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L85 IDEntryStruct] This depicts an single ID, namely the Connection ID and the MAC information of the node being described. So far we are not using this, as this is used for Network Entry Protocol. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L90 IDStruct] This contains the list and the number of ids which correspond to the changes to be made in the new map. This is used both for deletion as well as for newly added subscriber ids. So far we are not using this, as this is used for Network Entry Protocol. == == '''Base Station''' [[Image(BSScheduler.JPG, align=left, 650)]] == == == == [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.h@360#L68 BSQueueStruct] This is the Base Station data structure, for keeping record of the number of subscribers and for their Receive and Transmit Queues. == == == == == == == == == == == == == == == == == == == == == == == == == == '''Subscriber Station''' [[Image(SSScheduler.JPG, align=left, 650)]] == == [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.h@361#L52 SSQueueStruct] This is the Subscriber Station data structure, for keeping record of its Receive and Transmit Queues. == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == Base Station Functions == [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L75 rxPhyGood] This function is called when a packet with the correct CRC is received. It copies the packet into the memory. It then checks the state of the BS machine and the Connection ID of the packet received with the expected Connection ID. Else it simply frees the buffer and in the end resets the receiver. Note, the resetting of the receiver is a must and it must be the last step after packet processing. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L157 BSRxInsertQueuebyMAC] The function is called when a packet needs to be inserted into a specific queue of the Base Station. This abstracts the behaviour of the PHY-MAC interaction. The queues are circular and this maintains a notion of a flag, to ensure it does not overwrite on any queue location. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L239 CopyMAPs] Another utility function for Copying one Map into another. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L325 ackmac_main] The first funtion to be called when the program begins the execution. It extracts the last byte of the MAC Address. This allocates the Memmory Buffer for the program . It then calls the function for Hardware Initialisation, followed by the Software Initialization and finally triggering off the State Machine. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L372 InitialiseBS] This is the main software Initialization funtion. It allocates memory for all the receive and transmit queues for the specified number of queues. Note the data in the queues is allocated as and when required. For the transmit queues it is done by the Dummy Application i.e the dummy generator. Initially the length of the queue is set as MAXQUEUELEN and the queue ID is set as that of the subscriber ID. The read and the write indexes are initialised to zero. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L CreateMaps] This function takes in old maps and the number of new users added to the system along with their ids. It also inputs the nos of users that would deleted from the system. It then process all the information to create the most update map verion. It does that both for the uplink and the downlink. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L429 InitialiseMAP] This is a utility function for initialising the first uplink and downlink maps. It allocates memory to the entries. For the time being we only had three entries, one for contention and one each for two subscribers. Note by defaut: The zeroth entry of the Downlink Map specifies the Contention Period Timings. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L558 TxMapsNewIds] This function takes in the Uplink and the Downlink Map and puts them into a pdu packet. It first puts in the Downlink Map followed by the Uplink Map. It allocates memory for the data part of the packet thus created. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L693 TxBSPDUs] The function is resposnsible for reading the Downlink Map and according to that, setting the timers for each of the downlink slots corresponding to each subscriber [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L727 TransmitfrmQ] This function makes the call to pull out packets from the queue specified and hands them over to the PHY layer. It simply waits in the while loop as long the timer goes on. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L747 BSTxRemoveQueuebyMAC] This function is responsible for taking out the pdu from one of the circular queue specified. This is responsible for updating the queue data structure so that we dont over write on any queue location. This is done by incrementing the read index of the circular transmit queue. The packet is copied into passed argument and memory is allocated for the data. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L859 ReceivefrmPhy] All this function does it to set a timer and wait for a packet to be received. It also changes the global variable queueidRx to the specified queueid, so that packets corresponding to the correct subscriber can be used. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L886 RxBSPDUs] It receives the Uplink Map and processes it in order to receive from each one of the subscribers. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L906 StateMachineBS] This is the main State Machine for the Basetation. It coordinates the way the execution takes place. It runs the dummy application to fill up the transmit queues. It then enters a never ending while loop, and starts to process Maps, transmit them, transmit and receive the payloads to and from each of the subscribers. If it does not receive anything on the Uplink, like in the Inital Stage it enters a '''Map-Sending''' stage. In that stage it simple transmits a Map after regular intervals, till it receives something from the Uplink. == == == == == Subscriber Station Functions == [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L79 InitialiseSS] This is the main software initialization funtion for the subscriber station. It allocates memory for all the receive and transmit queues for a given subscriber. Note the data in the queues is allocated as and when required. For the transmit queues it is done by the Dummy Application i.e the dummy generator. Initially the length of the queue is set as MAXQUEUELEN and the queue ID is set as that of the subscriber ID. The read and the write indexes are initialised to zero. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L387 RxMap] This function begins with an infinite loop simply waiting for a correct MAP to be received. The print statement in this function is important, otherwise the code just stops executing as it senses an infinite while loop. After having the received the Map into the global variable CurrMap, it then extracts the Uplink and the Downlink Map. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L466 StateMachineSS] This is the state machine for the Subscriber Station. It begins with the dummy application generator filling up the transmit queue for the subscriber station. Note that the interrupts for the good and the bad have been enabled here rather than in the hardware. This is to ensure that no packet is received before this and thus preventing the machine from going into a bad state. The machine basically goes in a loop waiting for a valid map and extracting out its receive and transmit time slots from them. After each loop the de-allocation of the Map entries is done. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L576 SSFreeQueues] This function does the de-allocation of the queues allocated for the transmit and the receive of the Subscriber Station [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L595 ackmac_main] The first funtion to be called when the program begins the execution. It extracts the last byte of the MAC Address. This allocates the Memmory Buffer for the program . It then calls the function for Hardware Initialisation, followed by the Software Initialization and finally triggering off the State Machine. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L647 RxSSPDUs] This function waits in a while loop till the timer goes off on the global variable notEndRxPDU. It expects to receive packets from the Base Station during this time interval. Note the setting of the timer is not done in this function unlike the Base Station, instead it is done in the state machine itself just after reading the Maps. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L664 TxSSPDUs] This function keeps on calling the function to remove packets from the transmit queue and sending them to the physcial layer. It waits on the global variable notEndTxPDU, which again is set in the state machine and not inside this function. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L683 SSTxRemoveQueuebyMAC] This function is responsible for taking out the pdu from one of the circular queue specified. This is responsible for updating the queue data structure so that we dont over write on any queue location. This is done by incrementing the read index of the circular transmit queue. The packet is copied into passed argument and memory is allocated for the data. [source:/ResearchApps/MAC/WANMAC/Subscriber/substation.c@361#L748 SSRxInsertQueuebyMAC] This function is responsible for inserting the pdu into one of the circular queue specified. This is responsible for updating the queue data structure so that we dont over write on any queue location. This is done by incrementing the write index of the circular receive queue. The packet is copied into passed argument and memory is allocated for the data. For simualting the behaviour of reception of packets, we are not using this function right now. == == == == == Common Functions == [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L1036 pb_int_handler] Interrupt handler for the pushbuttons on the WARP board. This is a low-priority interrupt because it is primarily used for debugging purposes. The five buttons on the board correspond to the switch cases for this handler. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L804 dummyPktGenerator] This is a virtual application layer function. It simply fills up a specified queue with dummy payloads. This is essentially simulating the application layer behaviour. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L717 SetTimer] The setTimer function allows the use of software timers for the MAC. Currently, the two types of timers for transmitting and the other for receiving. This function is called each time a Map entry is read and a specific time needs to be set for waiting or transmitting. Once the timer expires, the timer hadler function is called and the state of the machine can be changed. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L321 txPhy] This fuction hands over a PDU to the Phy layer, copies the header, payload into the memory and triggers the transmission. After having transmitted the packet, it then frees the data of that packet. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L40 timer_a_int_handler] This is the interrupt handler for the first timer peripheral. It checks to see which was the state it was called in and then changes values of global variables accordingly. This is mainly used to tell when the slot for receiving and transmitting ends. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L64 rxPhyBad] This function is used to keep a track of the number of bad packets ( CRC Error ) Received. After receiving it simply resets the receiver. [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L213 PrintPacket] A utility function for printing out any given pduStruct. Helpful in debugging !! [source:/ResearchApps/MAC/WANMAC/Basestation/basestation.c@360#L250 clearTimer] This function is called when u want to clear an already set timer. If an event happens before the desired end time for that event, then we can call this function to prevent the timer from going off unnecessarily. == == == == == Hardware Related Funtions == Base Station Hardware Initialization [source:/ResearchApps/MAC/WANMAC/Basestation/hardware.h@360#L79 InitializeHW] For the Base Station, this is the main function resposnsible for initialization of the hardware and setting up the warp boards for usage. This is a well commented funtion, highlighting the various steps involved. It initializes the LEDs and the push buttons on the board. It configures the device in the loopback mode and sets all the necessary options. It also registers the interrupt handlers and various timers. It can either accept hard coded gain values or use the AGC depending on the harware compatibily. It does the OFDM transmitter and receiver initialization. [source:/ResearchApps/MAC/WANMAC/Subscriber/hardware.h@361#L79 InitializeHW] This is the same as the above function, it simply does all the things mentioned with the Subscriber Station board. == == == == == Important Tips == '''Allocating Memory''' Create a buffer of Desired WIDTH and HEIGHT. Use Bufmalloc from that buffer. Also free into that buffer. 1) Ensure that for every allocation, there is a corresponding free. 2) If the WIDTH and HEIGHT values are too high, their will be a compilation error !! 3) Every time we do a malloc, capture the Status Message returned and print it out. Some useful ''code snippet'' for the above: #define BUFWIDTH 45 #define BUFHEIGHT 2096 static membuf_t mbuft; char membuf[BUFWIDTH][BUFHEIGHT] __attribute__ ((aligned(4))); ''Creating the Buffer'' int var; var = bufcreate (&mbuft, membuf, BUFWIDTH, BUFHEIGHT); if (var == -1){ xil_printf ("Error while creating memory pool. Errno: %d.\r\r\n", errno); ; } ''Destroying the Buffer'' bufdestroy (mbuft); ''Allocation Example and Capturing'' data = (unsigned char*)bufmalloc(mbuft,sizeof(char) * (data length)); if (data == 0) { xil_printf ("Error allocating Errno: %d.\r\n", errno); ; } ''Deallocation'' : Again using mbuft buffree(mbuft,data); ---- '''Printing out stuff on the Terminal''' We can use any terminal display for that. 1) Ensure it is connected to the the right Serial Port. (COMM1 / COMM2) 2) Use the baud rate of 57600, else you will see SYMBOLS instead of alphanumerics 3) Making LOGS: When priting out huge stuff, use File->Log of the Terminal. You can pause the logging process in between. 4) use xil_printf(), it has the same parameters %d %x %c etc like printf. For NEWLINE, use both \r\n. ---- '''Using Buttons on the Board''' for triggering Interrupt, so that we can see things. This is useful for printing out values of variable, parameters when the code is running. This helps you check the values whenever you want to see them. B3 B2 B1 B5 B4 See the code of pb_handler() for how the various cases are handled. Button B1 (center) is responsible for case 1 and can be used for printing out Statistics. The Button B4(Bottom Most and Middle) is used for resetting the Warp Board.