An Adaptive Jam-Resistant Cross-Layer Protocol for Mobile Ad-Hoc Networks In Noisy Environments Except where reference is made to the work of others, the work described in this dissertation is my own or was done in collaboration with my advisory committee. This dissertation does not include proprietary or classi ed information. Mark Gregory Kuhr Certi cate of Approval: Richard O. Chapman Associate Professor Computer Science and Software Engineering John A. Hamilton, Jr., Chair Professor Computer Science and Software Engineering David A. Umphress Associate Professor Computer Science and Software Engineering Martin C. Carlisle Professor Computer Science United States Air Force Academy George T. Flowers Dean Graduate School An Adaptive Jam-Resistant Cross-Layer Protocol for Mobile Ad-Hoc Networks In Noisy Environments Mark Gregory Kuhr A Dissertation Submitted to the Graduate Faculty of Auburn University in Partial Ful llment of the Requirements for the Degree of Doctor of Philosophy Auburn, Alabama May 9, 2009 An Adaptive Jam-Resistant Cross-Layer Protocol for Mobile Ad-Hoc Networks In Noisy Environments Mark Gregory Kuhr Permission is granted to Auburn University to make copies of this dissertation at its discretion, upon the request of individuals or institutions and at their expense. The author reserves all publication rights. Signature of Author Date of Graduation iii Dissertation Abstract An Adaptive Jam-Resistant Cross-Layer Protocol for Mobile Ad-Hoc Networks In Noisy Environments Mark Gregory Kuhr Doctor of Philosophy, May 9, 2009 (Master of Software Engineering, Auburn University, AL, 2008) (Bachelor of Science in Wireless Engineering, Auburn University, AL, 2006) 374 Typed Pages Directed by John A. Hamilton, Jr. This dissertation contributes a jam-resistant communications protocol for use in a mobile ad-hoc network (MANET). Speci c focus is given to the network layer rout- ing of packets within a MANET. A MANET is a self-organizing multi-hop wireless network that is comprised of many mobile hosts communicating wirelessly. As a result of their mobility and dependence on wireless communications, network layer routing is especially prone to errors. An algorithm has been developed using the concept of concurrent codes to allow for jam-resistant wireless communications without a pre- shared secret. The algorithm allows for the recovery of messages even in the presence of signi cant noise. Experimental results show that a cross-layer protocol designed to take advantage of this property allows for more e ective communications in noisy environments such as disaster sites where current network protocols experience signif- icant packet loss rates. Ultimately, this research presents a communications protocol iv that adapts to the level of interference in the environment to which the network is deployed to allow for e ective communication. v Acknowledgments Thanks to my wife Laura who has always had the utmost con dence in my abilities. Thank you for your continued love and support. Thanks to my graduate advisor and committee members for their support, advice, and encouragement. Thanks to the Information Assurance Center graduate students at Auburn Uni- versity for your support. Thanks to the US Air Force Academy Professors Bill Bahn, Leemon Baird, and Martin Carlisle for their tireless support, advice, and expertise. Thanks to my friend, Derek Sanders, for keeping my ideas grounded in reality. This work would not be possible without the continued nancial support of the Department of Defense (DoD) Information Assurance Scholarship Program (IASP) who has funded me through this research. vi Style manual or journal used Journal of Approximation Theory (together with the style known as \aums"). Bibliography follows van Leunen?s A Handbook for Scholars. Computer software used The document preparation package TEX (speci cally LATEX) together with the departmental style- le aums.sty. vii Table of Contents List of Figures xi 1 Introduction 1 1.1 Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.2 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3 Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2 Background on Wireless Communications 10 2.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2 Wireless Transmission Techniques . . . . . . . . . . . . . . . . . . . . 10 2.2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.2 Mobile Radio Propagation . . . . . . . . . . . . . . . . . . . . 11 2.2.3 Multiple Access Schemes . . . . . . . . . . . . . . . . . . . . . 13 2.2.4 Signal Jamming . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2.3 BBC Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.3.2 Theoretical Background . . . . . . . . . . . . . . . . . . . . . 20 2.3.3 BBC Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.3.4 BBC Decoding . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.4 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3 Mobile Ad Hoc Network Routing 26 3.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.2 Proactive Routing Protocols . . . . . . . . . . . . . . . . . . . . . . . 28 3.3 Reactive Routing Protocols . . . . . . . . . . . . . . . . . . . . . . . 33 3.4 Hybrid Routing Protocols . . . . . . . . . . . . . . . . . . . . . . . . 45 3.5 Interference Aware Routing Protocols . . . . . . . . . . . . . . . . . . 52 3.6 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4 Mobile Ad Hoc Network Address Auto-Configuration 58 4.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.2 IP-Based Approaches . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.3 Non-IP-Based Approaches . . . . . . . . . . . . . . . . . . . . . . . . 61 4.4 Duplicate Address Detection . . . . . . . . . . . . . . . . . . . . . . . 62 4.5 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 viii 5 Adaptive Jam-Resistant Cross-Layer Protocol Initial Design 64 5.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 5.2 Network Layer Routing . . . . . . . . . . . . . . . . . . . . . . . . . . 64 5.3 Network Layer Addressing . . . . . . . . . . . . . . . . . . . . . . . . 66 5.4 Dynamic Jam-Resistance . . . . . . . . . . . . . . . . . . . . . . . . . 67 5.5 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 6 Protocol Design and Implementation Phase 68 6.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 6.2 System Components . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 6.2.1 Hardware Components . . . . . . . . . . . . . . . . . . . . . . 70 6.2.2 Software Components . . . . . . . . . . . . . . . . . . . . . . . 74 6.3 Physical Layer Implementation . . . . . . . . . . . . . . . . . . . . . 90 6.4 Data Link Layer Implementation . . . . . . . . . . . . . . . . . . . . 97 6.5 Network Layer Implementation . . . . . . . . . . . . . . . . . . . . . 103 6.6 Software Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.7 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 7 Phase I Experimental Results 111 7.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 7.2 Hidden Station Problem Experiment . . . . . . . . . . . . . . . . . . 112 7.3 Exposed Station Problem Experiment . . . . . . . . . . . . . . . . . . 113 7.4 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 8 Phase II Experimental Results 116 8.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 8.2 Wi-Fi 802.11G Experimental Setup . . . . . . . . . . . . . . . . . . . 117 8.3 BBC-Enabled Protocol Experimental Setup . . . . . . . . . . . . . . 121 8.4 Wi-Fi 802.11G at 1.2GHz Experimental Setup . . . . . . . . . . . . . 124 8.5 Comparison of Wi-Fi 802.11G and BBC-Enabled Protocol Stack Ex- periments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 8.6 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 9 Phase III Experimental Results 130 9.1 Chapter Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 9.2 Experiment 1: USRPs Only . . . . . . . . . . . . . . . . . . . . . . . 132 9.2.1 Experiment Setup . . . . . . . . . . . . . . . . . . . . . . . . . 132 9.2.2 OLSR vs. BBC-OLSR Without Interference . . . . . . . . . . 133 9.2.3 OLSR vs. BBC-OLSR With Interference . . . . . . . . . . . . 134 9.3 Experiment 2: USRPs and Virtual Nodes . . . . . . . . . . . . . . . 137 ix 9.3.1 Experiment Setup . . . . . . . . . . . . . . . . . . . . . . . . . 138 9.3.2 OLSR vs. BBC-OLSR Without Interference . . . . . . . . . . 140 9.3.3 OLSR vs. BBC-OLSR With Interference . . . . . . . . . . . . 140 9.4 Discussion of Results . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 9.5 Interference Adaptive Routing Discussion . . . . . . . . . . . . . . . . 145 9.6 Chapter Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 10 Key Contributions 147 11 Conclusion 149 Appendices 164 A USRP Command and Control GUI Screenshots 164 B Phase III Diagrams 171 C Source Code Listing 174 C.1 USRP C2 GUI and Data-Link Layer . . . . . . . . . . . . . . . . . . 174 C.1.1 BBC Packet Class . . . . . . . . . . . . . . . . . . . . . . . . 260 C.2 BBC Encoder/Decoder [Bahn 2007] . . . . . . . . . . . . . . . . . . . 261 C.2.1 usrp.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 C.2.2 source.c and source.h . . . . . . . . . . . . . . . . . . . . . . . 270 C.2.3 sink.c and sink.h . . . . . . . . . . . . . . . . . . . . . . . . . 280 C.2.4 con g.c and con g.h . . . . . . . . . . . . . . . . . . . . . . . 290 C.2.5 bbcftp.c and bbcftp.h . . . . . . . . . . . . . . . . . . . . . . . 304 C.2.6 codec.c and codec.h . . . . . . . . . . . . . . . . . . . . . . . . 313 C.2.7 bu er.c and bu er.h . . . . . . . . . . . . . . . . . . . . . . . 326 C.2.8 bytes.c and bytes.h . . . . . . . . . . . . . . . . . . . . . . . . 332 C.2.9 modem.c and modem.h . . . . . . . . . . . . . . . . . . . . . . 336 C.3 USRP Radio Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 C.3.1 USRP BBC Transmitter . . . . . . . . . . . . . . . . . . . . . 344 C.3.2 USRP BBC Receiver . . . . . . . . . . . . . . . . . . . . . . . 349 C.3.3 USRP Signal Jammer . . . . . . . . . . . . . . . . . . . . . . 354 C.3.4 USRP RSSI Measurement . . . . . . . . . . . . . . . . . . . . 358 x List of Figures 1.1 Battle eld MANET Scenario . . . . . . . . . . . . . . . . . . . . . . . 5 2.1 Spread Spectrum Process . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.2 Direct Sequence Spread Spectrum (DSSS) Example . . . . . . . . . . 15 2.3 Hidden Station Problem . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 Exposed Station Problem . . . . . . . . . . . . . . . . . . . . . . . . 17 3.1 ALIR?s Computation of Interference [Zhang et al. 2007] . . . . . . . . 55 6.1 Universal Software Radio Peripheral External View with Casing . . . 72 6.2 Universal Software Radio Peripheral Internal View . . . . . . . . . . . 73 6.3 Universal Software Radio Peripheral Block Diagram . . . . . . . . . . 74 6.4 RFX-1200 Transceiver Daughterboard . . . . . . . . . . . . . . . . . 75 6.5 VERT400 Vertical Omnidirectional 7-inch Antenna . . . . . . . . . . 76 6.6 USRP Command and Control GUI Screenshot 1 . . . . . . . . . . . . 81 6.7 USRP Command and Control GUI Screenshot 2 . . . . . . . . . . . . 82 6.8 Topology Control Packet Format [Clausen, Dearlove and Jacquet 2008] 90 6.9 Hello Packet Format [Clausen, Dearlove and Jacquet 2008] . . . . . . 90 6.10 Interpolation Example [IEEE 1979, MathWorks 2009] . . . . . . . . . 93 6.11 Under Sampling Example [EFunda 2009] . . . . . . . . . . . . . . . . 94 6.12 Physical Layer State Diagram . . . . . . . . . . . . . . . . . . . . . . 107 6.13 Physical and Data Link Layer State Diagram . . . . . . . . . . . . . . 108 xi 6.14 Physical, Data Link, and Network Layer State Diagram . . . . . . . . 109 7.1 Hidden Station Problem Experimental Setup with USRP Devices . . 112 7.2 Exposed Station Problem Experimental Setup with USRP Devices . 114 8.1 Microwave Oven Signal in Time Domain [Taher et al. 2006] . . . . . . 119 8.2 802.11G Experiment Setup . . . . . . . . . . . . . . . . . . . . . . . . 119 8.3 Wi-Fi 802.11G Experiment Data . . . . . . . . . . . . . . . . . . . . 120 8.4 BBC-enabled Protocol Experiment Setup . . . . . . . . . . . . . . . . 123 8.5 BBC Experiment Data . . . . . . . . . . . . . . . . . . . . . . . . . . 123 8.6 802.11G at 1.2GHz Experiment Setup . . . . . . . . . . . . . . . . . . 125 8.7 802.11G at 1.2GHz Experiment Data . . . . . . . . . . . . . . . . . . 125 8.8 802.11G Versus BBC Protocols: Packet Error Rate . . . . . . . . . . 127 8.9 802.11G at 1.2GHz Versus BBC Protocol: Packet Error Rate . . . . . 128 9.1 USRP Network Topology . . . . . . . . . . . . . . . . . . . . . . . . . 133 9.2 OLSR With Interference Data . . . . . . . . . . . . . . . . . . . . . . 136 9.3 BBC-OLSR With Interference Data . . . . . . . . . . . . . . . . . . . 136 9.4 OLSR vs. BBC-OLSR Chart . . . . . . . . . . . . . . . . . . . . . . . 137 9.5 USRPs and Virtual Nodes Network Topology . . . . . . . . . . . . . 138 9.6 USRPs and Virtual Nodes Network Topology with Broken Links . . . 139 9.7 Pure OLSR With Noise Diagram . . . . . . . . . . . . . . . . . . . . 143 9.8 BBC-OLSR With Noise Diagram . . . . . . . . . . . . . . . . . . . . 144 A.1 USRP Command and Control GUI Screenshot 1 . . . . . . . . . . . . 165 A.2 USRP Command and Control GUI Screenshot 2 . . . . . . . . . . . . 166 xii A.3 USRP Command and Control GUI Screenshot 3 . . . . . . . . . . . . 167 A.4 USRP Command and Control GUI Screenshot 4 . . . . . . . . . . . . 168 A.5 USRP Command and Control GUI Screenshot 5 . . . . . . . . . . . . 169 A.6 USRP Command and Control GUI Screenshot 6 . . . . . . . . . . . . 170 B.1 Pure OLSR With Noise Diagram . . . . . . . . . . . . . . . . . . . . 172 B.2 BBC-OLSR With Noise Diagram . . . . . . . . . . . . . . . . . . . . 173 xiii Chapter 1 Introduction Mobile Ad-Hoc Networks (MANETs) consist of a number of mobile devices which self-organize to form a network without any infrastructure in place at the deployment location. Each node will communicate wirelessly with other nodes within its trans- mission range. Due to the lack of infrastructure, each node will act as a router and will be partially responsible for routing packets throughout the network. Formally, a MANET is the union of a set of autonomous nodes that communicate via unpre- dictable wireless communications to form an arbitrary communication graph. This graph, otherwise known as network topology, will vary with time as mobile nodes move in and out of range with their surrounding nodes. Essentially, these networks are peer-to-peer multi-hop wireless networks that transmit packets of information in a store-and-forward manner. In a store-and-forward scheme, a receiving node may choose to store a packet temporarily if it currently does not have any neighboring nodes within its transmission range. In the presence of neighbors, the receiving node must decide whether to forward the packet or not. The ability for this type of net- work to function is dependent upon the network layer protocol used to route packets among nodes in the network. MANETs have several characteristics that a ect communication throughout the network. 1 Dynamic Topologies: Since nodes are free to move in any direction and at any speed, the network topology may change rapidly. When bidirectional communication is necessary, frequent topology changes may cause signi cant routing protocol overhead. Furthermore, as a result of the wireless medium, some nodes may only be able to form unidirectional links. A more detailed discussion of the issues with this dynamic topology will be covered later. Power Constraints: Most nodes in a MANET rely on batteries for power. In this case, processing messages has a direct correlation to consumption of energy. For this reason, protocol e ciency is especially important. The network protocol designed in this research dynamically adjusts power consumption in response to environmental conditions such as noise. Bandwidth Limitations: Wireless links have a signi cantly lower transmis- sion rate than wired infrastructures. In addition to an already constrained capacity, the e ects of wireless communication further decrease bandwidth. For example, some of these e ects on wireless transmissions may include noise, inter- ference, and fading. The term bandwidth also has another meaning depending on the context. Another de nition for bandwidth in wireless communications concerns the frequency limitations of the wireless channel. The network proto- col designed in this dissertation will attempt to use the full spectrum allowed through spread spectrum techniques, while maximizing the transmission rate. 2 In addition, the protocol adapts its transmissions to resist interference if neces- sary which may result in reduced data rate. Limited Physical Security: Most MANET nodes are susceptible to physical attack since they are deployed to remote and often unattended locations. This research will not cover physical security attacks on wireless nodes. Due to the characteristics listed above, communications in disaster and battle- eld situations is especially troublesome (Figure 1.1). In these scenarios, there is no network infrastructure to rely upon, therefore MANETs are well suited for the job. Furthermore, there may be environmental conditions or intentional jamming by an adversary that a ects network availability. Current MANET designs have problems with noise because it causes signi cant packet loss which triggers retransmissions. However, these current designs also depend upon sensing the medium to avoid packet collisions. Packet loss due to interference and collisions a ects the reliability and availability of the MANET. In an emergency situation, network availability is of the utmost importance even at the sacri ce of the data rate. The communications protocol developed in this research is a cross-layer protocol in the sense that it will mainly operate at the network layer, yet it will manipulate data encoding and decoding at the data-link layer. Furthermore, in order to provide a working prototype, the physical layer functionality is implemented on software de ned radios. A form of error correcting codes, known as concurrent codes, forms the basis for this new cross-layer protocol. As a subset of concurrent codes, this protocol 3 will use BBC (named after creators Baird, Bahn, and Collins) codes [Baird, Bahn and Collins 2007] which are superimposed codes that can be decoded in polynomial time. These codes can help a receiver recover messages that have been a ected by noise. Noise adds energy to a signal and thus changes bits from 0?s to 1?s, but the use of concurrent codes allows the receiver to decode the corrupted signal up to a certain threshold. This research provides a cross-layer protocol that takes advantage of the jam-resistance provided by concurrent codes to allow MANETs to operate in environments with signi cant spectrum interference. According to the Open Systems Interconnection Basic Reference Model (com- monly referred to as the OSI Model), the network layer (layer 3) is responsible for the source-to-destination delivery of a packet in a network. The network layer has two major functions in the OSI model: Addressing: The network layer must assign a logical address using a scheme that allows every network device to have a universally unique address on the network. For example, an Internet Protocol (IP) address uniquely identi es one connection to the wired Internet. In a MANET, pre-con gurating unique network addresses is common prior to node deployment. Routing: To accomplish end-to-end delivery of a packet within a network, the network layer must decide the most e ective way to route the packet. In the traditional wired Internet, routers use extensive routing tables to route packets 4 e ciently. In a MANET, the route is constructed "on-the- y" as the packet traverses the ad-hoc network. This cross-layer protocol will mainly operate at the network layer, however it will manipulate data encoding and decoding at the data link layer to provide adaptive jam-resistance. In this way, it is considered a cross-layer protocol. Figure 1.1: Battle eld MANET Scenario 5 1.1 Goals This dissertation demonstrates the following contributions: A contribution to the area of address auto-con guration in MANETs. The cross-layer protocol adapts the addressing scheme to the number of nodes in the network automatically. This is validated using software de ned radios and a kernel network stack. A contribution to the area of MANET addressing in the form of an addressing scheme that provides unique addressing in network merges. This is validated using software de ned radios and a kernel network stack. A contribution to the area of autonomic tuning of routing in a MANET to adapt to current spectrum conditions such as the presence of noise by adjusting the routing protocol control packets to resist destruction by interference. This is validated using software de ned radios. A contribution to the area of cross-layer cooperation in wireless communications. The network protocol will pass parameters to the data-link layer to control the encoding of packets for transmission. The cross-layer protocol will adjust signal encoding based on spectrum interference conditions to guarantee availability. This is validated using software de ned radios. A contribution to the MANET network protocol realm in the form of a net- work layer that adjusts to pre-de ned priorities for network performance. The 6 protocol should allow for the prioritization of bandwidth (data bit rate in the network) or availability which compete under the BBC encoding scheme. This is validated using software de ned radios. 1.2 Challenges The nature of MANETs make routing packets among their nodes inherently dif- cult. The main challenge for a network protocol is to provide a communications platform that is adaptive, dynamic, and resilient in the presence of uctuating con- ditions in the wireless spectrum and node mobility. The BBC-based communications protocol presented in this dissertation advances this area of research and has met the research challenges identi ed below. The protocol must adjust the BBC message encoding in all network nodes in a top-down fashion based on feedback from the data-link and physical layers to ensure jam-resistance. Only with cross-layer support is this protocol able to adapt to changing spectrum conditions. The network protocol must uniquely and universally address the nodes in the network as nodes move in and out of the network. Most current auto-con guration protocols rely on periodic or reliable ooding which consumes considerable bandwidth. A BBC-enabled routing protocol is able to ood the network in a more reliable fashion due to fewer packet collisions. 7 As spectrum conditions change, the protocol must optimize the network to op- erate under pre-set priorities. This involves a trade-o between availability and bandwidth. As availability in terms of the degree of jam-resistance increases, the bandwidth will be reduced. This tradeo is managed dynamically and con- tinuously throughout the entire network. The BBC encoding algorithm allows for jam-resistant communication, but it imposes a penalty in the form of reduced data rates. This new routing protocol limits the size of messages passed in the network to allow for continuous jam- resistant communication. 1.3 Outline The remainder of this dissertation is organized as follows: Chapter 2 provides a background on Wireless Communications and the BBC Algorithm. Chapter 3 discusses network layer routing protocols for MANETs to include proactive, reactive, hybrid, and interference aware protocols. Chapter 4 discusses mobile node address auto-con guration techniques and methods for consideration. Chapter 5 provides the initial design for the cross-layer protocol. 8 Chapter 6 describes the design and implementation of the physical, data link and network layers for the jam-resistant communications protocol. Chapter 7 describes how the jam-resistant protocol developed in this research solves the hidden and exposed station problems. Chapter 8 provides a comparison study of 802.11G to the BBC-enabled protocol. Chapter 9 discusses experimental results of the BBC-enabled network layer and provides a comparison to a traditional OLSR based network routing layer. Chapter 10 discusses the key contributions of this research to the eld. Chapter 11 concludes with a discussion of the anticipated nal contribution of this dissertation. 9 Chapter 2 Background on Wireless Communications 2.1 Chapter Introduction Understanding the basics of wireless communication is essential to understand- ing the problems that most mobile networks face. The purpose of this section is to familiarize the reader with wireless communications techniques and the problems inherent to the wireless medium. These problems are further exacerbated by the mo- bility among nodes and spectrum interference. Furthermore, this chapter will discuss the BBC algorithm [Baird, Bahn and Collins 2007] in enough detail to understand its resistance to jamming and application to the cross-layer protocol described in this dissertation. 2.2 Wireless Transmission Techniques 2.2.1 Introduction Most people are familiar with the idea of wireless communication since we use it in our everyday lives. However, few are familiar with the details of how it works and why the wireless medium is inherently lossy. In wireless systems, signals are broadcast through free space (either air or a vacuum) and are available to any receiver capable of receiving them. Consider the MANET scenario where multiple nodes are transmitting and every node within range is capable of receiving the transmission. It is for this 10 reason MANETs are especially prone to unintentional jamming by other nodes. The remainder of this section will provide more detail on wave propagation in free space and schemes for allowing multiple nodes to share the wireless spectrum. First, it is important to understand a few terms common to this area of study. Terminology Spectrum A range of wavelengths of electromagnetic radiation. Omnidirectional Transmitting signals in all directions. Bandwidth A range of frequencies used for transmitting a signal or the transmission capacity of a computer network. Interference The disturbance of received radio signals caused by unwanted signals from other sources. Also, the act of combination of two or more waves to form a resultant wave (constructive) or cancellation (destructive). Propagation The transmission of electromagnetic waves through a particular medium. Path Loss The average propagation loss over an area due to distance between receiver and transmitter, antenna gains, transmitter and receiver power, envi- ronmental obstacles, and carrier frequency. 2.2.2 Mobile Radio Propagation In an ideal world, radio wave propagation in free space without obstacles is the ideal situation. However, this is only possible in a perfect vacuum. In most real-world 11 situations, radio waves encounter obstacles during transmission. For the purposes of this example, assume all mobile stations are using omnidirectional antennas so their transmissions radiate from the transmitter like ripples in a pond. MANETs rely on wireless communications in order to operate e ectively and propagation loss repre- sents a major reason a receiver cannot decode a transmitted message correctly. The combination of waves creates errors in the signal and as a result nodes must retrans- mit the message. When radio waves encounter obstacles, the following propagation e ects may occur and result in path loss [Agrawal and Zeng 2006]. 1. Di raction: Occurs when a wave bends around an object with sharp irregular surfaces. For instance, consider the case where line of sight does not exist between a transmitter and receiver, but the receiver still receives the signal. A good example of this scenario occurs when a wave bends around a sharp corner such as the edge of a building. 2. Re ection: Occurs when a propagating wave encounters an object that is larger compared to its wavelength. For example, when a radio wave encounters the face of a building it will re ect o the building. 3. Scattering: Similar to re ection, except this occurs when a wave encounters an object that is smaller than the wavelength of the propagating wave. For instance, a radio wave will scatter into several weaker signals if it hits a street sign. 12 2.2.3 Multiple Access Schemes In mobile ad-hoc networks, it is necessary to allow multiple nodes to utilize limited spectrum space simultaneously. In general, there are three ways to allow for multiple communication channels within the same allocated bandwidth to include frequency, time, and code division [Agrawal and Zeng 2006, Forouzan 2007]. Frequency Division Multiple Access (FDMA): Each user is assigned a di erent carrier frequency to transmit their messages. A related approach is Orthogonal Frequency-Division Multiple Access (OFDMA) where each user is a assigned a subset of orthogonal carrier frequencies Time Division Multiple Access (TDMA): Each user is assigned a di erent time slot to transmit their messages. Code Division Multiple Access (CDMA): Each user is assigned a di erent code (also called a \chip sequence") to use to transmit their messages. Under this scheme, the assigned code spreads the signal over the entire bandwidth range (known as spread spectrum). Jam-resistance is achieved through spread- spectrum techniques since the modulated signal is spread over the entire allo- cated bandwidth. In order to jam a spread spectrum signal, the jammer must add power to the entire channel (requires signi cant resources) or must possess the spreading code [Agrawal and Zeng 2006, Forouzan 2007] to focus their ef- forts. Figure 2.1 demonstrates the process used in spread spectrum techniques to spread the signal. 13 Figure 2.1: Spread Spectrum Process In practice, there are two main types of spread spectrum techniques: 1. Frequency Hopping Spread Spectrum (FHSS): A pseudorandom sequence (or code) is used to spread a frequency across a frequency band. The transmitter will hop from frequency to frequency according to the assigned code. Multiple users may use this technique as long as no two users occupy the same frequency at the same instant in time, but collisions may occur if the hop sequences are not chosen carefully. 2. Direct Sequence Spread Spectrum (DSSS): A pseudorandom sequence (or code) directly phase modulates a carrier frequency as shown in Figure 2.2. Each data bit of the original signal is replaced with a code of n bits called chips and where the chip rate is n times that of the data bit. The resulting signal resembles noise to any receiver within range. Only the receiver that possesses the pre-shared spreading code will be able to recover the signal. Privacy and jam-resistance is only guaranteed while the chip sequence remains private. If the sequence is known, an attacker may broadcast a strong signal using that sequence to interfere with a legitimate user. For 14 the purposes of this research, the jam-resistant network layer protocol will assume all mobile nodes use DSSS for their transmissions as this is common in current 802.11 wireless systems [Forouzan 2007]. Figure 2.2: Direct Sequence Spread Spectrum (DSSS) Example 2.2.4 Signal Jamming Mobile ad-hoc networks operate in a wireless spectrum that is highly susceptible to signal jamming. In general, this jamming is either due to interference with other nodes in the network or purposeful jamming by an adversary. In a crowded and 15 unregulated spectrum, the jamming can be a result of other signals propagating in the spectrum. For example, consider the unintentional jamming caused in the 2.4 GHz frequency band by kitchen microwave ovens. Friendly (Unintentional) Jamming: Jamming from adjacent nodes is a common problem when many nodes share the same channel. In this scenario, a mobile node receives data from more than one station at a time which results in a collision. A collision of this nature can be in the form of constructive or destructive interference that prevents the re- ceiver from decoding any signals. It is anticipated that the protocol developed in this dissertation will compensate for these problems by allowing for concur- rent messages to be decoded properly even when interference between stations exists. Two common friendly station interference scenarios are described below [Forouzan 2007]. 1. Hidden Station Problem: As shown below in Figure 2.3, nodes B and C are hidden from each other with respect to A. To understand this situation, consider the case where node B is sending data to node A. While this transmission is occurring, node C also sends data to node A since it does not know node B is already transmitting to A. The result is a collision at node A since it is receiving data from both B and C simultaneously. 2. Exposed Station Problem: As shown in Figure 2.4, transmission ranges for each node overlap. As a result, node C is exposed to transmissions from 16 Figure 2.3: Hidden Station Problem node A to node B. Consider the case where node A is transmitting data to node B, and node C would like to transmit data to node D. This is not a problem, except that node C is exposed to the tra c from node A and does not transmit because it senses the medium is busy. Therefore, node C wastes channel capacity and time by waiting for node A to complete its transmission to node B. Figure 2.4: Exposed Station Problem 17 Adversarial (Intentional) Jamming: Jamming from an adversary is prevalent in military communications scenarios. In addition, as hardware for jammers is fairly cheap and readily available, net- works are susceptible to malicious denial-of-service attacks. For simple wireless signals, signal jamming can increase the power of a signal ( ipping bits from 0 to 1) or decrease power in the signal by propagating a wave that is 180-degrees out of phase ( ipping bits from 1 to 0). To combat this simple attack, spread spectrum techniques discussed in the previous section are used. However, the jam resistance of traditional spread spectrum systems depends on the use of a secret key to control the sequence of frequencies for example in FHSS. There- fore, in order to jam a spread spectrum system, an adversary possessing the secret may add power to the channel to corrupt signals. 2.3 BBC Codes The basis for this new network protocol lies in the jam-resistance properties of the BBC algorithm[Baird, Bahn and Collins 2007]. For this reason, it is important to understand how this algorithm is able to decode signals in the presence of signi cant interference. 2.3.1 Introduction Spread spectrum techniques provide some jam-resistance but the transmitter and receiver must each possess the pseudorandom code sequence. Sharing this secret 18 prior to communications is analogous to the use of symmetric keys in cryptography. Symmetric keys do not scale well to large systems because the compromise of one key exposes the entire system to attack. Consider the case where a single spreading code is used by every radio in a military unit. The compromise of one radio handset would then allow the enemy to jam communications for the entire unit. The creators of BBC developed the algorithm in response to this situation. The BBC algorithm allows two parties to communicate without a pre-shared secret in a jam-resistant manner. The algorithm works by de ning codewords that can be combined with a bitwise OR, transmitted, and then e ciently decoded by the receiver. The remainder of this chapter will discuss details of how the algorithm operates and its resistance to jamming. Terminology The following lexicon is used within the BBC algorithm description and will be used in this dissertation when referring to the algorithm. Location The position of a single bit in a bit string. Indelible Mark A change of a bit from 0 to 1 purposefully by the encoder. An attacker cannot practically remove the mark from a radio signal and change the bit from 1 to 0. Data The bits that form the payload of a message to be transmitted. Message The bits of the data plus the header, padding, and checksum bits. 19 Codeword The encoder takes the message and produces a codeword. Packet The combination of one or more codewords with a bitwise OR. The packet is the same length as a codeword. Expansion Factor The ratio of the codeword length to the data length. The algorithm functions in two modes: encoding and decoding. During the encoding stage, the algorithm takes in a binary string to be encoded and maps it to the proper transmission buckets. The bucket is used for conceptualization, and could be represented as speci c frequencies, timeslots, or any other distinguishable radio transmission. The following sections describe the jam-resistant properties of BBC, and then shows a simple pulse-based broadcast using BBC to encode then decode a message. 2.3.2 Theoretical Background In the realm of coding theory, there are currently two main types of codes in- cluding error detecting codes and error correcting codes [Forouzan 2007, Ayanoglu et al. 1993]. The authors of [Baird, Bahn and Collins 2007] propose a new family of codes known as concurrent codes to which BBC belongs. BBC codes belong to a larger family codes known as superimposed codes. In short, a concurrent code is a su- perimposed code that can be decoded in polynomial time. Furthermore, a concurrent code translates each message into a binary codeword. The idea of concurrency comes from the ability to combine several codewords with a bitwise OR to form a single 20 combined string. Then, the receiver can analyze the combined string and recover all of the original codewords and messages. As shown in [Baird, Bahn and Collins 2007], the equations below describe the relationships among the maximum number of simultaneous messages, the bit rate, and the number of expected hallucinations. The network layer protocol described in this dissertation will make use of these relationships to adapt the MANET to changing spectrum conditions to optimize the balance between bit rate and degree of jam-resistance. Notation Ms = number of messages intentionally put into a packet by senders. R = MSe = the bit rate ratio of the maximum message bits per second for simultane- ous broadcast divided by the maximum bits per second for ordinary sequential broadcast. e = cm = codeword expansion. h = MR MS = hallucination rate (expected number of hallucinations per packet). A hallucination is an unintended message that the receiver accidentally decodes but it is not authentic since it was not sent by any sender. k = the number of 0 bits appended to the message as a checksum. m = bit length of a message. up = the probability that a packet bit is 1 (mark density) MS = 1lg(1 m lg(h) me ) (2.1) R = MSe (2.2) 21 k = em(1 (1 up) 1MS ) m (2.3) 2.3.3 BBC Encoding During encoding step, the input binary string is appended with k checksum bits that are actually just 0?s. The number of checksum bits, k, is determined in advance. Each bit string pre x is then sent through a hash function that maps a bit string to a bucket. The buckets that are identi ed by the hash function are considered marked and will be transmitted as a 1. In this example, the buckets identi ed with marks will be transmitted as a pulse. Using this example described in [Baird, Bahn and Collins 2007] which uses 25 buckets and 2 checksum bits, the encoding of the message M where M = 1011 proceeds as follows: 1. Append two checksum zeros to M: 101100. 2. Encode each pre x string, s, using the hash function, H as shown in Table 2.1. s H(s) 1 21 10 9 101 24 1011 2 10110 14 101100 12 Table 2.1: Pre x Hash Table 3. Transmit a \1" at the corresponding bucket locations for the H(s) results as demonstrated in Table 2.2 below. 22 Bucket 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 251011 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 Table 2.2: Transmission Buckets 2.3.4 BBC Decoding During decoding, the receiver is required to do more work than the encoder. The receiver will begin with a message that looks like Table 2.2 and needs to decode the message based on the speci c buckets that received a 1 during transmission. Since it is unknown whether the message began with a 0 or a 1, the receiver must hash both and determine whether a 1 was transmitted in that bucket. The decoding phase proceeds as follows: 1. Determine whether a 0 or 1 was transmitted. H(0) = 4 and H(1) = 21, and so the receiver will listen at buckets 4 and 21. Given the message from Table 2.2, it is seen that no transmission occurs at bucket 4; however, one occurs at bucket 21 indicating the message begins with a 1. 2. Next, the current string pre x is appended with a 0 and 1 account for each possible pre x. H(10) = 9 and H(11) = 21 in which case both of these have a message transmission, indicating there is the possibility for two encoded mes- sages. 3. Again, a 1 and 0 is appended to the string pre xes that are still alive. H(100) = 20, H(101) = 24, H(110) = 16, and H(111) = 2. Of these buckets, only buckets 24 and 2 have transmissions and will continue to be decoded. 23 4. Append a 1 and 0 to the string pre xes that are still alive. H(1010) = 15, H(1011) = 2, H(1110) = 14, and H(1111) = 23. Only buckets 2 and 14 have transmissions and continue to be decoded. 5. At this point the length of the transmitted message (4-bits) has been reached. Thus, the surviving pre xes will be appended with k-bits (only 0-bits) for at most two times since k = 2. H(10110) = 14 and H(11100) = 13. Only bucket 14 has a transmission and continues to be decoded. 6. Finally, the last stage in the decoding process is reached as we append the last k-bit to the message. H(101100) = 12, and bucket 12 does indeed have a transmission. Stripping the two checksum k-bits from the received message yield M0 = 1011 which is the same as the message that the transmitter sent. Notice that during step 5 of the decoding process, the original message can be seen but there is a second surviving message. This is considered a hallucination as termed by [Baird, Bahn and Collins 2007]. The k checksum bits help eliminate hallucinations in the received messages and as a result play a vital role in the decoding process. Without the checksum bits, the algorithm would have determined that multiple messages had been sent instead of the fact that the transmitter only sent one message. This example demonstrated the basic functionality of the BBC algorithm. If noise had been present in the system, more bits would have been received as 1-bits and the decoding process would have eliminated more hallucinations. 24 2.4 Chapter Conclusion This chapter covered the basics of wireless communication technology and pro- vided an overview of the BBC algorithm. In addition, this chapter discussed several major problems that arise with wireless nodes in a MANET such as the hidden sta- tion and exposed station problems. A BBC-based cross-layer protocol developed in this research allows inter-node communication in environments with signi cant noise and is less susceptible to the aforementioned problems. 25 Chapter 3 Mobile Ad Hoc Network Routing 3.1 Chapter Introduction As discussed in Chapter 1, the routing of data through a MANET is a challenging task due to several factors that include the lack of xed infrastructure, the dynamic topology caused by node mobility, the power constraints, and the limited bandwidth resulting from wireless communications. Consequently, the choice of routing protocol at the network layer is especially important to maximize the use of limited resources such as power and bandwidth. For the purposes of this research, all nodes in this MANET will operate using the same routing protocol and thus will use the same metrics to make routing decisions. With each node acting as a router, route compu- tation in MANETs is distributed and made on a hop-to-hop basis. A major challenge to this approach is that in order to route a packet, a node must know which nodes are within transmission range (called neighbor nodes). Moreover, in a MANET with high mobility, these neighbor nodes will change rapidly [Jubin and Truong 1987]. Further complicating the issue is the number of nodes in the network. As the number of nodes in the network increases, the number of potential destination also increases proportionally. With vast numbers of mobile nodes, the amount of data that must be exchanged also increases since nodes will need to exchange route information includ- ing routes, route updates, or routing tables (scalability). With limited bandwidth 26 and power, a routing protocol should strive to minimize the number of transmissions. In addition, increasing the number of transmissions further increases packet collisions and interference among nodes which will degrade network performance. Many rout- ing protocols rely on broadcasting to discover routes and this usually results in what is known as the broadcast storm problem [Tseng, Ni, Chen and Shieu 2002] since this causes contention, collision and redundancy. The BBC-based network routing layer described in this research will not su er from interference issues (to a certain upper bound) and will operate in highly noisy environments where current routing protocols fail. Before embarking on the development of a new adaptive cross-layer routing pro- tocol, it is important to understand the many routing protocols that already exist. This section will provide an overview of several of the most popular protocols and demonstrate the originality of the adaptive cross-layer protocol developed in this re- search. There are literally hundreds of network routing protocols for MANETs, but they fall into several major categories [Royer and Toh 1999]. First, this chapter will discuss proactive protocols where nodes continuously maintain the status of routes in the network. Secondly, this chapter will provide an overview of reactive protocols which only discover routes on-demand when data needs to be sent. Next, the chapter will cover hybrid protocols that attempt to combine the best attributes of both proac- tive and reactive protocols. Lastly, this chapter will introduce a newer category called adaptive protocols that adapt to changing conditions in the network. The protocol 27 developed in this research ts into the category of adaptive protocols since it adapts to spectrum interference. 3.2 Proactive Routing Protocols Proactive protocols are also commonly referred to as table-driven protocols since they store some amount of routing information in tables. It is the goal of these types of protocols to propagate network topology updates to the entire network so each node has the same view of the network. The following section will discuss various proactive routing protocols and highlight their key characteristics. Optimized Link State Routing (OLSR): OLSR version 2 (OLSRv2) [Clausen, Dearlove and Jacquet 2008] represents an update to OLSR version 1 as of July 2008. The main idea behind this protocol is to reduce the number of transmissions required for control tra c by e ciently ooding selected nodes. Each node selects a set of its neighbor nodes to be \MultiPoint Relays" (MPRs). As control tra c oods the network, a node will only forward tra c directly received from a node that selected it as an MPR. For example, if node A selected node B as an MPR, then node B will only forward control tra c directly received from A. \MPR ooding" decreases the load of control tra c on the MANET and thus improves performance. Furthermore, a node selects MPRs from a one-hop neighbor that is connected via a bidirectional 28 link. As a result, all routes through MPRs are bidirectional routes instead of unidirectional. Standard Link State Routing (SLS): In SLS [Santivanez, Mcdonald, Stavrakakis and Ramanathan 2002], each node simply sends a Link State Update (LSU) packet whenever a change in link state occurs. In the absence of changes, the node will send an LSU on a pre- determined timer. This algorithm has been almost completely superseded by the optimized link state routing (OLSR) algorithm. Destination Sequenced Distance Vector (DSDV): DSDV [Perkins and Bhagwat 1994] is a table-driven routing protocol based on the Bellman-Ford [Cormen, Leiserson, Rivest and Stein 2001] routing algorithm which is designed to nd the shortest path between two nodes in a communi- cations graph. In this protocol, each node maintains a full routing table with a route to every possible destination in the known network. In the table, routes are marked by sequence numbers which are assigned by the destination node. The sequence numbers server two main purposes. First, a sequence number will help expose stale routes when a higher sequence number supersedes it. Second, the sequence number will help prevent the formation of routing loops in the table. Routing table consistency in the presence of mobility is maintained through the use of periodic network broadcasts containing the table updates. To prevent 29 mobility and route updates from overwhelming the network, the nodes keep track of a \settling" time during which a better route may be discovered. The nodes then delay their update broadcast by the settling time in the hope of receiving a more stable route. In addition, when an update does occur, the protocol determines which type of update packet to send: a full dump packet or an incremental update packet. To prevent unnecessary load on the network, incremental update packets are most often used if possible since they are smaller in size. Cluster Head Gateway Switch Routing (CGSR): First, one must understand that CGSR [Chiang, Wu, Liu and Gerla 1997] uses DSDV as an underlying protocol. CGSR forms a hierarchical network topology (DSDV forms a at topology) where Cluster Heads (CHs) control a group of nodes. A node is classi ed as either an internal node, a cluster head, or a gateway node. The assignment to clusters and designation of the cluster head is completed through a distributed algorithm. The distributed algorithm adds overhead to the network and operates poorly in high mobility situations. CGSR only allows cluster heads to change when two cluster heads come into the same cluster or a node moves out of range of any cluster head. This algorithm is coined the Least Cluster Change (LCC) algorithm, but it still results in frequent cluster head changes in the presence of high mobility. CGSR does have some interesting properties in that a cluster head is able to control dynamic channel scheduling 30 within nodes in the cluster. For example, the cluster head can assigned di erent CDMA codes to each node to reduce interference. Cluster membership is maintained through a cluster member table. Along with this table, each node maintains a DV-routing table which contains next-hop routing information. To distinguish stale routes and stale member tables, CGSR uses sequence numbers as described in DSDV. Routing is conducted in the same way as DSDV, except route selection is based on the nearest cluster head to a destination node. Then, the routing proceeds through gateway and cluster head nodes. If an internal node wishes to send a packet to a destination node in another cluster, the packet is sent to the internal node?s cluster head rst. Then, this cluster head selects a gateway to send the packet through to the next best cluster head. This process repeats until the destination node?s cluster head receives the packet and delivers it to the nal destination. Wireless Routing Protocol (WRP): In WRP [Murthy and Garcia-Luna-Aceves 1996], each node must maintain four tables that include the routing table, the distance table, the link-cost table, and the message retransmission list (MRL) table. Update messages are used to update neighboring nodes of link changes. The MRL table keeps track of which updates should be retransmitted and which nodes must acknowledge the transmission. With the four tables at its disposal, the node must determine routing information. Since nodes must acknowledge receipt of update messages, 31 WRP provides faster route convergence than SLS, Bellman-Ford, and DSDV. However, maintaining four state tables is costly and the algorithm requires signi cant amounts of communication to operate. Topology Dissemination based on Reverse-Path Forwarding (TBRPF): TBRPF [Ogier, Templin and Lewis 2004] is composed of two independent mod- ules: the neighbor discovery module (TND) and the routing module. The routing module performs topology discovery and route computation, while the TND discovers neighbor nodes. However, the protocol as a whole aims to pro- vide the shortest path to each destination through a modi cation of Dijkstra?s algorithm. Each node computes a source tree based on partial topology infor- mation that provides paths to all reachable nodes. To reduce overhead, each node reports only a portion of its source tree to reachable neighbors. However, in cases of high mobility, nodes have the option to report more of their source tree to neighboring nodes. A major feature of TBRPF is that each module uses \di erential" update messages which only report changes in the status of neighbors. As a result, the message size is on average much smaller than other protocols for status update or routing update messages. In addition, since the modules are independent, developers are free to use a di erent neighbor discov- ery protocol or routing protocol. 32 3.3 Reactive Routing Protocols Reactive routing protocols are commonly referred to as \on-demand" protocols since they start route determination procedures when there is a need to transmit a message. It is the goal of these protocols to save energy and bandwidth by not transmitting control tra c periodically as proactive protocols do. Unfortunately, the global search initiated by a route discovery protocol usually requires signi cant control tra c. In addition, messages will be delayed until the route discovery process is complete. Plain Flooding (PF): In the classical PF algorithm, each packet is forwarded by every node in the network except for the nal destination. This approach requires signi cant bandwidth and will result in many messages traversing the network before the nal destination is reached. With every node retransmitting to all neighbors, this approach requires N 1 transmissions for each packet and can lead to the broadcast storm problem [Tseng, Ni, Chen and Shieu 2002]. Ad Hoc On-Demand Distance Vector (AODV): The AODV protocol [Castenada and Das 1999, Perkins, Belding-Royer and Das 2002] is a distance vector protocol based on the DSDV algorithm described above. The main di erence is that AODV uses on-demand route acquisition and a more e cient way to communicate route information. It still selects routes based on the distance to a speci ed destination. For example, only nodes 33 along a particular route will participate in the routing table changes. Moreover, each node will only store information about the routes in which they actively participate. In comparison to DSDV, AODV uses fewer broadcasts and does not require every node to store the complete routing table. The route discovery aspect of AODV relies on the use of route request (RREQ) packets. First, the source will broadcast a RREQ to all of its neighbors, who will forward it to all of their neighbors and so on. As this RREQ traverses the network, each intermediate node records the address from which they rst received a copy of the broadcast packet. In this way, a reverse path is formed from intermediate nodes back to the source. The packet will propagate the network until the nal destination is reached or an intermediate node is found which has a fresh route to the destination node. Since each intermediate node recorded a reverse path, the route reply (RREP) packet follows the reverse path to the source from the destination. Due to its use of the reverse paths, AODV only supports symmetric bi-directional links. Stale routes are eliminated through the use of sequence numbers and a route timer. In this protocol, every node has a sequence number and a higher sequence number identi es a more current route. Furthermore, link failures are propagated using RREP packets. Overall, AODV avoids the Bellman-Ford \count to in nity" problem [Cormen et al. 2001] and o ers quick convergence on new routes [Perkins, Belding-Royer and Das 2002]. A drawback to this protocol is that it does not scale well to large numbers of nodes [Aron and Gupta 2001]. 34 Dynamic Source Routing (DSR): DSR [Johnson and Maltz 1996] is based on source routing where every node in the network maintains a cache of all source routes they are aware of in the network. The protocol operates in two phases: route discovery and route main- tenance. When a source does not have a reliable route to a destination, the route discovery procedure is started and a route request (RREQ) packet is broadcast to all immediate neighbors. In DSR, the route request packet contains a source address, destination address, and a unique identi cation number. At each hop, nodes determine whether or not they have a route to the destination address. If not, they add their own address to the route record of the route request packet and rebroadcast it to their immediate neighbors. The main purpose of the route record is to prevent nodes from retransmitting route request packets they have already analyzed, thus reducing control tra c overhead. Finally, once the RREQ packet reaches the destination, the destination sends a reply packet with the route record which allows the packet to follow a step-by-step breadcrumb trail back to the source. Prior to reaching the destination node, If an interme- diate node has a route to the destination, this node simply copies its cached record into the route reply packet for the same breadcrumb trail e ect. In the example just described, symmetric links are supported. However, if symmetric links were not supported by the network, the destination would have to initiate a route discovery packet to nd the source and include the route record in the 35 new RREQ packet. The second phase of DSR is the route maintenance oper- ation. The protocol uses route-error packets and acknowledgments to clean up routing cache entries which results in quick route convergence[Boukerche 2001]. Upon noti cation from the data link layer that a link is no longer available, the protocol will immediately transmit route-error packets to the route initiator. DSR has been proven to not scale e ciently due to its use of blind broadcasts in the route discovery process [Aron and Gupta 2001, Santivanez, Mcdonald, Stavrakakis and Ramanathan 2002]. Dynamic MANET On-demand (DYMO): The DYMO routing protocol is a reactive multihop protocol for unicast routing [Chakeres and Perkins 2008] and its a direct descendant from DSR and AODV. By design, it is built to handle frequent topology changes through the use of sequence numbers to identify stale routes. The protocol consists of two basic operations that include route discovery and route maintenance. During route discovery, the protocol uses Route Request (RREQ) and Route Reply (RREP) packets to establish bi-directional links. To reduce congestion, the route discovery mechanism uses a binary exponential backo time in cases where a RREP is not received within a speci ed time limit. Through the use of sequence numbers, a node decides whether to forward the packet or update the route cache by analyzing the sequence number in the packet (RREQ or RREP). The sequence number in the cache is used to rate the routes as stale, 36 loop-possible, inferior, or superior. Furthermore, the sequence numbers prevent routing loops [Perkins and Belding-Royer 1999]. These classi cations are the basis for this protocol?s ability to handle frequent topology changes. In addition, the route maintenance mechanism uses a route error (RERR) packet to identify missing or invalid routes. Associativity-Based Routing (ABR): ABR [Toh 1997] strives to discover longer-lived routes through the use of a met- ric called the degree of association stability. The degree of association stability is the idea of measuring the connection stability between two nodes over time and space. As a result, nodes with high mobility will have a low degree of asso- ciation stability. On the other hand, nodes with low mobility will have a high degree of association stability. New routes are selected based on this metric to prefer more stable routes. Each node in this protocol broadcasts a beacon packet to let neighbors know it is in range. When a node receives a beacon packet, it increases the associativity tick (incremental counter) for the speci ed node. With this metric, the protocol consists of three phases that include route discovery, route reconstruction (RRC), and route deletion. The route discovery phase consists of a broadcast query (BQ) packet that traverses the network in a similar way to the Route Request (RREQ) packets previously mentioned. However, at each node relaying the BQ, the node appends their address and associativity ticks with neighbors to the BQ message. At the destination, the 37 best route is selected by examining the associativity ticks of all nodes along the path. Using this best route, the destination sends a reply packet to the source. When a node along a path moves, the RRC process begins which just causes the BQ messages to be sent to nd new routes if the source node has moved. In the case a downstream (closer to the sink) node has moved, then a route noti cation (RN) message is used to erase stale route entries. Lastly, the route deletion phase is used to eliminate routes from the table that a source node no longer needs. The route deletion is a full broadcast to all nodes since the source may not be aware of intermediate nodes that do not exist in the path after the RRC phase. It is the stated goal of this protocol to improve network through- put by using more stable links for transmission, however this protocol does not account for the breakage of a link after the routing path decision has been made [Chin, Judge, Williams and Kermode 2002]. In e ect, it would have to start from the beginning in order to compensate for node mobility that moved nodes out of range faster than the transmission time. Signal Stability-Based Routing (SSR): Similar to ABR, the SSR protocol [Dube 1997] selects routes based on the signal strength between the nodes and the mobility of the node. The protocol selects routes that operate over strong channels with su ciently strong signal strength [Chlamtac and Lerner 1986]. A good way to look at the SSR protocol is to look at its subcomponents which consist of the dynamic routing protocol (DRP) and 38 the static routing protocol (SRP). First, the DRP protocol maintains a table for signal stability (SST) and a routing table (RT). The SST keeps track of signal strengths of the links to neighboring nodes. Depending on implementation, the channel may be recorded with a quantitative or qualitative metric. For this explanation, consider a qualitative metric is used to classify a channel as either \strong" or \weak" about some threshold value. The DRP manages all transmissions since it has the signal strength table, and it will update the routing table as well. The SRP will process any received packets that DRP passes it. The main role of SRP is to process data packets and determine whether to forward or deliver the packet to the next layer in the stack based on the routing table. In this protocol, packets are only transmitted over strong channels and therefore link reliability increases. However, the protocol will experience delays in the presence of high mobility since it must still ood the network to nd routes and it is very selective about these routes based on signal strength parameters. On-Demand Multipath Routing: On-demand multipath routing [Nasipuri and Das 1999] is an improvement upon DSR (sometimes called MDSR) to allow for multiple paths from source to desti- nation. More improvements on DSR include the reduction in the query ooding frequency used to discover new routes. In addition, it improves performance by giving intermediate nodes alternative routes as well. This protocol begins in the 39 same way as DSR by ooding the network with route discovery query messages. As the message traverses the network, each hop is added to its header. When the packet nally arrives at the destination, the destination simply copies the path from the query packet and sends the message back. As with DSR, each node maintains a route cache which stores complete routes learned through the route reply packets. To provide nodes with multiple paths, the destination node replies to several received query packets from a source route that is link-wise disjoint from the primary source route. Essentially, this provides intermediate nodes with an alternative path to the destination. Ad Hoc On-Demand Vector-Backing Routing (AODV-BR): AODV-BR is an o shoot of AODV but provides multiple paths for redundancy as opposed to a single path [Lee and Gerla 2000]. As with AODV, the protocol consists of two phases including Route Construction and Route Maintenance. The main di erence is that during the route construction phase each node pre- pares an alternate route table. To form the alternate route table, a node will listen for route reply packets not directed toward it, but sent by one of its neighbors on the primary route. Now when the primary route is not available, the packets will have an alternate route to send data through. The combined primary and alternate routing tables form a mesh structure within the network and allow for highly redundant communications paths so data can be routed around broken links. 40 Split Multipath Routing (SMR): The SMR protocol [Lee and Gerla 2001] strives to construct maximally disjoint routes between a source and destination node. Once these disjoint routes are established, the protocol will split tra c among the various routes to ease con- gestion and use the limited resources e ciently. Of course, these routes may not be the same length, but they do build in some redundancy. As with other pro- tocols, SMR consists of route discovery and route maintenance phases. Route discovery proceeds in the same way as DSR and AODV, and the destination node will respond to the source using the path recorded in the request packet. However, in SMR, the destination node sends the response packet and then will wait to receive more route request packets for a certain amount of time. After this time, it will select another route that is maximally disjoint to the source it just responded to and sends a route response packet to this maximally disjoint source. Given a choice of many disjoint routes, the destination node chooses the one with the shortest path length by default. The route maintenance phase is quite similar to previous protocols as well, except the alternate route will be used prior to starting the route discovery process again. When both the pri- mary and alternate routes have been disconnected, the route discovery process will start again. A major bene t to this protocol is the ability to send tra c on multiple routes to ease congestion. 41 Caching and Multipath Routing Protocol (CHAMP): Another multicast protocol is the CHAMP protocol [Valera, Seah and Rao 2003] which aims to reduce packet loss due to link disruption using a temporal based scheme. Every node keeps a cache of data packets that pass through the node. Therefore, when a downstream node encounters an error, an upstream node is still capable of retransmitting the packet when it receives the error noti cations. In addition, each node must maintain a route cache that contains forwarding information to every active destination and a route request cache that stores recent route requests that were processed. The route cache contains the data elements such as the destination identi er, the distance to the destination, the set of next hop nodes for the destination, the time each successor node was last used and the number of times each successor node is used. The caches play a major role in the two phases of the protocol. CHAMP has two phases that include the route discovery and the data forward- ing. During route discovery, the protocol builds a directed acyclic graph (DAG) rooted at the source node in a similar fashion to the Temporally-Ordered Rout- ing Algorithm (TORA) protocol [Park and Corson 2001]. As is common in these types of protocols, the RREQ packet traverses the network through in- termediate nodes. Using CHAMP though, each intermediate node increments a forward count eld in the message. This forward count allows the intermedi- ate nodes to determine their hop count from the source. When a destination sends a route reply packet, it selects which nodes can accept the reply packet 42 to become part of the route based on the path the request packet took and it resets the forward count (hop count). A node listed in the route reply packet will accept the route if it is the shortest route to the destination or an existing route is too old as determined by a timer threshold. After a node accepts the route, it will forward the packet to upstream nodes with an updated forward count. This process will repeat until the route reply packet reaches the source node. In the second phase of CHAMP, data packets are forwarded through the es- tablished routes. The data packets are stored in the data cache and forwarded on a hop-by-hop basis. If a node has multiple routes to the destination, it will send data on the routes in a round robin fashion. As previously mentioned, a major bene t to this protocol is its ability to cache data packets. In the event of errors, upstream nodes can use the cached data packet to transmit the packet through a di erent route. The authors claim that CHAMP outperforms AODV and DSR using a ve packet data cache [Valera, Seah and Rao 2003] due to this redundancy and ability to use multiple routes in the event of link failures instead of starting route discovery again. This protocol proves that the ability to cache packets is a suitable approach to countering link failures. Neighbor-Table-Based Multipath Routing (NTBMR): The NTBMR protocol [Yao, Ma and Cao 2003] is designed to compensate for frequent topology changes due to mobility by using multipath routing. Unlike 43 SMR, the routes do not need to be disjoint routes. In this protocol, each node maintains a neighbor table and a route cache. In addition to the formation of the neighbor table and route cache, NTBMR also requires route discovery and route maintenance phases. To keep a current neighbor table, nodes periodically broadcast beacon packets which contain a time-to-live (TTL) eld. The beacon packets are only transmitted to two-hop neighbors. The protocol allows for two approaches to manage the neighbor table that include a time driven and data driven approach. In the time driven approach, when a node receives a beacon packet along a speci c route, it assumes the route is active and adds the beacon packet?s information to its neighbor table. However, if the node does not receive a beacon packet along the route before the timer expires, the route is consid- ered dormant and deleted. The timer driven approach has obvious limitations since the nodes cannot learn about changes that are two-hops away without a transmission. Instead, it would be better to use a data-driven approach which noti es neighbors of the unreachable station using a beacon packet that tells neighbors which station to remove explicitly. In the route discovery phase, the source rst consults its route cache to nd a route to the destination. The route cache contains the list of routes that the station is familiar with as obtained from routing control packets. In the case where there are multiple routes available, the source picks a route based on several parameters that include route setup time, route distance, and route extraction reason. The route extraction reason represents the reason the route 44 cache has stored the route. In order of priority, the route cache prefers to obtain routes from the reply packets rather than data packets. In the event there is no suitable route, the route discovery process proceeds in much the same way as DSR. During the route maintenance phase, alternate routes are preferred over starting a new route discovery process. This protocol has a better packet delivery ratio and decreased end-to-end delay as compared to DSR [Yao, Jiang, Fan, Cao and Li 2003]. However, this protocol does use beacon packets which cause congestion and add overhead. 3.4 Hybrid Routing Protocols Hybrid routing protocols combine aspects of both reactive and proactive proto- cols. In most cases, hybrid protocols initiate route discovery in an on-demand fashion but try to limit the cost of the path search through the network. Zone Routing Protocol (ZRP): In the ZRP protocol [Haas and Pearlman 1998, Haas, Pearlman and Samar 2002c], the network is divided up into routing zones. More speci cally, a node?s routing zone is de ned as the set of nodes whose minimum distance in hops is no greater than the zone radius. The protocol strives to limit the proactive route discovery to a node?s local area or zone. However, it performs reactive route discovery for routing data between zones. First, it is important to under- stand that the ZRP is highly adaptable to various network scenarios. The main 45 parameter to con gure in ZRP is the routing zone radius. Large routing zone work best when mobility is low and there are many nodes communicating since these nodes would be proactively managed. On the other hand, smaller routing zones work best for high mobility situations involving few nodes. In extreme circumstances of either case, the protocol will adjust to being entirely proactive (large xed topology) or entirely reactive (very high mobility). However, in most common network scenarios, ZRP performs better than a purely reactive or purely proactive protocol [Haas, Pearlman and Samar 2002c]. A node identi es a routing zone by identifying its one-hop neighbors. In ZRP, nodes use the neighbor discovery protocol (NDP) [Clausen, Dearlove and Dean 2008] to discover neighbors. Then, to maintain routes, ZRP uses two proactive protocols. First, the intra-zone routing protocol (IARP) [Haas, Pearlman and Samar 2002b] is used to maintain routes within a zone. For reference, IARP is a distance vector protocol customize for use in ZRP. The other proactive protocol used is the inter-zone routing protocol (IERP) [Haas, Pearlman and Samar 2002a] which is used for routing to nodes beyond the current zone. The inter-zone communication is handled in a reactive manner through a normal query-response scheme as discussed previously. For example, when a source needs to contact a destination that is in a di erent zone, the source initiates a route query packet. This route query packet is sent to the neighbor nodes rst. If the route is still unknown, these nodes add their unique ID to the query packet and then forward the packet to a border node. The border node will 46 reactively search for the destination until it is found. Finally, the destination will observe the reverse path of nodes added to the packet and respond with a reply message. The source may receive multiple routes and will choose the best route for a given situation based on pre-determined parameters such as hop count or tra c metrics. Temporally-Ordered Routing Algorithm (TORA): TORA [Park and Corson 1997; 2001] is a complex distributed routing protocol based on the concept of link reversal, rather than being distance-vector or link- state based routing. The main idea behind TORA is to decouple the generation of control messages that propagate the network from the dynamics of the net- work topology. In addition, the algorithm allows for multipath routing. This algorithm also contains a blend between proactive and reactive routing, so it is a hybrid approach to routing. TORA is proactive in the sense that multiple routing options are available when a link fails. It also proactively optimizes the routes. However, it can be considered reactive since route creation is done in an on-demand fashion. The following paragraphs will highlight the major features of this algorithm. First, it is important to understand how the multipath operation works within TORA at a high-level. Its design has been proven to decrease the amount of control packets necessary in the presence of high mobility nodes [Park and Corson 2001]. To understand TORA, consider the concept of a pin ball machine 47 on an incline. From the ball drop location (source), there are multiple paths to the destination (sink), hence multiple paths. When TORA starts up, it assigns a height to every node in range. As with the pin ball machine, a lower height value is closer to the sink since the balls (representing data ow) ow down hill. When a path becomes jammed in the game (due to user control), the ball will ow back uphill and come down a di erent path. In a similar way, TORA allows for link reversal to route data around broken or jammed links to the sink. Unfortunately, the path selected may not be the shortest path and most often it is longer since it routes data around failed nodes. In addition, when nodes use the protocol, they run a separate copy of TORA for each possible destination. As a result, nodes running TORA may have di erent heights and directions for di erent destinations. In other words, each node maintains a separate directed acyclic graph (DAG) to every destination [Park and Corson 2001]. In order to simplify this explanation, consider a speci c instance of TORA running on a speci c node for a speci c destination. This will all become clear in the following paragraphs which go into more detail. As mentioned earlier, TORA assigns a height to their neighboring routers. In addition, it also assigns a direction to all links as a result of this height. The direction is either upstream or downstream. A link is an upstream link for the \lower" neighboring router, but it may also be a downstream link for a \higher" neighboring router due to its assigned height metric. To add meaning to this designation, an upstream link for a node would imply that data ows to the 48 corresponding destination node can only come to this node from the upstream node. Downstream ows work in a similar way but in the reverse direction. At its core, TORA has four main phases that include route creation, route maintenance, route erasure, and route optimization [Park and Corson 2001]. In response to the need for a route to a speci c destination, the source will broadcast a query (QRY) packet containing the destination address as part of the route creation. The route query will propagate the network until the nal destination is reached or an intermediate node is reached which has a route to the destination. Once this node is found, it will respond with an update (UPD) packet which contains its height with respect to the destination. This height value is based on path length it has to the destination. For example, in the case the query (QRY) packet reaches the destination, it will respond with a "0" height to destination. As the UPD packet proceeds back through the network, each node that receives it sets its own height to a value greater than that of its neighbor who sent it the update packet. So, once the update packet reaches the initiator, there is a series of directed links from the node that sent the QRY packet to the node that sent the UPD packet. In route maintenance, when a node nds a route to a destination that is no longer valid, the node adjusts its height to be higher than its neighbors so that it may nd another route to the destination. When this height adjustment occurs, an update packet is broadcast to all neighbors notifying them of the change. If none of the neighbors possesses a route to the destination, TORA restarts the route creation procedure. In the 49 next aspect of this protocol, the route erasure procedure simply sets a node?s height to null and sets links to undirected as a result of network partitions. A clear (CLR) packet is used to broadcast route erasures which erase invalid routes from the network. Finally, the route optimization aspect of TORA is a proactive route discovery algorithm which uses optimization (OPT) packets to create shorter path length routes to speci c destinations. The OPT packet traverses the network in a similar fashion to the UPD packets, and updates the height of other nodes with respect to the speci c destination node [Park and Corson 2001]. TORA presents some interesting features which make it suitable for lossy envi- ronments, however it has some critical drawbacks. The protocol works on top of the Internet MANET encapsulation protocol (IMEP) which provides reliable, in-order delivery of routing messages from a node to some set of neighbor nodes [Corson and Park 1997]. IMEP attempts to reduce overhead by grouping sev- eral TORA and IMEP control messages (referred to as objects) together into a a single message (referred to as an object block) prior to transmission. Each of the blocks are identi ed with a unique sequence number and the blocks are transmitted on a periodic basis until a speci ed limit is reached or all necessary acknowledgments have been received. The idea behind this is to reduce the overall message volume by combining multiple messages into one, however it still faces the same problems with message collision and interference as other protocols. Another issue with TORA is that the height metric is dependent 50 on the logical time of the links failure. The algorithm makes the assumption that all nodes are time-synchronized with each other [Park and Corson 2001]. Unfortunately, this really is not possible without a central source of timing in- formation such as a network time server or a global positioning system (GPS). Hazy Sighted Link State (HSLS): The HSLS protocol [Santivanez and Ramanathan 2003, Santivanez, Ramanathan and Stavrakakis 2001] strives to blend the best features of proactive and reactive routing schemes to limit link state updates in time and space. HSLS reduces overhead by limiting the nodes the link state updates are transmitted to and by limiting the time between successive link status information updates. The basis for HSLS comes from the family of Fuzzy Sighted Link State (FSLS) pro- tocols where the frequency of link state updates propagated to distant nodes is reduced based on the concept that distant nodes do not have much immediate impact in the nearby hop-by-hop routing decision. Therefore, FSLS protocols often queue link state updates and transmit them at the same time on a periodic interval. HSLS is an optimized version of FSLS so that total overhead is glob- ally minimized. Furthermore, HSLS strikes a balance between refresh periods and distances so that the probability of making a suboptimal next hop decision is the same for every destination in the network. Simulations show a signif- icant reduction of routing packets transmitted while maintaining throughput and packet delay metrics [Koltsidas, Dimitriadis and Pavlidou 2004]. 51 Fisheye State Routing (FSR): The FSR protocol [Iwata, Chiang, Pei, Gerla and Chen 1999] aims to reduce congestion in large networks through the use of multilevel sheye scopes. In a similar way to HSLS, nodes using FSR exchange link-state entries with neigh- bors more frequently depending on the distance to a destination. It operates with the concept that nearby network changes are more important than distant network changes. Using the sheye idea, changes in nearby nodes are seen with higher resolution more frequently, while distant nodes are seen less frequently with lower resolution. Due to its reduction in network wide topology updates, this protocol has been proven a scalable solution in MANETs. However, it does still su er the problems with interference as other protocols and may not oper- ate optimally in the presence of high mobility nodes depending on the network size [Pei, Gerla and wei Chen 2000]. A similar protocol is the LANMAR pro- tocol [Pei, Gerla and Hong 2000] which combines FSR with landmark routing where a landmark is a set of nodes that move together as a group. This is very similar to the ZRP protocol [Haas, Pearlman and Samar 2002c] and will not be discussed further. 3.5 Interference Aware Routing Protocols In MANETs, packets transmitted by a node are often received by many nodes that are nearby. As a result of the vast amount of wireless transmissions, signal interference may occur. Currently, there is not a uni ed de nition for interference 52 since it depends on many factors such as the propagation loss model for the signal. Interference is basically the combination of signals received by the same node simul- taneously which prevents the receiver from decoding valid signals. Since valid signals are disrupted, interference results in packet collisions which triggers numerous redun- dant retransmissions of the same packets. The retransmissions consume energy and decrease throughput in the network. Many have studied interference within MANETs recently including [Krunz, Muqat- tash and Lee 2004], [Tan and Seah 2005], [Tang, Xue, Chandler and Zhang 2005], [Burkhart, Rickenbach, Wattenhofer and Zollinger 2004], and [Johansson and Carr- Motyckova 2005]. 1. [Krunz, Muqattash and Lee 2004] computes the potential interference of re- ceivers and adjusts node transmission power to reduce the probability of inter- fering with other nodes in the network. 2. [Tan and Seah 2005] proposes a scheme to adjust transmission range to avoid interference with non-neighbor nodes. The scheme relies on broadcasting \hello" packets to nd the minimum transmission distance to the neighbor nodes and then adjust the power of the transmitter accordingly. However, since it uses broadcasted \hello" packets, the overhead for this scheme is signi cant. 3. [Tang, Xue, Chandler and Zhang 2005] proposes methods to calculate link and path interference. Then, based on these values, the authors propose a single 53 path routing algorithm based on limiting interference through the use of direc- tional antennas. 4. [Burkhart, Rickenbach, Wattenhofer and Zollinger 2004] and [Johansson and Carr-Motyckova 2005] devise a way to minimize interference using topology control to reduce power while maintaining connectivity. The topology control methods de ne the interference as the coverage of a link e = (u;v) to be the cardinality of the set of nodes covered by the disks induced by the range of nodes u and v. Average Link Interference-Aware Routing (ALIR): In the ALIR protocol [Zhang, Liu, Shi, Liu and Yu 2007], the authors present explicit de nition for interference since there is not a uni ed de nition of in- terference. From this de nition, the authors derive formulas for computing node-interference (3.1), link-interference (3.2), and path-interference (3.3). I(u) = N1 + N2 + N3 (3.1) where I(u) is the interference of node u, N1 is the number of nodes in the dark shaded region of Figure 3.1, N2 is the number of nodes in the lighter shaded region of Figure 3.1, and N3 is the number of nodes in the yellow colored region of Figure 3.1. Also, and are less than 1 and represent the weights of N2 and N3 respectively. 54 Figure 3.1: ALIR?s Computation of Interference [Zhang et al. 2007] I(e) = I(u) +I(v)2 (3.2) where I(u) and I(v) represent the node interference of nodes u and v respec- tively. [Zhang, Liu, Shi, Liu and Yu 2007] de ne the path interference along a path as shown below. Since the path interference is dependent on the length of the path, the authors choose to de ne path-interference as the average link-interference of a path divided by the total number of links in the path. 55 I(P) = I(e1) +I(e2) + +I(en) Metric(P) = I(P)n (3.3) where Metric(P) is the path-interference and n is the total number of links in the path. The concept behind ALIR is to use DSR as a base protocol and then compute interference metrics for links. From these interference metrics, ALIR will route packets along the path with the least interference. This usually results in a path around a troubled network area at the cost of an increased path length. ALIR is shown to operate at higher throughput than DSR due to its reduction in packet collisions and retransmissions resulting from interference [Zhang, Liu, Shi, Liu and Yu 2007]. 3.6 Chapter Conclusion The contents of this chapter should provide the reader with signi cant back- ground on the various types of MANET routing protocols currently in use today. First, this chapter explored proactive protocols where nodes continuously maintain routes in the network by broadcasting control packets. In an alternative approach, this chapter presented several reactive protocols that attempt to reduce control packet broadcasts by discovering routes only when necessary. As a combination of these 56 approaches, several hybrid protocols are discussed which attempt to nd the best combination of proactive and reactive routing techniques. Lastly, this chapter pre- sented some work related to routing in the presence of interference, however none of the approaches covered resemble the approach taken in this dissertation. 57 Chapter 4 Mobile Ad Hoc Network Address Auto-Configuration 4.1 Chapter Introduction Most MANET research is focused on the development of e cient routing proto- cols. Most neglect the issue of addressing and assume that all nodes have a unique address in the network. This assumption works ne in the rare case that nodes are pre-con gured prior to deployment and no other nodes join the network after de- ployment. The tasks of dynamically and automatically assigning unique addresses to every node in the MANET remains an open research problem [Weniger and Zitter- bart 2004, Jeong, Oh, Kim, Park, Kim and Toh 2007]. There have been numerous attempts to solve this problem, and they are categorized below into IP-address and non-IP address assignment. 4.2 IP-Based Approaches The main bene t to assigning unique IP addresses to nodes in a MANET comes from the ability to connect to a gateway node which has a connection to the Internet. However, most MANETs that operate in remote regions or in disaster scenarios do not require this capability. The following is an enumeration of several common approaches to this problem: 58 1. Automatic Con guration of IPv6 Addresses for Nodes in a MANET with Mul- tiple Gateways [Ru no and Stupar 2006] proposes a stateless method to auto- matically con gure IPv6 addresses for MANET nodes in the presence of multiple gateways that are connected to the Internet backbone. It provides a mechanism for optimal address pre x-selection to improve routing. Similar approaches us- ing Internet gateways are found in [Cha, Park and Kim 2003, Jelger, Noel and Frey 2004, Templin, Russert and Chakeres 2006, Lee, Yoo, Kang, Kim and Kang 2006, Hofmann 2006]. 2. IP address Autocon guration for Ad Hoc Networks [Fazio, Villari and Pulia to 2006] uses random address selection to pick an IPv4 or IPv6 address. Then, it uses an address request-reply protocol to verify uniqueness of the selected address. A similar approach is taken in [Ros and Ruiz 2006]. 3. IPv6 Autocon guration in Large Scale Mobile Ad-Hoc Networks [Weniger and Zitterbart 2002] automatically assigns IPv6 addresses in MANETs using an al- gorithm that elects \leader nodes" to assign addresses to a set of hosts. This approach allows most nodes to receive addresses in a way similar to DHCP. Duplicate address detection is still necessary using this protocol though. Sim- ilar approaches are taken by [Fazio, Palazzi, Das and Gerla 2006, Nesargi and Prakash 2002, Zhou, Ni and Mutka 2003]. 59 4. Ad Hoc IP Address Autocon guration [Jeong, Park, Kim, Jeong and Kim 2006] assigns IPv4 addresses automatically by combining the IP address with a gener- ated key to guarantee uniqueness in a form of weak duplicate address detection (DAD) to be discussed later. 5. IP Address Assignment in a Mobile Ad Hoc Network [Mohsin and Prakash 2002] makes every node a DHCP server that is capable of assigning addresses, then nodes exchange address lists to keep the network synchronized. A similar approach is taken in [Kim, Kim, Yu, Song and Mah 2007] and [Tayal and Patnaik 2004] where each node is given a unique set of addresses which they can assign to other nodes. 6. Address Autocon guration in Optimized Link State Routing Protocol [Adjih, Boudjit, Jacquet, Laouiti and Muhlethaler 2005] relies upon control messages to make sure self-assigned addresses do not con ict with other nodes on the network. This approach requires that nodes exchange their addresses for com- parison. A similar approach is taken in [Sun and Belding-Royer 2003, Clausen and Baccelli 2005, Mase and Adjih 2006]. 7. Global Connectivity for IPv6 Mobile Ad Hoc Networks [Wang, Li, Hwang and Chen 2005] uses the local address of the node as the 64-bit interface ID in IPv6. 8. Passive Autocon guration for Mobile Ad Hoc Networks (PACMAN) [Weniger 2005] assigns each node a compressed version of an IP address so the address 60 size is smaller than a full IPv4 or IPv6 address. The address space grows with the number of nodes in the network. 4.3 Non-IP-Based Approaches The focus of this research is on MANET communication in a jam-resistant man- ner to compensate for noisy environments such as disaster zones or battle elds; there- fore, the need to connect to external gateways is not necessarily a priority. Further- more, since jam-resistant message encoding adds overhead to the communication, the use of full length IP addresses adds signi cant unnecessary overhead. For example, IPv4 uses 32-bit addresses which provides 4,294,967,296 unique addresses while IPv6 uses 128-bit addresses which provides 2128 unique addresses. It is di cult to imagine the need for a MANET to address this many nodes at one time. Consequently, the preferred solution for MANETs that will be used in this dissertation is to use a non-IP based addressing scheme to improve e ciency and eliminate overhead. As presented in [Boleng 2002], e cient network layer addressing is possible with non-IP addressing since the wasted address space is reduced to a minimal level. If connections to gate- way nodes are necessary to allow communication with the broader Internet at some later time, then a protocol such as Network Address Translation (NAT) can be used at the gateway. 61 4.4 Duplicate Address Detection Duplicate address detection is a necessary service when auto-con guration pro- tocols may result in address collision. Consider the birthday paradox as an analogy to represent when two networks merge. If these two networks use the same auto- addressing scheme, there is a high probability that two nodes will have the same address and thus create an address collision. For this reason, auto-addressing proto- cols usually include duplicate address detection as shown in [Jeong, Oh, Kim, Park, Kim and Toh 2007], [Vaidya 2002], [Weniger and Mase 2006] and [Weniger 2003]. These protocols usually add overhead to the network since duplicate addresses must be resolved in some way. In other words, when there is an address con ict, one node must give up its address and acquire a new one. For this reason, it is better to reduce the number of statistically probable address collisions during the initial address gen- eration phase of the auto-con guration protocol. The network layer described in this research will provide an e cient network layer auto-addressing scheme which reduces address collisions to a statistically negligible chance. 4.5 Chapter Conclusion This chapter focused on techniques for providing nodes in a MANET with unique network-layer logical addresses. In self-organizing networks, the capability to deploy 62 nodes to a region without pre-con guring the addresses is quite powerful. Further- more, dynamic addressing schemes support MANET merges on-the- y since unique addresses can be negotiated post deployment. 63 Chapter 5 Adaptive Jam-Resistant Cross-Layer Protocol Initial Design 5.1 Chapter Introduction The jam-resistant cross-layer protocol uses a combination of several disciplines to achieve its goal of providing adaptive jam-resistant communications in noisy envi- ronments where other protocols simply fail. These disciplines include wireless com- munications, coding theory for signal encoding (BBC concurrent codes), MANET network layer routing, and nally MANET network layer addressing. This protocol is considered to be cross-layer since it involves signal encoding which is a data-link layer function. By managing the jam-resistance parameters at the network layer, the network is more e ective as a whole. In this research, a new data-link layer is created to provide the necessary feedback to the network layer. 5.2 Network Layer Routing The initial protocol design calls for a hybrid protocol which combines proactive and reactive routing techniques. In this initial design, the protocol handles routing proactively. As an optimization, the protocol combines multiple control messages into a single message which is encoded using concurrent codes as described in BBC [Baird, Bahn and Collins 2007]. For example, when a routing table needs to be exchanged, these entries are encoded into a single message for transmission simultaneously and 64 the receiving nodes will decode a single message to receive the entire routing table. The reactive portion of the protocol adapts message encoding throughout the net- work to increase and decrease the level of jam-resistance that nodes are using. This requires broadcasting to notify nodes of the change, but ooding does not result in as many packet collisions as traditional protocols generate since the decoder is able to decode messages that have been corrupted. The reactive nature of this protocol im- proves throughput in the absence of jamming by reducing the level of jam resistance, but decreases throughput for the sake of availability in the presence of jamming by increasing the level of jam resistance. In addition to the routing characteristics, the protocol allows the following net- work operations: 1. Network Initiate: Sets up the network initially after node deployment and starts address auto-con guration. 2. Network Combine: Allow two compatible MANETs to combine if so desired by a member of one of the networks. This does not automatically occur in case two MANETs want to move past each other and switch operating areas. At a smaller scale, the protocol will allow the following node-level operations: 1. Node Join: Allows a compatible node to join an existing MANET. This join procedure may occur as a result of a node coming back into range after link failure. When a node joins, it has to generate an address that is not already in use. 65 2. Node Separate: Allows nodes to separate from the MANET. This occurs au- tomatically due to link failure. If a node is out of contact for more than an acceptable time threshold, it is removed from the viable node list in the routing table. When it rejoins the network, the node join operation begins. 5.3 Network Layer Addressing The basic concept of variable length addressing comes from [Boleng 2002]. In variable length addressing, there is a balancing act between the minimum address length and the need to recon gure all nodes in the network when the address space runs out. For this reason, it is important to choose a large enough minimum address length during network initialization in order to prevent unnecessary transmissions as the network grows. Another important aspect of variable addressing is the scale of address space increase when the network does grow. For example, if the network starts with 16 nodes, technically only 4 bits are required for the addresses. However, when a 17th node wants to join the network, the addressing protocol must determine by how much to increase the address space. A logical approach is to use multiples of two, so all nodes would then increase their address size to 8 bits. This protocol also auto-con gures addresses in the network. The auto-con guration protocol allows a node to generate an address for itself where the chances of address collision are statistically negligible. This approach involves the use of a random num- ber generator to generate the unique addresses. 66 5.4 Dynamic Jam-Resistance Dynamic jam-resistance is a crucial aspect of this protocol. Adapting the BBC algorithm [Baird, Bahn and Collins 2007] to handle levels of jam-resistance is required by this feature. Altering the length of the packet will allow the protocol to adjust the degree of jam-resistance. For example, extending the packet length should increase the degree of jam-resistance. Conversely, decreasing the packet length should decrease the degree of jam-resistance and allow for more e cient messaging to take place. This feature requires modi cations to the BBC encoding and decoding algorithms discussed in Chapter 2, Section 2.3. 5.5 Chapter Conclusion The Adaptive Jam-Resistant Cross-Layer MANET protocol is designed to lever- age knowledge from the wireless communications, coding theory, and computer net- working areas of study. It is meant to solve many of the problems that plague MANETs today to including friendly interference caused by the hidden station and exposed station problems. Furthermore, it is built to resist intentional jamming and adapt to several levels of spectrum interference. Jam-resistance comes at a cost in throughput and latency, but using a simpli ed routing algorithm and an e cient vari- able addressing scheme should compensate. The next chapter details the nal design and implementation of this communications protocol. The nal protocol provides network availability in noisy environments where other protocols simply fail. 67 Chapter 6 Protocol Design and Implementation Phase 6.1 Chapter Introduction During the protocol design and implementation phase, the various system com- ponents are assembled into a working prototype that is used for testing the research ideas described in this dissertation. There are many interconnected pieces to the over- all system and it is important to understand how they will interact in the prototype to fully understand the complexity of this system. With a mix of hardware and soft- ware components, the problem space is multiplied as hardware limitations may arise and software bugs may a ect hardware outputs. In this phase, a divide-and-conquer approach is taken to this rather large and complex communications system. In this approach, the overall system is divided into smaller problems that can be implemented and tested independently. Once the component is fully tested and veri ably correct, the component will be integrated into the overall system. At the beginning of this research, only a basic physical layer implementation existed for the BBC algorithm [Baird, Bahn and Collins 2007]. The implementation simply took some text, encoded it with BBC, and broadcasted it continuously using a software radio. Another software radio would run the receiver script on the software radio and decode the message that was transmitted. This physical layer implemen- tation was an initial prototype built by the creators of the BBC algorithm. This 68 provided a good foundation for this research, but the lack of higher-level layers in the form of a protocol stack precludes its use for a unicast communications system. Therefore, to build a MANET communications system based on the BBC algorithm required the implementation of physical, data-link and network layers, as well as a suitable application layer for testing purposes. From an implementation standpoint, the implementation of multiple layers pro- vides a signi cant challenge since the entire protocol stack from the physical to the application layer must be constructed. The focus of this research is on network layer routing in the presence of interference, but in order to build a working prototype that operates on real radios instead of a simulator, the implementation of the other layers proved absolutely necessary. The purpose of this chapter is to familiarize the reader with the design and implementation phases of this research in addition to demonstrating the level of e ort involved in building this system. The remaining sections will discuss the system components, the implementation of the three lower layers, and provide a discussion of the software architecture of this prototype with applicable diagrams. 6.2 System Components The prototype system developed during the course of this research is composed of both hardware and software components. In the following section, the speci c hard- ware and software components that come together in this prototype will be discussed in detail. An important relationship to realize is that the chosen hardware does a ect 69 the design of the software since the software drives the software de ned radios (SDRs) in this prototype. The speci c details concerning the interaction between the software and hardware components will be discussed in the software architecture section. 6.2.1 Hardware Components Computer: By far the most important hardware component in this system is the computer which drives the Universal Software Radio Peripheral (USRP) software radio device. In this case, the computer used is an Apple Macbook Pro with the relevant speci cations of an Intel Core 2 Duo 2.5GHz processor, 4GB of RAM, and two USB 2.0 ports. The USB ports are critical to this prototype since any communication with the software radios takes place over the USB ports. The speed of the USB ports also a ects the signal throughput on the USRP which will be discussed in detail later. The actual computer is not necessarily important to this system, except that it must be able to run the required software and operate at USB 2.0 speeds over the bus. The speci c requirements for the software will be discussed in the next section, but this prototype is a cross-platform solution so any operating system on the driver computer should work without substantial modi cations. Universal Software Radio Peripheral (USRP): The USRP represents the core of the software radio platform. This hardware device is closely coupled with the GNU Radio software framework which allows the hardware to be manipulated by software. GNU Radio communicates with 70 the USRP via a USB 2.0 interface with speeds approaching 32 Mb/s. The USB 2.0 speci cation allows for speeds up to 480Mb/s, but this is not currently possible with the FPGA. The radio signal processing is handled on the USRP while the commands to the hardware pass through the USB. In order to fully understand some aspects of this research, it is important to understand some details of the USRP circuitry. The USRP board is controlled by an Altera Cyclone Field Programmable Gate Array (FPGA) which has a customizable rmware written in the Verilog programming language. The USRP also has four 64 Mega-Sample (MS)/s 12-bit analog to digital converters (ADC) for receiving and four 128MS/s 14-bit digital to analog converters (DAC) for transmitting. The FPGA drives these converters that are provided by the AD9862 chip. The AD9862 chip is a mixed signal processor with dual receive and dual transmit channels. The AD9862 also contains the decimation and interpolation lters for the receive and transmit chains respectively. Furthermore, the AD9862 allows the USRP to process real or complex IQ signals. Additional details on the terms mentioned above, including decimation and interpolation, will be discussed in the upcoming section on the physical layer implementation to this system. RFX-1200 Daughterboard: The USRP supports a variety of daughterboards for many common spectrums of interest. For this research, the RFX-1200 is being used which supports any fre- quency between 1150-1450MHz with a transmit power of 200mW (or 23dBm). 71 Figure 6.1: Universal Software Radio Peripheral External View with Casing This is a common frequency band for navigation and satellites, but it is useful for the purposes of this research because it is less crowded than the 2.4GHz band that is used by 802.11b/g Wi-Fi devices. The RFX-1200 has many useful fea- tures including a connector that is used for both transmitting and receiving, so an antenna can be shared for the two operations. With a 20MHz transmit and receive bandwidth, the board can support fairly wide signals. The daughter- board is full-duplex capable with some limitations that preclude its use in this research. The main limitation to full duplex operations are that the TX and RX side of the board have to be on separate frequencies. The board also contains an analog Received Signal Strength Indicator (RSSI) measurement via an aux- iliary analog to digital converter (ADC) chip. Furthermore, this daughterboard 72 Figure 6.2: Universal Software Radio Peripheral Internal View allows for adjustable transmit power and has a 70 dB automatic gain control (AGC) range. Another quite useful feature of this board are the independent local oscillator (LOs) for TX and RX which allows the board to transmit on one frequency and receive on another. The RFX-1200 is shown below in 6.4. Omnidirectional Antenna: The antenna for this system is a 7-inch vertical tri-band antenna that operates at 144MHz, 400 MHz, and 1200 MHz. The purpose of the antenna is to extend the range of the receiver or transmitter. The current setup requires an antenna 73 Figure 6.3: Universal Software Radio Peripheral Block Diagram attached to each daughterboard within a USRP, so that is two antennas per USRP. A picture of the antenna in use is shown below in Figure 6.5. 6.2.2 Software Components GNU Radio Platform: The GNU Radio platform is a free software development toolkit that provides the signal processing runtime and processing blocks to implement software ra- dios using the USRP as the RF hardware. The libraries are used in hobbyist, academic and commercial environments to support wireless communications 74 Figure 6.4: RFX-1200 Transceiver Daughterboard research and implement prototype real-world radio systems. The research con- tained in this dissertation leverages the GNU Radio Platform for all transmis- sion and receiving of RF signals. Operations with the USRP are conducted through the GNU Radio Application Programming Interface (API). The GNU Radio client applications are mostly written in Python, while the signal pro- cessing blocks are written in C++. At the time of this writing, a C++ API 75 Figure 6.5: VERT400 Vertical Omnidirectional 7-inch Antenna for client applications was available but existed only in the Beta stage of de- velopment. Using this platform, a developer is able manipulate RF signals and perform complex digital signal processing operations quickly and e ectively. USRP API and Libraries: As a part of the GNU Radio Platform, there is a compilation of libraries for operations involving the USRP device. The opera- tions are speci c to the USRP and control sub-devices such as daughterboards attached to the USRP. There is even a library extension that allows some ac- cess to the FPGA controls and registers. This becomes useful as more advanced signal processing techniques are employed and more control over the hardware is necessary. wxPython GUI Library: wxPython is a graphical user interface (GUI) toolkit for the Python program- ming language [Dunn 2009]. It is a Python extension of the wxWidgets cross- platform GUI library which is written in C++. Since Python is a wrapper 76 around the C++ libraries, it implements the same features as the wxWidgets libraries. This project is open source and is used by GNU Radio developers and other Python developers that wish to create rich GUIs for their applications. In the case of this research, the wxPython library is used to build a GUI for observing communication among USRPs and to control the parameters of the communication. As a cross-platform library, any GUI created with wxPython is well-suited to operate on any operating system that may be used to host a USRP. USB Interface Library: The USB library used by GNU Radio to access the USRP is the libusb library [Erdfelt 2008]. This library allows a user level application to search for and access connected USB devices from any operating system. The project is open source and customizable to the developer?s needs. In this case, the distributed library is used without any modi cations since it suites the needs of the radio platform. The main limitation with this library concerning the USRP devices is that once a USB port is claimed by a host process (such as a Python client application using GNU Radio) for reading or writing, the port cannot be opened again for that operation without the original process releasing the USB port. For example, if daughterboard A is conducting a transmission inside a USRP, and then daughterboard B wants to start transmitting as well, this operation will result in an error that the USB device cannot be claimed. The correct 77 way to do this is to stop all processes on the device and restart a process with instructions for both daughterboards in the same process. The details of this involve modifying some of the signal processing on the signals, but this will be discussed in detail in the physical layer implementation section. Noise Signal Generator via GNU Radio: To test the protocol?s tolerance for noise in the spectrum, a jammer that adds noise to the spectrum is required. Rather than purchasing additional hardware, a separate USRP and RFX-1200 daughterboard acted as a signal jammer. The jammer script written in Python using the GNU Radio framework instructs the RFX-1200 to transmit either a uniform random or Gaussian random distribution of signals according to command line parameters. When in Gaussian mode, the signal is a random normally distributed Raleigh distribution with a mean about zero and a variance of one. It also takes an amplitude parameter to adjust the signal?s amplitude and hence the strength of the jammer. Of course, the jammer operates on any speci ed frequency within the capabilities of the daughterboard. The jammer script is used to test the protocol?s resistance to jamming. The source code for the jammer script is contained in the source code listing at the end of this document. USRP Command and Control Application: As mentioned above, the USRP must be driven by a computer that runs the GNU Radio platform. With two USRPs and one laptop, it becomes challenging 78 to transmit signals between two USRPs. Furthermore, it is useful to be able to get feedback from the devices when there is a successful transmission or re- ception of data. Otherwise, it is quite cumbersome to do testing and evaluate di erent parameters of the experiments. For this reason, a command and con- trol application with a GUI was written that allows the operator of the host computer to send signals to two separate USRPs on two di erent USB ports. In addition, the application allows the operator to control individual daughter- boards and receive textual feedback from the devices. The application is written in Python and leverages all of the software packages mentioned above including wxPython for the GUI, GNU Radio for the signaling, libusb for the commu- nication with the devices, and the USRP libraries for giving instructions to the USRP. The application has several bene cial features that are enumerated below. 1. Allows an operator to control two USRPs and four daughterboards from a single computer. 2. Provides feedback on the success of data received or transmitted. 3. The operator may choose any data le or packet to send. Essentially, this application provides an application layer to the protocol stack. 4. Parameters for each daughterboard?s transmit or receive activity may be changed separately and on-the- y. 79 5. Allows access to the current internal transmit and receive packet queues in real-time for each daughterboard. Note that the packet queues are an aspect of the layer 2 implementation that will be discussed soon. 6. Keeps a historical record of transmitted or received messages for o ine analysis and allows access to these queues in real-time. 7. Display meaningful feedback to the operator for informational or debugging purposes. 8. The display updates in real-time as the system changes parameters. For instance, if a radio switches from transmit to receive mode in preparation for receiving an acknowledgement, then the parameter eld will update in the GUI for the operator to see. The custom command and control application took a signi cant amount of time to develop, but it provides a useful application layer to the communications pro- tocol developed in this research. The application also reduces testing overhead as it allows an operator to control twice as many USRPs as before. The appli- cation could easily be extended to support more USRPs if a computer had more than two USB ports, but this is not a priority at this point since geographically separating radios is useful for testing. Figures 6.6 and 6.7 show screenshots of the application used to control the radios from the computer. These two screen- shots do not necessarily demonstrate all of the features of this application, but 80 merely show a preview of the interface. More screenshots are contained in the appendix section of this document. Figure 6.6: USRP Command and Control GUI Screenshot 1 81 Figure 6.7: USRP Command and Control GUI Screenshot 2 82 Received Signal Strength Indicator (RSSI) Measurement Applica- tion: In wireless communication systems, a device?s RSSI is used to determine the amount of power present in the spectrum. Most often, this is used in carrier- sensing schemes that control access to the medium. For example, in 802.11, if the medium is sensed with a high RSSI value, that indicates that other stations are transmitting in the medium and the station performing the sensing must wait a random back-o period before attempting to transmit. In the protocol developed in the course of this research, the RSSI measurement is not used for carrier sensing. Rather, the measurement is used to determine the level of jamming or power in the spectrum at a given point in time. The presence of a jammer will undoubtedly increase the value of the signal strength indicator, while less jamming will be have the opposite e ect. As discussed in the section on the USRP and the RFX-1200, the daughterboard has an auxiliary (AUX) analog to digital converter (ADC) which is on its own chip that does not interfere with the rest of the transmit or receive chains. This chip can be used to measure the RSSI value and determine the power within +/- 15MHz of the carrier frequency. Speci cally, the AUX ADC reads the power in the analog baseband signals (power (I) + power (Q)). For an overview of complex IQ signal pairs, consult the discussion provided in Section 6.3. The RSSI measurement of the chip returns an integer value between 0 and 4095, inclusive. To change the bandwidth to something other than the +/- 83 15MHz requires moving some of the inductors and capacitors on the USRP, but in testing this RSSI value is accurate when correlated with the output of the signal jammer. As the level of jamming increases with the amplitude of the signal output from the signal jamming script, the RSSI measurement increases proportionally. In order to automate this reading, a Python script was developed with use of the GNU Radio platform to calculate the average reading of the RSSI value from the AUX ADC. The reading is conducted by the FPGA in an asynchronous manner, therefore the increase accuracy it is necessary to average the RSSI reading over several thousand readings. Currently, the script averages the RSSI value over two-thousand readings and returns the average. Runtime for this script is quite fast and it returns the average RSSI value in about a second. As with other scripts run from the host computer, the program accepts parameters for the USB identi cation number to identify the USRP and another parameter to identify the speci c daughterboard from which to take the reading. The source code for this script is contained in the source code listing. BBC Encoder: The BBC encoder software written in C performs the actual encoding of the data into complex IQ pairs for transmission via the USRP [Bahn 2007]. The data is encoded as binary data with a series of indelible marks that are repre- sented by one-bits, while the absence of data is represented by a zero-bit. The 84 original implementation shown in Algorithm 1 [Baird, Bahn and Collins 2007] does not adapt to varied levels of interference in the spectrum. However, the newer version shown in Algorithm 2 dynamically adjusts the codeword length in response to the RSSI measurement taken at the data link layer and a route dependent threshold determination performed by the network routing layer. The threshold and codeword length determination is covered in the upcoming section on the adaptive jam-resistant network routing layer implementation. Algorithm 1 BBCEncodeOriginal(M) This function encodes an m-bit message M[1...m] adding k checksum bits to the end of the message. H is a hash function. The de nition of H and the value of m and k are public (not secret). The de nition of "indelible mark" and "location" are speci c to the physical instantiation of BBC used. Append k zero bits to the end of M for i = 1 ... m+k do Make an indelible mark at the location given by H(M[1...i]) end for Algorithm 2 BBCEncodeDynamic(M, J) This function encodes an m-bit message M[1...m] adding k checksum bits to the end of the message. H is a hash function which is truncated according to the level of jam-resistance. By default, H returns a SHA-1 hash of 160-bits. Truncate this 160-bits according to the jam-resistance level. The de nition of H and the value of m and k are public (not secret). The de nition of "indelible mark" and "location" are speci c to the physical instantiation of BBC used. Append k zero bits to the end of M Jam resistance level is dictated by thresholding implemented at network layer and is a parameter J with a possible integer value [1..5] for i = 1 ... m+k do Htruncated = Horiginal truncated to length 32*J Make an indelible mark at the location given by Htruncated(M[1...i]) end for 85 BBC Decoder: As with the BBC encoder software, the BBC decoder is written in C in its current form [Bahn 2007]. This software was left in C for speed considerations with the bit-level manipulations. Decoding is especially taxing on the host computer because the source le that is created by the received signal from the USRP can be quite large. For example, if the receiver is in receiver mode for approximately 10 seconds, the received IQ pairs from the radio form a binary le that is about 300Mb large. In the presence of more noise, this receiver may have to receive for an extended period of time and the received signal le may exceed 1 GB. The original BBC decoder algorithm is shown in Algorithm 3 [Baird, Bahn and Collins 2007]. It does not adjust to the dynamic codeword length and simply proceeds through the decoding phase by translating the indelible marks back into the original le and using the checksum bits to eliminate hallucinations. The dynamic BBC decoder algorithm shown in Algorithm 4 decodes messages through a series of codeword lengths dictated by the parameter it is passed. An- other variant of this decoder may use a breadth- rst search algorithm to search for messages at the various codeword lengths that are used by the dynamic BBC encoder, however this has not yet been implemented. 86 Algorithm 3 BBCDecodeOriginal(n) This recursive function can be used to decode all the messages found in a given packet by calling BBCDecode(1). There must be a global M[1...m + k] which is a string of m + k bits. The number of bits in a message is m, and the number of checksum zeros appended to the message is k. The de nition of H and the value of m and k are public (not secret). The de nition of "indelible mark" and "location" are speci c to the physical instantiation of BBC used. if n = m+k + 1 then print ??"One of the messages is:" M[1:::m]?? else if n>m then limit(0 else limit(1 end if for i = 0 ... limit do M[n] (i if there is an indelible mark at location H(M[1:::n]) then BBCDecode(M,n+ 1) end if end for end if 87 Algorithm 4 BBCDecodeDynamic(n, J) This recursive function can be used to decode all the messages found in a given packet by calling BBCDecode(1). There must be a global M[1...m + k] which is a string of m + k bits. The number of bits in a message is m, and the number of checksum zeros appended to the message is k. The de nition of H and the value of m and k are public (not secret). H will be truncated to the value related to the jam resistance level parameter passed to the function. The de nition of "indelible mark" and "location" are speci c to the physical instantiation of BBC used. if n = m+k + 1 then print ??"One of the messages is:" M[1:::m]?? else if n>m then limit(0 else limit(1 end if for i = 0 ... limit do M[n] (i Htruncated = Horiginal truncated to length 32*J if there is an indelible mark at location Htruncated(M[1:::n]) then BBCDecode(M,n+ 1) end if end for end if 88 Optimized Link State Routing (OLSR) daemon: A major software component to this system is a modi ed OLSR layer that maintains route tables for nodes in the network [Clausen, Dearlove and Jacquet 2008], [Tonnesen 2009]. Some additional background information on the OLSR protocol is contained in Chapter 3, Section 3.2. The OLSRd open source project has many contributors, including myself, and maintains a highly active develop- ment community unlike other routing protocols. The algorithm is a proactive routing algorithm that uses topology control and \hello" message broadcasts to share information with other nodes in the mesh. OLSR?s \Hello" messages are used to nd one and two hop neighbors based on the responses from other nodes. Among these neighbors, the sender selects its multipoint relay (MPR). As a criteria to be selected as an MPR, the MPR must have a path to each of the sending node?s two-hop neighbors. The MPR node will then forward topology control (TC) messages containing the nodes that have selected the MPR as their relay. Unlike other link state protocols, not all inks of a node are advertised. In order to prevent problems due to signi cant message ood- ing, the nodes that have selected MPRs share their link state information. The format of the topology control and hello messages is shown below in Figure 6.8 and 6.9. The routing tables are kept current and reliable through the periodic broadcasts of the hello and topology control messages. In this research, the determination of the route is modi ed to choose the best route according to spectrum interference that may a ect link quality. Furthermore, the routing 89 layer determines what is the most e ective jam-resistant encoding scheme to ensure availability between the source and destination nodes. Figure 6.8: Topology Control Packet Format [Clausen, Dearlove and Jacquet 2008] Figure 6.9: Hello Packet Format [Clausen, Dearlove and Jacquet 2008] 6.3 Physical Layer Implementation The following section will discuss implementation details of the physical layer for this jam-resistant communication system. The detailed operation of the physical layer and implementation of speci c features at this layer will be discussed. Key portions of this section include a discuss of in-phase quadrature modulation used, the 90 decimation and interpolation factors, and the custom implementation for activating simultaneous receive or transmit chains on the same USRP. In this system, the data to be transmitted via the USRP is stored on a host computer. In some way, this data must be converted into a suitable format prior to transmission in the wireless medium. Radio frequency data is often stored as in- phase quadrature (IQ) data which can be represented in a le stored on the computer. IQ modulation is also known by many other names including complex or base-band modulation. An IQ signal is a mathematical representation of a real valued signal combined with a complex sinusoid, with the resulting complex data (i,q) being stored as a 32-bit signed integer with 16 bits for I and 16 bits for Q. Each IQ pair represents a sample of the complex signal. In this research project, the actual IQ modulation of the source data is handled in software by the BBC real-time engine. As mentioned in previous sections, the USRP contains DSP chips to handle reception or transmission of IQ pairs, as well as the critical operations of decimation and interpolation of these signals. To enhance understanding and readability, it is important to de ne some of the terms mentioned above. First, decimation is the process of reducing the sample rate. Decimation is usually accomplished through the use of a low-pass lter and tossing some of the samples out. A similar activity is known as down-sampling which reduces the sample rate by throwing away some samples without the use of a low-pass lter. When using decimation with the USRP, a decimation factor is provided on the command line. The decimation factor is the ratio of the input rate to the output rate. The most 91 common reason for using decimation or down-sampling is to reduce the cost of signal processing. The opposite process of decimation, interpolation is used in this case on the transmitter to increase the original sampling rate to a higher rate. During this process, zero-valued samples are inserted between the original samples to increase the sampling rate. This insertion process, sometimes called up-sampling, adds undesired spectral images to the signal in integer multiples of the original sampling rate. Interpolation is speci cally performing up-sampling on a signal and ltering the results to remove the undesired spectral images. At the end of this process, the result is a signal that appears as if it had been sampled at a higher rate than it was originally sampled. When using interpolation with the USRP, an interpolation factor is provided on the command line of the transmitter. The most common reason to interpolate a signal is to increase the sampling rate at the output of one system so that another system operating at a higher sampling rate can input the signal, but also provides some cost savings on signal processing. Figure 6.10 provides a visual example of interpolation in practice. The relationship between decimation and interpolation is dictated by the Nyquist Sampling Theorem. The theorem states that for a band-limited signal with maximum frequency, fmax, the sampling frequency fs must be greater than twice the maximum frequency fmax in order to have the signal reconstructed without aliasing. Another name for aliasing is under sampling. Under sampling causes frequency components that are higher than half of the sampling frequency to overlap with lower frequency 92 Figure 6.10: Interpolation Example [IEEE 1979, MathWorks 2009] components causing distortion of the reconstructed signal. Figure 6.11 provides a visual example of under sampling and illustrates how the reconstructed signal does not match the original signal when the Nyquist Theorem is not followed. When it comes to transmission between USRPs, a decimation factor of 64 is used on the receiver while an interpolation factor of 128 is used on the transmitter to allow the receiver to receive a complete signal while saving on signal processing costs. As is required by the Nyquist Sampling Theorem, if we want N samples per second on the receiver, we need to choose a decimation rate such that the decimated frequency is greater than or equal to N/2. Therefore, a decimation rate of 64 on the receiver should allow us to sample 1M samples per second when the original sampling frequency set by an interpolation rate of 128 by the transmitter produces also 1M samples per second which works well. The higher sampling rate is not absolutely necessary, but increased sampling rates reduce the signal-to-noise-ratio (SNR) in analog to digital conversion operations. With a current USB maximum bus speed of 32MB/s, and each complex IQ sample taking 4 bytes, it is important to make sure the sampling rates 93 do not exceed the capacity of the bus. Of course, all receive and transmit channels share the same USB when communicating with the computer. Figure 6.11: Under Sampling Example [EFunda 2009] The current setup for the USRP in this research involves placing two RFX-1200 daughterboards on a single USRP unit. As one would expect from a communications system, it became necessary for both daughterboards inside the USRP to be in a transmit state or receive state simultaneously. The case where board A is in a TX state and board B is a RX state works by default, however the case of simultaneous and identical states required special signal processing to take place. In order for both daughterboards inside a USRP to transmit or receive at the same time, multiple channels must be used on the USRP. The board supports up to four real-valued signal channels and up to two complex-IQ signal channels. 94 In the transmit case, two channels are setup on the USRP board. Each channel is assigned a source for the transmission. In the case of this protocol, the source is a le that contains the IQ modulated signal ready for transmission. To transmit from both channels simultaneously, the signals are interleaved. The AD9862 signal processing chip contains hardware to do the interleaving on the USRP rather than the host computer which saves signi cant processing costs. At transmission time, if two IQ signals are interleaved, the data will appear as the following: I0 Q0 I1 Q1 I0 Q0 I1 Q1 and so on. The essence of this process in software is shown in the code excerpt below. The full source code for this operation is located in the source code listing. Listing 6.1: Signal Interleaving for Simultaneous Transmissions #establish transmit source for the two channels self . txfileA = gr . file source (gr . sizeof gr complex , sink path , 1) self . txfileB = gr . file source (gr . sizeof gr complex , sink path B , 1) #establish the USRP object with appropriate USB port self . usrp = usrp . sink c (which=usb num , interp rate=self . interp , nchan=nchan) #setup interleaver intl = gr . interleave (gr . sizeof gr complex ) #connect components self . connect( self . txfileA , ( intl , 0)) self . connect( self . txfileB , ( intl , 1)) self . connect( intl , self . usrp) On the receive side, the receiver must deinterleave the signals and process them separately. A similar process takes place but it must occur in reverse. In order for both receivers to receive simultaneously, multiple channels are setup. Multiple channel sinks are setup as well so that each channel stores its received IQ signals in a separate location. Then, as the receiving operation starts, the signals are deinterleaved and 95 separated into di erent le sinks containing separate IQ data pairs. Continuing with the example described above, an interleaved signal will be of the form I0 Q0 I1 Q1 I0 Q0 I1 Q1. Then, the received signal after being deinterleaved will be I0 Q0 I0 Q0 for the rst channel and I1 Q1 I1 Q1 for the second channel. The essence of this process in software is shown in the code excerpt below. The full source code for this operation is located in the source code listing. Listing 6.2: Signal Interleaving for Simultaneous Receptions #establish separate file sinks for the two channels self . dst A = gr . file sink (gr . sizeof gr complex , filename A) self . dst B = gr . file sink (gr . sizeof gr complex , filename B ) #establish the USRP object with appropriate USB port self .u = usrp . source c (which=options .usb num , decim rate=options . decim) #setup deinterleaver di = gr . deinterleave (gr . sizeof gr complex ) #connect components self . connect( self .u, di ) self . connect (( di ,0) , self . dst A) self . connect (( di ,1) , self . dst B) As discussed above, the source data is put in complex IQ pair form prior to transmission in the physical medium. As a series of binary data comprised of 0?s and 1?s, the signal modulation scheme currently in use is a simple pulse-based system. A zero-bit is transmitted as a at zero-gain pulse and a one-bit is transmitted as a high-pulse according the the gain. More complicated schemes are available, but the current scheme is working as desired. More sophisticated schemes of interest include direct sequence spread spectrum (DSSS), but this was not implemented in this version of the physical layer because it requires some synchronization between the waveforms which is not well supported with the current USRP setup. Speci cally, the clock 96 pulse is shared between both daughterboards in the USRP and synchronization is accomplished through a physical wire between the two boards or between USRPs connected to an external clock. A better solution to the waveform synchronization problem is necessary to accommodate synchronization among multiple USRPs that contain multiple daughterboards driven by multiple host machines. 6.4 Data Link Layer Implementation In order to test the adaptive network layer, a simple data-link layer proved to be a necessary component. For this reason, a data-link layer was implemented with the goal in mind to be as simple as possible in order to reduce packet processing overhead. This goal led to the investigation of using the simple Aloha protocol for the data-link layer, and perhaps even the slotted aloha protocol. A contention based protocol that uses carrier sensing to determine whether to transmit or not would likely not operate well in the presence of jamming since the medium would always be sensed as busy. Therefore, a scheme similar to what 802.11 networks use with request-to-send (RTS) and clear-to-send (CTS) broadcasts seemed inappropriate for the likely use case of this jam-resistant communications protocol stack. With these principles in mind, a simple Aloha medium access control (MAC) protocol was implemented in Python to leverage the GNU Radio framework and the GUI interfaces via wxPython. The Aloha protocol is quite simple to understand in comparison to some other modern schemes. Devised in the 1970s to enable wireless communications between the Hawaiian Islands, the Aloha protocol dictates that a network node will transmit 97 whenever it has a packet to send. If the packet successfully reaches the destination, the next packet can be sent. Otherwise, the packet is retransmitted since a collision occurred as other nodes attempted to transmit at the same time. Successful reception of a packet is determined by the successful reception of an acknowledgement from the receiver that the packet has indeed arrived. This form of Aloha, coined "Pure Aloha", has a maximum theoretical throughput of 18%. Given the dismal throughput of the original Aloha protocol, a variant of this con- cept improved this protocol by using time slots to assign discrete transmission times to nodes. The improved protocol, known as \Slotted Aloha", dictated that transmis- sions must occur within a speci c slot which is equal to the amount of time necessary for a xed length packet to be transmitted. Therefore, when a packet is ready to be sent by a node, the node must wait until the start of the next time slot. In this scheme, packets overlap completely or not at all. Slotted Aloha improves upon Pure Aloha by 100% with a theoretical throughput of 36%. The Slotted Aloha approach did not seem necessary to implement at this point in time since synchronization among USRPs is limited in some aspects by the hardware device. The typical analysis of the Aloha family of protocols is particularly critical of the performance since the throughputs of the two approaches are extremely low compared to the bandwidth of the channel. For this reason, carrier sensing schemes are created which use the request-to-send (RTS) and clear-to-send (CTS) messages to make sure the channel is clear prior to transmission. Retransmissions are still frequent under the RTS/CTS style since nodes out of the range of these beacon packets are unaware 98 that other nodes are transmitting as well. The hidden station and exposed station problems are rooted in this critical aw in the RTS/CTS style of contention resolution. In the communications protocol developed in this research, resistance to jam- ming is a critical component. As a part of this resistance to jamming, there is an added capability supplied by the BBC algorithm which allows a receiver to decode several messages at the same time from the same received signal. Given this capa- bility, collisions are not as much of a problem since messages will still be decoded in signi cant levels of noise caused by the collisions with other nodes. Pure Aloha has poor throughput since it relies on transmitting one message at a time and waiting on an acknowledgement for each message. Instead of this approach, the jam-resistant network stack simply combines all of the messages in the queue into a single message for transmission all at once. Furthermore, with jam-resistance built into the signal encoding, the likelihood that a message has to be retransmitted due to corruption from a collision is reduced signi cantly. All of these factors combine to increase the throughput of the Pure Aloha MAC protocol used with the USRPs. As USRPs receive messages, they decode them and analyze their contents. If the message is original and addressed to them, the message is accepted and added to the receive queue. Af- ter it is added to the receive queue, the node sends a unicast acknowledgement to the appropriate node. If a node receives an acknowledgement packet for a message it transmitted, that previously transmitted message is moved to a historical record keeping queue. However, if no acknowledgement is received within a predetermined amount of time, the message will be retransmitted. This process continues until there 99 are no more messages in any node?s transmit queue. The main limitation of using this type of Aloha protocol on USRPs is that a daughterboard cannot transmit and receive at the same time. Therefore, if a daughterboard A on USRP 0 is transmitting a message to daughterboard A on USRP 1, no reception will occur while these two operations overlap since none of the nodes are in a receiving mode. This state is unlikely given the Aloha protocol since the default state for the nodes is the receive mode and both nodes would have to be synchronized almost exactly since transmis- sion does not take longer than a few seconds even for large messages. In either case, experiments have proven that reliable transmission is possible between four daughter- boards operating on the same frequency and all exchanging multiple messages among each other. Throughput of this MAC protocol is di cult to measure since there is a sig- ni cant amount of time spent on message processing once a message is received. Experiments have shown that it takes between 4 and 12 seconds to run the decode algorithm on a 4KB packet since the received signal is approximately 300Mb if the receiver operates for 10 seconds. Packet analysis is conducted in negligible time and encoding takes between 0.5 and 5 seconds depending on the packet size of course. The upper limit of the throughput is dictated by the speed of the USB which is shared among the USRPs connected to the driving computer. In any case, the main goal of this jam-resistance protocol is not to increase the speed of wireless communications, but rather to guarantee delivery of messages in the presence of noise where other pro- tocols fail. The data link layer protocol based on Pure Aloha that was implemented 100 and tested in this research has shown that guaranteed delivery of messages is possible with signi cant levels of noise. The details of this experimentation will be discussed in future sections. An additional feature added to the data link layer is logical addressing. A simple logical addressing scheme using random addresses is used to assign unique addresses to every node from the control application. The random addresses are generated using standard library random number generator functions. Even considerably large sets of these pseudorandom numbers did not present any duplicate addresses. The system time is used as a seed to the generator and sets of up to twenty thousand did not present any duplicates. It is highly unlikely that a network will contain this many nodes, but it is good to push the addressing scheme to unforeseen limits. The layer automatically handles addressing collisions if one does occur. The address is integrated into the packet header prior to the BBC encoding process. The header currently has several elds which are listed below that are assigned by the light-weight MAC layer. checksum of 4 Bytes (32 Bits) sequence number of 2 Bytes (16 Bits) packet id number of 2 Bytes (16 Bits) to address of 2 Bytes (16 Bits) from address of 2 Bytes (16 Bits) 101 RSSI measurement of 2 Bytes (16 Bits) The USRP has a media access control (MAC) hardware address, but this is not guaranteed to be unique in a larger network. Therefore, it is not being used for addressing at any layer. For the sake of simplicity in the addressing scheme, the logical addressing performed at the network layer is translated down to the data-link layer directly. Essentially, there is only one addressing scheme for a daughterboard which can transmit and receive in the network. If there is an address collision, the node?s address will match the \to address" eld of a received packet and this triggers the node to assign itself another address at random. Currently, this is the only form of duplicate address detection (DAD), but more sophisticated schemes could be employed in the future as the network grows. However, having collisions of random 16-bit addresses is rather unlikely even in networks with hundreds of nodes. Furthermore, there does not seem to be a need for additional addressing at the hardware level such as that used in typical data-link layer frames. By reducing the addressing overhead and reducing the size of the address by 50% (IPv4 has 32-bit addresses), the jam-resistant protocol compensates for some of the overhead imposed by the BBC encoding scheme. In summary, the light-weight data link layer created in this research is meant to add the additional functionality to the pure physical layer wireless communications. This data link layer disassembles data to be transmitted into packets of 512 bytes (equal to the size of a USB frame), and adds a header with elds designed to build reliable messaging into an unreliable wireless transmission medium. With a Pure Aloha design, simple logical addressing, and an acknowledgement framework, this 102 layer has proven through experimentation that reliable messaging is possible in the presence of signi cant spectrum interference. These experimental results are covered in the Phase I Results chapter. In addition to the physical and data link layers discussed thus far, an additional network layer that makes global routing decisions based on spectrum interference is built on top of these two layers. The network layer accommodates networks with more nodes by incorporating intelligent routing and instructs the data link layer how to most e ectively encode the transmitted packets for successful reception by a receiver. The speci cs of the routing protocol adapted for use in this wireless communications stack will be discussed in the next section. 6.5 Network Layer Implementation As discussed in Chapter 3 on MANET routing protocols, a popular proac- tive routing protocol is the Optimized Link State Routing (OLSR) routing proto- col (Section 3.2). OLSR attempts to reduce the number of transmissions required for control tra c by e ciently ooding through nodes selected as multi-point relays (MPRs). OLSR version 2 [Clausen, Dearlove and Jacquet 2008] improves throughput in MANETs since it creates bi-directional routes with control tra c instead of uni- directional routes. This protocol has been selected for adaptation and use within the jam-resistant protocol stack because it has been tested in mobile IP-based networks with some success. Furthermore, choosing a protocol as popular as OLSR as the foun- dation for the jam-resistant network layer developed in this research will hopefully encourage its use and adoption in the developer community. 103 Modifying existing software is usually not an easy task. As expected, modifying the existing OLSR implementation for use on software de ned radios such as the USRP is complex. For starters, the existing OLSR implementation connects to the outside world through Ethernet ports only. It assigns IPv4 and IPv6 addresses to con- nected interfaces and broadcasts control packets only over the prede ned interfaces. The current design is problematic for use with the USRP because all communications with the USRP pass through the USB 2.0 ports, rather than the standard Ethernet interfaces. Consequently, rewriting the current OLSR implementation to handle com- munications with the USB ports of Unix and Linux operating systems is a challenge. Moreover, OLSR uses sockets to open speci c ports and even uses iptables rewall rules to route packets inside the system which increases the number of dependencies that must be changed. The modi ed OLSR implementation, coined \BBC-OLSR", makes the following changes: 1. All communications with external nodes pass through the USB port in order to use the USRP software de ned radios. 2. IPv4 addresses are converted to a smaller address space that uses 16-bits. IPv6 addresses are not used. The address conversion is handled in a similar way to Network Address Translation (NAT). A table is maintained that translates between the IPv4 and 16-bit address formats, but only the 16-bit addresses are 104 transmitted and used with the software radios. The data link layer uses the 16- bit addresses as well, but OLSRd uses the IPv4 addresses internally to maintain the capability for network extension to the Internet if necessary in the future. 3. Packet headers are modi ed to include the necessary BBC message header in- formation 4. Routing decisions incorporate feedback from the data-link layer pertaining to the RSSI measurement to determine the level of spectrum interference present. 5. The data-link layer is instructed to use a speci c codeword length to account for spectrum interference and to guarantee node availability. As noise increases, so does the codeword length (level of jam-resistance). As noise decreases, the codeword length decreases accordingly. 6. Node-to-node delivery is handled by the data-link layer. Global routing be- tween nodes is handled by the network protocol. As such, control tra c in- cludes noise measurements to guide network-wide jam-resistance initiatives to guarantee availability. 7. Topology Control (TC) and \Hello" messages are grouped into sets of ten or more packets before being encoded with the BBC algorithm and transmitted on the radios. The reason for this is to alleviate some of the delays from the decoding and encoding step. For example, in the current implementation, the \hello" messages are transmitted every half-second. If the message was passed 105 to the encoder directly, many more messages would be in the queue while en- coding is taking place on the rst packet. Furthermore, these messages are only twenty-bytes so it is more e cient to group them in a bundle for encoding and transmission. In order to provide adaptive jam-resistance, BBC-OLSR analyzes the RSSI mea- surements taken at each node and transmitted with every message exchanged in the network. Therefore, when BBC-OLSR receives a packet from another node, it will know the noise level present in the spectrum at the time the packet is transmitted from the node. With this knowledge, BBC-OLSR determines the proper level of jam- resistance to employ at the data link layer in order to ensure message delivery to an intended recipient. For example, if there are four nodes in the network A, B, C, and D. And a path from A to D passes through B and C, so the route to be taken by a message is A-B-C-D. The BBC-OLSR agent at A will have relatively recent (de- pendent on broadcast interval) RSSI values for itself and the other nodes. Then, a simple scheme of resisting the highest level of noise among all nodes on the path is taken. By setting the level of jam resistant to accommodate the highest known level of spectrum interference along a path, the protocol ensures that message delivery and node availability are given the highest priority. Other schemes could surely be employed, but if the jamming source is mobile, then it is likely other nodes along the path may experience increased levels of noise after transmission from the originating node. For this reason, the scheme of resisting the highest known noise level is taken. 106 The experimental results involving the deployment and use of BBC-OLSR and the associated physical and data link layers are detailed in Chapter 9. 6.6 Software Architecture The purpose of this section is to detail the software architecture of this commu- nications system. Without design documentation, understanding the relationships among the various software and hardware components becomes rather complex. As the software has evolved, so have these diagrams. Furthermore, the diagrams con- tained in this section represent only the most useful representations of the software that have been deemed necessary to the understanding the interactions among com- ponents. First, the physical layer state diagram is provided below in Figure 6.12. At the physical layer, the radio is either idle, receiving, or transmitting. These high-level states represent the physical radio states that are relevant to the upper layers. Figure 6.12: Physical Layer State Diagram 107 Next, the data-link layer state diagram is shown below in Figure 6.13. These diagram also incorporates the states of the physical layer so the interactions between the two layers can be illustrated. The legend provides a key to identify which states belong to which layer. A clear distinction between the layers is necessary to pro- mote loose-coupling among components to promote future integration e orts with externally developed layers. Figure 6.13: Physical and Data Link Layer State Diagram The state diagram for the network layer built on top of the previously discussed physical and data link layers is shown below in Figure 6.14. The various states of the layers are shown as well as the interactions between the three layers. The network layer?s main function is to maintain routing information for the network. However, 108 the network layer in this research also controls data encoding at the data link layer to adjust the level of jam resistance throughout the network. At any one time, the various layers may be in any number of states. For example, the data link layer could be decoding a recently received message while the physical layer is transmitting another message. If messages are to be transmitted but the physical layer is in a receive state, the messages are queued for transmission for the next time the physical layer enters the transmit state. Figure 6.14: Physical, Data Link, and Network Layer State Diagram 109 6.7 Chapter Conclusion The purpose of this chapter is to explain the implementation of the communica- tions protocol developed in this research. We began the chapter with a discussion of the hardware and software components. Then, implementation details of the phys- ical, data link, and network layers are discussed. In addition, the application layer command and control application is introduced which provides the necessary visu- alization layer for testing the protocol. Near the end of the chapter, some software architecture diagrams are provided to enhance understanding of the design. As with any large research or engineering e ort, there will always be pieces that can be im- proved upon or designed in a di erent way. The implementation described in this chapter is meant to provide a working prototype to prove the technical feasibility of the research ideas. Future development e orts will of course result in improvements to this system as the software and hardware components evolve over time. 110 Chapter 7 Phase I Experimental Results 7.1 Chapter Introduction Phase I results demonstrate that a BBC-enabled protocol stack for wireless de- vices provides a solution to the hidden station and exposed station problems that plague nodes in a wireless network. Wireless nodes su er friendly jamming as a con- sequence of multiple nodes attempting to transmit at the same time as detailed in Chapter 2, Section 2.2.4. The traditional solution to this problem has been carrier- sensing where a node will use request-to-send (RTS) and clear-to-send(CTS) packets to claim the wireless medium for their transmission. The hidden station problem exists since a node out of range will not receive the noti cation that another node is transmitting and therefore a collision occurs as it transmits. In a similar scenario, the exposed station problem occurs when a node wishing to transmit is exposed to another station?s transmission and senses the medium as busy when it is in fact free. In the presence of jamming where the spectrum is full of noise, carrier sensing schemes will always detect the medium as busy and therefore cease to operate. Jamming also causes collisions such as those that occur in the hidden station issue. The BBC- enabled protocol stack uses jam-resistant message encoding to resist jamming and is well-suited to solve the problem of friendly station interference. 111 7.2 Hidden Station Problem Experiment In this experiment, the main goal is to prove a solution to the common hidden station problem among wireless devices. Figure 7.1 shows the node setup for this experiment and Table 7.1 shows the parameters used in the experiment. Since no carrier-sensing schemes are used in the data link layer, there are not RTS or CTS packets transmitted between nodes. Instead, packets transmit when they are ready to transmit. In this experiment, as node USRP 0A is transmitting to USRP1A, USRP 0B starts to transmit to USRP 1A as well. The trials were conducted through the use of the application layer GUI to control the nodes and repeat this scenario fty times. In traditional Wi-Fi networks, the collision would result in USRP 1A not receiving any messages since it would be unable to decode the corrupted signal caused by the simultaneous transmission. Instead, in this experiment, USRP 1A decoded the message from USRP 0A successfully through 50 trials. Through the use of the BBC-enabled protocol stack, the hidden station problem is solved. Figure 7.1: Hidden Station Problem Experimental Setup with USRP Devices 112 Parameter Value Frequency 1200MHz Decimation Factor (RX) 64 Interpolation Factor (TX) 128 RX Time 10 sec TX Time 10 sec Trials 50 Successful Receptions 50 Table 7.1: Hidden Station Experiment Parameters 7.3 Exposed Station Problem Experiment In this experiment, the main goal is to prove a solution to the common exposed station problem that causes loss of throughput in wireless networks. Figure 7.2 shows the node setup for this experiment and Table 7.2 shows the parameters used in the experiment. As previously mentioned, the data link layer does not contain carrier sensing medium access controls. As a result, nodes transmit when they are ready to transmit messages instead of asking permission beforehand. Under this experiment, nodes are exposed to many transmissions and are forced to decode messages despite numerous collisions. Speci cally, USRP 0B transmitted a message while USRP 1B transmitted a message. Simultaneously, USRP 0A and USRP 1A were in receive mode so they could receive any available transmissions. The application layer GUI is used to control this scenario and conduct the trials. In every trial of the 50 total trials, the receiving nodes decoded messages. The messages were not always intended for them, but messages were received successfully on every trial. In other words, USRP 0A would decode messages from USRP 0B in some trials and in USRP 1B in other 113 trials. Which message it received is related to which message the decoder encountered rst in the received signal data and which it could assemble completely without any retransmissions. To explain this further, the receiver at USRP 0A is on a timer and stops receiving after the speci ed amount of time. Then, the decoder determines what messages have been received. Consequently, USRP 0A may not receive complete messages from USRP 0B and USRP 1B. Therefore, the receiver decodes messages from USRP 0B in some trials and USRP 1B in other trials. Given that the collisions between the two simultaneous message transmissions did not corrupt the reception of at least one message at the receiver and there is no carrier sensing that prevented the transmission, the exposed station problem did not arise. For these aforementioned reasons, the exposed station problem is solved through the use of the BBC-enabled protocol stack. Figure 7.2: Exposed Station Problem Experimental Setup with USRP Devices 114 Parameter Value Frequency 1200MHz Decimation Factor (RX) 64 Interpolation Factor (TX) 128 RX Time 10 sec TX Time 10 sec Trials 50 Successful Receptions 50 Table 7.2: Exposed Station Experiment Parameters 7.4 Chapter Conclusion The focus of this chapter is on the hidden and exposed station problems that com- monly occur when wireless nodes are densely populated. Migrating away from carrier- sensing medium access schemes is necessary in any environment where there exists signi cant spectrum interference or potential adversarial jamming sources. With this in mind, the BBC protocol stack developed in this research does not incorporate any carrier-sensing techniques. It should be clari ed that the experiments conducted in this chapter involve only the physical and data link layers of the BBC-enabled proto- col stack. When collisions occur or noise a ects the received signal in other ways, the BBC algorithm compensates for packet collisions with error correcting codes. When collisions occur as nodes transmit simultaneously, the algorithm is able to correct for this and allow wireless nodes to correctly decode messages. This chapter presents a solution to two major problems that plague wireless nodes in today?s world where ubiquitous wireless communications are becoming ever more popular. 115 Chapter 8 Phase II Experimental Results 8.1 Chapter Introduction In Phase II, an experiment is devised to compare traditional 802.11G [IEEE 2007] wireless communications with the BBC-enabled protocol stack developed in this research. Speci cally, the goal of the experiment is to measure the tolerance to interference in the spectrum for each protocol and make a comparison between the two protocols in terms of node availability. In theory, 802.11G should not tolerate jamming sources as well as the BBC-enabled protocol due to its lack of su cient error correction coding and its contention-based data link layer. Conversely, the BBC- enabled protocol should operate e ectively in high levels of spectrum interference due to the jam-resistant encoding scheme and a non-contention based data link layer. The experimental results described in this chapter demonstrate unequivocally that a BBC-enabled protocol stack resists jamming more e ectively than 802.11G and guarantees node availability in the presence of interference where nodes using the 802.11G protocol simply fail. The upcoming sections in this chapter will discuss the experiment setup for the two protocols and provide a comparison between the two in the presence of varying levels of spectrum interference. 116 8.2 Wi-Fi 802.11G Experimental Setup The goal of this part of this experiment is to collect data on an 802.11G based wireless system to facilitate making a comparison to the system running the BBC protocol created in this research. The experiment involves transmitting 1000 messages between two 802.11G nodes and determining the message delivery success rate. In the rst scenario, the messages will be transmitted without a signal jammer adding noise to the spectrum. In the second scenario, a jammer will add noise to the spectrum while the nodes attempt to communicate. Various levels of noise will be used during the second scenario for the sake of comparison. The rst scenario serves as a control group so that the di erences between the noiseless and noisy environments become apparent. In an e ort to reduce external interference sources that may a ect the outcome of the experiment, the physical environment for this experiment is a clear grassy eld away from visible sources of electronic interference. At the experiment site, no Wi-Fi hotspots were found using Wi-Fi network location software built into a laptop computer. The noise generator for the 802.11G protocol used in this experiment is a con- ventional microwave oven operating at the 2.4GHz frequency which is shared with 802.11G devices. The average consumer can test this jamming source e ectively by placing their Wi-Fi devices in close proximity to their microwave oven. However, a more technical discussion of this interference is necessary. The residential microwave oven contains a single magnetron that periodically turns on and o as the 60Hz AC 117 line voltage oscillates from positive to negative as shown in Figure 8.1. The mag- netron generates RF signals to cook food at in the 2.4GHz band and operates in a similar fashion to Frequency Modulated (FM) signals [Taher et al. 2006]. This RF energy from the magnetron leaks from the case of the microwave and causes interfer- ence with 802.11G devices. The strength of the signal emitted varies with the power used in the microwave. Therefore, a microwave with 10 di erent power settings will emit 10 di erent signals of varying power. Essentially, the microwave oven acts like any jammer and adds power to the spectrum about a certain carrier frequency [Taher et al. 2008] and prevents an eligible receiver from correctly decoding the received signal. The speci c center carrier frequency varies by model, but the microwave used in this experiment has a center frequency of 2.45GHz. The idea of using a microwave oven to test 802.11G networks? tolerance for interference and jamming has been stud- ied before by [Pietikainen et al. 2005], [Kamerman and Erkocevic 1997], [Taher et al. 2006]. In this experiment, two 802.11G nodes were positioned 10-feet from a microwave oven jamming source on opposite sides of the jammer as shown in Figure 8.2. The experiment was conducted outside in an open eld as mentioned above and the power was supplied via an automobile nearby equipped with a DC-to-AC converter. The oven used is capable of 10 di erent power settings and therefore 10 di erent jamming signal strengths. The nodes exchanged UDP messages in an echo-echo reply message exchange pattern and the results were logged for o ine analysis. Figure 8.3 below 118 Figure 8.1: Microwave Oven Signal in Time Domain [Taher et al. 2006] represents the data taken during the experiment where 1000 messages were sent and acknowledged. Figure 8.2: 802.11G Experiment Setup A packet error rate greater than 100% indicates that a message had to be retrans- mitted multiples times. Since the BBC-enabled data link layer uses acknowledgements 119 Figure 8.3: Wi-Fi 802.11G Experiment Data to con rm the receipt of messages and trigger retransmissions if necessary, the mes- sages exchanged in the 802.11G experiment were also acknowledged and retransmitted until the message arrived successfully. The microwave generates signals in a periodic \on" and \o " state, so it is quite likely that messages were retransmitted during an \o " state and therefore the delivery was successful. At high power levels, the \on" state lasts longer than the \o " state and thus more energy is added to the spectrum. For example, at a 50% power level, the \on" state splits equal time with the \o " state. In a cooking example, if a meal is put in the microwave for 2 minutes on 50% power, then only 1 minute of that time will the food receive microwave energy. The food is cooked slower as the microwave alternates \on" and \o " states and the food cools during the \o " states. In the case of an adversarial jammer, the jammer would likely output power constantly and with the maximum energy possible. This type of jammer would consume massive amounts of energy and would result in an 802.11G device not being able to communicate any packets successfully. Clearly, this experiment shows that 802.11G devices do not operate e ectively in environments with signi cant spectrum interference. 120 8.3 BBC-Enabled Protocol Experimental Setup The goal of this part of the experiment is to collect data using the USRPs and the BBC-enabled protocol layers developed in this research in order to make a compari- son to popular 802.11G protocol devices. As with the previously discussed 802.11G experiment, this experiment involves transmitting 1000 messages between two USRPs with RFX-1200 daughterboards to determine the message delivery success rate. In the rst scenario, the messages will be transmitted without a signal jammer adding noise to the spectrum. In the second scenario, a jammer will add noise to the spec- trum while the nodes attempt to communicate. In a similar approach to the 802.11G experiment, varying levels of noise will be used during the second scenario to gather data useful in comparing resistance to jamming. The rst scenario serves as a control group so that the di erences between the noiseless and noisy environments is evi- dent. In an e ort to reduce external interference sources that may a ect the outcome of the experiment, the physical environment for this experiment is a clear grassy eld away from visible sources of electronic interference such as radio towers. At the experiment site, an RSSI measurement is taken to determine the environmental interference present for the control group and no signi cant noise is discovered. The experiment is conducted using a frequency of 1.2GHz which is within the capabilities of the RFX-1200 daughterboard. To generate the noise, the signal generator script discussed in the software com- ponents portion of Section 6.2 is used. As a parameter, the noise generator takes a 121 value to indicate the amplitude of the signal to generate. There is a direct correlation between the signal amplitude and the signal strength. Therefore, a larger amplitude value will cause a more powerful signal to be generated. The signal into the USRP is a 16-bit signed number where 32767 represents the full scale amplitude possible given the hardware. Using this maximum as the highest level of noise, the experiment is conducted with various levels of noise o set from this maximum value. Table 8.1 shows the notional power level in conjunction with the amplitude value supplied to the jammer and the perceived noise level given by the RSSI measurement from the auxiliary analog-to-digital converter (ADC). The RSSI measurement is taken at the intended receiver of the message and averaged over the trials. The purpose of the RSSI measurement is to provide con rmation that the jammer is working as speci ed and the jamming signal is indeed being modulated by the USRP as desired. In this experiment, two USRP nodes were positioned 10-feet from the host com- puter on opposite sides of the host as shown in Figure 8.4. As with the previous experiment with 802.11G, this experiment was conducted outside in an open eld and the power was supplied via an automobile nearby equipped with a DC-to-AC converter. The USRP nodes exchanged messages in an echo-echo reply message ex- change pattern and the results were logged for o ine analysis. Figure 8.5 shown below represents the data taken during the experiment where 1000 messages were sent and acknowledged. The nodes in this experiment transmitted their messages for 10 sec- onds and the receivers only received data for 10 seconds. Varying this parameter is possible, but for consistency and reducing variables in the experiment, 10 seconds on 122 both the transmitter and the receiver worked e ectively. The nodes alternate between the transmit mode and receive mode since a single daughterboard of the RFX-1200 series cannot be in full duplex operation simultaneously on the same frequency. Figure 8.4: BBC-enabled Protocol Experiment Setup Figure 8.5: BBC Experiment Data From the data collected in this experiment, the conclusion is that a BBC-enabled protocol stack is highly resistant to jamming due to its message encoding. Even with maximum power from the jammer, messages were rarely corrupted and few retransmissions were necessary. 123 Jamming Power Noise Signal Power (Amplitude) RSSI [0,4095] 10 32000 4081 9 28000 4065 8 24000 3939 7 20000 3424 6 16000 2411 5 12000 2116 4 8000 1507 3 4000 542 2 2000 180 1 1000 163 0 0 155 Table 8.1: Signal Jamming Power Correlated to RSSI 8.4 Wi-Fi 802.11G at 1.2GHz Experimental Setup The goal of this experiment is to solidify a comparison between the 802.11G protocol and the BBC-enabled protocol stack developed in this research. As with the previous experiments, this experiment involves transmitting 1000 messages between two USRPs with RFX-1200 daughterboards to determine the message delivery success rate. In the rst scenario, the messages will be transmitted without a signal jammer adding noise to the spectrum. In the second scenario, a jammer will add noise to the spectrum while the nodes attempt to communicate. As in the BBC experiment above, varying levels of noise will be used during the second scenario to gather data useful in comparing resistance to jamming. Moreover, the noise source is the same jammer used in the previous experiment for BBC. The rst scenario serves as a control group so that the di erences between the noiseless and noisy environments is evident. 124 In this experiment, two USRP nodes were positioned 10-feet from the host com- puter on opposite sides of the host as shown in Figure 8.6. As with the BBC ex- periment discussed previously, these nodes operate at 1.2GHz. The data for this experiment consists of random 1500-byte 802.11G frames captured from the host computer?s Wi-Fi connection. These 802.11 packets are used in order to determine how varying levels of noise a ects them and to make a comparison to the impact of noise on the packets of the BBC-protocol stack. Figure 8.6: 802.11G at 1.2GHz Experiment Setup Figure 8.7: 802.11G at 1.2GHz Experiment Data 125 From the data collected in this experiment, clearly the 802.11G packets are highly susceptible to corruption in the presence of jamming. The packets only contain a 32- bit cyclic redundancy check (CRC) to alert the protocol that there is an error in the packet. The 32-bit CRC is an error-detecting code and is not able to correct multiple bit errors in the same packet. In contrast, the BBC encoding is an error-correcting code which is able to successfully correct for multiple bit errors in a message. In this experiment, the receiver computed CRCs for every packet to determine if there was an error. With any level of noise from the jammer, the CRC for all 1000 messages detected an error. On an actual 802.11G device, any CRC mismatch automatically triggers a retransmission of the packet, so this would be quite devastating from a performance standpoint. As the data in Figure 8.7 shows, the receiver was able to decode messages with jamming power below 4, but with higher levels of jamming the receiver was unable to decode any messages. At a jamming power level of 3, the packet error rate rose to 93.6%. Clearly, the 802.11G protocol is unable to successfully operate in areas with signi cant noise. 8.5 Comparison of Wi-Fi 802.11G and BBC-Enabled Protocol Stack Ex- periments The data collected clearly demonstrates that 802.11G does not operate e ectively in the presence of noise. Figure 8.8 shows a comparison of the data collected in the 802.11G experiment at 2.4GHz to the BBC experiment at 1.2GHz. In addition, Figure 8.9 shows a comparison of the data collected in the 802.11G experiment at 126 1.2GHz to the BBC experiment at 1.2GHz. In the 802.11G experiment with the microwave as the jammer, only the lowest power settings on the jammer allowed messages to be received on the rst attempt. With jamming power above level 2, all packets transmitted would have been lost due to error if not for the retransmission capability provided by the data link layer. In the 802.11G experiment at 1.2GHz, the receiver did not receive any messages past jamming level 3. In comparison, the BBC- enabled protocol stack operates e ectively in even the highest levels of noise. With the jamming source at maximum power, a mere 4% of packets had to be retransmitted due to errors. Figure 8.8: 802.11G Versus BBC Protocols: Packet Error Rate 127 Figure 8.9: 802.11G at 1.2GHz Versus BBC Protocol: Packet Error Rate From these experiments, the BBC-enabled protocol developed in this research has shown signi cantly improved node availability over the popular Wi-Fi 802.11G communications protocol. In disaster or battle eld scenarios, node availability is of the utmost importance and this capability is provided by the BBC-enabled protocol stack. 8.6 Chapter Conclusion Clearly, improvements are necessary to the 802.11G protocol and encoding scheme in order to prevent jamming in this increasingly crowded spectrum. Common con- sumer appliances should not interfere with wireless networks in such a dramatic way. Even while operating in an uncrowded spectrum at 1.2GHz, the 802.11G protocol did not perform well in the presence of noise. 802.11G?s poor tolerance to spectrum 128 interference precludes its use in environments with signi cant noise such as the bat- tle eld or even densely populated areas with many 802.11G devices. Channelization does help mitigate some of the interference with 802.11G devices; however, a robust jammer or one that operates with a wide-bandwidth such as the microwave will causes 802.11G devices to stop working due to bit errors at the receiver [Pietikainen et al. 2005]. The BBC-enabled jam-resistant protocol developed in this research is a step toward wireless devices that tolerate jamming and can guarantee node availability in environments with signi cant spectrum noise or intentional jamming. 129 Chapter 9 Phase III Experimental Results 9.1 Chapter Introduction In Phase III of this research, the network routing layer implementation is tested on the USRP software radio platform. The BBC-OLSR protocol combines the strengths of both OLSR and BBC to create a jam-resistant network layer with e ective routing in the presence of noise. Unlike other network protocols, this network layer will op- erate in noisy environments due to the jam-resistant BBC encoding taking place at the data link layer. Furthermore, BBC-OLSR improves the reliability of OLSR since it will not lose as many messages to jamming or interference. Network availability is the primary concern for this protocol since it is designed to operate in environments with signi cant spectrum interference. As stated in the implementation discussion of Chapter 6, BBC-OLSR analyzes the RSSI measurements taken at each node prior to the transmission of a message. Therefore, when it comes time to assign a message a path to take in the network, the network layer agent has interference information available for each hop along the route. Using this knowledge, BBC-OLSR instructs the data link layer to use a certain level of jam resistance in the BBC encoding. Currently, there are ve levels of jam-resistance corresponding to four codeword lengths to be used in the BBC algorithm as shown in Table 9.1 below. BBC-OLSR 130 determines the appropriate level to use based on the scheme discussed earlier to ensure delivery to the node with the greatest amount of interference present along a certain path. The implementation of the BBC encoding and decoding with the various levels of jam-resistance is still under development via a parallel research e ort into a new data link layer speci cally created for this purpose. Until this is implemented, the encoding and decoding of the various levels is not testable, however this is a data link layer function and not a network layer issue. The BBC-OLSR network layer is concerned with the use of the RSSI measurements collected to ensure adaptation to interference in the network as a whole. Jam-Resistance Level Codeword Length RSSI Range 5 160 3500-4092 4 128 2500-3500 3 96 1500-2500 2 64 750-1500 1 32 0-750 Table 9.1: Threshold Levels for Jam-Resistance Based on RSSI Measurements The BBC-OLSR feature of using RSSI measurements to make adaptive routing decisions is tested and proven in this chapter. In the remainder of this chapter, the experiments with OLSR and BBC-OLSR are discussed. As expected, the chapter concludes that BBC-OLSR allows nodes in the network to adapt to varying levels of noise throughout the network. Furthermore, the BBC-OLSR protocol ensures node availability with message delivery where the original OLSR protocol simply fails in the presence of noise. 131 9.2 Experiment 1: USRPs Only The purpose of this experiment is to test the e ectiveness of this BBC-OLSR protocol on the software de ned radios. Many networking protocols are constructed and only tested in a simulated environment such as NS-2 (refer to Chapter 3), but it is important to this research for this protocol stack to operate well on actual hardware radios. Delays due to encoding, decoding, transmission, and reception become more important with real hardware and are not usually discovered in the design phase. In addition, signaling issues such as timing and synchronization with waveforms do not become apparent without the use of real hardware. For these reasons, this protocol stack from the application layer to the physical layer is tested in this experiment on the four USRP devices on hand. 9.2.1 Experiment Setup In order to make a comparison between the OLSR and BBC-OLSR protocols, there is a shared experimental setup between the two. First, there will only be four nodes in this experiment as shown in Figure 9.1. Each node is an RFX-1200 daugh- terboard and the nodes are mounted on two USRPs containing two separate FPGAs as discussed in previous chapters. The nodes will be distributed as far apart as pos- sible similarly to the experiments conducted in Phase II. The data link and physical layers used by each network layer protocol will be the ones developed in this research and described in the preceding chapters. Therefore, the only experimental variable is the network layer being used. During the experiments, the application layer will 132 drive the exchange of messages in the network and provide a visualization of the protocol?s operation. In the experiment with noise, the noise generator script will be used to add interference at the 1200 MHz operating frequency. The main goal of this experiment is to determine if the network layer successfully uses the RSSI measure- ments included in the transmitted messages to change the level of jam-resistance that it instructs the data link layer to use. As a secondary goal, the experiment should expose any di erences in routing decisions between the two protocols in the presence of noise. Figure 9.1: USRP Network Topology 9.2.2 OLSR vs. BBC-OLSR Without Interference Without interference, the protocols behave in an almost identical manner. BBC- OLSR?s threshold for increasing the level of jam-resistance is not triggered unless there is an interference source nearby. As expected, both protocols choose the same routes and receive all of the messages that are transmitted when there is no mobility. Since 133 BBC-OLSR bundles control messages into groups of ten messages before encoding and transmitting them, it does not build up as large of a transmit queue. Furthermore, it allows nodes running BBC-OLSR to receive more timely updates to topology changes since more control messages arrive at a time. By the time the original OLSR protocol is nished encoding a control message (1.5 sec) and transmitting (0.5 sec), there are already on average 5 more messages in the transmit queue if the broadcast interval is 0.5 sec. Mobility is simulated in this experiment by dropping packets from a speci c node on the host computer so that the routing agent does not receive messages from that node. When this occurs in the experiment, BBC-OLSR removes the node from any routes faster since it bundles the control messages. This experiment provides a good control study to show the problems noise can cause in wireless communications since it is a straightforward comparison of the two protocols without any message corruption due to interference. The data for this experiment is shown in Figure 9.2 for OLSR and Figure 9.3 for BBC-OLSR in the row where the jamming power is zero. 9.2.3 OLSR vs. BBC-OLSR With Interference In this experiment with the USRPs, noise is added to the spectrum through the use of the signal generator script to add random noise. Adding power to a signal will ip 0?s to 1?s and prevent the successful decoding of messages. At the network layer, the main concern is that noise will corrupt control messages and routes will become stale. To avoid this, BBC-OLSR uses the RSSI values sent from nodes in the network to adjust the message?s BBC encoding to improve reliability. To simulate 134 routes changing due to mobility, packets are dropped for certain nodes on the host computer. In this experiment, OLSR did not use the RSSI value at all. OLSR?s individual control messages became corrupted by the interference because they were only 20 bytes in length. With a 20 byte message, the decoder has a di cult time distinguish- ing the noise signal and the actual signal since the received signal is about 150Mb worth of IQ pairs. At RSSI values over 3100, OLSR failed to decode any messages and all of the routes became stale. In contrast, BBC-OLSR continued to operate even in the highest levels of jam- ming (RSSI over 4000) since the messages were bundled together to form a longer message. A longer message meant that more of the received signal is message content and not noise. For all practical purposes, some of the message bits were probably made stronger with the addition of noise by mere coincidence. As an added bene t, the routes were updated more frequently than pure OLSR as discovered in the pre- vious experiment. The RSSI values from the nodes on a path were used to trigger thresholds for the levels of jam resistance. The greatest RSSI value along a route is used to determine the level of jam-resistance to use for maximum availability. As ex- pected, the data link layer successfully received the threshold value prior to encoding the messages and could therefore e ect the change prior to transmission. With the level of jam-resistance assigned, the encoder will use a di erent codeword length in response. The decoders at the receiver side do not need modi cation since they will search for the proper codeword length if necessary during the decoding process. 135 The following data tables in Figures 9.2 and 9.3 illustrate a sample run for noise added to USRP nodes running OLSR and BBC-OLSR respectively. In addition, a comparison chart is shown in Figure 9.4. Figure 9.2: OLSR With Interference Data Figure 9.3: BBC-OLSR With Interference Data From this experiment, it is concluded the BBC-OLSR operates more reliably in the presence of noise than pure OLSR. BBC-OLSR enabled nodes to receive topology updates quicker and resist higher levels of jamming more e ectively. Furthermore, BBC-OLSR?s determination for the best level of jam-resistant encoding operates ef- fectively on real hardware and in the presence of real signal jammers. 136 Figure 9.4: OLSR vs. BBC-OLSR Chart 9.3 Experiment 2: USRPs and Virtual Nodes In order to test the protocol stack?s ability to handle more dispersed nodes due to mobility and scale to a larger number of nodes, more than four nodes are neces- sary. For this experiment, the four real radios are being used in conjunction with six simulated nodes running on virtual network interfaces. To identify the nodes in this discussion, the real radios are identi ed by USRP0A, USRP0B, USRP1A, and USRP1B. The virtual nodes are identi ed by virt1 through virt6. The BBC protocol stack used in the previous experiment will also be used in this experiment, except the six virtual nodes will be using virtual network interfaces instead of the USB. The topology for this experiment is shown in Figure 9.5 below. 137 Figure 9.5: USRPs and Virtual Nodes Network Topology 9.3.1 Experiment Setup The main purpose of this experiment is still to make a comparison between pure OLSR and BBC-OLSR at the network layer. By using ten nodes, instead of four, the addressing scheme and routing issues will become more pronounced. Although six of the nodes are operating in software, they are still using virtual network interfaces that act like real hardware. The host computer does not distinguish between the virtual interfaces used and the hardware interfaces since it is just a le descriptor object to the operating system. The main di erence between the two protocol stacks remains the network layer and this is where a comparison between OLSR and BBC- OLSR is made. The noise used will be from the actual radios and from the virtual nodes as well. In addition to simulating mobility, dropping packets of a certain node can simulate noise at that point in the network as well. An example of node loss 138 due to simulated mobility or noise is shown in Figure 9.6 where packets are dropped for the disconnected nodes. Random RSSI values are reported to the BBC-OLSR protocol when a node?s packets are being dropped due to a simulated noise event. From this, the protocol determines the most suitable level of jam-resistance for the communications path. Figure 9.6: USRPs and Virtual Nodes Network Topology with Broken Links With more than a few nodes in the network, addressing may become an issue. All of the nodes carry randomly assigned addresses. In this protocol stack, addresses are IP-based at the network layer, but at the data link layer they are randomly assigned integers. An address translation is completed between the two layers to ensure that the non-IP based addressing scheme is used over the wireless link for e ciency. As discussed in Chapter 6, address collisions are extremely rare but are resolved e ectively. 139 The following sections discuss the experimental results of the network layer com- parison with and without interference. 9.3.2 OLSR vs. BBC-OLSR Without Interference In this experiment, the ten nodes are brought online in an environment without interference. The nodes communicate with each other through the topology control and \hello" messages successfully under both protocols. Ordinarily, there would be message collisions with so many messages being exchanged in the network. How- ever, there are transmit and receive message queues at the data link layer which allow a node to queue messages for processing. The pure OLSR protocol consistently builds up hundreds of packets in the receive and transmit queues because it generates messages every 0.5 seconds on the default broadcast interval. On the other hand, BBC-OLSR combines ten messages at a time and delivers them all at once. So while the messages are larger, they are decoded and analyzed faster because there is less switching time between messages. With the simulated mobility, the results are the same as the experiment with four nodes. BBC-OLSR received the updates faster than OLSR due to shorter queuing delays. 9.3.3 OLSR vs. BBC-OLSR With Interference This experiment is similar to the previous experiment, except that two sources of noise are introduced to the network. One noise source is on a real radio and the other is on a virtual node. The virtual node?s packets will be dropped by the operating 140 system kernel of the host computer when the noise source is active and nodes on either side of the virtual node will report higher RSSI values. For example, consider virtual node 4 is the jammer. Then virtual node 3 and 5 will report increased RSSI values to BBC-OLSR. The actual RSSI value reported does not necessarily matter as long as BBC-OLSR registers the change and modi es its jam-resistance level accordingly for the a ected routes. For the real radios in the network, the actual RSSI values will be used as measured by the auxiliary ADC. In this experiment, pure OLSR built up extremely large transmit queues of sev- eral hundred messages in just a few minutes. Although not directly related to the noise, this allowed routes to become stale since the signi cant queuing delays did not allow topology updates to be delivered in a timely manner. With a jammer active on a USRP node and a virtual node, the successful delivery of topology updates became sporadic. This delivery of corrupted messages from the radios increased the queu- ing delay since the decoder spent time attempting to decode a corrupted message (ending in failure) while the receive queue continued to build. In a similar fashion to Experiment 1, the small size of the messages allowed them to be easily corrupted. With the larger network, more messages traversed the network and exacerbated the topology update problems since the queuing delays were signi cant at each node and the message delivery was not reliable. When simulated mobility took down three of the virtual nodes by dropping their packets, the network routes did not stabilize due to the queuing problems created by the noise. 141 In contrast to the results of pure OLSR, BBC-OLSR excelled in the larger net- work size. The transmit or receive queues did not exceed fteen messages on average at any time. Bundling the frequent but small topology control and hello messages together prior to encoding is an important aspect to the success of this protocol. The BBC algorithm needs time to encode and decode, and therefore it is important to make these steps proceed as e ciently as possible. Furthermore, the same ex- periments described above with pure OLSR were conducted with BBC-OLSR. With the two jammers active, topology updates were still successfully delivered due to the larger message size. Through observation, the RSSI values were properly reported from the USRP sensors as well as the random RSSI values from the virtual nodes. The threshold algorithm worked properly with several routes traversing the various nodes that each reported di erent RSSI values. The data link layer registered the level of jam-resistance assigned by the network layer and con rmed the encoding scheme selected. With simulated mobility, the packets of three virtual nodes were dropped as these nodes moved out of range. The routes in the network stabilized within thirty-seconds as sets of ten control messages were delivered successfully. To further illustrate the results, Figures 9.7 and 9.8 show the results of a network scenario similar to the one described above. In the scenario represented below, a USRP node?s packets are dropped to simulate it moving out of range and then it acts as a jammer to interfere with the transmissions from other nodes. Then, two virtual nodes move out of range and their packets are dropped. With noise added to the spectrum, BBC-OLSR messages are still decoded and the routing tables stabilize 142 properly. On the other hand, pure OLSR experiences problems in the decoding stage and consequently large transmit queues are built up which do not allow the routing tables to stabilize properly. Complete gures are quite large and must be shown in landscape mode. Therefore, these diagrams are included as Appendix Figures B.1 and B.2. Figure 9.7: Pure OLSR With Noise Diagram From these experiments, it is concluded the BBC-OLSR operates more reliably and scales better in the presence of noise than pure OLSR. BBC-OLSR enabled nodes receive topology updates more consistently as mobility increased. The higher levels of jamming were resisted by bundling messages together, but this also had the added bene t of reducing queueing delays for the protocol. Lastly, as discovered in the previous experiment with the four nodes, BBC-OLSR?s determination for the best 143 Figure 9.8: BBC-OLSR With Noise Diagram level of jam-resistant encoding operates e ectively on real hardware. It also operates e ectively on virtual nodes and in the presence of message corruption. 9.4 Discussion of Results The experiments conducted in Phase III are meant to validate the design of the adaptive jam resistant network routing layer that is part of the jam resistant protocol stack. Building on top of the physical and data link layers already described, the purpose of the network layer is to determine the level of jam resistance required to guarantee message delivery in the presence of interference. Each network route consists of nodes that are geographically distributed and this geographic dispersion may place some nodes in areas of interference. Furthermore, node mobility causes interference since signals become di racted or re ected from environmental obstacles. 144 The purpose of this protocol stack is to ensure availability and message delivery in this type of noisy environment. Clearly, as proven by these experiments, a regular network layer protocol such as pure OLSR will not be e ective with this encoding scheme due to the inherent delays of the algorithm. 9.5 Interference Adaptive Routing Discussion As discussed in Chapter 3, the ALIR protocol [Zhang, Liu, Shi, Liu and Yu 2007] attempts to route data around noisy areas by extending the path length. Instead of this approach, BBC-OLSR adjusts the level of jam resistance used for message en- coding and uses the same path despite interference levels. If the message is not acknowledged, another message is sent along a di erent path. In the mean time though, it is highly likely that topology control messages have already updated the route with a new path. However, in an infrastructure-less network with few nodes, such as the battle eld scenario shown in Figure 1.1 at the beginning of this disser- tation, it is not always possible to nd a route around the area of interference. For this reason, BBC-OLSR does not attempt to route around areas of interference and chooses instead to leverage the capabilities of the BBC algorithm to overcome noise in the spectrum. 9.6 Chapter Conclusion The experiments conducted in Phase III described in this chapter focus on the e ectiveness of the BBC-OLSR network layer implemented in this research. While 145 the focus is on the network layer in these experiments, the experiments provide a capstone testing event for the physical and data link layers as well. Most newly developed network protocols are only tested through simulation which may lead to protocols that do not operate well in real-world environments on actual hardware. In this research, the design and implementation of this jam-resistant communications protocol is validated on USRP software de ned radios which adds some creditability to the implementation. The physical, data link, and network layers work cooperatively to provide a network protocol stack that resists jamming and provides node availability in the presence of spectrum interference where current network protocols fail. 146 Chapter 10 Key Contributions Created a cross-layer communications protocol for Mobile Ad-Hoc Networks (MANETs) that proactively determines routes for message delivery yet reac- tively adjusts to spectrum interference. Implemented a working prototype of a mobile jam-resistant communications system on software de ned radios (USRPs) including physical, data link, and network layers. Constructed a collision-resistant addressing scheme involving the assignment of pseudo-random addresses and duplicate address detection mechanisms. Proved that the BBC algorithm can be used in conjunction with other protocol layers to provide network availability in the presence of spectrum interference or noise. Improved the reliability of the OLSR protocol by incorporating a global link quality determination and encoding adjustment based on data link layer feed- back on the level of noise in the spectrum at the time of physical layer trans- mission. Provided a solution to the hidden station problem through the use of the BBC algorithm at the data link layer. 147 Provided a solution to the exposed station problem through the use of the BBC algorithm at the data link layer. Improved the e ciency of the Optimized Link State Routing (OLSR) protocol by using a variable-length address space. Explored various ways to modify the BBC algorithm to compensate for variable amount of jamming. Further research with colleagues into this aspect of the protocol is ongoing. Explored various ways to modify the BBC algorithm to allow for variable length messages. Further research with colleagues into this aspect of the protocol is ongoing. Performed an extensive literature review on the BBC algorithm, MANET Net- work Layer Routing, and MANET Network Layer Addressing. 148 Chapter 11 Conclusion The research described in this dissertation has crossed several elds of study including wireless communications, coding theory, signal jamming, mobile ad-hoc network routing, and mobile ad-hoc network addressing. In each of these domains, a detailed explanation of the previous work in the eld has been presented. As any user of consumer wireless network devices can attest, current wireless networks are plagued by interference sources in their spectrum of operations. In mobile ad-hoc networks, the spectrum interference may be caused by some environmental or disaster situation. Or, it may be a result of adversarial jamming in a military communications example. Moreover, another common source of interference are the transmissions of nearby friendly stations. Currently, the solution to the interference problem is a human- based frequency decon iction scheme where devices operating near each other are set to utilize di erent frequencies. These schemes are problematic at best and quite e ort intensive on the part of engineers. In many cases, these decon iction schemes involve agreements between the administrators of the various wireless systems to ensure unintentional jamming does not occur among cooperating systems. Clearly, a better scheme is needed to ensure unintentional jamming does not occur due to human error in these spectrum assignments. 149 This research e ort creates a cross-layer protocol that can be deployed on many nodes and platforms to provide ad-hoc communications in these aforementioned situ- ations. To date, there is not an adaptive jam-resistant scheme in existence that uses the approach described in this dissertation. The research described in this dissertation creates a network protocol stack that allows for jam-resistant communications in ar- eas with high spectrum interference caused by either friendly station transmissions or adversarial signal jammers. Through the development of custom physical, data link, and network layers to form a jam-resistant communications protocol stack, the overall goal of creating an adaptive jam-resistant protocol has been achieved. The physical layer handles the signal processing, the data link layer ensures the delivery of mes- sages hop-to-hop, and the network layer determines the best level of jam-resistance to employ to ensure network-wide node availability. Moreover, an application layer drives the rest of the layers in this working prototype. Unlike many other newly de- veloped communications protocols, the prototype developed in this research operates on real hardware devices instead of a computer simulation. Furthermore, it has the capability to be deployed on many nodes in a self-organizing mobile ad-hoc network that can operate in environments where current 802.11-based protocols fail due to noise. 150 Bibliography Adjih, C., Boudjit, S., Jacquet, P., Laouiti, A. and Muhlethaler, P. [2005], ?Address autocon guration in optimized link state routing protocol?, Internet Engineering Task Force (IETF) draft . Agrawal, D. and Zeng, Q.-A. [2006], Introduction to Wireless and Mobile Systems, Thomson Canada Limited, pp. 303{331. Aron, I. D. and Gupta, S. K. S. [2001], ?On the scalability of on-demand routing pro- tocols for mobile ad hoc networks: An analytical study?, Journal of Interconnection Networks 2, 5{29. Ayanoglu, E., Chih-Lin, I., Gitlin, R. D. and Mazo, J. E. [1993], ?Diversity cod- ing for transparent self-healing and fault-tolerant communication networks?, IEEE Transactions on Communications 41, 1677{1686. Bahn, W. [2007], ?Bbc real-time engine?, http://www.williambahn.com/bbc/. Baird, L., Bahn, W. and Collins, M. [2007], Jam-resistant communication without shared secrets through the use of concurrent codes, Technical report, U.S. Air Force Academy. Boleng, J. [2002], ?E cient network layer addressing for mobile ad hoc networks?, Proceedings of the International Conference on Wireless Networks pp. 271{277. 151 Boukerche, A. [2001], ?Performance comparison and analysis of ad hoc routing algo- rithms?, Proceedings of IEEE International Conference on Performance, Computing and Communications pp. 171{178. Burkhart, M., Rickenbach, P. V., Wattenhofer, R. and Zollinger, A. [2004], ?Does topology control reduce interference??, Proceedings of ACM MobiHoc pp. 9{19. Castenada, R. and Das, S. [1999], ?Query localization techniques for on-demand rout- ing protocols in ad hoc networks?, Mobile Computing and Communications Con- ference . Cha, H.-W., Park, J.-S. and Kim, H.-J. [2003], ?Extended support for global connec- tivity for ipv6 mobile ad hoc networks?, Internet Engineering Task Force (IETF) draft . Chakeres, I. and Perkins, C. [2008], ?Dynamic manet on-demand (dymo) routing?, Internet Engineering Task Force (IETF) draft . Chiang, C.-C., Wu, H.-K., Liu, W. and Gerla, M. [1997], ?Routing in clustered multi- hop, mobile wireless networks with fading channel?, IEEE Singapore International Conference on Networks (SICON?97) pp. 197{211. Chin, K.-W., Judge, J., Williams, A. and Kermode, R. [2002], Implementation expe- rience with manet routing protocols, in ?ACM SIGCOMM Computer Communica- tions Review?, Vol. 32, ACM. 152 Chlamtac, L. and Lerner, A. [1986], ?Link allocation in mobile radio networks with noisy channel?, Proceedings of the IEEE INFOCOM pp. 1243{1257. Clausen, T., Dearlove, C. and Dean, J. [2008], ?Manet neighborhood discovery proto- col (nhdp)?, Internet Engineering Task Force (IETF) draft . Clausen, T., Dearlove, C. and Jacquet, P. [2008], The optimized link state rout- ing protocol version 2, Technical report, Internet Engineering Task Force (IETF), http://tools.ietf.org/html/draft-ietf-manet-olsrv2-07. Clausen, T. H. and Baccelli, E. [2005], ?Simple manet address autocon guration?, Internet Engineering Task Force (IETF) draft . Cormen, T. H., Leiserson, C. E., Rivest, R. L. and Stein, C. [2001], Introduction to Algorithms, 2nd Edition, The MIT Press. Corson, M. S. and Park, V. D. [1997], ?An internet manet encapsulation protocol (imep) speci cation?, Internet Engineering Task Force (IETF) draft . Dube, R. [1997], ?Signal stability based adaptive routing for ad hoc mobile networks?, Proceedings of IEEE Personal Communications pp. 36{45. Dunn, R. [2009], ?wxpython gui toolkit?, http://www.wxpython.org/index.php. EFunda [2009], ?Under sampling?, http://www.efunda.com. Erdfelt, J. [2008], ?Usb library?, http://libusb.wiki.sourceforge.net/. 153 Fazio, M., Palazzi, C. E., Das, S. and Gerla, M. [2006], Automatic ip address con g- uration in vanets, in ?VANET ?06: Proceedings of the 3rd international workshop on Vehicular ad hoc networks?, ACM, New York, NY, USA, pp. 100{101. Fazio, M., Villari, M. and Pulia to, A. [2006], ?Ip address autocon guration in ad hoc networks: design, implementation and measurements?, Computer Networks: The International Journal of Computer and Telecommunications Networking 50, 898{ 920. Forouzan, B. A. [2007], Data Communications and Networking, McGraw Hill. Haas, Z. and Pearlman, M. [1998], ?The performance of query control schemed for the zone routing protocol?, Proceedings of ACM SIGCOMM ?98 pp. 360{368. Haas, Z., Pearlman, M. and Samar, P. [2002a], ?The interzone routing protocol (ierp) for ad hoc networks?, Internet Engineering Task Force (IETF) draft . Haas, Z., Pearlman, M. and Samar, P. [2002b], ?The intrazone routing protocol (iarp) for ad hoc networks?, Internet Engineering Task Force (IETF) draft . Haas, Z., Pearlman, M. and Samar, P. [2002c], ?The zone routing protocol (zrp) for ad hoc networks?, Internet Engineering Task Force (IETF) draft . Hofmann, P. [2006], ?Multihop radio access network (mran) protocol speci cation?, Internet Engineering Task Force (IETF) draft . IEEE [1979], Programs for Digital Signal Processing, IEEE Press. 154 IEEE [2007], Ieee standard for information technology-telecommunications and in- formation exchange between systems-local and metropolitan area networks-speci c requirements - part 11: Wireless lan medium access control (mac) and physical layer (phy) speci cations, Technical report, IEEE. Iwata, A., Chiang, C. C., Pei, G., Gerla, M. and Chen, T. W. [1999], ?Scalable routing strategies for ad hoc networks?, IEEE Journal on Selected Areas of Communications pp. 1369{1379. Jelger, C., Noel, T. and Frey, A. [2004], ?Gateway and address autocon guration for ipv6 ad hoc networks?, Internet Engineering Task Force (IETF) draft . Jeong, H., Oh, S., Kim, D., Park, J., Kim, H. and Toh, C. [2007], ?Passive du- plicate address detection for on-demand routing protocols?, Internet Engineering Task Force (IETF) draft . Jeong, J., Park, J., Kim, E., Jeong, H. and Kim, D. [2006], ?Ad hoc ip address autocon guration?, Internet Engineering Task Force (IETF) draft . Johansson, T. and Carr-Motyckova, L. [2005], ?Reducing interference in ad hoc net- works through topology control?, Proceedings of the ACM/SIGMOBILE Workshop on Foundations of Mobile Computing . Johnson, D. and Maltz, D. [1996], Dynamic Source Routing in Ad Hoc Wireless Net- works, Kluwer Academic Publishers, pp. 153{181. 155 Jubin, J. and Truong, T. [1987], Distributed algorithm for e cient and interference- free broadcasting in radio networks, in ?Proceedings of IEEE INFOCOM?87?, Vol. 3, pp. 21{32. Kamerman, A. and Erkocevic, N. [1997], ?Microwave oven interference on wireless lans operating in the 2.4 ghz ism band?, Personal, Indoor and Mobile Radio Com- munications 3, 1221{1227. Kim, H., Kim, S. C., Yu, M., Song, J. and Mah, P. [2007], ?Dap: Dynamic address assignment protocol in dap: Dynamic address assignment protocol in mobile ad-hoc networks?, IEEE International Symposium on consumer Electronics (ISCE) . Koltsidas, G., Dimitriadis, G. and Pavlidou, F. [2004], ?A performance study of the hsls routing algorithm for ad hoc networks?, Vehicular Technology Conference (VTC 2004) . Krunz, M., Muqattash, A. and Lee, S. [2004], ?Transmission power control in wireless ad hoc networks: Challenges, solutions, and open issues?, IEEE Network pp. 8{14. Lee, D., Yoo, J., Kang, H., Kim, K. and Kang, K. [2006], ?Distributed ipv6 addressing technique for mobile ad-hoc networks?, ACM SAC . Lee, S. J. and Gerla, M. [2000], Aodv-br: Backup routing in ad hoc networks, in ?Proceedings of the IEEE, Wireless Communications and Networking Conference 2000 (WCNC 2000)?, Vol. 3, pp. 1311{1316. 156 Lee, S. J. and Gerla, M. [2001], ?Split multipath routing with maxmimally disjoint paths in ad hoc networks?, Proceedings of the IEEE International Conference on Communications 2001 (ICC 2001) 10. Mase, K. and Adjih, C. [2006], ?No overhead autocon guration olsr?, Internet Engi- neering Task Force (IETF) draft . MathWorks [2009], ?Signal processing toolbox: Interpolation?, http://www.mathworks.com. Mohsin, M. and Prakash, R. [2002], ?Ip address assignment in a mobile ad hoc net- work?, IEEE MILCOM . Murthy, S. and Garcia-Luna-Aceves, J. J. [1996], ?An e cient routing protocol for wireless networks?, ACM Mobile Networks and Applications Journals pp. 183{197. Nasipuri, A. and Das, S. R. [1999], On-demand multipath routing for mobile ad hoc networks, in ?Proceedings of Eighth International Conference on Computer Communications and Networks?, pp. 64{70. Nesargi, S. and Prakash, R. [2002], ?Manetconf: Con guration of hosts in a mobile ad hoc network?, Proceedings of IEEE INFOCOM . Ogier, R., Templin, F. and Lewis, M. [2004], Topology dissemination based on reverse- path forwarding (tbrpf), Technical report, Internet Engineering Task Force (IETF). 157 Park, V. D. and Corson, M. S. [1997], ?A highly adaptive distributed routing algorithm for mobile and wireless networks?, Proceedings of the IEEE INFOCOM?97 pp. 103{ 112. Park, V. D. and Corson, M. S. [2001], ?Temporally-ordered routing algorithm (tora) version 1 functional speci cation?, Internet Engineering Task Force (IETF) draft . Pei, G., Gerla, M. and Hong, X. [2000], ?Lanmar: Landmark routing for large scale wireless ad hoc networks with group mobility?, ACM MobiHoc . Pei, G., Gerla, M. and wei Chen, T. [2000], Fisheye state routing: A routing scheme for ad hoc wireless networks, in ?IEEE INFOCOM?, pp. 70{74. Perkins, C. and Belding-Royer, E. [1999], ?Ad hoc on-demand distance vector (aodv) routing?, IEEE Workshop on Mobile Computing Systems and Applications . Perkins, C. E., Belding-Royer, E. M. and Das, S. R. [2002], ?Ad hoc on-demand distance vector (aodv) routing?, Internet Engineering Task Force (IETF) draft . Perkins, C. E. and Bhagwat, P. [1994], ?Highly dynamic destination-sequenced distance-vector routing (dsdv) for mobile computers?, Computer Communications Review pp. 234{244. Pietikainen, K., Silvennoinen, A., Hall, M. and Haggman, S.-G. [2005], ?Ieee 802.11g tolerance to narrowband jamming?, Military Communications Journal . 158 Ros, F. and Ruiz, P. [2006], ?Extensible manet auto-con guration protocol (emap)?, Internet Engineering Task Force (IETF) draft . Royer, E. and Toh, C. [1999], A review of current routing protocols for ad hoc mobile wireless networks, in ?IEEE Personal Communications?, Vol. 7, IEEE, pp. 46{55. Ru no, S. and Stupar, P. [2006], ?Automatic con guration of ipv6 addresses for nodes in a manet with multiple gateways?, Internet Engineering Task Force (IETF) draft . Santivanez, C. A., Mcdonald, B., Stavrakakis, I. and Ramanathan, R. [2002], On the scalability of ad hoc routing protocols, in ?IEEE Conference on Computer Communications (INFOCOM)?, IEEE. Santivanez, C. A., Ramanathan, R. and Stavrakakis, I. [2001], ?Making link-state routing scale for ad hoc networks?, Proceedings of the ACM International Sympo- sium on Mobile Ad Hoc Networking and Computing . Santivanez, C. and Ramanathan, R. [2003], Hazy sighted link state (hsls) routing: A scalable link state algorithm, Technical report, BBN Technologies, Cambridge, MA. Sun, Y. and Belding-Royer, E. M. [2003], Dynamic address con guration in mobile ad hoc networks, Technical Report 2003-11, University of California - Santa Barbara, Santa Barbara, CA. 159 Taher, T. M., Al-Banna, A. Z., Ucci, D. R. and LoCicero, J. L. [2006], ?Characteriza- tion of an unintentional wi- interference device: the residential microwave oven?, Military Communications Journal pp. 1{7. Taher, T. M., Misurac, M. J., LoCicero, J. L. and Ucci, D. R. [2008], ?Microwave oven signal interference mitigation for wi- communication systems?, Consumer Communications and Networking Conference (CCNC) 10, 67{68. Tan, H. and Seah, W. [2005], ?Dynamic topology control to reduce interference in manets?, Proceedings of Second International Conference on Mobile Computing and Ubiquitous Networking . Tang, J., Xue, G., Chandler, C. and Zhang, W. [2005], ?Interference-aware routing in multihop wirelesss networks using directional antennas?, Proceedings of IEEE INFOCOM . Tayal, A. P. and Patnaik, L. M. [2004], ?An address assignment for the automatic con- guration of mobile ad hoc networks?, Personal and Ubiquitous Computing 8, 47{54. Templin, F., Russert, S. and Chakeres, I. [2006], ?Manet autocon guration using dhcp?, Internet Engineering Task Force (IETF) draft . Toh, C. K. [1997], ?Associativity-based routing for ad-hoc networks?, Wireless Per- sonal Communications Journal, Special Issue on Mobile Networking and Computing Systems 4, 103{139. 160 Tonnesen, A. [2009], ?olsrd: an ad-hoc wireless mesh routing daemon?, http://www.olsr.org/. Tseng, Y.-C., Ni, S.-Y., Chen, Y.-S. and Shieu, J.-P. [2002], The broadcast storm problem in a mobile ad hoc network, in ?Wireless Networks?, Vol. 8, Kluwer Aca- demic Publishers, pp. 153{167. Vaidya, N. H. [2002], Weak duplicate address detection in mobile ad hoc networks, in ?The ACM International Symposium on Mobile Ad Hoc Networking and Computing (MOBIHOC)?, ACM. Valera, A., Seah, W. K. G. and Rao, S. [2003], ?Cooperative packet caching and shortest multipath routing in mobile ad hoc networks?, IEEE INFOCOM pp. 260{ 269. Wang, C.-Y., Li, C.-Y., Hwang, R.-H. and Chen, Y.-S. [2005], ?Global connectiv- ity for mobile ipv6-based ad hoc networks?, Proceedings of the 19th International Conference on Advanced Information Networking and Applications (AINA) . Weniger, K. [2003], ?Passive duplicate address detection in mobile ad hoc networks?, Proceedings of IEEE WCNC . Weniger, K. [2005], ?Pacman: Passive autocon guration for mobile ad hoc networks?, IEEE JSAC, Special Issue on Wireless Ad Hoc Networks . Weniger, K. and Mase, K. [2006], ?Pdad-olsr: Passive duplicate address detection for olsr?, Internet Engineering Task Force (IETF) draft . 161 Weniger, K. and Zitterbart, M. [2002], Ipv6 autocon guration in large scale mobile ad-hoc networks, in ?In Proceedings of European Wireless 2002?, pp. 142{148. Weniger, K. and Zitterbart, M. [2004], ?Address autocon guration in mobile ad hoc networks: Current approaches and future directions?, IEEE Network pp. 6{11. Yao, Z., Jiang, J., Fan, P., Cao, Z. and Li, V. O. [2003], ?A neighbor-table-based multi- path routing in ad hoc networks?, The 57th IEEE Semiannual Vehicular Technology Conference (VTC 2003) . Yao, Z., Ma, Z. and Cao, Z. [2003], ?A multipath routing scheme combating with frequent topology changes in wireless ad hoc networks?, Proceedings of the Interna- tional Conference in Communication Technology 2003 (ICCT 2003) pp. 1250{1253. Zhang, X., Liu, Q., Shi, D., Liu, Y. and Yu, X. [2007], An average link interference- aware routing protocol for mobile ad hoc networks, in ?Proceedings of the Third International Conference on Wireless and Mobile Communications (ICWMC?07)?, IEEE, pp. 10{16. Zhou, H., Ni, L. M. and Mutka, M. W. [2003], ?Prophet address allocation for large scale manets?, Proceedings of IEEE INFOCOM 2, 1304{1311. 162 Appendices 163 Appendix A USRP Command and Control GUI Screenshots 164 Figure A.1: USRP Command and Con trol GUI Screenshot 1 165 Figure A.2: USRP Command and Con trol GUI Screenshot 2 166 Figure A.3: USRP Command and Con trol GUI Screenshot 3 167 Figure A.4: USRP Command and Con trol GUI Screenshot 4 168 Figure A.5: USRP Command and Con trol GUI Screenshot 5 169 Figure A.6: USRP Command and Con trol GUI Screenshot 6 170 Appendix B Phase III Diagrams 171 Figure B.1: Pure OLSR With Noise Diagram 172 Figure B.2: BBC-OLSR With Noise Diagram 173 Appendix C Source Code Listing C.1 USRP C2 GUI and Data-Link Layer 1 #!/ usr/bin/env python 2 # coding : <> 3 # 4 # Mark Kuhr 5 # USRP GUI Control Application 6 # 7 8 import wxversion 9 wxversion . select (" 2.8 ") 10 import wx, wx. html 11 import sys 12 import os 13 import time 14 import struct 15 from fcntl import ioctl 16 import array 17 import threading 18 import subprocess 19 import re 20 import packet 21 import random 22 23 #unique identifiers for varous elements 24 ID UPDATE USB0A=0 25 ID UPDATE USB0B=1 26 ID UPDATE USB1A=2 27 ID UPDATE USB1B=3 28 ID UPDATE VIRT1=260 29 ID UPDATE VIRT2=261 30 ID UPDATE VIRT3=262 31 ID UPDATE VIRT4=263 32 ID UPDATE VIRT5=264 33 ID UPDATE VIRT6=265 34 35 ID RADIO USB0A=4 36 ID RADIO USB0B=5 174 37 ID RADIO USB1A=6 38 ID RADIO USB1B=7 39 ID LOGWIN USB0A=8 40 ID LOGWIN USB0B=9 41 ID LOGWIN USB1A=10 42 ID LOGWIN USB1B=11 43 44 ID TXRX USB0A=12 45 ID TXRX USB0B=13 46 ID TXRX USB1A=14 47 ID TXRX USB1B=15 48 ID TXRX VIRT1=266 49 ID TXRX VIRT2=267 50 ID TXRX VIRT3=268 51 ID TXRX VIRT4=269 52 ID TXRX VIRT5=270 53 ID TXRX VIRT6=271 54 55 ID SRC NAME USB0A=16 56 ID SRC NAME USB0B=17 57 ID SRC NAME USB1A=18 58 ID SRC NAME USB1B=19 59 SRC ID USB0A=20 60 SRC ID USB0B=21 61 SRC ID USB1A=22 62 SRC ID USB1B=23 63 ID MSG BITS USB0A=24 64 ID MSG BITS USB0B=25 65 ID MSG BITS USB1A=26 66 ID MSG BITS USB1B=27 67 ID RAND BITS USB0A=28 68 ID RAND BITS USB0B=29 69 ID RAND BITS USB1A=30 70 ID RAND BITS USB1B=31 71 ID CLAMP BITS USB0A=32 72 ID CLAMP BITS USB0B=33 73 ID CLAMP BITS USB1A=34 74 ID CLAMP BITS USB1B=35 75 ID FRAG BITS USB0A=36 76 ID FRAG BITS USB0B=37 77 ID FRAG BITS USB1A=38 78 ID FRAG BITS USB1B=39 79 ID STOP BITS USB0A=40 80 ID STOP BITS USB0B=41 81 ID STOP BITS USB1A=42 175 82 ID STOP BITS USB1B=43 83 ID EXPANSION USB0A=44 84 ID EXPANSION USB0B=45 85 ID EXPANSION USB1A=46 86 ID EXPANSION USB1B=47 87 ID PKT LOAD USB0A=48 88 ID PKT LOAD USB0B=49 89 ID PKT LOAD USB1A=50 90 ID PKT LOAD USB1B=51 91 ID DECODE LIM USB0A=52 92 ID DECODE LIM USB0B=53 93 ID DECODE LIM USB1A=54 94 ID DECODE LIM USB1B=55 95 ID BUF PKT USB0A=56 96 ID BUF PKT USB0B=57 97 ID BUF PKT USB1A=58 98 ID BUF PKT USB1B=59 99 ID BUF LAMBDA USB0A=60 100 ID BUF LAMBDA USB0B=61 101 ID BUF LAMBDA USB1A=62 102 ID BUF LAMBDA USB1B=63 103 ID PKT RATE USB0A=64 104 ID PKT RATE USB0B=65 105 ID PKT RATE USB1A=66 106 ID PKT RATE USB1B=67 107 ID SAMPLES PER BIT USB0A=68 108 ID SAMPLES PER BIT USB0B=69 109 ID SAMPLES PER BIT USB1A=70 110 ID SAMPLES PER BIT USB1B=71 111 ID GAIN USB0A=72 112 ID GAIN USB0B=73 113 ID GAIN USB1A=74 114 ID GAIN USB1B=75 115 ID CHANNEL LOSS USB0A=76 116 ID CHANNEL LOSS USB0B=77 117 ID CHANNEL LOSS USB1A=78 118 ID CHANNEL LOSS USB1B=79 119 ID THRESHOLD PCT USB0A=80 120 ID THRESHOLD PCT USB0B=81 121 ID THRESHOLD PCT USB1A=82 122 ID THRESHOLD PCT USB1B=83 123 ID HYSTERESIS USB0A=84 124 ID HYSTERESIS USB0B=85 125 ID HYSTERESIS USB1A=86 126 ID HYSTERESIS USB1B=87 176 127 ID JITTER USB0A=88 128 ID JITTER USB0B=89 129 ID JITTER USB1A=90 130 ID JITTER USB1B=91 131 ID CUSHION PCT USB0A=92 132 ID CUSHION PCT USB0B=93 133 ID CUSHION PCT USB1A=94 134 ID CUSHION PCT USB1B=95 135 ID SINK NAME USB0A=96 136 ID SINK NAME USB0B=97 137 ID SINK NAME USB1A=98 138 ID SINK NAME USB1B=99 139 ID SINK SAMPLE LIM USB0A=100 140 ID SINK SAMPLE LIM USB0B=101 141 ID SINK SAMPLE LIM USB1A=102 142 ID SINK SAMPLE LIM USB1B=103 143 144 ID START USB0A=104 145 ID START USB0B=105 146 ID START USB1A=106 147 ID START USB1B=107 148 ID START VIRT1=280 149 ID START VIRT2=281 150 ID START VIRT3=282 151 ID START VIRT4=283 152 ID START VIRT5=284 153 ID START VIRT6=285 154 155 ID PROCESS 1=108 156 ID PROCESS 2=109 157 ID PROCESS 3=110 158 ID PROCESS 4=111 159 ID PROCESS 5=248 160 ID PROCESS 6=249 161 ID PROCESS 7=250 162 ID PROCESS 8=251 163 ID PROCESS 9=252 164 ID PROCESS 10=253 165 166 ID STOP USB0A=112 167 ID STOP USB0B=113 168 ID STOP USB1A=114 169 ID STOP USB1B=115 170 ID STOP VIRT1=254 171 ID STOP VIRT2=255 177 172 ID STOP VIRT3=256 173 ID STOP VIRT4=257 174 ID STOP VIRT5=258 175 ID STOP VIRT6=259 176 177 ID PROCESS ENC 1=116 178 ID PROCESS ENC 2=117 179 ID PROCESS ENC 3=118 180 ID PROCESS ENC 4=119 181 ID PROCESS ENC 5=200 182 ID PROCESS ENC 6=201 183 ID PROCESS ENC 7=202 184 ID PROCESS ENC 8=203 185 ID PROCESS ENC 9=204 186 ID PROCESS ENC 10=205 187 188 ID PROCESS DEC 1=120 189 ID PROCESS DEC 2=121 190 ID PROCESS DEC 3=122 191 ID PROCESS DEC 4=123 192 ID PROCESS DEC 5=206 193 ID PROCESS DEC 6=207 194 ID PROCESS DEC 7=208 195 ID PROCESS DEC 8=209 196 ID PROCESS DEC 9=210 197 ID PROCESS DEC 10=211 198 199 ID RECIPIENT USB0A=124 200 ID RECIPIENT USB0B=125 201 ID RECIPIENT USB1A=126 202 ID RECIPIENT USB1B=127 203 ID RECIPIENT VIRT1=212 204 ID RECIPIENT VIRT2=213 205 ID RECIPIENT VIRT3=214 206 ID RECIPIENT VIRT4=215 207 ID RECIPIENT VIRT5=216 208 ID RECIPIENT VIRT6=217 209 210 ID PRINT RX QUEUE USB0A=128 211 ID PRINT RX QUEUE USB0B=129 212 ID PRINT RX QUEUE USB1A=130 213 ID PRINT RX QUEUE USB1B=131 214 ID PRINT RX QUEUE VIRT1=218 215 ID PRINT RX QUEUE VIRT2=219 216 ID PRINT RX QUEUE VIRT3=220 178 217 ID PRINT RX QUEUE VIRT4=221 218 ID PRINT RX QUEUE VIRT5=222 219 ID PRINT RX QUEUE VIRT6=223 220 221 ID PRINT TX QUEUE USB0A=132 222 ID PRINT TX QUEUE USB0B=133 223 ID PRINT TX QUEUE USB1A=134 224 ID PRINT TX QUEUE USB1B=135 225 ID PRINT TX QUEUE VIRT1=224 226 ID PRINT TX QUEUE VIRT2=225 227 ID PRINT TX QUEUE VIRT3=226 228 ID PRINT TX QUEUE VIRT4=227 229 ID PRINT TX QUEUE VIRT5=228 230 ID PRINT TX QUEUE VIRT6=229 231 232 ID PRINT RX QUEUE HISTORICAL USB0A=136 233 ID PRINT RX QUEUE HISTORICAL USB0B=137 234 ID PRINT RX QUEUE HISTORICAL USB1A=138 235 ID PRINT RX QUEUE HISTORICAL USB1B=139 236 ID PRINT RX QUEUE HISTORICAL VIRT1=230 237 ID PRINT RX QUEUE HISTORICAL VIRT2=231 238 ID PRINT RX QUEUE HISTORICAL VIRT3=232 239 ID PRINT RX QUEUE HISTORICAL VIRT4=233 240 ID PRINT RX QUEUE HISTORICAL VIRT5=234 241 ID PRINT RX QUEUE HISTORICAL VIRT6=235 242 243 ID PRINT TX QUEUE HISTORICAL USB0A=140 244 ID PRINT TX QUEUE HISTORICAL USB0B=141 245 ID PRINT TX QUEUE HISTORICAL USB1A=142 246 ID PRINT TX QUEUE HISTORICAL USB1B=143 247 ID PRINT TX QUEUE HISTORICAL VIRT1=236 248 ID PRINT TX QUEUE HISTORICAL VIRT2=237 249 ID PRINT TX QUEUE HISTORICAL VIRT3=238 250 ID PRINT TX QUEUE HISTORICAL VIRT4=239 251 ID PRINT TX QUEUE HISTORICAL VIRT5=240 252 ID PRINT TX QUEUE HISTORICAL VIRT6=241 253 254 ID CLEAR LOGWIN ALL=144 255 ID CLEAR LOGWIN 1=145 256 ID CLEAR LOGWIN 2=146 257 ID CLEAR LOGWIN 3=147 258 ID CLEAR LOGWIN 4=148 259 ID CLEAR LOGWIN 5=242 260 ID CLEAR LOGWIN 6=243 261 ID CLEAR LOGWIN 7=244 179 262 ID CLEAR LOGWIN 8=245 263 ID CLEAR LOGWIN 9=246 264 ID CLEAR LOGWIN 10=247 265 266 ID RESET=149 267 ID ABOUT=150 268 ID EXIT=151 269 ID WAIT PROCESS=152 270 271 ID PROCESS OLSR 1=153 #real interface 272 ID PROCESS OLSR 2=154 #real interface 273 ID PROCESS OLSR 3=155 #real interface 274 ID PROCESS OLSR 4=156 #real interface 275 ID PROCESS OLSR 5=157 #virtual interface 276 ID PROCESS OLSR 6=158 #virtual interface 277 ID PROCESS OLSR 7=159 #virtual interface 278 ID PROCESS OLSR 8=160 #virtual interface 279 ID PROCESS OLSR 9=161 #virtual interface 280 ID PROCESS OLSR 10=162#virtual interface 281 282 ID VIEW OLSR 1=163 #virtual interface viewer 283 ID VIEW OLSR 2=164 #virtual interface viewer 284 ID VIEW OLSR 3=165 #virtual interface viewer 285 ID VIEW OLSR 4=166 #virtual interface viewer 286 ID VIEW OLSR 5=167 #virtual interface viewer 287 ID VIEW OLSR 6=168 #virtual interface viewer 288 289 ID VIEW TABLE USRP0A = 270 290 ID VIEW TABLE USRP0B = 271 291 ID VIEW TABLE USRP1A = 272 292 ID VIEW TABLE USRP1B = 273 293 ID VIEW TABLE VIRT1 = 274 294 ID VIEW TABLE VIRT2 = 275 295 ID VIEW TABLE VIRT3 = 276 296 ID VIEW TABLE VIRT4 = 277 297 ID VIEW TABLE VIRT5 = 278 298 ID VIEW TABLE VIRT6 = 279 299 300 #OLSR SUPPORT FUNCTIONS 301 #SUPPORT FOR ETHERNET AND IP DATAGRAMS 302 #DEVELOPED WITH SUPPORT OF D. SANDERS. 303 304 experiment path = "/ Users / marker / Desktop / sdr /" 305 306 class ethernet frame : 180 307 def init ( self , raw frame) : 308 self . raw frame = raw frame 309 self . dest addr = raw frame [ : 6 ] . encode(" hex ") 310 self . src addr = raw frame [6:12]. encode(" hex ") 311 #tmp = struct . unpack("H", raw frame [12:14]) 312 self . type = raw frame [12:14]. encode(" hex ") #tmp[0] 313 self . datagram = None 314 if self . type == " 0800 " : 315 self . datagram = ip datagram(raw frame [14:]) 316 else : 317 self . datagram = raw frame [14:] 318 319 def toString ( self ) : 320 return self . dest addr+" "+self . src addr+" "+self . type 321 322 def repr ( self ) : 323 if self . type== " 0800 " : 324 s = self . toString () + "\n" + self . datagram . toString () 325 else : 326 s = self . toString () + "\n" + self . datagram 327 return s 328 329 class ip datagram : 330 def init ( self , raw dg) : 331 self . raw dg = raw dg 332 self . ver hlen = raw dg [ : 1 ] . encode(" hex ") 333 self . version = self . ver hlen [:1] 334 self . hlen = self . ver hlen [1:] 335 self . service = raw dg [1:2]. encode(" hex ") 336 self . total length = raw dg [2:4]. encode(" hex ") 337 self . id = raw dg [4:6]. encode(" hex ") 338 self . flags fragmentation = raw dg [6:8]. encode(" hex ") 339 self . ttl = raw dg [8:9]. encode(" hex ") 340 self . protocol = raw dg [9:10]. encode(" hex ") 341 self . hd checksum = raw dg [10:12]. encode(" hex ") 342 self . sourceip = raw dg [12:16]. encode(" hex ") 343 self . destip = raw dg [16:20]. encode(" hex ") 344 tmp = struct . unpack("B" , self . hlen) 345 self . option = None 346 if tmp[0] > 20: 347 self . option = raw dg [20:tmp [ 0 ] ] . encode(" hex ") 348 self . packet = None 349 #if self . protocol == "0011": 350 self . packet = udp packet(raw dg [tmp [ 0 ] : ] ) 351 #elif self . protocol == "0006": 181 352 # self . packet = tcp packet (raw dg [tmp [ 0 ] : ] ) 353 #elif self . protocol == "0001": 354 # self . packet = icmp packet(raw dg [tmp [ 0 ] : ] ) 355 #elif self . protocol == "0002": 356 # self . packet = igmp packet(raw dg [tmp [ 0 ] : ] ) 357 358 def toString ( self ) : 359 s = " " . join (( self . version , self . hlen , self . service , self . total length )) 360 s+=?\n ? 361 s+= " " . join (( self . id , self . flags fragmentation )) 362 s+=?\n ? 363 s+= " " . join (( self . ttl , self . protocol , self . hd checksum)) 364 s+=?\n ? 365 s+=self . sourceip 366 s+=?\n ? 367 s+=self . destip 368 return s + "\n" + self . packet . toString () 369 370 class tcp packet : 371 def init ( self , raw packet) : 372 self . raw packet = raw packet 373 374 def toStringt ( self ) : 375 return self . raw packet . encode(" hex ") 376 377 class udp packet : 378 def init ( self , raw packet) : 379 self . raw packet = raw packet 380 381 def toString ( self ) : 382 return self . raw packet . encode(" hex ") 383 384 class icmp packet : 385 def init ( self , raw packet) : 386 self . raw packet = raw packet 387 388 class igmp packet : 389 def init ( self , raw packet) : 390 self . raw packet = raw packet 391 392 393 394 ############################################ 395 ## TAP INTERFACE OPEN & CONFIGURE GLOBAL ## 396 ############################################ 182 397 398 class tap device ( threading . Thread) : 399 def init ( self , device , address ) : 400 self . running = 1 401 self . device = device 402 self . tap fd = os . open("/ dev /"+device , os .ORDWR) 403 404 #print self . tap fd 405 subprocess .Popen([ r" ifconfig " ,device , address ]) . wait () 406 threading . Thread. init ( self ) 407 408 def run( self ) : 409 while self . running : 410 #read from tap device 411 count = 10 412 payload bundle="" 413 payload stack = [] 414 415 #bundle packets into groups of 10 416 while(count >= 0) : 417 payload = os . read( self . tap fd , 1500) 418 payload stack . append(payload) 419 count = count 1 420 421 #setup local path for file prior to transmission 422 file = open(experiment path+self . device to radio id ( self . device )+"/ pkt_ "+ self . device+ "_"+str (time . time () )+". pcap " , "w") 423 424 #write pkt to file to be source of USRP TX 425 #file . write (payload) 426 427 while( len ( payload stack )>0): 428 current payload = payload stack .pop() 429 file . write ( current payload ) 430 os . write ( self . tap fd , current payload ) 431 432 #print str (time . time () )+" Received frame on ", self . device 433 #frame = ethernet frame (payload) 434 #print frame 435 #print "nn" 436 437 #print "Sending Ethernet Frame:" , frame . raw frame . encode("hex") 438 439 #write frame to specific tap device for testing 440 #os . write ( self . tap fd , payload)#frame . raw frame) 183 441 442 #not running anymore , close this file descriptor 443 self . close () 444 445 def device to radio id ( self , device ) : 446 if ( device==" tap0 ") : 447 return " usrp0A " 448 elif ( device==" tap1 ") : 449 return " usrp0B " 450 elif ( device==" tap2 ") : 451 return " usrp1A " 452 elif ( device==" tap3 ") : 453 return " usrp1B " 454 #virtual nodes 455 elif ( device==" tap4 ") : 456 return " virt1 " 457 elif ( device==" tap5 ") : 458 return " virt2 " 459 elif ( device==" tap6 ") : 460 return " virt3 " 461 elif ( device==" tap7 ") : 462 return " virt4 " 463 elif ( device==" tap8 ") : 464 return " virt5 " 465 elif ( device==" tap9 ") : 466 return " virt6 " 467 else : return "" #should never occur 468 469 470 def stop( self ) : 471 self . running = 0 472 #self . close () 473 474 def close ( self ) : 475 os . close ( self . tap fd ) 476 477 478 ###################### 479 ## BEGIN MAIN FRAME ## 480 ###################### 481 482 class Frame(wx.Frame) : 483 def init ( self , title ) : 484 wx.Frame. init ( self , None, title=title , pos=(20,20) , size =(1400,900)) 485 184 486 self . experiment path = "/ Users / marker / Desktop / sdr /" 487 #self . experiment path = "/home/mark/Desktop/sdr/" 488 #this is not sychronized with in range nodes 489 self . recipients=[? All ? , ? usrp0A ? , ? usrp0B ? , ? usrp1A ? , ? usrp1B ? , ? virt1 ? , ? virt2 ? , ? virt3 ? , ? virt4 ? , ? virt5 ? , ? virt6 ? ] 490 self . transmission mode = [ ?TX ? , ?RX ? ] 491 self .Bind(wx.EVT CLOSE, self . OnClose) 492 self . rssi = 0 493 494 #10 tap devices for bbc olsr daemons 495 self . tap0 = None #for real node usrp0A 496 self . tap1 = None #for real node usrp0B 497 self . tap2 = None #for real node usrp1A 498 self . tap3 = None #for real node usrp1B 499 self . tap4 = None #virtual node 1 500 self . tap5 = None #virtual node 2 501 self . tap6 = None #virtual node 3 502 self . tap7 = None #virtual node 4 503 self . tap8 = None #virtual node 5 504 self . tap9 = None #virtual node 6 505 506 self . txt cmd = "" 507 508 self . nat table = None #table for Layer3 to Layer2 address mappings 509 510 #current abridged route tables (addr : rssi ) 511 #used for testing 512 self . usrp0A table = None 513 self . usrp0B table = None 514 self . usrp1A table = None 515 self . usrp1B table = None 516 self . virt1 table = None 517 self . virt2 table = None 518 self . virt3 table = None 519 self . virt4 table = None 520 self . virt5 table = None 521 self . virt6 table = None 522 523 #has node been killed by action? 524 self . kill 0A=False 525 self . kill 0B=False 526 self . kill 1A=False 527 self . kill 1B=False 528 self . kill virt1=False 529 self . kill virt2=False 185 530 self . kill virt3=False 531 self . kill virt4=False 532 self . kill virt5=False 533 self . kill virt6=False 534 535 #must interleave 536 self . dual rx 0 = False 537 self . dual rx 1 = False 538 539 #virtual node modes (rx or tx) 540 self . rxtx virt1 = " RX " #initial mode 541 self . rxtx virt2 = " RX " 542 self . rxtx virt3 = " RX " 543 self . rxtx virt4 = " RX " 544 self . rxtx virt5 = " RX " 545 self . rxtx virt6 = " RX " 546 547 #define processes for each daughterboard 548 self . process usb0A = None 549 self . process usb0B = None 550 self . process usb1A = None 551 self . process usb1B = None 552 #define processes for each virtual node 553 self . process virt1 = None 554 self . process virt2 = None 555 self . process virt3 = None 556 self . process virt4 = None 557 self . process virt5 = None 558 self . process virt6 = None 559 #define process for encoding for each daughterboard 560 self . encode process usb0A = None 561 self . encode process usb0B = None 562 self . encode process usb1A = None 563 self . encode process usb1B = None 564 #define process for encoding for each virtual node 565 self . encode process virt1 = None 566 self . encode process virt2 = None 567 self . encode process virt3 = None 568 self . encode process virt4 = None 569 self . encode process virt5 = None 570 self . encode process virt6 = None 571 #encode cmd var 572 self . encode cmd = "" 573 #define process for decoding for each daughterboard 574 self . decode process usb0A = None 186 575 self . decode process usb0B = None 576 self . decode process usb1A = None 577 self . decode process usb1B = None 578 #define process for decoding for each virtual node 579 self . decode process virt1 = None 580 self . decode process virt2 = None 581 self . decode process virt3 = None 582 self . decode process virt4 = None 583 self . decode process virt5 = None 584 self . decode process virt6 = None 585 #decode cmd var 586 self . decode cmd = "" 587 #define bbc olsr processes for each daughterboard 588 self . olsr process usb0A = None 589 self . olsr process usb0B = None 590 self . olsr process usb1A = None 591 self . olsr process usb1B = None 592 #define virtual bbc olsr processes for each non hardware node 593 self . olsr process virt1 = None 594 self . olsr process virt2 = None 595 self . olsr process virt3 = None 596 self . olsr process virt4 = None 597 self . olsr process virt5 = None 598 self . olsr process virt6 = None 599 600 #define variables to store output of bbc olsr nodes not shown in Log Windows 601 self . olsr v1 output = "" 602 self . olsr v2 output = "" 603 self . olsr v3 output = "" 604 self . olsr v4 output = "" 605 self . olsr v5 output = "" 606 self . olsr v6 output = "" 607 #olsr cmd var 608 self . olsr cmd = "" 609 610 #define process id ?s 611 self . process id usb0A=0 612 self . process id usb0B=0 613 self . process id usb1A=0 614 self . process id usb1B=0 615 self . process id virt1=0 616 self . process id virt2=0 617 self . process id virt3=0 618 self . process id virt4=0 619 self . process id virt5=0 187 620 self . process id virt6=0 621 622 #define encode process id ?s 623 self . encode process id usb0A=0 624 self . encode process id usb0B=0 625 self . encode process id usb1A=0 626 self . encode process id usb1B=0 627 self . encode process id virt1=0 628 self . encode process id virt2=0 629 self . encode process id virt3=0 630 self . encode process id virt4=0 631 self . encode process id virt5=0 632 self . encode process id virt6=0 633 #define decode process id ?s 634 self . decode process id usb0A=0 635 self . decode process id usb0B=0 636 self . decode process id usb1A=0 637 self . decode process id usb1B=0 638 self . decode process id virt1=0 639 self . decode process id virt2=0 640 self . decode process id virt3=0 641 self . decode process id virt4=0 642 self . decode process id virt5=0 643 self . decode process id virt6=0 644 645 #define process id for bbc olsr for each daughterboard 646 self . olsr process id usb0A=0 647 self . olsr process id usb0B=0 648 self . olsr process id usb1A=0 649 self . olsr process id usb1B=0 650 #define process id for bbc olsrd virtual processes 651 self . olsr process id v1=0 652 self . olsr process id v2=0 653 self . olsr process id v3=0 654 self . olsr process id v4=0 655 self . olsr process id v5=0 656 self . olsr process id v6=0 657 658 #define pkt queues for each radio 659 #define rx packet queue for each radio 660 self . rx pkt queue usrp0A =[] 661 self . rx pkt queue usrp0B =[] 662 self . rx pkt queue usrp1A =[] 663 self . rx pkt queue usrp1B =[] 664 self . rx pkt queue virt1 =[] 188 665 self . rx pkt queue virt2 =[] 666 self . rx pkt queue virt3 =[] 667 self . rx pkt queue virt4 =[] 668 self . rx pkt queue virt5 =[] 669 self . rx pkt queue virt6 =[] 670 671 #define tx packet queue for each radio 672 self . tx pkt queue usrp0A =[] 673 self . tx pkt queue usrp0B =[] 674 self . tx pkt queue usrp1A =[] 675 self . tx pkt queue usrp1B =[] 676 self . tx pkt queue virt1 =[] 677 self . tx pkt queue virt2 =[] 678 self . tx pkt queue virt3 =[] 679 self . tx pkt queue virt4 =[] 680 self . tx pkt queue virt5 =[] 681 self . tx pkt queue virt6 =[] 682 #define historical pkt queues for each radio (to be used for analysis ) 683 #define historical rx queues for each radio 684 self . rx pkt queue historical usrp0A =[] 685 self . rx pkt queue historical usrp0B =[] 686 self . rx pkt queue historical usrp1A =[] 687 self . rx pkt queue historical usrp1B =[] 688 self . rx pkt queue historical virt1 =[] 689 self . rx pkt queue historical virt2 =[] 690 self . rx pkt queue historical virt3 =[] 691 self . rx pkt queue historical virt4 =[] 692 self . rx pkt queue historical virt5 =[] 693 self . rx pkt queue historical virt6 =[] 694 #define historical tx queues for each radio 695 self . tx pkt queue historical usrp0A =[] 696 self . tx pkt queue historical usrp0B =[] 697 self . tx pkt queue historical usrp1A =[] 698 self . tx pkt queue historical usrp1B =[] 699 self . tx pkt queue historical virt1 =[] 700 self . tx pkt queue historical virt2 =[] 701 self . tx pkt queue historical virt3 =[] 702 self . tx pkt queue historical virt4 =[] 703 self . tx pkt queue historical virt5 =[] 704 self . tx pkt queue historical virt6 =[] 705 706 707 menuBar = wx.MenuBar() 708 menu = wx.Menu() 709 m clear win1 = menu.Append(ID CLEAR LOGWIN 1, " Clear Log 1" , " Clear Log Window 1") 189 710 m clear win2 = menu.Append(ID CLEAR LOGWIN 2, " Clear Log 2" , " Clear Log Window 2") 711 m clear win3 = menu.Append(ID CLEAR LOGWIN 3, " Clear Log 3" , " Clear Log Window 3") 712 m clear win4 = menu.Append(ID CLEAR LOGWIN 4, " Clear Log 4" , " Clear Log Window 4") 713 m clear win5 = menu.Append(ID CLEAR LOGWIN 5, " Clear Log 5" , " Clear Log Window 5") 714 m clear win6 = menu.Append(ID CLEAR LOGWIN 6, " Clear Log 6" , " Clear Log Window 6") 715 m clear win7 = menu.Append(ID CLEAR LOGWIN 7, " Clear Log 7" , " Clear Log Window 7") 716 m clear win8 = menu.Append(ID CLEAR LOGWIN 8, " Clear Log 8" , " Clear Log Window 8") 717 m clear win9 = menu.Append(ID CLEAR LOGWIN 9, " Clear Log 9" , " Clear Log Window 9") 718 m clear win10 = menu.Append(ID CLEAR LOGWIN 10, " Clear Log 10 " , " Clear Log Window 10 ") 719 m clear winAll = menu.Append(ID CLEAR LOGWIN ALL, " Clear All Logs " , " Clear All Log Windows ") 720 721 m reset = menu.Append(ID RESET, " Reset Queues " , " Reset All TX / RX Queues .") 722 m about = menu.Append(ID ABOUT, " About " , " About this application .") 723 m exit = menu.Append(ID EXIT, "E& xit \ tAlt -X" , " Close window and exit program .") 724 725 menu2 = wx.Menu() 726 m rx0A = menu2.Append(ID PRINT RX QUEUE USB0A, " Print RX Packet Queue 0A" , " Print USRP0A RX Queue ") 727 m rx0B = menu2.Append(ID PRINT RX QUEUE USB0B, " Print RX Packet Queue 0B" , " Print USRP0B RX Queue ") 728 m rx1A = menu2.Append(ID PRINT RX QUEUE USB1A, " Print RX Packet Queue 1A" , " Print USRP1A RX Queue ") 729 m rx1B = menu2.Append(ID PRINT RX QUEUE USB1B, " Print RX Packet Queue 1B" , " Print USRP1B RX Queue ") 730 m rxv1 = menu2.Append(ID PRINT RX QUEUE VIRT1, " Print RX Packet Queue V1 " , " Print VIRT1 RX Queue ") 731 m rxv2 = menu2.Append(ID PRINT RX QUEUE VIRT2, " Print RX Packet Queue V2 " , " Print VIRT2 RX Queue ") 732 m rxv3 = menu2.Append(ID PRINT RX QUEUE VIRT3, " Print RX Packet Queue V3 " , " Print VIRT3 RX Queue ") 733 m rxv4 = menu2.Append(ID PRINT RX QUEUE VIRT4, " Print RX Packet Queue V4 " , " Print VIRT4 RX Queue ") 734 m rxv5 = menu2.Append(ID PRINT RX QUEUE VIRT5, " Print RX Packet Queue V5 " , " Print VIRT5 RX Queue ") 735 m rxv6 = menu2.Append(ID PRINT RX QUEUE VIRT6, " Print RX Packet Queue V6 " , " Print VIRT6 RX Queue ") 736 737 menu3 = wx.Menu() 738 m tx0A = menu3.Append(ID PRINT TX QUEUE USB0A, " Print TX Packet Queue 0A" , " Print USRP0A TX Queue ") 739 m tx0B = menu3.Append(ID PRINT TX QUEUE USB0B, " Print TX Packet Queue 0B" , " Print USRP0B TX Queue ") 740 m tx1A = menu3.Append(ID PRINT TX QUEUE USB1A, " Print TX Packet Queue 1A" , " Print USRP1A TX Queue ") 190 741 m tx1B = menu3.Append(ID PRINT TX QUEUE USB1B, " Print TX Packet Queue 1B" , " Print USRP1B TX Queue ") 742 m txv1 = menu3.Append(ID PRINT TX QUEUE VIRT1, " Print TX Packet Queue V1 " , " Print VIRT1 TX Queue ") 743 m txv2 = menu3.Append(ID PRINT TX QUEUE VIRT2, " Print TX Packet Queue V2 " , " Print VIRT2 TX Queue ") 744 m txv3 = menu3.Append(ID PRINT TX QUEUE VIRT3, " Print TX Packet Queue V3 " , " Print VIRT3 TX Queue ") 745 m txv4 = menu3.Append(ID PRINT TX QUEUE VIRT4, " Print TX Packet Queue V4 " , " Print VIRT4 TX Queue ") 746 m txv5 = menu3.Append(ID PRINT TX QUEUE VIRT5, " Print TX Packet Queue V5 " , " Print VIRT5 TX Queue ") 747 m txv6 = menu3.Append(ID PRINT TX QUEUE VIRT6, " Print TX Packet Queue V6 " , " Print VIRT6 TX Queue ") 748 749 menu4 = wx.Menu() 750 m rx hist 0A = menu4.Append(ID PRINT RX QUEUE HISTORICAL USB0A, " Print Historical RX Packet Queue 0A" , " Print USRP0A Historical RX Queue ") 751 m rx hist 0B = menu4.Append(ID PRINT RX QUEUE HISTORICAL USB0B, " Print Historical RX Packet Queue 0B" , " Print USRP0B Historical RX Queue ") 752 m rx hist 1A = menu4.Append(ID PRINT RX QUEUE HISTORICAL USB1A, " Print Historical RX Packet Queue 1A" , " Print USRP1A Historical RX Queue ") 753 m rx hist 1B = menu4.Append(ID PRINT RX QUEUE HISTORICAL USB1B, " Print Historical RX Packet Queue 1B" , " Print USRP1B Historical RX Queue ") 754 m rx hist v1 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT1, " Print Historical RX Packet Queue V1 " , " Print VIRT1 Historical RX Queue ") 755 m rx hist v2 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT2, " Print Historical RX Packet Queue V2 " , " Print VIRT2 Historical RX Queue ") 756 m rx hist v3 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT3, " Print Historical RX Packet Queue V3 " , " Print VIRT3 Historical RX Queue ") 757 m rx hist v4 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT4, " Print Historical RX Packet Queue V4 " , " Print VIRT4 Historical RX Queue ") 758 m rx hist v5 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT5, " Print Historical RX Packet Queue V5 " , " Print VIRT5 Historical RX Queue ") 759 m rx hist v6 = menu4.Append(ID PRINT RX QUEUE HISTORICAL VIRT6, " Print Historical RX Packet Queue V6 " , " Print VIRT6 Historical RX Queue ") 760 761 menu5 = wx.Menu() 762 m tx hist 0A = menu5.Append(ID PRINT TX QUEUE HISTORICAL USB0A, " Print Historical TX Packet Queue 0A" , " Print USRP0A Historical TX Queue ") 763 m tx hist 0B = menu5.Append(ID PRINT TX QUEUE HISTORICAL USB0B, " Print Historical TX Packet Queue 0B" , " Print USRP0B Historical TX Queue ") 764 m tx hist 1A = menu5.Append(ID PRINT TX QUEUE HISTORICAL USB1A, " Print Historical TX Packet Queue 1A" , " Print USRP1A Historical TX Queue ") 191 765 m tx hist 1B = menu5.Append(ID PRINT TX QUEUE HISTORICAL USB1B, " Print Historical TX Packet Queue 1B" , " Print USRP1B Historical TX Queue ") 766 m tx hist v1 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT1, " Print Historical TX Packet Queue V1 " , " Print VIRT1 Historical TX Queue ") 767 m tx hist v2 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT2, " Print Historical TX Packet Queue V2 " , " Print VIRT2 Historical TX Queue ") 768 m tx hist v3 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT3, " Print Historical TX Packet Queue V3 " , " Print VIRT3 Historical TX Queue ") 769 m tx hist v4 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT4, " Print Historical TX Packet Queue V4 " , " Print VIRT4 Historical TX Queue ") 770 m tx hist v5 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT5, " Print Historical TX Packet Queue V5 " , " Print VIRT5 Historical TX Queue ") 771 m tx hist v6 = menu5.Append(ID PRINT TX QUEUE HISTORICAL VIRT6, " Print Historical TX Packet Queue V6 " , " Print VIRT6 Historical TX Queue ") 772 773 menu6 = wx.Menu() 774 m olsr v1 = menu6.Append(ID VIEW OLSR 1, " View BBC - OLSR VIRT1 " , " View BBC - OLSR VIRT1 ") 775 m olsr v2 = menu6.Append(ID VIEW OLSR 2, " View BBC - OLSR VIRT2 " , " View BBC - OLSR VIRT2 ") 776 m olsr v3 = menu6.Append(ID VIEW OLSR 3, " View BBC - OLSR VIRT3 " , " View BBC - OLSR VIRT3 ") 777 m olsr v4 = menu6.Append(ID VIEW OLSR 4, " View BBC - OLSR VIRT4 " , " View BBC - OLSR VIRT4 ") 778 m olsr v5 = menu6.Append(ID VIEW OLSR 5, " View BBC - OLSR VIRT5 " , " View BBC - OLSR VIRT5 ") 779 m olsr v6 = menu6.Append(ID VIEW OLSR 6, " View BBC - OLSR VIRT6 " , " View BBC - OLSR VIRT6 ") 780 781 menu7 = wx.Menu() 782 m usrp0A table = menu7.Append(ID VIEW TABLE USRP0A, " View Table USRP0A " , " View Table USRP0A ") 783 m usrp0B table = menu7.Append(ID VIEW TABLE USRP0B, " View Table USRP0B " , " View Table USRP0B ") 784 m usrp1A table = menu7.Append(ID VIEW TABLE USRP1A, " View Table USRP1A " , " View Table USRP1A ") 785 m usrp1B table = menu7.Append(ID VIEW TABLE USRP1B, " View Table USRP1B " , " View Table USRP1B ") 786 m virt1 table = menu7.Append(ID VIEW TABLE VIRT1, " View Table VIRT1 " , " View Table VIRT1 ") 787 m virt2 table = menu7.Append(ID VIEW TABLE VIRT2, " View Table VIRT2 " , " View Table VIRT2 ") 788 m virt3 table = menu7.Append(ID VIEW TABLE VIRT3, " View Table VIRT3 " , " View Table VIRT3 ") 789 m virt4 table = menu7.Append(ID VIEW TABLE VIRT4, " View Table VIRT4 " , " View Table VIRT4 ") 790 m virt5 table = menu7.Append(ID VIEW TABLE VIRT5, " View Table VIRT5 " , " View Table VIRT5 ") 791 m virt6 table = menu7.Append(ID VIEW TABLE VIRT6, " View Table VIRT6 " , " View Table VIRT6 ") 792 793 #bind events for File menu 794 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win1 ) 795 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win2 ) 796 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win3 ) 797 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win4 ) 798 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win5 ) 192 799 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win6 ) 800 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win7 ) 801 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win8 ) 802 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win9 ) 803 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear win10 ) 804 self .Bind(wx.EVTMENU, self .OnClearWindow , m clear winAll ) 805 self .Bind(wx.EVTMENU, self .OnResetQueue , m reset ) 806 self .Bind(wx.EVTMENU, self .OnAbout, m about) 807 self .Bind(wx.EVTMENU, self .OnClose , m exit) 808 #bind events for RX queue printing 809 self .Bind(wx.EVTMENU, self . printQueue , m rx0A) 810 self .Bind(wx.EVTMENU, self . printQueue , m rx0B) 811 self .Bind(wx.EVTMENU, self . printQueue , m rx1A) 812 self .Bind(wx.EVTMENU, self . printQueue , m rx1B) 813 self .Bind(wx.EVTMENU, self . printQueue , m rxv1) 814 self .Bind(wx.EVTMENU, self . printQueue , m rxv2) 815 self .Bind(wx.EVTMENU, self . printQueue , m rxv3) 816 self .Bind(wx.EVTMENU, self . printQueue , m rxv4) 817 self .Bind(wx.EVTMENU, self . printQueue , m rxv5) 818 self .Bind(wx.EVTMENU, self . printQueue , m rxv6) 819 #bind events for TX queue printing 820 self .Bind(wx.EVTMENU, self . printQueue , m tx0A) 821 self .Bind(wx.EVTMENU, self . printQueue , m tx0B) 822 self .Bind(wx.EVTMENU, self . printQueue , m tx1A) 823 self .Bind(wx.EVTMENU, self . printQueue , m tx1B) 824 self .Bind(wx.EVTMENU, self . printQueue , m txv1) 825 self .Bind(wx.EVTMENU, self . printQueue , m txv2) 826 self .Bind(wx.EVTMENU, self . printQueue , m txv3) 827 self .Bind(wx.EVTMENU, self . printQueue , m txv4) 828 self .Bind(wx.EVTMENU, self . printQueue , m txv5) 829 self .Bind(wx.EVTMENU, self . printQueue , m txv6) 830 #bind events for historical RX queue printing 831 self .Bind(wx.EVTMENU, self . printQueue , m rx hist 0A ) 832 self .Bind(wx.EVTMENU, self . printQueue , m rx hist 0B ) 833 self .Bind(wx.EVTMENU, self . printQueue , m rx hist 1A ) 834 self .Bind(wx.EVTMENU, self . printQueue , m rx hist 1B ) 835 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v1 ) 836 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v2 ) 837 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v3 ) 838 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v4 ) 839 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v5 ) 840 self .Bind(wx.EVTMENU, self . printQueue , m rx hist v6 ) 841 #bind events for historical TX queue printing 842 self .Bind(wx.EVTMENU, self . printQueue , m tx hist 0A ) 843 self .Bind(wx.EVTMENU, self . printQueue , m tx hist 0B ) 193 844 self .Bind(wx.EVTMENU, self . printQueue , m tx hist 1A ) 845 self .Bind(wx.EVTMENU, self . printQueue , m tx hist 1B ) 846 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v1 ) 847 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v2 ) 848 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v3 ) 849 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v4 ) 850 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v5 ) 851 self .Bind(wx.EVTMENU, self . printQueue , m tx hist v6 ) 852 #bind events for bbc olsr process viewing in separate window 853 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v1 ) 854 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v2 ) 855 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v3 ) 856 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v4 ) 857 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v5 ) 858 self .Bind(wx.EVTMENU, self . printOLSRProcess , m olsr v6 ) 859 #bind events for testing level neighbor table viewing in separate window 860 self .Bind(wx.EVTMENU, self . printTable , m usrp0A table) 861 self .Bind(wx.EVTMENU, self . printTable , m usrp0B table) 862 self .Bind(wx.EVTMENU, self . printTable , m usrp1A table) 863 self .Bind(wx.EVTMENU, self . printTable , m usrp1B table) 864 self .Bind(wx.EVTMENU, self . printTable , m virt1 table ) 865 self .Bind(wx.EVTMENU, self . printTable , m virt2 table ) 866 self .Bind(wx.EVTMENU, self . printTable , m virt3 table ) 867 self .Bind(wx.EVTMENU, self . printTable , m virt4 table ) 868 self .Bind(wx.EVTMENU, self . printTable , m virt5 table ) 869 self .Bind(wx.EVTMENU, self . printTable , m virt6 table ) 870 871 #add menus to menuBar 872 menuBar.Append(menu, "& File ") 873 menuBar.Append(menu2, " RX Queues ") 874 menuBar.Append(menu3, " TX Queues ") 875 menuBar.Append(menu4, " RX Queues (H)") 876 menuBar.Append(menu5, " TX Queues (H)") 877 menuBar.Append(menu6, " BBC - OLSR ") 878 menuBar.Append(menu7, " Neighbor Tables ") 879 880 #activate menu bar 881 self .SetMenuBar(menuBar) 882 self . statusbar = self . CreateStatusBar () 883 884 #initialize offsets for controls in frame 885 self . x offset = 0 886 self . y offset = 0 887 888 #create controls , bind events , and do the layout 194 889 for i in range (4) : 890 self . createParameterControls () 891 self . bindEvents () 892 self . doLayout() 893 self . y offset = self . y offset+200 894 self . x offset = self . x offset + 250 895 896 #initialize bbc olsr processes 897 self . olsr init () 898 899 ################ 900 #END OF INIT 901 ################ 902 903 904 def olsr init ( self ) : 905 #print "Starting OLSR" 906 # open the tap interfaces , and bring them up with ifconfig 907 self . tap0 = tap device (" tap0 " , " 192.168.2.21 ") 908 self . tap1 = tap device (" tap1 " , " 192.168.3.22 ") 909 self . tap2 = tap device (" tap2 " , " 192.168.4.23 ") 910 self . tap3 = tap device (" tap3 " , " 192.168.5.24 ") 911 912 #open tap interfaces for virtual bbc olsr nodes 913 self . tap4 = tap device (" tap4 " , " 192.168.6.25 ") 914 self . tap5 = tap device (" tap5 " , " 192.168.7.26 ") 915 self . tap6 = tap device (" tap6 " , " 192.168.8.27 ") 916 self . tap7 = tap device (" tap7 " , " 192.168.9.28 ") 917 self . tap8 = tap device (" tap8 " , " 192.168.10.29 ") 918 self . tap9 = tap device (" tap9 " , " 192.168.11.30 ") 919 920 time . sleep (1) 921 922 #setup Network Address Translation table 923 self . setup nat () 924 925 #start interface reads and writes in tap device threads 926 self . olsr bring up interfaces () 927 928 #start olsr daemons on each tap device 929 self . olsr start process () 930 931 932 def setup nat ( self ) : 933 #generate addresses for nodes 195 934 addr list = [] 935 for i in range (0 ,10) : 936 addr list .append(random. randint (1 ,9999) ) 937 938 self . nat table = f" 192.168.2.21 " : str ( addr list .pop() ) , 939 " 192.168.3.22 " : str ( addr list .pop() ) , 940 " 192.168.4.23 " : str ( addr list .pop() ) , 941 " 192.168.5.24 " : str ( addr list .pop() ) , 942 #virtual interfaces 943 " 192.168.6.25 " : str ( addr list .pop() ) , 944 " 192.168.7.26 " : str ( addr list .pop() ) , 945 " 192.168.8.27 " : str ( addr list .pop() ) , 946 " 192.168.9.28 " : str ( addr list .pop() ) , 947 " 192.168.10.29 " : str ( addr list .pop() ) , 948 " 192.168.11.30 " : str ( addr list .pop() )g 949 950 def olsr bring up interfaces ( self ) : 951 #print "interfaces coming up" 952 self . tap0 . start () 953 self . tap1 . start () 954 self . tap2 . start () 955 self . tap3 . start () 956 957 #virtual interfaces 958 self . tap4 . start () 959 self . tap5 . start () 960 self . tap6 . start () 961 self . tap7 . start () 962 self . tap8 . start () 963 self . tap9 . start () 964 965 966 def olsr bring down interfaces ( self ) : 967 #print "interfaces going down" 968 self . tap0 . stop () 969 self . tap1 . stop () 970 self . tap2 . stop () 971 self . tap3 . stop () 972 973 #virtual interfaces 974 self . tap4 . stop () 975 self . tap5 . stop () 976 self . tap6 . stop () 977 self . tap7 . stop () 978 self . tap8 . stop () 196 979 self . tap9 . stop () 980 981 def olsr stop tap0 ( self ) : 982 self . tap0 . stop () 983 def olsr stop tap1 ( self ) : 984 self . tap1 . stop () 985 def olsr stop tap2 ( self ) : 986 self . tap2 . stop () 987 def olsr stop tap3 ( self ) : 988 self . tap3 . stop () 989 def olsr stop tap4 ( self ) : #virtual node 990 self . tap4 . stop () 991 def olsr stop tap5 ( self ) : #virtual node 992 self . tap5 . stop () 993 def olsr stop tap6 ( self ) : #virtual node 994 self . tap6 . stop () 995 def olsr stop tap7 ( self ) : #virtual node 996 self . tap7 . stop () 997 def olsr stop tap8 ( self ) : #virtual node 998 self . tap8 . stop () 999 def olsr stop tap9 ( self ) : #virtual node 1000 self . tap9 . stop () 1001 1002 def olsr start process ( self ) : 1003 if ( self . olsr process usb0A is None) : 1004 #sudo olsrd f /usr/local/etc/olsrd . conf i tap0 d 4 1005 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd0 . conf -i tap0 -d 4 - hint 5.0 - tcint 7.0 " 1006 self . olsr process usb0A = wx. Process ( self , id=ID PROCESS OLSR 1) 1007 self . olsr process usb0A . Redirect () 1008 self . olsr process id usb0A = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process usb0A ) 1009 self . display0A(" > Starting BBC - OLSR Daemon \n") 1010 self . display0A(" > Executing : "+self . olsr cmd+"\n") 1011 if ( self . olsr process usb0B is None) : 1012 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd1 . conf -i tap1 -d 4 - hint 5.0 - tcint 7.0 " 1013 self . olsr process usb0B = wx. Process ( self , id=ID PROCESS OLSR 2) 1014 self . olsr process usb0B . Redirect () 1015 self . olsr process id usb0B = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process usb0B ) 1016 self . display0B(" > Starting BBC - OLSR Daemon \n") 1017 self . display0B(" > Executing : "+self . olsr cmd+"\n") 1018 if ( self . olsr process usb1A is None) : 197 1019 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd2 . conf -i tap2 -d 4 - hint 5.0 - tcint 7.0 " 1020 self . olsr process usb1A = wx. Process ( self , id=ID PROCESS OLSR 3) 1021 self . olsr process usb1A . Redirect () 1022 self . olsr process id usb1A = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process usb1A ) 1023 self . display1A(" > Starting BBC - OLSR Daemon \n") 1024 self . display1A(" > Executing : "+self . olsr cmd+"\n") 1025 if ( self . olsr process usb1B is None) : 1026 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd3 . conf -i tap3 -d 4 - hint 5.0 - tcint 7.0 " 1027 self . olsr process usb1B = wx. Process ( self , id=ID PROCESS OLSR 4) 1028 self . olsr process usb1B . Redirect () 1029 self . olsr process id usb1B = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process usb1B ) 1030 self . display1B(" > Starting BBC - OLSR Daemon \n") 1031 self . display1B(" > Executing : "+self . olsr cmd+"\n") 1032 1033 #start virtual bbc olsr processes 1034 if ( self . olsr process virt1 is None) : 1035 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd4 . conf -i tap4 -d 4 - hint 5.0 - tcint 7.0 " 1036 self . olsr process virt1 = wx. Process ( self , id=ID PROCESS OLSR 5) 1037 self . olsr process virt1 . Redirect () 1038 self . olsr process id v1 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt1 ) 1039 self . olsr v1 output+=" > Starting BBC - OLSR Daemon \n" 1040 self . olsr v1 output+=" > Executing : "+self . olsr cmd+"\n" 1041 if ( self . olsr process virt2 is None) : 1042 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd5 . conf -i tap5 -d 4 - hint 5.0 - tcint 7.0 " 1043 self . olsr process virt2 = wx. Process ( self , id=ID PROCESS OLSR 6) 1044 self . olsr process virt2 . Redirect () 1045 self . olsr process id v2 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt2 ) 1046 self . olsr v2 output+=" > Starting BBC - OLSR Daemon \n" 1047 self . olsr v2 output+=" > Executing : "+self . olsr cmd+"\n" 1048 if ( self . olsr process virt3 is None) : 1049 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd6 . conf -i tap6 -d 4 - hint 5.0 - tcint 7.0 " 1050 self . olsr process virt3 = wx. Process ( self , id=ID PROCESS OLSR 7) 1051 self . olsr process virt3 . Redirect () 1052 self . olsr process id v3 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt3 ) 1053 self . olsr v3 output+=" > Starting BBC - OLSR Daemon \n" 198 1054 self . olsr v3 output+=" > Executing : "+self . olsr cmd+"\n" 1055 if ( self . olsr process virt4 is None) : 1056 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd7 . conf -i tap7 -d 4 - hint 5.0 - tcint 7.0 " 1057 self . olsr process virt4 = wx. Process ( self , id=ID PROCESS OLSR 8) 1058 self . olsr process virt4 . Redirect () 1059 self . olsr process id v4 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt4 ) 1060 self . olsr v4 output+=" > Starting BBC - OLSR Daemon \n" 1061 self . olsr v4 output+=" > Executing : "+self . olsr cmd+"\n" 1062 if ( self . olsr process virt5 is None) : 1063 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd8 . conf -i tap8 -d 4 - hint 5.0 - tcint 7.0 " 1064 self . olsr process virt5 = wx. Process ( self , id=ID PROCESS OLSR 9) 1065 self . olsr process virt5 . Redirect () 1066 self . olsr process id v5 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt5 ) 1067 self . olsr v5 output+=" > Starting BBC - OLSR Daemon \n" 1068 self . olsr v5 output+=" > Executing : "+self . olsr cmd+"\n" 1069 if ( self . olsr process virt6 is None) : 1070 self . olsr cmd = " olsrd -f / usr / local / etc / olsrd9 . conf -i tap9 -d 4 - hint 5.0 - tcint 7.0 " 1071 self . olsr process virt6 = wx. Process ( self , id=ID PROCESS OLSR 10) 1072 self . olsr process virt6 . Redirect () 1073 self . olsr process id v6 = wx. Execute( self . olsr cmd ,wx.EXEC ASYNC, self . olsr process virt6 ) 1074 self . olsr v6 output+=" > Starting BBC - OLSR Daemon \n" 1075 self . olsr v6 output+=" > Executing : "+self . olsr cmd+"\n" 1076 1077 1078 def bindEvents( self ) : 1079 for control , event , handler in n 1080 [ 1081 ( self . updateButton , wx.EVT BUTTON, self .onUpdate) , 1082 ( self .TxOrRx, wx.EVT RADIOBOX, self . radioClick ) , 1083 ( self . startButton , wx.EVT BUTTON, self . startClick ) , 1084 ( self . stopButton , wx.EVT BUTTON, self . stopClick ) , 1085 ( self , wx.EVT IDLE, self . OnIdle) , 1086 ( self , wx.EVT END PROCESS, self . OnProcessEnded) , 1087 1088 ]: 1089 control .Bind(event=event , handler=handler) 1090 1091 1092 def printQueue( self , event) : 199 1093 #rx queue 1094 if (event . GetId()==ID PRINT RX QUEUE USB0A) : 1095 queue = self . rx pkt queue usrp0A 1096 elif (event . GetId()==ID PRINT RX QUEUE USB0B) : 1097 queue = self . rx pkt queue usrp0B 1098 elif (event . GetId()==ID PRINT RX QUEUE USB1A) : 1099 queue = self . rx pkt queue usrp1A 1100 elif (event . GetId()==ID PRINT RX QUEUE USB1B) : 1101 queue = self . rx pkt queue usrp1B 1102 elif (event . GetId()==ID PRINT RX QUEUE VIRT1) : 1103 queue = self . rx pkt queue virt1 1104 elif (event . GetId()==ID PRINT RX QUEUE VIRT2) : 1105 queue = self . rx pkt queue virt2 1106 elif (event . GetId()==ID PRINT RX QUEUE VIRT3) : 1107 queue = self . rx pkt queue virt3 1108 elif (event . GetId()==ID PRINT RX QUEUE VIRT4) : 1109 queue = self . rx pkt queue virt4 1110 elif (event . GetId()==ID PRINT RX QUEUE VIRT5) : 1111 queue = self . rx pkt queue virt5 1112 elif (event . GetId()==ID PRINT RX QUEUE VIRT6) : 1113 queue = self . rx pkt queue virt6 1114 #tx queue 1115 elif (event . GetId()==ID PRINT TX QUEUE USB0A) : 1116 queue = self . tx pkt queue usrp0A 1117 elif (event . GetId()==ID PRINT TX QUEUE USB0B) : 1118 queue = self . tx pkt queue usrp0B 1119 elif (event . GetId()==ID PRINT TX QUEUE USB1A) : 1120 queue = self . tx pkt queue usrp1A 1121 elif (event . GetId()==ID PRINT TX QUEUE USB1B) : 1122 queue = self . tx pkt queue usrp1B 1123 elif (event . GetId()==ID PRINT TX QUEUE VIRT1) : 1124 queue = self . tx pkt queue virt1 1125 elif (event . GetId()==ID PRINT TX QUEUE VIRT2) : 1126 queue = self . tx pkt queue virt2 1127 elif (event . GetId()==ID PRINT TX QUEUE VIRT3) : 1128 queue = self . tx pkt queue virt3 1129 elif (event . GetId()==ID PRINT TX QUEUE VIRT4) : 1130 queue = self . tx pkt queue virt4 1131 elif (event . GetId()==ID PRINT TX QUEUE VIRT5) : 1132 queue = self . tx pkt queue virt5 1133 elif (event . GetId()==ID PRINT TX QUEUE VIRT6) : 1134 queue = self . tx pkt queue virt6 1135 #rx queue historical 1136 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL USB0A) : 1137 queue = self . rx pkt queue historical usrp0A 200 1138 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL USB0B) : 1139 queue = self . rx pkt queue historical usrp0B 1140 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL USB1A) : 1141 queue = self . rx pkt queue historical usrp1A 1142 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL USB1B) : 1143 queue = self . rx pkt queue historical usrp1B 1144 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT1) : 1145 queue = self . rx pkt queue historical virt1 1146 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT2) : 1147 queue = self . rx pkt queue historical virt2 1148 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT3) : 1149 queue = self . rx pkt queue historical virt3 1150 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT4) : 1151 queue = self . rx pkt queue historical virt4 1152 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT5) : 1153 queue = self . rx pkt queue historical virt5 1154 elif (event . GetId()==ID PRINT RX QUEUE HISTORICAL VIRT6) : 1155 queue = self . rx pkt queue historical virt6 1156 #tx queue historical 1157 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL USB0A) : 1158 queue = self . tx pkt queue historical usrp0A 1159 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL USB0B) : 1160 queue = self . tx pkt queue historical usrp0B 1161 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL USB1A) : 1162 queue = self . tx pkt queue historical usrp1A 1163 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL USB1B) : 1164 queue = self . tx pkt queue historical usrp1B 1165 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT1) : 1166 queue = self . tx pkt queue historical virt1 1167 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT1) : 1168 queue = self . tx pkt queue historical virt1 1169 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT2) : 1170 queue = self . tx pkt queue historical virt2 1171 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT3) : 1172 queue = self . tx pkt queue historical virt3 1173 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT4) : 1174 queue = self . tx pkt queue historical virt4 1175 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT5) : 1176 queue = self . tx pkt queue historical virt5 1177 elif (event . GetId()==ID PRINT TX QUEUE HISTORICAL VIRT6) : 1178 queue = self . tx pkt queue historical virt6 1179 else : 1180 print " Error : Print Queue Event ID Not Found !\ n" 1181 1182 if queue is not None: 201 1183 for i in queue : 1184 i . print pkt () 1185 1186 #from menu, display running bbc olsr process 1187 def printOLSRProcess( self , event) : 1188 if (event . GetId()==ID VIEW OLSR 1) : 1189 print self . olsr v1 output 1190 elif (event . GetId()==ID VIEW OLSR 2) : 1191 print self . olsr v2 output 1192 elif (event . GetId()==ID VIEW OLSR 3) : 1193 print self . olsr v3 output 1194 elif (event . GetId()==ID VIEW OLSR 4) : 1195 print self . olsr v4 output 1196 elif (event . GetId()==ID VIEW OLSR 5) : 1197 print self . olsr v5 output 1198 elif (event . GetId()==ID VIEW OLSR 6) : 1199 print self . olsr v6 output 1200 1201 1202 #from menu, display neighbor table for testing purposes 1203 def printTable ( self , event) : 1204 if (event . GetId()==ID VIEW TABLE USRP0A) : 1205 print self . usrp0A table . items () 1206 elif (event . GetId()==ID VIEW TABLE USRP0B) : 1207 print self . usrp0B table . items () 1208 elif (event . GetId()==ID VIEW TABLE USRP1A) : 1209 print self . usrp1A table . items () 1210 elif (event . GetId()==ID VIEW TABLE USRP1B) : 1211 print self . usrp1B table . items () 1212 elif (event . GetId()==ID VIEW TABLE VIRT1) : 1213 print self . virt1 table . items () 1214 elif (event . GetId()==ID VIEW TABLE VIRT2) : 1215 print self . virt2 table . items () 1216 elif (event . GetId()==ID VIEW TABLE VIRT3) : 1217 print self . virt3 table . items () 1218 elif (event . GetId()==ID VIEW TABLE VIRT4) : 1219 print self . virt4 table . items () 1220 elif (event . GetId()==ID VIEW TABLE VIRT5) : 1221 print self . virt5 table . items () 1222 elif (event . GetId()==ID VIEW TABLE VIRT6) : 1223 print self . virt6 table . items () 1224 1225 def killOLSRProcesses( self ) : 1226 if ( self . olsr process usb0A is not None) : 1227 res=self . olsr process usb0A . Kill ( self . olsr process id usb0A ,2) 202 1228 if ( self . olsr process usb0B is not None) : 1229 res=self . olsr process usb0B . Kill ( self . olsr process id usb0B ,2) 1230 if ( self . olsr process usb1A is not None) : 1231 res=self . olsr process usb1A . Kill ( self . olsr process id usb1A ,2) 1232 if ( self . olsr process usb1B is not None) : 1233 res=self . olsr process usb1B . Kill ( self . olsr process id usb1B ,2) 1234 if ( self . olsr process virt1 is not None) : 1235 res=self . olsr process virt1 . Kill ( self . olsr process id v1 ,2) 1236 if ( self . olsr process virt2 is not None) : 1237 res=self . olsr process virt2 . Kill ( self . olsr process id v2 ,2) 1238 if ( self . olsr process virt3 is not None) : 1239 res=self . olsr process virt3 . Kill ( self . olsr process id v3 ,2) 1240 if ( self . olsr process virt4 is not None) : 1241 res=self . olsr process virt4 . Kill ( self . olsr process id v4 ,2) 1242 if ( self . olsr process virt5 is not None) : 1243 res=self . olsr process virt5 . Kill ( self . olsr process id v5 ,2) 1244 if ( self . olsr process virt6 is not None) : 1245 res=self . olsr process virt6 . Kill ( self . olsr process id v6 ,2) 1246 1247 #stop a node ?s complete operation 1248 def stopClick ( self , event) : 1249 if (event . GetId()==ID STOP USB0A) : 1250 self . olsr stop tap0 () 1251 if ( self . process usb0A is not None) : 1252 self . kill 0A = True 1253 res=self . process usb0A . Kill ( self . process id usb0A ,2) 1254 self . display0A(" > Terminated USRP0A Process .\ n") 1255 else : self . display0A(" > USRP0A process already terminated .\ n") 1256 if ( self . olsr process usb0A is not None) : 1257 res=self . olsr process usb0A . Kill ( self . olsr process id usb0A ,2) 1258 self . display0A(" > Terminated OLSR Process .\ n") 1259 else : self . display0A(" > OLSR Process already terminated \n") 1260 elif (event . GetId()==ID STOP USB0B) : 1261 self . olsr stop tap1 () 1262 if ( self . process usb0B is not None) : 1263 self . kill 0B = True 1264 res=self . process usb0B . Kill ( self . process id usb0B ,2) 1265 self . display0B(" > Terminated USRP0B Process .\ n") 1266 else : self . display0B(" > USRP0B process already terminated .\ n") 1267 if ( self . olsr process usb0B is not None) : 1268 res=self . olsr process usb0B . Kill ( self . olsr process id usb0B ,2) 1269 self . display0B(" > Terminated OLSR Process .\ n") 1270 else : self . display0B(" > OLSR Process already terminated .\ n") 1271 elif (event . GetId()==ID STOP USB1A) : 1272 self . olsr stop tap2 () 203 1273 if ( self . process usb1A is not None) : 1274 self . kill 1A = True 1275 res=self . process usb1A . Kill ( self . process id usb1A ,2) 1276 self . display1A(" > Terminated USRP1A Process .\ n") 1277 else : self . display1A(" > USRP1A process already terminated .\ n") 1278 if ( self . olsr process usb1A is not None) : 1279 res=self . olsr process usb1A . Kill ( self . olsr process id usb1A ,2) 1280 self . display1A(" > Terminated OLSR Process .\ n") 1281 else : self . display1A(" > OLSR Process already terminated .\ n") 1282 elif (event . GetId()==ID STOP USB1B) : 1283 self . olsr stop tap3 () 1284 if ( self . process usb1B is not None) : 1285 self . kill 1B = True 1286 res=self . process usb1B . Kill ( self . process id usb1B ,2) 1287 self . display1B(" > Terminated USRP1B Process .\ n") 1288 else : self . display1B(" > USRP1B process already terminated .\ n") 1289 if ( self . olsr process usb1B is not None) : 1290 res=self . olsr process usb1B . Kill ( self . olsr process id usb1B ,2) 1291 self . display1B(" > Terminated OLSR Process .\ n") 1292 else : self . display1B(" > OLSR Process already terminated .\ n") 1293 #virtual nodes 1294 elif (event . GetId()==ID STOP VIRT1) : 1295 self . olsr stop tap4 () 1296 if ( self . process virt1 is not None) : 1297 #self . kill 1B = True 1298 res=self . process virt1 . Kill ( self . process id virt1 ,2) 1299 self . olsr v1 output+=" > Terminated VIRT1 Process .\ n" 1300 else : self . olsr v1 output+=" > VIRT1 process already terminated .\ n" 1301 if ( self . olsr process virt1 is not None) : 1302 res=self . olsr process virt1 . Kill ( self . olsr process id virt1 ,2) 1303 self . olsr v1 output+=" > Terminated OLSR Process .\ n" 1304 else : self . olsr v1 output+=" > OLSR Process already terminated .\ n" 1305 elif (event . GetId()==ID STOP VIRT2) : 1306 self . olsr stop tap5 () 1307 if ( self . process virt2 is not None) : 1308 #self . kill 2B = True 1309 res=self . process virt2 . Kill ( self . process id virt2 ,2) 1310 self . olsr v2 output+=" > Terminated VIRT2 Process .\ n" 1311 else : self . olsr v2 output+=" > VIRT2 process already terminated .\ n" 1312 if ( self . olsr process virt2 is not None) : 1313 res=self . olsr process virt2 . Kill ( self . olsr process id virt2 ,2) 1314 self . olsr v2 output+=" > Terminated OLSR Process .\ n" 1315 else : self . olsr v2 output+=" > OLSR Process already terminated .\ n" 1316 elif (event . GetId()==ID STOP VIRT3) : 1317 self . olsr stop tap6 () 204 1318 if ( self . process virt3 is not None) : 1319 #self . kill 3B = True 1320 res=self . process virt3 . Kill ( self . process id virt3 ,2) 1321 self . olsr v3 output+=" > Terminated VIRT3 Process .\ n" 1322 else : self . olsr v3 output+=" > VIRT3 process already terminated .\ n" 1323 if ( self . olsr process virt3 is not None) : 1324 res=self . olsr process virt3 . Kill ( self . olsr process id virt3 ,2) 1325 self . olsr v3 output+=" > Terminated OLSR Process .\ n" 1326 else : self . olsr v3 output+=" > OLSR Process already terminated .\ n" 1327 elif (event . GetId()==ID STOP VIRT4) : 1328 self . olsr stop tap7 () 1329 if ( self . process virt4 is not None) : 1330 #self . kill 4B = True 1331 res=self . process virt4 . Kill ( self . process id virt4 ,2) 1332 self . olsr v4 output+=" > Terminated VIRT4 Process .\ n" 1333 else : self . olsr v4 output+=" > VIRT4 process already terminated .\ n" 1334 if ( self . olsr process virt4 is not None) : 1335 res=self . olsr process virt4 . Kill ( self . olsr process id virt4 ,2) 1336 self . olsr v4 output+=" > Terminated OLSR Process .\ n" 1337 else : self . olsr v4 output+=" > OLSR Process already terminated .\ n" 1338 elif (event . GetId()==ID STOP VIRT5) : 1339 self . olsr stop tap8 () 1340 if ( self . process virt5 is not None) : 1341 #self . kill 5B = True 1342 res=self . process virt5 . Kill ( self . process id virt5 ,2) 1343 self . olsr v5 output+=" > Terminated VIRT5 Process .\ n" 1344 else : self . olsr v5 output+=" > VIRT5 process already terminated .\ n" 1345 if ( self . olsr process virt5 is not None) : 1346 res=self . olsr process virt5 . Kill ( self . olsr process id virt5 ,2) 1347 self . olsr v5 output+=" > Terminated OLSR Process .\ n" 1348 else : self . olsr v5 output+=" > OLSR Process already terminated .\ n" 1349 elif (event . GetId()==ID STOP VIRT6) : 1350 self . olsr stop tap9 () 1351 if ( self . process virt6 is not None) : 1352 #self . kill 6B = True 1353 res=self . process virt6 . Kill ( self . process id virt6 ,2) 1354 self . olsr v6 output+=" > Terminated VIRT6 Process .\ n" 1355 else : self . olsr v6 output+=" > VIRT6 process already terminated .\ n" 1356 if ( self . olsr process virt6 is not None) : 1357 res=self . olsr process virt6 . Kill ( self . olsr process id virt6 ,2) 1358 self . olsr v6 output+=" > Terminated OLSR Process .\ n" 1359 else : self . olsr v6 output+=" > OLSR Process already terminated .\ n" 1360 1361 1362 def startClick ( self , event) : 205 1363 if (event . GetId()==ID START USB0A) : 1364 node id = self .FindWindowById(ID RADIO USB0A) . GetLabelText () 1365 if ( self . process usb0A is None) : 1366 if ( self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()==" TX ") : 1367 if ( self . process usb0B is not None and self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" TX ") : 1368 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp0B ")) 1369 self . display0B("\n > Stopping this transmission to restart TX block to TX on both daughterboards .\ n") 1370 self . txt cmd = self . experiment path+ " usrp "+node id [3]+ node id [4]+"/ bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -C 2 -f 1250 M - i 64 " + " -S " + self . experiment path+" usrp0A /"+self .FindWindowById( ID SINK NAME USB0A) . GetValue() + " -P B -N " + self . experiment path+ " usrp0B /"+self .FindWindowById(ID SINK NAME USB0B) . GetValue() 1371 self . display0A("\n > Transmitting ...\ n") 1372 self . display0B("\n > Transmitting ...\ n") 1373 else : 1374 self . display0A("\ nTransmitting ...\ n") 1375 self . txt cmd = self . experiment path+ " usrp "+node id [3]+ node id [4]+"/ bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -f 1250 M -i 64 " + " -S " + self . experiment path+" usrp0A /"+self .FindWindowById( ID SINK NAME USB0A) . GetValue() 1376 else : #0A is in RX mode 1377 if ( self . process usb0B is not None and self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" RX ") : 1378 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp0B ")) 1379 self . dual rx 0 = True 1380 self . display0B("\n > Stopping this transmission to restart RX block to RX on both daughterboards .\ n") 1381 self . txt cmd = self . experiment path+ " usrp0A / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -C 2 -f 1250 M -d 32 " + self . experiment path+" usrp0A /"+self .FindWindowById(ID SRC NAME USB0A) . GetValue() + " " + self . experiment path+" usrp0B /"+self .FindWindowById (ID SRC NAME USB0B) . GetValue() 1382 self . display0A("\n > Receiving ...\ n") 1383 self . display0B("\n > Receiving ...\ n") 1384 else : 1385 self . display0A("\n > Receiving ...\ n") 1386 self . txt cmd = self . experiment path+ " usrp0A / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -f 1250 M -d 32 " + self . experiment path+" usrp0A /"+self .FindWindowById(ID SRC NAME USB0A) . GetValue() 1387 self . process usb0A = wx. Process ( self , id=ID PROCESS 1) 206 1388 self . process usb0A . Redirect () 1389 self . process id usb0A = wx. Execute( self . txt cmd ,wx.EXEC ASYNC, self . process usb0A) 1390 self . display0A("\n > Executing : "+self . txt cmd+"\n") 1391 1392 elif (event . GetId()==ID START USB0B) : 1393 node id = self .FindWindowById(ID RADIO USB0B) . GetLabelText () 1394 if ( self . process usb0B is None) : 1395 if ( self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" TX ") : 1396 if ( self . process usb0A is not None and self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" TX ") : 1397 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp0A ")) 1398 self . display0A("\n > Stopping this transmission to restart TX block to TX on both daughterboards .\ n") 1399 self . txt cmd = self . experiment path+ " usrp "+node id [3]+ node id [4]+"/ bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -C 2 -f 1250 M - i 64 " + " -S " + self . experiment path+" usrp0B /"+self .FindWindowById( ID SINK NAME USB0B) . GetValue() + " -P A -N " + self . experiment path+ " usrp0A /"+self .FindWindowById(ID SINK NAME USB0A) . GetValue() 1400 self . display0A("\n > Transmitting ...\ n") 1401 self . display0B("\n > Transmitting ...\ n") 1402 else : 1403 self . display0B("\ nTransmitting ...\ n") 1404 self . txt cmd = self . experiment path+ " usrp0B / bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -f 1250 M -i 64 " + " -S " + self . experiment path+" usrp0B /"+self .FindWindowById(ID SINK NAME USB0B) . GetValue() 1405 else : 1406 if ( self . process usb0A is not None and self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()==" RX ") : 1407 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp0A ")) 1408 self . dual rx 0 = True 1409 self . display0A("\n > Stopping this transmission to restart RX block to RX on both daughterboards .\ n") 1410 self . txt cmd = self . experiment path+ " usrp0B / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -C 2 -f 1250 M -d 32 " + self . experiment path+" usrp0A /"+self .FindWindowById(ID SRC NAME USB0A) . GetValue() + " " + self . experiment path+" usrp0B /"+self .FindWindowById (ID SRC NAME USB0B) . GetValue() 1411 self . display0A("\n > Receiving ...\ n") 1412 self . display0B("\n > Receiving ...\ n") 1413 else : 1414 self . display0B("\ nReceiving ...\ n") 207 1415 self . txt cmd = self . experiment path+ " usrp0B / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -f 1250 M -d 32 " + self . experiment path+" usrp0B /"+self .FindWindowById(ID SRC NAME USB0B) . GetValue() 1416 self . process usb0B = wx. Process ( self , id=ID PROCESS 2) 1417 self . process usb0B . Redirect () 1418 self . process id usb0B = wx. Execute( self . txt cmd ,wx.EXEC ASYNC, self . process usb0B) 1419 self . display0B("\n > Executing : "+self . txt cmd+"\n") 1420 elif (event . GetId()==ID START USB1A) : 1421 node id = self .FindWindowById(ID RADIO USB1A) . GetLabelText () 1422 if ( self . process usb1A is None) : 1423 if ( self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" TX ") : 1424 if ( self . process usb1B is not None and self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" TX ") : 1425 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp1B ")) 1426 self . display1B("\n > Stopping this transmission to restart TX block to TX on both daughterboards .\ n") 1427 self . txt cmd = self . experiment path+ " usrp "+node id [3]+ node id [4]+"/ bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -C 2 -f 1250 M -i 64 " + " -S " + self . experiment path+" usrp1A /"+self .FindWindowById( ID SINK NAME USB1A) . GetValue() + " -P B -N " + self . experiment path+" usrp1B /"+self .FindWindowById(ID SINK NAME USB1B) . GetValue() 1428 self . display1A("\n > Transmitting ...\ n") 1429 self . display1B("\n > Transmitting ...\ n") 1430 else : 1431 self . display1A("\ nTransmitting ...\ n") 1432 self . txt cmd = self . experiment path+ " usrp1A / bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -f 1250 M -i 64 " + " -S " + self . experiment path+" usrp1A /"+self .FindWindowById(ID SINK NAME USB1A) . GetValue() 1433 else : 1434 if ( self . process usb1B is not None and self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" RX ") : 1435 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp1B ")) 1436 self . dual rx 1 = True 1437 self . display1B("\n > Stopping this transmission to restart RX block to RX on both daughterboards .\ n") 1438 self . txt cmd = self . experiment path+ " usrp1A / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -C 2 -f 1250 M -d 32 " + self . experiment path+" usrp1A /"+self .FindWindowById(ID SRC NAME USB1A) . GetValue() + " " + self . experiment path+" usrp1B /"+self .FindWindowById (ID SRC NAME USB1B) . GetValue() 1439 self . display1A("\n > Receiving ...\ n") 208 1440 self . display1B("\n > Receiving ...\ n") 1441 else : 1442 self . display1A("\ nReceiving ...\ n") 1443 self . txt cmd = self . experiment path+ " usrp1A / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -f 1250 M -d 32 " + self . experiment path+" usrp1A /"+self .FindWindowById(ID SRC NAME USB1A) . GetValue() 1444 self . process usb1A = wx. Process ( self , id=ID PROCESS 3) 1445 self . process usb1A . Redirect () 1446 self . process id usb1A = wx. Execute( self . txt cmd ,wx.EXEC ASYNC, self . process usb1A) 1447 self . display1A("\n > Executing : "+self . txt cmd+"\n") 1448 elif (event . GetId()==ID START USB1B) : 1449 node id = self .FindWindowById(ID RADIO USB1B) . GetLabelText () 1450 if ( self . process usb1B is None) : 1451 if ( self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" TX ") : 1452 if ( self . process usb1A is not None and self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" TX ") : 1453 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp1A ")) 1454 self . display1A("\n > Stopping this transmission to restart TX block to TX on both daughterboards .\ n") 1455 self . txt cmd = self . experiment path+ " usrp "+node id [3]+ node id [4]+"/ bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -C 2 -f 1250 M - i 64 " + " -S " + self . experiment path+" usrp1B /"+self .FindWindowById( ID SINK NAME USB1B) . GetValue() + " -P A -N " + self . experiment path+ " usrp1A /"+self .FindWindowById(ID SINK NAME USB1A) . GetValue() 1456 self . display1A("\n > Transmitting ...\ n") 1457 self . display1B("\n > Transmitting ...\ n") 1458 else : 1459 self . display1B("\ nTransmitting ...\ n") 1460 self . txt cmd = self . experiment path+ " usrp1B / bbc_tx . py -U " + node id [3] + " -T " + node id [4] + " -f 1250 M -i 64 " + " -S " + self . experiment path+" usrp1B /"+self .FindWindowById(ID SINK NAME USB1B) . GetValue() 1461 else : 1462 if ( self . process usb1A is not None and self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" RX ") : 1463 self . SendEvent(mycontrol=self . stopButton , event=wx.EVT BUTTON, id=self . getStopButtonId(" usrp1A ")) 1464 self . dual rx 1 = True 1465 self . display1A("\n > Stopping this transmission to restart RX block to RX on both daughterboards .\ n") 209 1466 self . txt cmd = self . experiment path+ " usrp1B / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -C 2 -f 1250 M -d 32 " + self . experiment path+" usrp1B /"+self .FindWindowById(ID SRC NAME USB1B) . GetValue() + " " + self . experiment path+" usrp1A /"+self .FindWindowById (ID SRC NAME USB1A) . GetValue() 1467 self . display1A("\n > Receiving ...\ n") 1468 self . display1B("\n > Receiving ...\ n") 1469 else : 1470 self . display1B("\ nReceiving ...\ n") 1471 self . txt cmd = self . experiment path+ " usrp1B / usrp_rx_cfile . py -U " + node id [3] + " -R " + node id [4] + " -f 1250 M -d 32 " + self . experiment path+" usrp1B /"+self .FindWindowById(ID SRC NAME USB1B) . GetValue() 1472 self . process usb1B = wx. Process ( self , id=ID PROCESS 4) 1473 self . process usb1B . Redirect () 1474 self . process id usb1B = wx. Execute( self . txt cmd ,wx.EXEC ASYNC, self . process usb1B) 1475 self . display1B("\n > Executing : "+self . txt cmd+"\n") 1476 1477 1478 def CheckTxQueue( self ) : 1479 1480 if ( len ( self . tx pkt queue usrp0A)>0): 1481 #only called after the end of a TX, so no need to stop the current TX 1482 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" usrp0A ")) 1483 #receivers are not turned on at this point 1484 #use transmitToFrom instead? 1485 #or , make sure the other nodes are put into a receive mode by default? 1486 #else put in RX mode? 1487 #stop the TX, set RX radio box , update , and do the start button 1488 #else : 1489 #if the RSSI is above threshold , start RX cycle . 1490 if ( len ( self . tx pkt queue usrp0B)>0): 1491 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" usrp0B ")) 1492 if ( len ( self . tx pkt queue usrp1A)>0): 1493 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" usrp1A ")) 1494 if ( len ( self . tx pkt queue usrp1B)>0): 1495 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" usrp1B ")) 1496 #virtual nodes 1497 if ( len ( self . tx pkt queue virt1 )>0): 1498 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt1 ")) 210 1499 if ( len ( self . tx pkt queue virt2 )>0): 1500 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt2 ")) 1501 if ( len ( self . tx pkt queue virt3 )>0): 1502 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt3 ")) 1503 if ( len ( self . tx pkt queue virt4 )>0): 1504 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt4 ")) 1505 if ( len ( self . tx pkt queue virt5 )>0): 1506 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt5 ")) 1507 if ( len ( self . tx pkt queue virt6 )>0): 1508 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId (" virt6 ")) 1509 1510 #check idle events for the many many processes 1511 def OnIdle( self , event) : 1512 1513 #processing signals physical nodes 1514 if ( self . process usb0A is not None) : 1515 stream usb0A = self . process usb0A . GetInputStream () 1516 if (stream usb0A .CanRead() ) : 1517 text usb0A = stream usb0A . read () 1518 self . display0A(text usb0A) 1519 if ( self . process usb0B is not None) : 1520 stream usb0B = self . process usb0B . GetInputStream () 1521 if (stream usb0B .CanRead() ) : 1522 text usb0B = stream usb0B . read () 1523 self . display0B(text usb0B) 1524 if ( self . process usb1A is not None) : 1525 stream usb1A = self . process usb1A . GetInputStream () 1526 if (stream usb1A .CanRead() ) : 1527 text usb1A = stream usb1A . read () 1528 self . display1A(text usb1A) 1529 if ( self . process usb1B is not None) : 1530 stream usb1B = self . process usb1B . GetInputStream () 1531 if (stream usb1B .CanRead() ) : 1532 text usb1B = stream usb1B . read () 1533 self . display1B(text usb1B) 1534 1535 #processing signals virtual nodes 1536 if ( self . process virt1 is not None) : 1537 stream virt1 = self . process virt1 . GetInputStream () 1538 if ( stream virt1 .CanRead() ) : 211 1539 text virt1 = stream virt1 . read () 1540 self . olsr v1 output+=text virt1 1541 if ( self . process virt2 is not None) : 1542 stream virt2 = self . process virt2 . GetInputStream () 1543 if ( stream virt2 .CanRead() ) : 1544 text virt2 = stream virt2 . read () 1545 self . olsr v2 output+=text virt2 1546 if ( self . process virt3 is not None) : 1547 stream virt3 = self . process virt3 . GetInputStream () 1548 if ( stream virt3 .CanRead() ) : 1549 text virt3 = stream virt3 . read () 1550 self . olsr v3 output+=text virt3 1551 if ( self . process virt4 is not None) : 1552 stream virt4 = self . process virt4 . GetInputStream () 1553 if ( stream virt4 .CanRead() ) : 1554 text virt4 = stream virt4 . read () 1555 self . olsr v4 output+=text virt4 1556 if ( self . process virt5 is not None) : 1557 stream virt5 = self . process virt5 . GetInputStream () 1558 if ( stream virt5 .CanRead() ) : 1559 text virt5 = stream virt5 . read () 1560 self . olsr v5 output+=text virt5 1561 if ( self . process virt6 is not None) : 1562 stream virt6 = self . process virt6 . GetInputStream () 1563 if ( stream virt6 .CanRead() ) : 1564 text virt6 = stream virt6 . read () 1565 self . olsr v6 output+=text virt6 1566 1567 #encoding physical nodes 1568 if ( self . encode process usb0A is not None) : 1569 stream encode usb0A = self . encode process usb0A . GetInputStream () 1570 if (stream encode usb0A .CanRead() ) : 1571 text encode usb0A = stream encode usb0A . read () 1572 self . display0A(text encode usb0A) 1573 if ( self . encode process usb0B is not None) : 1574 stream encode usb0B = self . encode process usb0B . GetInputStream () 1575 if (stream encode usb0B .CanRead() ) : 1576 text encode usb0B = stream encode usb0B . read () 1577 self . display0B(text encode usb0B) 1578 if ( self . encode process usb1A is not None) : 1579 stream encode usb1A = self . encode process usb1A . GetInputStream () 1580 if (stream encode usb1A .CanRead() ) : 1581 text encode usb1A = stream encode usb1A . read () 1582 self . display1A(text encode usb1A) 1583 if ( self . encode process usb1B is not None) : 212 1584 stream encode usb1B = self . encode process usb1B . GetInputStream () 1585 if (stream encode usb1B .CanRead() ) : 1586 text encode usb1B = stream encode usb1B . read () 1587 self . display1B(text encode usb1B) 1588 1589 #encoding virtual nodes 1590 if ( self . encode process virt1 is not None) : 1591 stream encode virt1 = self . encode process virt1 . GetInputStream () 1592 if ( stream encode virt1 .CanRead() ) : 1593 text encode virt1 = stream encode virt1 . read () 1594 self . olsr v1 output+=text encode virt1 1595 if ( self . encode process virt2 is not None) : 1596 stream encode virt2 = self . encode process virt2 . GetInputStream () 1597 if ( stream encode virt2 .CanRead() ) : 1598 text encode virt2 = stream encode virt2 . read () 1599 self . olsr v2 output+=text encode virt2 1600 if ( self . encode process virt3 is not None) : 1601 stream encode virt3 = self . encode process virt3 . GetInputStream () 1602 if ( stream encode virt3 .CanRead() ) : 1603 text encode virt3 = stream encode virt3 . read () 1604 self . olsr v3 output+=text encode virt3 1605 if ( self . encode process virt4 is not None) : 1606 stream encode virt4 = self . encode process virt4 . GetInputStream () 1607 if ( stream encode virt4 .CanRead() ) : 1608 text encode virt4 = stream encode virt4 . read () 1609 self . olsr v4 output+=text encode virt4 1610 if ( self . encode process virt5 is not None) : 1611 stream encode virt5 = self . encode process virt5 . GetInputStream () 1612 if ( stream encode virt5 .CanRead() ) : 1613 text encode virt5 = stream encode virt5 . read () 1614 self . olsr v5 output+=text encode virt5 1615 if ( self . encode process virt6 is not None) : 1616 stream encode virt6 = self . encode process virt6 . GetInputStream () 1617 if ( stream encode virt6 .CanRead() ) : 1618 text encode virt6 = stream encode virt6 . read () 1619 self . olsr v6 output+=text encode virt6 1620 1621 #decoding physical nodes 1622 if ( self . decode process usb0A is not None) : 1623 stream decode usb0A = self . decode process usb0A . GetInputStream () 1624 if (stream decode usb0A .CanRead() ) : 1625 text decode usb0A = stream decode usb0A . read () 1626 self . display0A(text decode usb0A) 1627 if ( self . decode process usb0B is not None) : 1628 stream decode usb0B = self . decode process usb0B . GetInputStream () 213 1629 if (stream decode usb0B .CanRead() ) : 1630 text decode usb0B = stream decode usb0B . read () 1631 self . display0B(text decode usb0B) 1632 if ( self . decode process usb1A is not None) : 1633 stream decode usb1A = self . decode process usb1A . GetInputStream () 1634 if (stream decode usb1A .CanRead() ) : 1635 text decode usb1A = stream decode usb1A . read () 1636 self . display1A(text decode usb1A) 1637 if ( self . decode process usb1B is not None) : 1638 stream decode usb1B = self . decode process usb1B . GetInputStream () 1639 if (stream decode usb1B .CanRead() ) : 1640 text decode usb1B = stream decode usb1B . read () 1641 self . display1B(text decode usb1B) 1642 1643 #decoding virtual nodes 1644 if ( self . decode process virt1 is not None) : 1645 stream decode virt1 = self . decode process virt1 . GetInputStream () 1646 if ( stream decode virt1 .CanRead() ) : 1647 text decode virt1 = stream decode virt1 . read () 1648 self . olsr v1 output+=text decode virt1 1649 if ( self . decode process virt2 is not None) : 1650 stream decode virt2 = self . decode process virt2 . GetInputStream () 1651 if ( stream decode virt2 .CanRead() ) : 1652 text decode virt2 = stream decode virt2 . read () 1653 self . olsr v2 output+=text decode virt2 1654 if ( self . decode process virt3 is not None) : 1655 stream decode virt3 = self . decode process virt3 . GetInputStream () 1656 if ( stream decode virt3 .CanRead() ) : 1657 text decode virt3 = stream decode virt3 . read () 1658 self . olsr v3 output+=text decode virt3 1659 if ( self . decode process virt4 is not None) : 1660 stream decode virt4 = self . decode process virt4 . GetInputStream () 1661 if ( stream decode virt4 .CanRead() ) : 1662 text decode virt4 = stream decode virt4 . read () 1663 self . olsr v4 output+=text decode virt4 1664 if ( self . decode process virt5 is not None) : 1665 stream decode virt5 = self . decode process virt5 . GetInputStream () 1666 if ( stream decode virt5 .CanRead() ) : 1667 text decode virt5 = stream decode virt5 . read () 1668 self . olsr v5 output+=text decode virt5 1669 if ( self . decode process virt6 is not None) : 1670 stream decode virt6 = self . decode process virt6 . GetInputStream () 1671 if ( stream decode virt6 .CanRead() ) : 1672 text decode virt6 = stream decode virt6 . read () 1673 self . olsr v6 output+=text decode virt6 214 1674 1675 1676 #bbc olsr agent processes 1677 if ( self . olsr process usb0A is not None) : 1678 stream olsr usb0A = self . olsr process usb0A . GetInputStream () 1679 if ( stream olsr usb0A .CanRead() ) : 1680 text olsr usb0A = stream olsr usb0A . read () 1681 if ( re . search (" received " , text olsr usb0A )) : #parse feedback 1682 node output = text olsr usb0A . partition (" ,") [0] 1683 bytes = re . split (" " , node output) [0] 1684 ip = re . split (" " , node output) [3] 1685 addr = self . nat table . get( ip ) 1686 #self . display0A(node output) #keep only necessary output 1687 self . display0A(" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+")") 1688 self . display0A("\n") 1689 if ( self . olsr process usb0B is not None) : 1690 stream olsr usb0B = self . olsr process usb0B . GetInputStream () 1691 if ( stream olsr usb0B .CanRead() ) : 1692 text olsr usb0B = stream olsr usb0B . read () 1693 if ( re . search (" received " , text olsr usb0B )) : #parse feedback 1694 node output = text olsr usb0B . partition (" ,") [0] 1695 bytes = re . split (" " , node output) [0] 1696 ip = re . split (" " , node output) [3] 1697 addr = self . nat table . get( ip ) 1698 #self . display0A(node output) #keep only necessary output 1699 self . display0B(" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+")") 1700 self . display0B("\n") 1701 if ( self . olsr process usb1A is not None) : 1702 stream olsr usb1A = self . olsr process usb1A . GetInputStream () 1703 if ( stream olsr usb1A .CanRead() ) : 1704 text olsr usb1A = stream olsr usb1A . read () 1705 if ( re . search (" received " , text olsr usb1A )) : #parse feedback 1706 node output = text olsr usb1A . partition (" ,") [0] 1707 bytes = re . split (" " , node output) [0] 1708 ip = re . split (" " , node output) [3] 1709 addr = self . nat table . get( ip ) 1710 #self . display0A(node output) #keep only necessary output 1711 self . display1A(" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+")") 1712 self . display1A("\n") 1713 if ( self . olsr process usb1B is not None) : 1714 stream olsr usb1B = self . olsr process usb1B . GetInputStream () 1715 if ( stream olsr usb1B .CanRead() ) : 1716 text olsr usb1B = stream olsr usb1B . read () 1717 if ( re . search (" received " , text olsr usb1B )) : #parse feedback 1718 node output = text olsr usb1B . partition (" ,") [0] 215 1719 bytes = re . split (" " , node output) [0] 1720 ip = re . split (" " , node output) [3] 1721 addr = self . nat table . get( ip ) 1722 #self . display0A(node output) #keep only necessary output 1723 self . display1B(" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+")") 1724 self . display1B("\n") 1725 1726 #bbc olsr virtual nodes 1727 if ( self . olsr process id v1 is not None) : 1728 stream olsr v1 = self . olsr process virt1 . GetInputStream () 1729 if ( stream olsr v1 .CanRead() ) : 1730 text olsr v1 = stream olsr v1 . read () 1731 if ( re . search (" received " , text olsr v1 )) : #parse feedback 1732 node output = text olsr v1 . partition (" ,") [0] 1733 bytes = re . split (" " , node output) [0] 1734 ip = re . split (" " , node output) [3] 1735 addr = self . nat table . get( ip ) 1736 #self . display0A(node output) #keep only necessary output 1737 self . olsr v1 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1738 self . olsr v1 output+="\n" 1739 1740 1741 if ( self . olsr process id v2 is not None) : 1742 stream olsr v2 = self . olsr process virt2 . GetInputStream () 1743 if ( stream olsr v2 .CanRead() ) : 1744 text olsr v2 = stream olsr v2 . read () 1745 if ( re . search (" received " , text olsr v2 )) : #parse feedback 1746 node output = text olsr v2 . partition (" ,") [0] 1747 bytes = re . split (" " , node output) [0] 1748 ip = re . split (" " , node output) [3] 1749 addr = self . nat table . get( ip ) 1750 #self . display0A(node output) #keep only necessary output 1751 self . olsr v2 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1752 self . olsr v2 output+="\n" 1753 1754 if ( self . olsr process id v3 is not None) : 1755 stream olsr v3 = self . olsr process virt3 . GetInputStream () 1756 if ( stream olsr v3 .CanRead() ) : 1757 text olsr v3 = stream olsr v3 . read () 1758 if ( re . search (" received " , text olsr v3 )) : #parse feedback 1759 node output = text olsr v3 . partition (" ,") [0] 1760 bytes = re . split (" " , node output) [0] 1761 ip = re . split (" " , node output) [3] 216 1762 addr = self . nat table . get( ip ) 1763 #self . display0A(node output) #keep only necessary output 1764 self . olsr v3 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1765 self . olsr v3 output+="\n" 1766 1767 if ( self . olsr process id v4 is not None) : 1768 stream olsr v4 = self . olsr process virt4 . GetInputStream () 1769 if ( stream olsr v4 .CanRead() ) : 1770 text olsr v4 = stream olsr v4 . read () 1771 if ( re . search (" received " , text olsr v4 )) : #parse feedback 1772 node output = text olsr v4 . partition (" ,") [0] 1773 bytes = re . split (" " , node output) [0] 1774 ip = re . split (" " , node output) [3] 1775 addr = self . nat table . get( ip ) 1776 #self . display0A(node output) #keep only necessary output 1777 self . olsr v4 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1778 self . olsr v4 output+="\n" 1779 1780 if ( self . olsr process id v5 is not None) : 1781 stream olsr v5 = self . olsr process virt5 . GetInputStream () 1782 if ( stream olsr v5 .CanRead() ) : 1783 text olsr v5 = stream olsr v5 . read () 1784 if ( re . search (" received " , text olsr v5 )) : #parse feedback 1785 node output = text olsr v5 . partition (" ,") [0] 1786 bytes = re . split (" " , node output) [0] 1787 ip = re . split (" " , node output) [3] 1788 addr = self . nat table . get( ip ) 1789 #self . display0A(node output) #keep only necessary output 1790 self . olsr v5 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1791 self . olsr v5 output+="\n" 1792 1793 if ( self . olsr process id v6 is not None) : 1794 stream olsr v6 = self . olsr process virt6 . GetInputStream () 1795 if ( stream olsr v6 .CanRead() ) : 1796 text olsr v6 = stream olsr v6 . read () 1797 if ( re . search (" received " , text olsr v6 )) : #parse feedback 1798 node output = text olsr v6 . partition (" ,") [0] 1799 bytes = re . split (" " , node output) [0] 1800 ip = re . split (" " , node output) [3] 1801 addr = self . nat table . get( ip ) 1802 #self . display0A(node output) #keep only necessary output 217 1803 self . olsr v6 output+=" Received packet ("+bytes+" bytes ) from "+addr+" ("+ip+") " 1804 self . olsr v6 output+="\n" 1805 1806 def doWait( self , time) : 1807 wait process = wx. Process ( self , ID WAIT PROCESS) 1808 wait process . Redirect () 1809 cmd = " sleep "+time 1810 wait process id = wx. Execute(cmd,wx.EXEC ASYNC, wait process ) 1811 1812 def OnProcessEnded( self , event) : 1813 1814 if (event . GetId() == ID WAIT PROCESS) : 1815 self .CheckTxQueue() 1816 1817 #TX/RX processes 1818 if (event . GetId() == ID PROCESS 1) : 1819 if ( self . kill 0A == False ) : 1820 stream usb0A = self . process usb0A . GetInputStream () 1821 if (stream usb0A .CanRead() ) : 1822 text = stream usb0A . read () 1823 self . display0A( text ) 1824 if ( self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()==" RX ") : 1825 self . decodeRxData(ID PROCESS 1) 1826 #need to decode for the stopped process as well 1827 if ( self . dual rx 0 == True) : 1828 self . decodeRxData(ID PROCESS 2) 1829 self . process usb0A . Destroy () 1830 self . process usb0A = None 1831 self . kill 0A = False 1832 self .doWait(" 120 ") 1833 1834 if (event . GetId() == ID PROCESS 2) : 1835 if ( self . kill 0B == False ) : 1836 stream usb0B = self . process usb0B . GetInputStream () 1837 if (stream usb0B .CanRead() ) : 1838 text = stream usb0B . read () 1839 self . display0B( text ) 1840 if ( self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" RX ") : 1841 self . decodeRxData(ID PROCESS 2) 1842 #need to decode for the stopped process as well 1843 if ( self . dual rx 0 == True) : 1844 self . decodeRxData(ID PROCESS 1) 1845 self . process usb0B . Destroy () 1846 self . process usb0B = None 218 1847 self . kill 0B = False 1848 self .doWait(" 120 ") 1849 1850 if (event . GetId() == ID PROCESS 3) : 1851 if ( self . kill 1A == False ) : 1852 stream usb1A = self . process usb1A . GetInputStream () 1853 if (stream usb1A .CanRead() ) : 1854 text = stream usb1A . read () 1855 self . display1A( text ) 1856 if ( self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" RX ") : 1857 self . decodeRxData(ID PROCESS 3) 1858 if ( self . dual rx 1==True) : 1859 self . decodeRxData(ID PROCESS 4) 1860 self . process usb1A . Destroy () 1861 self . process usb1A = None 1862 self . kill 1A = False 1863 self .doWait(" 120 ") 1864 1865 if (event . GetId() == ID PROCESS 4) : 1866 if ( self . kill 1B == False ) : 1867 stream usb1B = self . process usb1B . GetInputStream () 1868 if (stream usb1B .CanRead() ) : 1869 text = stream usb1B . read () 1870 self . display1B( text ) 1871 if ( self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" RX ") : 1872 self . decodeRxData(ID PROCESS 4) 1873 if ( self . dual rx 1==True) : 1874 self . decodeRxData(ID PROCESS 3) 1875 self . process usb1B . Destroy () 1876 self . process usb1B = None 1877 self . kill 1B = False 1878 self .doWait(" 120 ") 1879 1880 # if (event . GetId() == ID PROCESS 5) : 1881 # if ( self . kill virt1 == False ) : 1882 # stream virt1 = self . process virt1 . GetInputStream () 1883 # if ( stream virt1 .CanRead() ) : 1884 # text = stream virt1 . read () 1885 # self . olsr v1 output+=text 1886 # if ( self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()=="RX") : 1887 # self . decodeRxData(ID PROCESS 5) 1888 # self . process virt1 . Destroy () 1889 # self . process virt1 = None 1890 # self . kill virt1 = False 1891 # self .doWait("120") 219 1892 1893 1894 #encoding 1895 if (event . GetId() == ID PROCESS ENC 1) : 1896 stream encode usb0A = self . encode process usb0A . GetInputStream () 1897 if (stream encode usb0A .CanRead() ) : 1898 text encode usb0A = stream encode usb0A . read () 1899 self . display0A(text encode usb0A) 1900 self . display0A(" > Encoding Complete .\ n") 1901 tx packet=self . makePacket(" usrp0A ") 1902 #add to TX ready queue 1903 self . display0A(" > Adding outgoing packet to TX queue .\ n") 1904 self . tx pkt queue usrp0A . append( tx packet ) 1905 if ( tx packet . IsAckPacket ()==True) : 1906 self . slideTxWindow(" usrp0A " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1907 self . display0A(" > Moving TX ?d ACK to TX History queue \n") 1908 self . encode process usb0A . Destroy () 1909 self . encode process usb0A = None 1910 if (event . GetId() == ID PROCESS ENC 2) : 1911 stream encode usb0B = self . encode process usb0B . GetInputStream () 1912 if (stream encode usb0B .CanRead() ) : 1913 text encode usb0B = stream encode usb0B . read () 1914 self . display0B(text encode usb0B) 1915 self . display0B(" > Encoding Complete .\ n") 1916 tx packet=self . makePacket(" usrp0B ") 1917 #add to TX ready queue 1918 self . display0B(" > Adding outgoing packet to TX queue .\ n") 1919 self . tx pkt queue usrp0B .append( tx packet ) 1920 if ( tx packet . IsAckPacket ()==True) : 1921 self . slideTxWindow(" usrp0B " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1922 self . display0B(" > Moving TX ?d ACK to TX History queue \n") 1923 self . encode process usb0B . Destroy () 1924 self . encode process usb0B = None 1925 if (event . GetId() == ID PROCESS ENC 3) : 1926 stream encode usb1A = self . encode process usb1A . GetInputStream () 1927 if (stream encode usb1A .CanRead() ) : 1928 text encode usb1A = stream encode usb1A . read () 1929 self . display1A(text encode usb1A) 1930 self . display1A(" > Encoding Complete .\ n") 1931 tx packet=self . makePacket(" usrp1A ") 1932 #add to TX ready queue 1933 self . display1A(" > Adding outgoing packet to TX queue .\ n") 1934 self . tx pkt queue usrp1A . append( tx packet ) 220 1935 if ( tx packet . IsAckPacket ()==True) : 1936 self . slideTxWindow(" usrp1A " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1937 self . display1A(" > Moving TX ?d ACK to TX History queue \n") 1938 self . encode process usb1A . Destroy () 1939 self . encode process usb1A = None 1940 if (event . GetId() == ID PROCESS ENC 4) : 1941 stream encode usb1B = self . encode process usb1B . GetInputStream () 1942 if (stream encode usb1B .CanRead() ) : 1943 text encode usb1B = stream encode usb1B . read () 1944 self . display1B(text encode usb1B) 1945 self . display1B(" > Encoding Complete .\ n") 1946 tx packet=self . makePacket(" usrp1B ") 1947 #tx packet . print pkt () 1948 self . display1B(" > Adding outgoing packet to TX queue .\ n") 1949 self . tx pkt queue usrp1B .append( tx packet ) 1950 if ( tx packet . IsAckPacket ()==True) : 1951 self . slideTxWindow(" usrp1B " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1952 self . display1B(" > Moving TX ?d ACK to TX History queue \n") 1953 self . encode process usb1B . Destroy () 1954 self . encode process usb1B = None 1955 1956 if (event . GetId() == ID PROCESS ENC 5) : 1957 stream encode virt1 = self . encode process virt1 . GetInputStream () 1958 if ( stream encode virt1 .CanRead() ) : 1959 text encode virt1 = stream encode virt1 . read () 1960 self . olsr v1 output+=text encode virt1 1961 self . olsr v1 output+=" > Encoding Complete .\ n" 1962 tx packet=self . makePacket(" virt1 ") 1963 #tx packet . print pkt () 1964 self . olsr v1 output+=" > Adding outgoing packet to TX queue .\ n" 1965 self . tx pkt queue virt1 . append( tx packet ) 1966 if ( tx packet . IsAckPacket ()==True) : 1967 self . slideTxWindow(" virt1 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1968 self . olsr v1 output+=" > Moving TX ?d ACK to TX History queue \n" 1969 self . encode process virt1 . Destroy () 1970 self . encode process virt1 = None 1971 if (event . GetId() == ID PROCESS ENC 6) : 1972 stream encode virt2 = self . encode process virt2 . GetInputStream () 1973 if ( stream encode virt2 .CanRead() ) : 1974 text encode virt2 = stream encode virt2 . read () 1975 self . olsr v2 output+=text encode virt2 1976 self . olsr v2 output+=" > Encoding Complete .\ n" 221 1977 tx packet=self . makePacket(" virt2 ") 1978 #tx packet . print pkt () 1979 self . olsr v2 output+=" > Adding outgoing packet to TX queue .\ n" 1980 self . tx pkt queue virt2 . append( tx packet ) 1981 if ( tx packet . IsAckPacket ()==True) : 1982 self . slideTxWindow(" virt2 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1983 self . olsr v2 output+=" > Moving TX ?d ACK to TX History queue \n" 1984 self . encode process virt2 . Destroy () 1985 self . encode process virt2 = None 1986 if (event . GetId() == ID PROCESS ENC 7) : 1987 stream encode virt3 = self . encode process virt3 . GetInputStream () 1988 if ( stream encode virt3 .CanRead() ) : 1989 text encode virt3 = stream encode virt3 . read () 1990 self . olsr v3 output+=text encode virt3 1991 self . olsr v3 output+=" > Encoding Complete .\ n" 1992 tx packet=self . makePacket(" virt3 ") 1993 #tx packet . print pkt () 1994 self . olsr v3 output+=" > Adding outgoing packet to TX queue .\ n" 1995 self . tx pkt queue virt3 . append( tx packet ) 1996 if ( tx packet . IsAckPacket ()==True) : 1997 self . slideTxWindow(" virt3 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 1998 self . olsr v3 output+=" > Moving TX ?d ACK to TX History queue \n" 1999 self . encode process virt3 . Destroy () 2000 self . encode process virt3 = None 2001 if (event . GetId() == ID PROCESS ENC 8) : 2002 stream encode virt4 = self . encode process virt4 . GetInputStream () 2003 if ( stream encode virt4 .CanRead() ) : 2004 text encode virt4 = stream encode virt4 . read () 2005 self . olsr v4 output+=text encode virt4 2006 self . olsr v4 output+=" > Encoding Complete .\ n" 2007 tx packet=self . makePacket(" virt4 ") 2008 #tx packet . print pkt () 2009 self . olsr v4 output+=" > Adding outgoing packet to TX queue .\ n" 2010 self . tx pkt queue virt4 . append( tx packet ) 2011 if ( tx packet . IsAckPacket ()==True) : 2012 self . slideTxWindow(" virt4 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 2013 self . olsr v4 output+=" > Moving TX ?d ACK to TX History queue \n" 2014 self . encode process virt4 . Destroy () 2015 self . encode process virt4 = None 2016 if (event . GetId() == ID PROCESS ENC 9) : 2017 stream encode virt5 = self . encode process virt5 . GetInputStream () 2018 if ( stream encode virt5 .CanRead() ) : 222 2019 text encode virt5 = stream encode virt5 . read () 2020 self . olsr v5 output+=text encode virt5 2021 self . olsr v5 output+=" > Encoding Complete .\ n" 2022 tx packet=self . makePacket(" virt5 ") 2023 #tx packet . print pkt () 2024 self . olsr v5 output+=" > Adding outgoing packet to TX queue .\ n" 2025 self . tx pkt queue virt5 . append( tx packet ) 2026 if ( tx packet . IsAckPacket ()==True) : 2027 self . slideTxWindow(" virt5 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 2028 self . olsr v5 output+=" > Moving TX ?d ACK to TX History queue \n" 2029 self . encode process virt5 . Destroy () 2030 self . encode process virt5 = None 2031 if (event . GetId() == ID PROCESS ENC 10) : 2032 stream encode virt6 = self . encode process virt6 . GetInputStream () 2033 if ( stream encode virt6 .CanRead() ) : 2034 text encode virt6 = stream encode virt6 . read () 2035 self . olsr v6 output+=text encode virt6 2036 self . olsr v6 output+=" > Encoding Complete .\ n" 2037 tx packet=self . makePacket(" virt6 ") 2038 #tx packet . print pkt () 2039 self . olsr v6 output+=" > Adding outgoing packet to TX queue .\ n" 2040 self . tx pkt queue virt6 . append( tx packet ) 2041 if ( tx packet . IsAckPacket ()==True) : 2042 self . slideTxWindow(" virt6 " , tx packet ) #move newly transmitted ACK packet from TX to TX History 2043 self . olsr v6 output+=" > Moving TX ?d ACK to TX History queue \n" 2044 self . encode process virt6 . Destroy () 2045 self . encode process virt6 = None 2046 2047 #decoding 2048 if (event . GetId() == ID PROCESS DEC 1) : 2049 stream decode usb0A = self . decode process usb0A . GetInputStream () 2050 if (stream decode usb0A .CanRead() ) : 2051 text decode usb0A = stream decode usb0A . read () 2052 self . display0A(text decode usb0A) 2053 self . display0A(" > Decoding Complete . Starting Analysis .\ n") 2054 self . analyzeReceivedData(" usrp0A ") 2055 self . decode process usb0A . Destroy () 2056 self . decode process usb0A = None 2057 if (event . GetId() == ID PROCESS DEC 2) : 2058 stream decode usb0B = self . decode process usb0B . GetInputStream () 2059 if (stream decode usb0B .CanRead() ) : 2060 text decode usb0B = stream decode usb0B . read () 2061 self . display0B(text decode usb0B) 223 2062 self . display0B(" > Decoding Complete . Starting Analysis .\ n") 2063 self . analyzeReceivedData(" usrp0B ") 2064 self . decode process usb0B . Destroy () 2065 self . decode process usb0B = None 2066 if (event . GetId() == ID PROCESS DEC 3) : 2067 stream decode usb1A = self . decode process usb1A . GetInputStream () 2068 if (stream decode usb1A .CanRead() ) : 2069 text decode usb1A = stream decode usb1A . read () 2070 self . display1A(text decode usb1A) 2071 self . display1A(" > Decoding Complete . Starting Analysis .\ n") 2072 self . analyzeReceivedData(" usrp1A ") 2073 self . decode process usb1A . Destroy () 2074 self . decode process usb1A = None 2075 if (event . GetId() == ID PROCESS DEC 4) : 2076 stream decode usb1B = self . decode process usb1B . GetInputStream () 2077 if (stream decode usb1B .CanRead() ) : 2078 text decode usb1B = stream decode usb1B . read () 2079 self . display1B(text decode usb1B) 2080 self . display1B(" > Decoding Complete . Starting Analysis .\ n") 2081 #print text decode usb1B 2082 self . analyzeReceivedData(" usrp1B ") 2083 self . decode process usb1B . Destroy () 2084 self . decode process usb1B = None 2085 if (event . GetId() == ID PROCESS DEC 5) : 2086 stream decode virt1 = self . decode process virt1 . GetInputStream () 2087 if ( stream decode virt1 .CanRead() ) : 2088 text decode virt1 = stream decode virt1 . read () 2089 self . olsr v1 output+=text decode virt1 2090 self . olsr v1 output+=" > Decoding Complete . Starting Analysis .\ n" 2091 self . analyzeReceivedData(" virt1 ") 2092 self . decode process virt1 . Destroy () 2093 self . decode process virt1 = None 2094 if (event . GetId() == ID PROCESS DEC 6) : 2095 stream decode virt2 = self . decode process virt2 . GetInputStream () 2096 if ( stream decode virt2 .CanRead() ) : 2097 text decode virt2 = stream decode virt2 . read () 2098 self . olsr v2 output+=text decode virt2 2099 self . olsr v2 output+=" > Decoding Complete . Starting Analysis .\ n" 2100 self . analyzeReceivedData(" virt2 ") 2101 self . decode process virt2 . Destroy () 2102 self . decode process virt2 = None 2103 if (event . GetId() == ID PROCESS DEC 7) : 2104 stream decode virt3 = self . decode process virt3 . GetInputStream () 2105 if ( stream decode virt3 .CanRead() ) : 2106 text decode virt3 = stream decode virt3 . read () 224 2107 self . olsr v3 output+=text decode virt3 2108 self . olsr v3 output+=" > Decoding Complete . Starting Analysis .\ n" 2109 self . analyzeReceivedData(" virt3 ") 2110 self . decode process virt3 . Destroy () 2111 self . decode process virt3 = None 2112 if (event . GetId() == ID PROCESS DEC 8) : 2113 stream decode virt4 = self . decode process virt4 . GetInputStream () 2114 if ( stream decode virt4 .CanRead() ) : 2115 text decode virt4 = stream decode virt4 . read () 2116 self . olsr v4 output+=text decode virt4 2117 self . olsr v4 output+=" > Decoding Complete . Starting Analysis .\ n" 2118 self . analyzeReceivedData(" virt4 ") 2119 self . decode process virt4 . Destroy () 2120 self . decode process virt4 = None 2121 if (event . GetId() == ID PROCESS DEC 9) : 2122 stream decode virt5 = self . decode process virt5 . GetInputStream () 2123 if ( stream decode virt5 .CanRead() ) : 2124 text decode virt5 = stream decode virt5 . read () 2125 self . olsr v5 output+=text decode virt5 2126 self . olsr v5 output+=" > Decoding Complete . Starting Analysis .\ n" 2127 self . analyzeReceivedData(" virt5 ") 2128 self . decode process virt5 . Destroy () 2129 self . decode process virt5 = None 2130 if (event . GetId() == ID PROCESS DEC 10) : 2131 stream decode virt6 = self . decode process virt6 . GetInputStream () 2132 if ( stream decode virt6 .CanRead() ) : 2133 text decode virt6 = stream decode virt6 . read () 2134 self . olsr v6 output+=text decode virt6 2135 self . olsr v6 output+=" > Decoding Complete . Starting Analysis .\ n" 2136 self . analyzeReceivedData(" virt6 ") 2137 self . decode process virt6 . Destroy () 2138 self . decode process virt6 = None 2139 2140 2141 2142 def makePacket( self , node id ) : 2143 #packet creation function 2144 path = self . experiment path+node id+"/" 2145 2146 if ( self .FindWindowById( self . getTxRxId( node id )) . GetStringSelection ()==" TX ") : 2147 filename=" logtx . txt " 2148 f=open(path+filename , ?r ?) 2149 msg marks=f . readline () . strip () 2150 msg count = "0" 2151 pkts lost = "0" 225 2152 current node name = node id 2153 current node address = self . getNodeAddress( node id ) 2154 pkt to address = self . getNodeAddress( self .FindWindowById( self . getRecipientId ( node id )) . GetValue() ) 2155 pkt from address = self . getNodeAddress( node id ) 2156 pkt file name = self .FindWindowById( self . getSrcNameId( node id )) . GetValue() 2157 pkt rssi value = self . rssi 2158 else : 2159 filename = " logrx . txt " 2160 f=open(path+filename , ?r ?) 2161 msg marks = f . readline () . strip () 2162 msg count = f . readline () . strip () 2163 pkts lost = f . readline () . strip () 2164 current node name = f . readline () . strip () 2165 current node address = f . readline () . strip () 2166 pkt to address = f . readline () . strip () 2167 pkt from address = f . readline () . strip () 2168 pkt file name = f . readline () . strip () 2169 pkt rssi value = f . readline () . strip () 2170 2171 2172 currentPacket = packet . packet( node id=current node name , node address=current node address , to address=pkt to address , 2173 from address=pkt from address , filename=pkt file name ,marks=msg marks , messages found=msg count , 2174 packets lost=pkts lost , rssi value=pkt rssi value ) 2175 #print packet for debugging 2176 #currentPacket . print pkt () 2177 2178 return currentPacket 2179 2180 def analyzeReceivedData( self , node id ) : 2181 path = self . experiment path+node id+"/" 2182 receivedPacket = self . makePacket( node id ) 2183 2184 if ( receivedPacket . GetToAddress()==receivedPacket . GetNodeAddress() ) : #accept packet 2185 #self .FindWindowById( self .getLogWindowId( node id )) .AppendText("nn>Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress() +".") 2186 #needs to be more efficient . . . . but this works 2187 if ( node id == " usrp0A ") :#add packet to RX queue for this node 2188 self . rx pkt queue usrp0A . append( receivedPacket ) 2189 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+".") 226 2190 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress() +" ?s RX Pkt Queue .") 2191 elif ( node id == " usrp0B ") : 2192 self . rx pkt queue usrp0B .append( receivedPacket ) 2193 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+".") 2194 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress() +" ?s RX Pkt Queue .") 2195 elif ( node id == " usrp1A ") : 2196 self . rx pkt queue usrp1A . append( receivedPacket ) 2197 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+".") 2198 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress() +" ?s RX Pkt Queue .") 2199 elif ( node id == " usrp1B ") : 2200 self . rx pkt queue usrp1B .append( receivedPacket ) 2201 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+".") 2202 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress() +" ?s RX Pkt Queue .") 2203 elif ( node id == " virt1 ") : 2204 self . rx pkt queue virt1 . append( receivedPacket ) 2205 self . olsr v1 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 2206 self . olsr v1 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2207 elif ( node id == " virt2 ") : 2208 self . rx pkt queue virt2 . append( receivedPacket ) 2209 self . olsr v2 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 2210 self . olsr v2 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2211 elif ( node id == " virt3 ") : 2212 self . rx pkt queue virt3 . append( receivedPacket ) 2213 self . olsr v3 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 2214 self . olsr v3 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2215 elif ( node id == " virt4 ") : 2216 self . rx pkt queue virt4 . append( receivedPacket ) 2217 self . olsr v4 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 227 2218 self . olsr v4 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2219 elif ( node id == " virt5 ") : 2220 self . rx pkt queue virt5 . append( receivedPacket ) 2221 self . olsr v5 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 2222 self . olsr v5 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2223 elif ( node id == " virt6 ") : 2224 self . rx pkt queue virt6 . append( receivedPacket ) 2225 self . olsr v6 output+="\n > Accepting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+"." 2226 self . olsr v6 output+="\n > Adding RX ?d Packet to node "+receivedPacket . GetToAddress () +" ?s RX Pkt Queue ." 2227 2228 #self .FindWindowById( self .getLogWindowId( node id )) .AppendText("nn>Adding RX?d Packet to node "+receivedPacket . GetToAddress() +"?s RX Pkt Queue.") 2229 2230 #if this packet received is not an ACK, trigger the transmission of an ACK packet 2231 if ( receivedPacket . IsAckPacket ()==False ) : 2232 #form ack packet for the received file 2233 ack name = " Ack "+receivedPacket . GetFilename () 2234 ack file name = path+ack name 2235 2236 #create ACK packet 2237 file=open( ack file name , ?w ?) 2238 file . write (" ACK "+receivedPacket . GetFilename ()+"\n") 2239 file . close () 2240 2241 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Sending ACK : "+ ack file name+" from "+receivedPacket . node id+"("+receivedPacket . GetNodeAddress()+") to "+receivedPacket . GetFromAddress() + ".") 2242 self . transmitToFrom( to radio=receivedPacket . GetFromAddress() , from radio= receivedPacket . GetNodeAddress() , message=ack name) 2243 #transmission of ACK is treated as "fire and forget" activity since 2244 # if a transmitter doesn ?t receive the ACK, it will retransmit anyway , so slide the RX window 2245 self . slideRxWindow(node id , receivedPacket ) #move received packet from RX to RX History after sending ACK 2246 2247 2248 else : #packet is an ACK 2249 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Received ACK ("+ receivedPacket . GetFilename ()+") from "+receivedPacket . GetFromAddress()+".") 228 2250 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Removing ACK ?d Packet from "+receivedPacket . GetToAddress() +" ?s TX Pkt Queue .") 2251 #move ACK?d packet from TX queue to TX history to keep record of successes 2252 self . slideTxWindow(node id , receivedPacket ) 2253 #add ACK packet to RX history queue for record keeping purposes 2254 self . slideRxWindow(node id , receivedPacket ) 2255 else : 2256 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > Rejecting packet addressed to "+receivedPacket . GetToAddress()+" from "+receivedPacket . GetFromAddress()+".") 2257 2258 2259 #setup a queue for each node , and if you transmit a response , move to a historical data queue 2260 #instead of keeping the information in the ready for action queue 2261 def slideTxWindow( self ,node name , packet) : 2262 if (node name==" usrp0A ") : 2263 self . tx pkt queue historical usrp0A . append( self . tx pkt queue usrp0A .pop( self . getTxIndexInList(node name , packet))) 2264 elif (node name==" usrp0B ") : 2265 self . tx pkt queue historical usrp0B .append( self . tx pkt queue usrp0B .pop( self . getTxIndexInList(node name , packet))) 2266 elif (node name==" usrp1A ") : 2267 self . tx pkt queue historical usrp1A . append( self . tx pkt queue usrp1A .pop( self . getTxIndexInList(node name , packet))) 2268 elif (node name==" usrp1B ") : 2269 self . tx pkt queue historical usrp1B .append( self . tx pkt queue usrp1B .pop( self . getTxIndexInList(node name , packet))) 2270 elif (node name==" virt1 ") : 2271 self . tx pkt queue historical virt1 . append( self . tx pkt queue virt1 .pop( self . getTxIndexInList(node name , packet))) 2272 elif (node name==" virt2 ") : 2273 self . tx pkt queue historical virt2 . append( self . tx pkt queue virt2 .pop( self . getTxIndexInList(node name , packet))) 2274 elif (node name==" virt3 ") : 2275 self . tx pkt queue historical virt3 . append( self . tx pkt queue virt3 .pop( self . getTxIndexInList(node name , packet))) 2276 elif (node name==" virt4 ") : 2277 self . tx pkt queue historical virt4 . append( self . tx pkt queue virt4 .pop( self . getTxIndexInList(node name , packet))) 2278 elif (node name==" virt5 ") : 2279 self . tx pkt queue historical virt5 . append( self . tx pkt queue virt5 .pop( self . getTxIndexInList(node name , packet))) 2280 elif (node name==" virt6 ") : 2281 self . tx pkt queue historical virt6 . append( self . tx pkt queue virt6 .pop( self . getTxIndexInList(node name , packet))) 229 2282 2283 def slideRxWindow( self ,node name , packet) : 2284 if (node name==" usrp0A ") : 2285 self . rx pkt queue historical usrp0A . append( self . rx pkt queue usrp0A .pop( self . getRxIndexInList(node name , packet))) 2286 elif (node name==" usrp0B ") : 2287 self . rx pkt queue historical usrp0B .append( self . rx pkt queue usrp0B .pop( self . getRxIndexInList(node name , packet))) 2288 elif (node name==" usrp1A ") : 2289 self . rx pkt queue historical usrp1A . append( self . rx pkt queue usrp1A .pop( self . getRxIndexInList(node name , packet))) 2290 elif (node name==" usrp1B ") : 2291 self . rx pkt queue historical usrp1B .append( self . rx pkt queue usrp1B .pop( self . getRxIndexInList(node name , packet))) 2292 elif (node name==" virt1 ") : 2293 self . rx pkt queue historical virt1 . append( self . rx pkt queue virt1 .pop( self . getRxIndexInList(node name , packet))) 2294 elif (node name==" virt2 ") : 2295 self . rx pkt queue historical virt2 . append( self . rx pkt queue virt2 .pop( self . getRxIndexInList(node name , packet))) 2296 elif (node name==" virt3 ") : 2297 self . rx pkt queue historical virt3 . append( self . rx pkt queue virt3 .pop( self . getRxIndexInList(node name , packet))) 2298 elif (node name==" virt4 ") : 2299 self . rx pkt queue historical virt4 . append( self . rx pkt queue virt4 .pop( self . getRxIndexInList(node name , packet))) 2300 elif (node name==" virt5 ") : 2301 self . rx pkt queue historical virt5 . append( self . rx pkt queue virt5 .pop( self . getRxIndexInList(node name , packet))) 2302 elif (node name==" virt6 ") : 2303 self . rx pkt queue historical virt6 . append( self . rx pkt queue virt6 .pop( self . getRxIndexInList(node name , packet))) 2304 2305 2306 def getTxIndexInList( self ,node name , packet) : 2307 if (node name==" usrp0A ") : 2308 for i in self . tx pkt queue usrp0A : 2309 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2310 return self . tx pkt queue usrp0A . index( i ) 2311 elif (node name==" usrp0B ") : 2312 for i in self . tx pkt queue usrp0B : 2313 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2314 return self . tx pkt queue usrp0B . index( i ) 2315 elif (node name==" usrp1A ") : 2316 for i in self . tx pkt queue usrp1A : 230 2317 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2318 return self . tx pkt queue usrp1A . index( i ) 2319 elif (node name==" usrp1B ") : 2320 for i in self . tx pkt queue usrp1B : 2321 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2322 return self . tx pkt queue usrp1B . index( i ) 2323 elif (node name==" virt1 ") : 2324 for i in self . tx pkt queue virt1 : 2325 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2326 return self . tx pkt queue virt1 . index( i ) 2327 elif (node name==" virt2 ") : 2328 for i in self . tx pkt queue virt2 : 2329 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2330 return self . tx pkt queue virt2 . index( i ) 2331 elif (node name==" virt3 ") : 2332 for i in self . tx pkt queue virt3 : 2333 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2334 return self . tx pkt queue virt3 . index( i ) 2335 elif (node name==" virt4 ") : 2336 for i in self . tx pkt queue virt4 : 2337 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2338 return self . tx pkt queue virt4 . index( i ) 2339 elif (node name==" virt5 ") : 2340 for i in self . tx pkt queue virt5 : 2341 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2342 return self . tx pkt queue virt5 . index( i ) 2343 elif (node name==" virt6 ") : 2344 for i in self . tx pkt queue virt6 : 2345 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2346 return self . tx pkt queue virt6 . index( i ) 2347 2348 2349 def getRxIndexInList( self ,node name , packet) : 2350 if (node name==" usrp0A ") : 2351 for i in self . rx pkt queue usrp0A : 2352 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2353 return self . rx pkt queue usrp0A . index( i ) 2354 elif (node name==" usrp0B ") : 2355 for i in self . rx pkt queue usrp0B : 2356 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2357 return self . rx pkt queue usrp0B . index( i ) 2358 elif (node name==" usrp1A ") : 2359 for i in self . rx pkt queue usrp1A : 2360 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2361 return self . rx pkt queue usrp1A . index( i ) 231 2362 elif (node name==" usrp1B ") : 2363 for i in self . rx pkt queue usrp1B : 2364 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2365 return self . rx pkt queue usrp1B . index( i ) 2366 elif (node name==" virt1 ") : 2367 for i in self . rx pkt queue virt1 : 2368 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2369 return self . rx pkt queue virt1 . index( i ) 2370 elif (node name==" virt2 ") : 2371 for i in self . rx pkt queue virt2 : 2372 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2373 return self . rx pkt queue virt2 . index( i ) 2374 elif (node name==" virt3 ") : 2375 for i in self . rx pkt queue virt3 : 2376 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2377 return self . rx pkt queue virt3 . index( i ) 2378 elif (node name==" virt4 ") : 2379 for i in self . rx pkt queue virt4 : 2380 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2381 return self . rx pkt queue virt4 . index( i ) 2382 elif (node name==" virt5 ") : 2383 for i in self . rx pkt queue virt5 : 2384 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2385 return self . rx pkt queue virt5 . index( i ) 2386 elif (node name==" virt6 ") : 2387 for i in self . rx pkt queue virt6 : 2388 if (packet . GetFilename () . find ( i . GetFilename () )>=0): 2389 return self . rx pkt queue virt6 . index( i ) 2390 2391 2392 def transmitToFrom( self , to radio , from radio , message) : 2393 #print "Inside transmitToFrom()" 2394 2395 to radio name = self .getNodeName( to radio ) 2396 from radio name = self .getNodeName( from radio ) 2397 message name = message #path included in this name 2398 2399 #change parameters for "to" radio so that it is in RX mode 2400 if ( to radio name != " All ") : 2401 id radio box = self . getTxRxId( to radio name ) 2402 self . toggleRadioBoxSelection ( id radio box ) 2403 self . SendEvent(mycontrol=self .TxOrRx, event=wx.EVT RADIOBOX, id=id radio box ) #calls radio button event 2404 self . SendEvent(mycontrol=self . updateButton , event=wx.EVT BUTTON, id=self . getUpateButtonId( to radio name ))#calls update button event 232 2405 #else : 2406 #handle event where all radios must be updated and put in RX mode 2407 2408 #change parameters for "from" radio so that it is in TX mode 2409 id radio box = self . getTxRxId(from radio name) 2410 self . toggleRadioBoxSelection ( id radio box ) 2411 self . SendEvent(mycontrol=self .TxOrRx, event=wx.EVT RADIOBOX, id=id radio box ) #calls radio button event 2412 self .FindWindowById( self . getSrcNameId(from radio name)) . SetValue(message name) 2413 self .FindWindowById( self . getRecipientId (from radio name)) . SetValue( to radio name ) 2414 self . SendEvent(mycontrol=self . updateButton , event=wx.EVT BUTTON, id=self . getUpateButtonId( from radio name))#calls update button event 2415 2416 #start RX 2417 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId ( to radio name )) 2418 #start TX 2419 self . SendEvent(mycontrol=self . startButton , event=wx.EVT BUTTON, id=self . getStartButtonId ( from radio name)) 2420 2421 def SendEvent ( self , mycontrol , event , id ) : 2422 cmd = wx.CommandEvent(event . evtType [0]) 2423 cmd. SetEventObject(mycontrol) 2424 cmd. SetId( id ) 2425 mycontrol . GetEventHandler () . ProcessEvent(cmd) 2426 2427 def display0A( self , some text) : 2428 self .FindWindowById(ID LOGWIN USB0A) .AppendText(some text) 2429 2430 def display0B( self , some text) : 2431 self .FindWindowById(ID LOGWIN USB0B) .AppendText(some text) 2432 2433 def display1A( self , some text) : 2434 self .FindWindowById(ID LOGWIN USB1A) .AppendText(some text) 2435 2436 def display1B( self , some text) : 2437 self .FindWindowById(ID LOGWIN USB1B) .AppendText(some text) 2438 2439 def getLogWindowId( self , node name) : 2440 if (node name==" usrp0A ") : 2441 return ID LOGWIN USB0A 2442 elif (node name==" usrp0B ") : 2443 return ID LOGWIN USB0B 2444 elif (node name==" usrp1A ") : 2445 return ID LOGWIN USB1A 233 2446 elif (node name==" usrp1B ") : 2447 return ID LOGWIN USB1B 2448 2449 def getNodeName( self , address ) : 2450 if ( address==self . nat table . items () [0][0]) : 2451 return " usrp0A " 2452 elif ( address==self . nat table . items () [1][0]) : 2453 return " usrp0B " 2454 elif ( address==self . nat table . items () [2][0]) : 2455 return " usrp1A " 2456 elif ( address==self . nat table . items () [3][0]) : 2457 return " usrp1B " 2458 elif ( address==self . nat table . items () [4][0]) : 2459 return " virt1 " 2460 elif ( address==self . nat table . items () [5][0]) : 2461 return " virt2 " 2462 elif ( address==self . nat table . items () [6][0]) : 2463 return " virt3 " 2464 elif ( address==self . nat table . items () [7][0]) : 2465 return " virt4 " 2466 elif ( address==self . nat table . items () [8][0]) : 2467 return " virt5 " 2468 elif ( address==self . nat table . items () [9][0]) : 2469 return " virt6 " 2470 elif ( address==" 888 ") : 2471 return " All " 2472 else : return " NO_NAME_MATCH " 2473 2474 def getNodeAddress( self , node name) : 2475 if (node name==" usrp0A ") : 2476 return self . nat table . items () [0][0] 2477 elif (node name==" usrp0B ") : 2478 return self . nat table . items () [1][0] 2479 elif (node name==" usrp1A ") : 2480 return self . nat table . items () [2][0] 2481 elif (node name==" usrp1B ") : 2482 return self . nat table . items () [3][0] 2483 elif (node name==" virt1 ") : 2484 return self . nat table . items () [4][0] 2485 elif (node name==" virt2 ") : 2486 return self . nat table . items () [5][0] 2487 elif (node name==" virt3 ") : 2488 return self . nat table . items () [6][0] 2489 elif (node name==" virt4 ") : 2490 return self . nat table . items () [7][0] 234 2491 elif (node name==" virt5 ") : 2492 return self . nat table . items () [8][0] 2493 elif (node name==" virt6 ") : 2494 return self . nat table . items () [9][0] 2495 elif (node name==" All ") : 2496 return " 888 " 2497 else : return " NO_ADDR_MATCH " 2498 2499 def getTxRxId( self , node name) : 2500 if (node name==" usrp0A ") : 2501 return ID TXRX USB0A 2502 elif (node name==" usrp0B ") : 2503 return ID TXRX USB0B 2504 elif (node name==" usrp1A ") : 2505 return ID TXRX USB1A 2506 elif (node name==" usrp1B ") : 2507 return ID TXRX USB1B 2508 elif (node name==" virt1 ") : 2509 return ID TXRX VIRT1 2510 elif (node name==" virt2 ") : 2511 return ID TXRX VIRT2 2512 elif (node name==" virt3 ") : 2513 return ID TXRX VIRT3 2514 elif (node name==" virt4 ") : 2515 return ID TXRX VIRT4 2516 elif (node name==" virt5 ") : 2517 return ID TXRX VIRT5 2518 elif (node name==" virt6 ") : 2519 return ID TXRX VIRT6 2520 2521 def getStartButtonId ( self , node name) : 2522 if (node name==" usrp0A ") : 2523 return ID START USB0A 2524 elif (node name==" usrp0B ") : 2525 return ID START USB0B 2526 elif (node name==" usrp1A ") : 2527 return ID START USB1A 2528 elif (node name==" usrp1B ") : 2529 return ID START USB1B 2530 elif (node name==" virt1 ") : 2531 return ID START VIRT1 2532 elif (node name==" virt2 ") : 2533 return ID START VIRT2 2534 elif (node name==" virt3 ") : 2535 return ID START VIRT3 235 2536 elif (node name==" virt4 ") : 2537 return ID START VIRT4 2538 elif (node name==" virt5 ") : 2539 return ID START VIRT5 2540 elif (node name==" virt6 ") : 2541 return ID START VIRT6 2542 2543 def getStopButtonId( self , node name) : 2544 if (node name==" usrp0A ") : 2545 return ID STOP USB0A 2546 elif (node name==" usrp0B ") : 2547 return ID STOP USB0B 2548 elif (node name==" usrp1A ") : 2549 return ID STOP USB1A 2550 elif (node name==" usrp1B ") : 2551 return ID STOP USB1B 2552 elif (node name==" virt1 ") : 2553 return ID STOP VIRT1 2554 elif (node name==" virt2 ") : 2555 return ID STOP VIRT2 2556 elif (node name==" virt3 ") : 2557 return ID STOP VIRT3 2558 elif (node name==" virt4 ") : 2559 return ID STOP VIRT4 2560 elif (node name==" virt5 ") : 2561 return ID STOP VIRT5 2562 elif (node name==" virt6 ") : 2563 return ID STOP VIRT6 2564 2565 def getUpateButtonId( self , node name) : 2566 if (node name==" usrp0A ") : 2567 return ID UPDATE USB0A 2568 elif (node name==" usrp0B ") : 2569 return ID UPDATE USB0B 2570 elif (node name==" usrp1A ") : 2571 return ID UPDATE USB1A 2572 elif (node name==" usrp1B ") : 2573 return ID UPDATE USB1B 2574 elif (node Name==" virt1 ") : 2575 return ID UPDATE VIRT1 2576 elif (node Name==" virt2 ") : 2577 return ID UPDATE VIRT2 2578 elif (node Name==" virt3 ") : 2579 return ID UPDATE VIRT3 2580 elif (node Name==" virt4 ") : 236 2581 return ID UPDATE VIRT4 2582 elif (node Name==" virt5 ") : 2583 return ID UPDATE VIRT5 2584 elif (node Name==" virt6 ") : 2585 return ID UPDATE VIRT6 2586 2587 def getSrcNameId( self , node name) : 2588 if (node name==" usrp0A ") : 2589 return ID SRC NAME USB0A 2590 elif (node name==" usrp0B ") : 2591 return ID SRC NAME USB0B 2592 elif (node name==" usrp1A ") : 2593 return ID SRC NAME USB1A 2594 elif (node name==" usrp1B ") : 2595 return ID SRC NAME USB1B 2596 2597 def getRecipientId ( self , node name) : 2598 if (node name==" usrp0A ") : 2599 return ID RECIPIENT USB0A 2600 elif (node name==" usrp0B ") : 2601 return ID RECIPIENT USB0B 2602 elif (node name==" usrp1A ") : 2603 return ID RECIPIENT USB1A 2604 elif (node name==" usrp1B ") : 2605 return ID RECIPIENT USB1B 2606 2607 def getDecodeProcessId( self , node name) : 2608 if (node name==" usrp0A ") : 2609 return ID PROCESS DEC 1 2610 elif (node name==" usrp0B ") : 2611 return ID PROCESS DEC 2 2612 elif (node name==" usrp1A ") : 2613 return ID PROCESS DEC 3 2614 elif (node name==" usrp1B ") : 2615 return ID PROCESS DEC 4 2616 elif (node name==" virt1 ") : 2617 return ID PROCESS DEC 5 2618 elif (node name==" virt2 ") : 2619 return ID PROCESS DEC 6 2620 elif (node name==" virt3 ") : 2621 return ID PROCESS DEC 7 2622 elif (node name==" virt4 ") : 2623 return ID PROCESS DEC 8 2624 elif (node name==" virt5 ") : 2625 return ID PROCESS DEC 9 237 2626 elif (node name==" virt6 ") : 2627 return ID PROCESS DEC 10 2628 2629 def getEncodeProcessId( self , node name) : 2630 if (node name==" usrp0A ") : 2631 return ID PROCESS ENC 1 2632 elif (node name==" usrp0B ") : 2633 return ID PROCESS ENC 2 2634 elif (node name==" usrp1A ") : 2635 return ID PROCESS ENC 3 2636 elif (node name==" usrp1B ") : 2637 return ID PROCESS ENC 4 2638 elif (node name==" virt1 ") : 2639 return ID PROCESS ENC 5 2640 elif (node name==" virt2 ") : 2641 return ID PROCESS ENC 6 2642 elif (node name==" virt3 ") : 2643 return ID PROCESS ENC 7 2644 elif (node name==" virt4 ") : 2645 return ID PROCESS ENC 8 2646 elif (node name==" virt5 ") : 2647 return ID PROCESS ENC 9 2648 elif (node name==" virt6 ") : 2649 return ID PROCESS ENC 10 2650 2651 def getDecodeProcess( self , node name) : 2652 if (node name==" usrp0A ") : 2653 return self . decode process usb0A 2654 elif (node name==" usrp0B ") : 2655 return self . decode process usb0B 2656 elif (node name==" usrp1A ") : 2657 return self . decode process usb1A 2658 elif (node name==" usrp1B ") : 2659 return self . decode process usb1B 2660 elif (node name==" virt1 ") : 2661 return self . decode process virt1 2662 elif (node name==" virt2 ") : 2663 return self . decode process virt2 2664 elif (node name==" virt3 ") : 2665 return self . decode process virt3 2666 elif (node name==" virt4 ") : 2667 return self . decode process virt4 2668 elif (node name==" virt5 ") : 2669 return self . decode process virt5 2670 elif (node name==" virt6 ") : 238 2671 return self . decode process virt6 2672 2673 def getEncodeProcess( self , node name) : 2674 if (node name==" usrp0A ") : 2675 return self . encode process usb0A 2676 elif (node name==" usrp0B ") : 2677 return self . encode process usb0B 2678 elif (node name==" usrp1A ") : 2679 return self . encode process usb1A 2680 elif (node name==" usrp1B ") : 2681 return self . encode process usb1B 2682 elif (node name==" virt1 ") : 2683 return self . encode process virt1 2684 elif (node name==" virt2 ") : 2685 return self . encode process virt2 2686 elif (node name==" virt3 ") : 2687 return self . encode process virt3 2688 elif (node name==" virt4 ") : 2689 return self . encode process virt4 2690 elif (node name==" virt5 ") : 2691 return self . encode process virt5 2692 elif (node name==" virt6 ") : 2693 return self . encode process virt6 2694 2695 def toggleRadioBoxSelection ( self , id ) : 2696 if ( self .FindWindowById( id ) . GetSelection ()==0): 2697 self .FindWindowById( id ) . SetSelection (1) 2698 else : 2699 self .FindWindowById( id ) . SetSelection (0) 2700 2701 def decodeRxData( self , id ) : 2702 if ( id==ID PROCESS 1) : 2703 if ( self . decode process usb0A is None) : 2704 self . decode cmd = self . experiment path+ " usrp0A / usrp "+ self . experiment path+" usrp0A / usrp0Aparams . ini " 2705 self . decode process usb0A = wx. Process ( self , id=ID PROCESS DEC 1) 2706 self . decode process usb0A . Redirect () 2707 self . decode process id usb0A = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process usb0A ) 2708 self . display0A(" > Decoding Received Message ...\ n") 2709 self . display0A(" > Executing : "+self . decode cmd+"\n") 2710 elif ( id==ID PROCESS 2) : 2711 if ( self . decode process usb0B is None) : 2712 self . decode cmd = self . experiment path+ " usrp0B / usrp "+ self . experiment path+" usrp0B / usrp0Bparams . ini " 239 2713 self . decode process usb0B = wx. Process ( self , id=ID PROCESS DEC 2) 2714 self . decode process usb0B . Redirect () 2715 self . decode process id usb0B = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process usb0B ) 2716 self . display0B(" > Decoding Received Message ...\ n") 2717 self . display0B(" > Executing : "+self . decode cmd+"\n") 2718 elif ( id==ID PROCESS 3) : 2719 if ( self . decode process usb1A is None) : 2720 self . decode cmd = self . experiment path+ " usrp1A / usrp "+ self . experiment path+" usrp1A / usrp1Aparams . ini " #used to be rx . ini 2721 self . decode process usb1A = wx. Process ( self , id=ID PROCESS DEC 3) 2722 self . decode process usb1A . Redirect () 2723 self . decode process id usb1A = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process usb1A ) 2724 self . display1A(" > Decoding Received Message ...\ n") 2725 self . display1A(" > Executing : "+self . decode cmd+"\n") 2726 elif ( id==ID PROCESS 4) : 2727 if ( self . decode process usb1B is None) : 2728 self . decode cmd = self . experiment path+ " usrp1B / usrp "+ self . experiment path+" usrp1B / usrp1Bparams . ini " 2729 self . decode process usb1B = wx. Process ( self , id=ID PROCESS DEC 4) 2730 self . decode process usb1B . Redirect () 2731 self . decode process id usb1B = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process usb1B ) 2732 self . display1B(" > Decoding Received Message ...\ n") 2733 self . display1B(" > Executing : "+self . decode cmd+"\n") 2734 #decode for additional nodes 2735 elif ( id==ID PROCESS 5) : 2736 if ( self . decode process virt1 is None) : 2737 self . decode cmd = self . experiment path+ " virt1 / usrp "+ self . experiment path+" virt1 / virt1params . ini " 2738 self . decode process virt1 = wx. Process ( self , id=ID PROCESS DEC 5) 2739 self . decode process virt1 . Redirect () 2740 self . decode process id virt1 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt1 ) 2741 self . olsr v1 output+=" > Decoding Received Message ...\ n" 2742 self . olsr v1 output+=" > Executing : "+self . decode cmd+"\n" 2743 elif ( id==ID PROCESS 6) : 2744 if ( self . decode process virt2 is None) : 2745 self . decode cmd = self . experiment path+ " virt2 / usrp "+ self . experiment path+" virt2 / virt2params . ini " 2746 self . decode process virt2 = wx. Process ( self , id=ID PROCESS DEC 6) 2747 self . decode process virt2 . Redirect () 2748 self . decode process id virt2 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt2 ) 240 2749 self . olsr v2 output+=" > Decoding Received Message ...\ n" 2750 self . olsr v2 output+=" > Executing : "+self . decode cmd+"\n" 2751 elif ( id==ID PROCESS 7) : 2752 if ( self . decode process virt3 is None) : 2753 self . decode cmd = self . experiment path+ " virt3 / usrp "+ self . experiment path+" virt3 / virt3params . ini " 2754 self . decode process virt3 = wx. Process ( self , id=ID PROCESS DEC 7) 2755 self . decode process virt3 . Redirect () 2756 self . decode process id virt3 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt3 ) 2757 self . olsr v3 output+=" > Decoding Received Message ...\ n" 2758 self . olsr v3 output+=" > Executing : "+self . decode cmd+"\n" 2759 elif ( id==ID PROCESS 8) : 2760 if ( self . decode process virt4 is None) : 2761 self . decode cmd = self . experiment path+ " virt4 / usrp "+ self . experiment path+" virt4 / virt4params . ini " 2762 self . decode process virt4 = wx. Process ( self , id=ID PROCESS DEC 8) 2763 self . decode process virt4 . Redirect () 2764 self . decode process id virt4 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt4 ) 2765 self . olsr v4 output+=" > Decoding Received Message ...\ n" 2766 self . olsr v4 output+=" > Executing : "+self . decode cmd+"\n" 2767 elif ( id==ID PROCESS 9) : 2768 if ( self . decode process virt5 is None) : 2769 self . decode cmd = self . experiment path+ " virt5 / usrp "+ self . experiment path+" virt5 / virt5params . ini " 2770 self . decode process virt5 = wx. Process ( self , id=ID PROCESS DEC 9) 2771 self . decode process virt5 . Redirect () 2772 self . decode process id virt5 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt5 ) 2773 self . olsr v5 output+=" > Decoding Received Message ...\ n" 2774 self . olsr v5 output+=" > Executing : "+self . decode cmd+"\n" 2775 elif ( id==ID PROCESS 10) : 2776 if ( self . decode process virt6 is None) : 2777 self . decode cmd = self . experiment path+ " virt6 / usrp "+ self . experiment path+" virt6 / virt6params . ini " 2778 self . decode process virt6 = wx. Process ( self , id=ID PROCESS DEC 10) 2779 self . decode process virt6 . Redirect () 2780 self . decode process id virt6 = wx. Execute( self . decode cmd ,wx.EXEC ASYNC, self . decode process virt6 ) 2781 self . olsr v6 output+=" > Decoding Received Message ...\ n" 2782 self . olsr v6 output+=" > Executing : "+self . decode cmd+"\n" 2783 2784 2785 def radioClick ( self , event) : 241 2786 #change source name and sink name to defaults 2787 if (event . GetId()==ID TXRX USB0A) : 2788 if ( self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()==" RX ") : 2789 self .FindWindowById(ID SRC NAME USB0A) . SetValue(" usrp . srp ") 2790 self .FindWindowById(ID SINK NAME USB0A) . SetValue(" usrp . rxd ") 2791 else : 2792 self .FindWindowById(ID SRC NAME USB0A) . SetValue(" ID456 . txt ") 2793 self .FindWindowById(ID SINK NAME USB0A) . SetValue(" usrp . srp ") 2794 elif (event . GetId()==ID TXRX USB0B) : 2795 if ( self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" RX ") : 2796 self .FindWindowById(ID SRC NAME USB0B) . SetValue(" usrp . srp ") 2797 self .FindWindowById(ID SINK NAME USB0B) . SetValue(" usrp . rxd ") 2798 else : 2799 self .FindWindowById(ID SRC NAME USB0B) . SetValue(" ID456 . txt ") 2800 self .FindWindowById(ID SINK NAME USB0B) . SetValue(" usrp . srp ") 2801 elif (event . GetId()==ID TXRX USB1A) : 2802 if ( self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" RX ") : 2803 self .FindWindowById(ID SRC NAME USB1A) . SetValue(" usrp . srp ") 2804 self .FindWindowById(ID SINK NAME USB1A) . SetValue(" usrp . rxd ") 2805 else : 2806 self .FindWindowById(ID SRC NAME USB1A) . SetValue(" ID456 . txt ") 2807 self .FindWindowById(ID SINK NAME USB1A) . SetValue(" usrp . srp ") 2808 elif (event . GetId()==ID TXRX USB1B) : 2809 if ( self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" RX ") : 2810 self .FindWindowById(ID SRC NAME USB1B) . SetValue(" usrp . srp ") 2811 self .FindWindowById(ID SINK NAME USB1B) . SetValue(" usrp . rxd ") 2812 else : 2813 self .FindWindowById(ID SRC NAME USB1B) . SetValue(" ID456 . txt ") 2814 self .FindWindowById(ID SINK NAME USB1B) . SetValue(" usrp . srp ") 2815 2816 def getRSSIMeasurement( self , node name) : 2817 self . rssi=subprocess .Popen ([ r"/ Users / marker / Documents / workspace / usrp_project / src / radio_interaction / usrp_rx_rssi . py " , 2818 " -U" ,node name [4] , " -R" ,node name [5] , " -f" ," 1250 M" ," -d" ," 128 " ] , 2819 stdout=subprocess .PIPE) . communicate() [0] 2820 2821 def onUpdate( self , event) : 2822 2823 2824 if (event . GetId()==ID UPDATE USB0A) : 2825 data = [ self .FindWindowById(ID RADIO USB0A) . GetLabelText () , self .FindWindowById( ID TXRX USB0A) . GetStringSelection () , 2826 self .FindWindowById(ID SRC NAME USB0A) . GetValue() , self .FindWindowById( SRC ID USB0A) . GetValue() , 242 2827 self .FindWindowById(ID MSG BITS USB0A) . GetValue() , self .FindWindowById( ID RAND BITS USB0A) . GetValue() , 2828 self .FindWindowById(ID CLAMP BITS USB0A) . GetValue() , self .FindWindowById( ID FRAG BITS USB0A) . GetValue() , 2829 self .FindWindowById(ID STOP BITS USB0A) . GetValue() , self .FindWindowById( ID EXPANSION USB0A) . GetValue() , 2830 self .FindWindowById(ID PKT LOAD USB0A) . GetValue() , self .FindWindowById( ID DECODE LIM USB0A) . GetValue() , 2831 self .FindWindowById(ID BUF PKT USB0A) . GetValue() , self .FindWindowById( ID BUF LAMBDA USB0A) . GetValue() , 2832 self .FindWindowById(ID PKT RATE USB0A) . GetValue() , self .FindWindowById( ID SAMPLES PER BIT USB0A) . GetValue() , 2833 self .FindWindowById(ID GAIN USB0A) . GetValue() , self .FindWindowById( ID CHANNEL LOSS USB0A) . GetValue() , 2834 self .FindWindowById(ID THRESHOLD PCT USB0A) . GetValue() , self .FindWindowById( ID HYSTERESIS USB0A) . GetValue() , 2835 self .FindWindowById(ID JITTER USB0A) . GetValue() , self .FindWindowById( ID CUSHION PCT USB0A) . GetValue() , 2836 self .FindWindowById(ID SINK NAME USB0A) . GetValue() , self .FindWindowById( ID SINK SAMPLE LIM USB0A) . GetValue() , 2837 self .FindWindowById(ID RECIPIENT USB0A) . GetValue() ] 2838 self . getRSSIMeasurement(" usrp0A ") 2839 self . writeParametersToFile(data) 2840 if ( self .FindWindowById(ID TXRX USB0A) . GetStringSelection ()==" TX ") : 2841 self . encodeTxData(event . GetId() ) 2842 #print "Data: ", data 2843 elif (event . GetId()==ID UPDATE USB0B) : 2844 data = [ self .FindWindowById(ID RADIO USB0B) . GetLabelText () , self .FindWindowById( ID TXRX USB0B) . GetStringSelection () , 2845 self .FindWindowById(ID SRC NAME USB0B) . GetValue() , self .FindWindowById( SRC ID USB0B) . GetValue() , 2846 self .FindWindowById(ID MSG BITS USB0B) . GetValue() , self .FindWindowById( ID RAND BITS USB0B) . GetValue() , 2847 self .FindWindowById(ID CLAMP BITS USB0B) . GetValue() , self .FindWindowById( ID FRAG BITS USB0B) . GetValue() , 2848 self .FindWindowById(ID STOP BITS USB0B) . GetValue() , self .FindWindowById( ID EXPANSION USB0B) . GetValue() , 2849 self .FindWindowById(ID PKT LOAD USB0B) . GetValue() , self .FindWindowById( ID DECODE LIM USB0B) . GetValue() , 2850 self .FindWindowById(ID BUF PKT USB0B) . GetValue() , self .FindWindowById( ID BUF LAMBDA USB0B) . GetValue() , 2851 self .FindWindowById(ID PKT RATE USB0B) . GetValue() , self .FindWindowById( ID SAMPLES PER BIT USB0B) . GetValue() , 2852 self .FindWindowById(ID GAIN USB0B) . GetValue() , self .FindWindowById( ID CHANNEL LOSS USB0B) . GetValue() , 243 2853 self .FindWindowById(ID THRESHOLD PCT USB0B) . GetValue() , self .FindWindowById( ID HYSTERESIS USB0B) . GetValue() , 2854 self .FindWindowById(ID JITTER USB0B) . GetValue() , self .FindWindowById( ID CUSHION PCT USB0B) . GetValue() , 2855 self .FindWindowById(ID SINK NAME USB0B) . GetValue() , self .FindWindowById( ID SINK SAMPLE LIM USB0B) . GetValue() , 2856 self .FindWindowById(ID RECIPIENT USB0B) . GetValue() ] 2857 self . getRSSIMeasurement(" usrp0B ") 2858 self . writeParametersToFile(data) 2859 if ( self .FindWindowById(ID TXRX USB0B) . GetStringSelection ()==" TX ") : 2860 self . encodeTxData(event . GetId() ) 2861 2862 #print "Data: ", data 2863 elif (event . GetId()==ID UPDATE USB1A) : 2864 data = [ self .FindWindowById(ID RADIO USB1A) . GetLabelText () , self .FindWindowById( ID TXRX USB1A) . GetStringSelection () , 2865 self .FindWindowById(ID SRC NAME USB1A) . GetValue() , self .FindWindowById( SRC ID USB1A) . GetValue() , 2866 self .FindWindowById(ID MSG BITS USB1A) . GetValue() , self .FindWindowById( ID RAND BITS USB1A) . GetValue() , 2867 self .FindWindowById(ID CLAMP BITS USB1A) . GetValue() , self .FindWindowById( ID FRAG BITS USB1A) . GetValue() , 2868 self .FindWindowById(ID STOP BITS USB1A) . GetValue() , self .FindWindowById( ID EXPANSION USB1A) . GetValue() , 2869 self .FindWindowById(ID PKT LOAD USB1A) . GetValue() , self .FindWindowById( ID DECODE LIM USB1A) . GetValue() , 2870 self .FindWindowById(ID BUF PKT USB1A) . GetValue() , self .FindWindowById( ID BUF LAMBDA USB1A) . GetValue() , 2871 self .FindWindowById(ID PKT RATE USB1A) . GetValue() , self .FindWindowById( ID SAMPLES PER BIT USB1A) . GetValue() , 2872 self .FindWindowById(ID GAIN USB1A) . GetValue() , self .FindWindowById( ID CHANNEL LOSS USB1A) . GetValue() , 2873 self .FindWindowById(ID THRESHOLD PCT USB1A) . GetValue() , self .FindWindowById( ID HYSTERESIS USB1A) . GetValue() , 2874 self .FindWindowById(ID JITTER USB1A) . GetValue() , self .FindWindowById( ID CUSHION PCT USB1A) . GetValue() , 2875 self .FindWindowById(ID SINK NAME USB1A) . GetValue() , self .FindWindowById( ID SINK SAMPLE LIM USB1A) . GetValue() , 2876 self .FindWindowById(ID RECIPIENT USB1A) . GetValue() ] 2877 self . getRSSIMeasurement(" usrp1A ") 2878 self . writeParametersToFile(data) 2879 if ( self .FindWindowById(ID TXRX USB1A) . GetStringSelection ()==" TX ") : 2880 self . encodeTxData(event . GetId() ) 2881 #print "Data: ",data 2882 elif (event . GetId()==ID UPDATE USB1B) : 244 2883 data = [ self .FindWindowById(ID RADIO USB1B) . GetLabelText () , self .FindWindowById( ID TXRX USB1B) . GetStringSelection () , 2884 self .FindWindowById(ID SRC NAME USB1B) . GetValue() , self .FindWindowById( SRC ID USB1B) . GetValue() , 2885 self .FindWindowById(ID MSG BITS USB1B) . GetValue() , self .FindWindowById( ID RAND BITS USB1B) . GetValue() , 2886 self .FindWindowById(ID CLAMP BITS USB1B) . GetValue() , self .FindWindowById( ID FRAG BITS USB1B) . GetValue() , 2887 self .FindWindowById(ID STOP BITS USB1B) . GetValue() , self .FindWindowById( ID EXPANSION USB1B) . GetValue() , 2888 self .FindWindowById(ID PKT LOAD USB1B) . GetValue() , self .FindWindowById( ID DECODE LIM USB1B) . GetValue() , 2889 self .FindWindowById(ID BUF PKT USB1B) . GetValue() , self .FindWindowById( ID BUF LAMBDA USB1B) . GetValue() , 2890 self .FindWindowById(ID PKT RATE USB1B) . GetValue() , self .FindWindowById( ID SAMPLES PER BIT USB1B) . GetValue() , 2891 self .FindWindowById(ID GAIN USB1B) . GetValue() , self .FindWindowById( ID CHANNEL LOSS USB1B) . GetValue() , 2892 self .FindWindowById(ID THRESHOLD PCT USB1B) . GetValue() , self .FindWindowById( ID HYSTERESIS USB1B) . GetValue() , 2893 self .FindWindowById(ID JITTER USB1B) . GetValue() , self .FindWindowById( ID CUSHION PCT USB1B) . GetValue() , 2894 self .FindWindowById(ID SINK NAME USB1B) . GetValue() , self .FindWindowById( ID SINK SAMPLE LIM USB1B) . GetValue() , 2895 self .FindWindowById(ID RECIPIENT USB1B) . GetValue() ] 2896 self . getRSSIMeasurement(" usrp1B ") 2897 self . writeParametersToFile(data) 2898 if ( self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" TX ") : 2899 self . encodeTxData(event . GetId() ) 2900 #print "Data: ",data 2901 elif (event . GetId()==ID UPDATE VIRT1) : 2902 #need to format data file correctly 2903 2904 self . rssi=random. randint (160 ,4092)#random rssi for these nodes 2905 self . writeParametersToFile(data) 2906 if ( self .FindWindowById(ID TXRX USB1B) . GetStringSelection ()==" TX ") : 2907 self . encodeTxData(event . GetId() ) 2908 2909 def encodeTxData( self , event id ) : 2910 #print "in encode algorithm ", id 2911 if ( event id==ID UPDATE USB0A) : 2912 if ( self . encode process usb0A is None) : 2913 2914 #self . encode cmd="ls al" 245 2915 self . encode cmd = self . experiment path + " usrp0A / usrp " + self . experiment path + " usrp0A / usrp0Aparams . ini " 2916 self . encode process usb0A = wx. Process ( self , id=ID PROCESS ENC 1) 2917 self . encode process usb0A . Redirect () 2918 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process usb0A ) 2919 self . display0A(" > Encoding TX Message .\ n") 2920 self . display0A(" > Executing : "+self . encode cmd+"\n") 2921 elif ( event id==ID UPDATE USB0B) : 2922 if ( self . encode process usb0B is None) : 2923 #self . encode cmd="ls al" 2924 self . encode cmd = self . experiment path + " usrp0B / usrp " + self . experiment path + " usrp0B / usrp0Bparams . ini " 2925 self . encode process usb0B = wx. Process ( self , id=ID PROCESS ENC 2) 2926 self . encode process usb0B . Redirect () 2927 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process usb0B ) 2928 self . display0B(" > Encoding TX Message .\ n") 2929 self . display0B(" > Executing : "+self . encode cmd+"\n") 2930 elif ( event id==ID UPDATE USB1A) : 2931 if ( self . encode process usb1A is None) : 2932 #self . encode cmd="ls al" 2933 self . encode cmd = self . experiment path + " usrp1A / usrp " + self . experiment path + " usrp1A / usrp1Aparams . ini " 2934 self . encode process usb1A = wx. Process ( self , id=ID PROCESS ENC 3) 2935 self . encode process usb1A . Redirect () 2936 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process usb1A ) 2937 self . display1A(" > Encoding TX Message .\ n") 2938 self . display1A(" > Executing : "+self . encode cmd+"\n") 2939 elif ( event id==ID UPDATE USB1B) : 2940 if ( self . encode process usb1B is None) : 2941 #self . encode cmd="ls al" 2942 self . encode cmd = self . experiment path + " usrp1B / usrp " + self . experiment path + " usrp1B / usrp1Bparams . ini " 2943 self . encode process usb1B = wx. Process ( self , id=ID PROCESS ENC 4) 2944 self . encode process usb1B . Redirect () 2945 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process usb1B ) 2946 self . display1B(" > Encoding TX Message .\ n") 2947 self . display1B(" > Executing : "+self . encode cmd+"\n") 2948 #additional nodes for testing 2949 elif ( event id==ID UPDATE VIRT1) : 2950 if ( self . encode process virt1 is None) : 2951 #self . encode cmd="ls al" 246 2952 self . encode cmd = self . experiment path + " virt1 / usrp " + self . experiment path + " virt1 / virt1params . ini " 2953 self . encode process virt1 = wx. Process ( self , id=ID PROCESS ENC 5) 2954 self . encode process virt1 . Redirect () 2955 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt1 ) 2956 self . olsr v1 output+=" > Encoding TX Message .\ n" 2957 self . olsr v1 output+=" > Executing : "+self . encode cmd+"\n" 2958 elif ( event id==ID UPDATE VIRT2) : 2959 if ( self . encode process virt2 is None) : 2960 #self . encode cmd="ls al" 2961 self . encode cmd = self . experiment path + " virt2 / usrp " + self . experiment path + " virt2 / virt2params . ini " 2962 self . encode process virt2 = wx. Process ( self , id=ID PROCESS ENC 6) 2963 self . encode process virt2 . Redirect () 2964 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt2 ) 2965 self . olsr v2 output+=" > Encoding TX Message .\ n" 2966 self . olsr v2 output+=" > Executing : "+self . encode cmd+"\n" 2967 elif ( event id==ID UPDATE VIRT3) : 2968 if ( self . encode process virt3 is None) : 2969 #self . encode cmd="ls al" 2970 self . encode cmd = self . experiment path + " virt3 / usrp " + self . experiment path + " virt3 / virt3params . ini " 2971 self . encode process virt3 = wx. Process ( self , id=ID PROCESS ENC 7) 2972 self . encode process virt3 . Redirect () 2973 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt3 ) 2974 self . olsr v3 output+=" > Encoding TX Message .\ n" 2975 self . olsr v3 output+=" > Executing : "+self . encode cmd+"\n" 2976 elif ( event id==ID UPDATE VIRT4) : 2977 if ( self . encode process virt4 is None) : 2978 #self . encode cmd="ls al" 2979 self . encode cmd = self . experiment path + " virt4 / usrp " + self . experiment path + " virt4 / virt4params . ini " 2980 self . encode process virt4 = wx. Process ( self , id=ID PROCESS ENC 8) 2981 self . encode process virt4 . Redirect () 2982 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt4 ) 2983 self . olsr v4 output+=" > Encoding TX Message .\ n" 2984 self . olsr v4 output+=" > Executing : "+self . encode cmd+"\n" 2985 elif ( event id==ID UPDATE VIRT5) : 2986 if ( self . encode process virt5 is None) : 2987 #self . encode cmd="ls al" 247 2988 self . encode cmd = self . experiment path + " virt5 / usrp " + self . experiment path + " virt5 / virt5params . ini " 2989 self . encode process virt5 = wx. Process ( self , id=ID PROCESS ENC 9) 2990 self . encode process virt5 . Redirect () 2991 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt5 ) 2992 self . olsr v5 output+=" > Encoding TX Message .\ n" 2993 self . olsr v5 output+=" > Executing : "+self . encode cmd+"\n" 2994 elif ( event id==ID UPDATE VIRT6) : 2995 if ( self . encode process virt6 is None) : 2996 #self . encode cmd="ls al" 2997 self . encode cmd = self . experiment path + " virt6 / usrp " + self . experiment path + " virt6 / virt6params . ini " 2998 self . encode process virt6 = wx. Process ( self , id=ID PROCESS ENC 60) 2999 self . encode process virt6 . Redirect () 3000 self . encode process id = wx. Execute( self . encode cmd ,wx.EXEC ASYNC, self . encode process virt6 ) 3001 self . olsr v6 output+=" > Encoding TX Message .\ n" 3002 self . olsr v6 output+=" > Executing : "+self . encode cmd+"\n" 3003 3004 3005 def writeParametersToFile( self , data) : 3006 #print "Data From File : ",data 3007 #print "Path: ", self . experiment path 3008 3009 if (data[0]==" USB0A ") : 3010 node id=" usrp0A " 3011 node address = self . nat table . items () [0][0] 3012 from address = self . nat table . items () [0][0] 3013 filename = self . experiment path+" usrp0A / usrp0Aparams . ini " 3014 self . display0A("\n > Writing parameters to file : "+filename+"\n") 3015 elif (data[0]==" USB0B ") : 3016 node id=" usrp0B " 3017 node address = self . nat table . items () [1][0] 3018 from address = self . nat table . items () [1][0] 3019 filename = self . experiment path+" usrp0B / usrp0Bparams . ini " 3020 self . display0B("\n > Writing parameters to file : "+filename+"\n") 3021 elif (data[0]==" USB1A ") : 3022 node id=" usrp1A " 3023 node address = self . nat table . items () [2][0] 3024 from address = self . nat table . items () [2][0] 3025 filename = self . experiment path+" usrp1A / usrp1Aparams . ini " 3026 self . display1A("\n > Writing parameters to file : "+filename+"\n") 3027 elif (data[0]==" USB1B ") : 3028 node id=" usrp1B " 248 3029 node address = self . nat table . items () [3][0] 3030 from address = self . nat table . items () [3][0] 3031 filename = self . experiment path+" usrp1B / usrp1Bparams . ini " 3032 self . display1B("\n > Writing parameters to file : "+filename+"\n") 3033 3034 try: 3035 file=open(filename , ?w ?) 3036 file . write ("# DIAGNOSTICS \n") 3037 file . write ("\n") 3038 file . write (" PATH =") 3039 file . write (" \" "+self . experiment path+" \" ") 3040 file . write ("\n") 3041 file . write ("# SCHEDULER Configuration \n") 3042 file . write (" SCHEDULER_TX_notRX =") 3043 if (data [1] == " TX ") : 3044 file . write ("1") 3045 elif (data [1] == " RX ") : 3046 file . write ("0") 3047 file . write ("\n") 3048 file . write (" SCHEDULER_REALTIME =0 ") 3049 file . write ("\n") 3050 file . write ("# SOURCE Configuration \n") 3051 file . write (" SOURCE_NAME =") 3052 file . write (" \" " + data [2] + " \" ") 3053 file . write ("\n") 3054 if (data [1] == " TX ") : 3055 file . write (" SOURCE_ID = ") 3056 file . write (data [3]) 3057 file . write ("\n") 3058 file . write ("# CODEC Configuration \n") 3059 file . write (" CODEC_MESSAGE_BITS = ") 3060 file . write (data [4]) 3061 file . write ("\n") 3062 file . write (" CODEC_RANDOM_BITS = ") 3063 file . write (data [5]) 3064 file . write ("\n") 3065 file . write (" CODEC_CLAMP_BITS =") 3066 file . write (data [6]) 3067 file . write ("\n") 3068 file . write (" CODEC_FRAGMENT_BITS = ") 3069 file . write (data [7]) 3070 file . write ("\n") 3071 file . write (" CODEC_STOP_BITS = ") 3072 file . write (data [8]) 3073 file . write ("\n") 249 3074 file . write (" CODEC_EXPANSION = ") 3075 file . write (data [9]) 3076 file . write ("\n") 3077 if (data [1] == " TX ") : 3078 file . write (" CODEC_PACKET_LOAD = ") 3079 file . write (data [10]) 3080 file . write ("\n") 3081 file . write (" CODEC_DECODE_LIMIT = ") 3082 file . write (data [11]) 3083 file . write ("\n") 3084 file . write ("# BUFFER Configuration \n") 3085 file . write (" BUFFER_PACKETS = ") 3086 file . write (data [12]) 3087 file . write ("\n") 3088 if (data [1] == " TX ") : 3089 file . write (" BUFFER_LAMBDA = ") 3090 file . write (data [13]) 3091 file . write ("\n") 3092 file . write ("# MODEM Configuration \n") 3093 file . write (" MODEM_PACKET_RATE_BPS = ") 3094 file . write (data [14]) 3095 file . write ("\n") 3096 file . write (" MODEM_SAMPLES_PER_BIT = ") 3097 file . write (data [15]) 3098 file . write ("\n") 3099 file . write (" MODEM_GAIN_DB = ") 3100 file . write (data [16]) 3101 file . write ("\n") 3102 file . write (" MODEM_CHANNEL_LOSS_DB = ") 3103 file . write (data [17]) 3104 file . write ("\n") 3105 file . write (" MODEM_THRESHOLD_PCT = ") 3106 file . write (data [18]) 3107 file . write ("\n") 3108 file . write (" MODEM_HYSTERESIS_PCT = ") 3109 file . write (data [19]) 3110 file . write ("\n") 3111 file . write (" MODEM_JITTER_BITS = ") 3112 file . write (data [20]) 3113 file . write ("\n") 3114 file . write (" MODEM_CUSHION_PCT = ") 3115 file . write (data [21]) 3116 file . write ("\n") 3117 file . write ("# SINK Configuration \n") 3118 file . write (" SINK_NAME = ") 250 3119 file . write (" \" " + data [22] + " \" ") 3120 file . write ("\n") 3121 file . write (" SINK_SAMPLE_LIMIT = ") 3122 file . write (data [23]) 3123 file . write ("\n") 3124 file . write (" NODE_ID =") 3125 file . write (" \" "+node id+" \" ") 3126 file . write ("\n") 3127 file . write (" NODE_ADDRESS =") 3128 file . write ( node address ) 3129 file . write ("\n") 3130 if (data[1]==" TX ") : 3131 #TO ADDRESS 3132 file . write (" TO_ADDRESS =") 3133 if (data[24]==" All ") : 3134 file . write (" 888 ") 3135 elif (data[24]==" usrp0A ") : 3136 file . write ( self . nat table . items () [0][0]) 3137 elif (data[24]==" usrp0B ") : 3138 file . write ( self . nat table . items () [1][0]) 3139 elif (data[24]==" usrp1A ") : 3140 file . write ( self . nat table . items () [2][0]) 3141 elif (data[24]==" usrp1B ") : 3142 file . write ( self . nat table . items () [3][0]) 3143 file . write ("\n") 3144 #FROM ADDRESS 3145 file . write (" FROM_ADDRESS =") 3146 file . write ( from address ) 3147 file . write ("\n") 3148 #rssi 3149 file . write (" RSSI =") 3150 file . write ( str ( self . rssi )) 3151 file . write ("\n") 3152 except IOError : 3153 self .FindWindowById( self .getLogWindowId( node id )) .AppendText("\n > File IO Error ! Cannot open " + filename + " .\ n") 3154 finally : 3155 file . close () 3156 3157 3158 def createParameterControls ( self ) : 3159 #self . parameterLabel = wx. StaticText ( self , label="Parameters :") 3160 self . logwindow label 1 = wx. StaticText ( self , label=" Log Window 1: ") 3161 self . logwindow label 2 = wx. StaticText ( self , label=" Log Window 2: ") 3162 self . logwindow label 3 = wx. StaticText ( self , label=" Log Window 3: ") 251 3163 self . logwindow label 4 = wx. StaticText ( self , label=" Log Window 4: ") 3164 self . recipient label = wx. StaticText ( self , label=" To :") 3165 self . source name label = wx. StaticText ( self , label=" MSG Source :") 3166 self . source id label = wx. StaticText ( self , label=" Source ID :") 3167 self . codec label = wx. StaticText ( self , label=" Codec Configuration :") 3168 self . codec message bits label = wx. StaticText ( self , label=" Message Bits :") 3169 self . codec random bits label = wx. StaticText ( self , label=" Random Bits :") 3170 self . codec clamp bits label = wx. StaticText ( self , label=" Clamp Bits :") 3171 self . codec fragment bits label = wx. StaticText ( self , label=" Fragment Bits :") 3172 self . codec stop bits label = wx. StaticText ( self , label=" Stop Bits :") 3173 self . codec expansion label = wx. StaticText ( self , label=" Expansion :") 3174 self . codec packet load label = wx. StaticText ( self , label=" Packet Load :") 3175 self . codec decode limit label = wx. StaticText ( self , label=" Decode Limit :") 3176 self . buffer label = wx. StaticText ( self , label=" Buffer Configuration :") 3177 self . buffer packets label = wx. StaticText ( self , label=" Buffer Packets :") 3178 self . buffer lambda label = wx. StaticText ( self , label=" Buffer Lambda :") 3179 self . modem label = wx. StaticText ( self , label=" Modem Configuration :") 3180 self . modem pkt rate bps label = wx. StaticText ( self , label=" Packet Rate ( BPS ):") 3181 self . modem samples per bit label = wx. StaticText ( self , label=" Samples Per Bit :") 3182 self . modem gain db label = wx. StaticText ( self , label=" Gain ( DB ):") 3183 self . modem channel loss db label = wx. StaticText ( self , label=" Channel Loss ( db ):") 3184 self . modem threshold pct label = wx. StaticText ( self , label=" Threshold Pct :") 3185 self . modem hysteresis pct label = wx. StaticText ( self , label=" Hysteresis Pct :") 3186 self . modem jitter bits label = wx. StaticText ( self , label=" Jitter Bits :") 3187 self . modem cusion pct label = wx. StaticText ( self , label=" Cushion Pct :") 3188 self . sink label = wx. StaticText ( self , label=" Sink Configuration :") 3189 self . sink name label = wx. StaticText ( self , label=" MSG Sink :") 3190 self . sink sample limit label = wx. StaticText ( self , label=" Sample Limit :") 3191 3192 if ( self . y offset==0): 3193 self . logwindow = wx. TextCtrl( self , id=ID LOGWIN USB0A, style=wx.TE MULTILINEjwx. TE AUTO SCROLL) 3194 elif ( self . y offset==200): 3195 self . logwindow = wx. TextCtrl( self , id=ID LOGWIN USB0B, style=wx.TE MULTILINEjwx. TE AUTO SCROLL) 3196 elif ( self . y offset==400): 3197 self . logwindow = wx. TextCtrl( self , id=ID LOGWIN USB1A, style=wx.TE MULTILINEjwx. TE AUTO SCROLL) 3198 elif ( self . y offset==600): 3199 self . logwindow = wx. TextCtrl( self , id=ID LOGWIN USB1B, style=wx.TE MULTILINEjwx. TE AUTO SCROLL) 3200 3201 if ( self . x offset==0): 3202 self . updateButton = wx. Button( self , id=ID UPDATE USB0A, label=" Update ") 3203 self . startButton = wx. Button( self , id=ID START USB0A, label=" Start ") 252 3204 self . stopButton = wx. Button( self , id=ID STOP USB0A, label=" Stop ") 3205 self . radioLabel = wx. StaticText ( self , id=ID RADIO USB0A, label=" USB0A ") 3206 self . recipient combo box = wx.ComboBox( self , id=ID RECIPIENT USB0A, value=self . recipients [0] , choices=self . recipients ) 3207 self .TxOrRx = wx.RadioBox( self , id=ID TXRX USB0A, choices=self . transmission mode , style=wx.RA HORIZONTAL) 3208 self . source name entry = wx. TextCtrl( self , id=ID SRC NAME USB0A, value=" ID456 . txt ") 3209 self . source id entry = wx. TextCtrl( self , id=SRC ID USB0A, value=" 456 ") 3210 self . codec message bits entry = wx. TextCtrl( self , id=ID MSG BITS USB0A, value=" 512 ") 3211 self . codec random bits entry = wx. TextCtrl( self , id=ID RAND BITS USB0A, value="8") 3212 self . codec clamp bits entry = wx. TextCtrl( self , id=ID CLAMP BITS USB0A, value="1") 3213 self . codec fragment bits entry = wx. TextCtrl( self , id=ID FRAG BITS USB0A, value="1") 3214 self . codec stop bits entry = wx. TextCtrl( self , id=ID STOP BITS USB0A, value=" 100 ") 3215 self . codec expansion entry = wx. TextCtrl( self , id=ID EXPANSION USB0A, value=" 100 ") 3216 self . codec packet load entry = wx. TextCtrl( self , id=ID PKT LOAD USB0A, value="2") 3217 self . codec decode limit entry = wx. TextCtrl( self , id=ID DECODE LIM USB0A, value=" 100 ") 3218 self . buffer packets entry = wx. TextCtrl( self , id=ID BUF PKT USB0A, value=" 4.0 ") 3219 self . buffer lambda entry = wx. TextCtrl( self , id=ID BUF LAMBDA USB0A, value=" 0.4 ") 3220 self . modem pkt rate bps entry = wx. TextCtrl( self , id=ID PKT RATE USB0A, value=" 500000 " ) 3221 self . modem samples per bit entry = wx. TextCtrl( self , id=ID SAMPLES PER BIT USB0A, value="4") 3222 self . modem gain db entry = wx. TextCtrl( self , id=ID GAIN USB0A, value=" 80.0 ") 3223 self . modem channel loss db entry = wx. TextCtrl( self , id=ID CHANNEL LOSS USB0A, value=" 3.0 ") 3224 self . modem threshold pct entry = wx. TextCtrl( self , id=ID THRESHOLD PCT USB0A, value=" 46.0 ") 3225 self . modem hysteresis pct entry = wx. TextCtrl( self , id=ID HYSTERESIS USB0A, value=" 5.0 " ) 3226 self . modem jitter bits entry = wx. TextCtrl( self , id=ID JITTER USB0A, value=" 2.0 ") 3227 self . modem cusion pct entry = wx. TextCtrl( self , id=ID CUSHION PCT USB0A, value=" 10.0 ") 3228 self . sink name entry = wx. TextCtrl( self , id=ID SINK NAME USB0A, value=" usrp . srp ") 3229 self . sink sample limit entry = wx. TextCtrl( self , id=ID SINK SAMPLE LIM USB0A, value=" 8000000 ") 3230 3231 elif ( self . x offset==250): 3232 self . updateButton = wx. Button( self , id=ID UPDATE USB0B, label=" Update ") 3233 self . startButton = wx. Button( self , id=ID START USB0B, label=" Start ") 3234 self . stopButton = wx. Button( self , id=ID STOP USB0B, label=" Stop ") 3235 self . radioLabel = wx. StaticText ( self , id=ID RADIO USB0B, label=" USB0B ") 3236 self . recipient combo box = wx.ComboBox( self , id=ID RECIPIENT USB0B, value=self . recipients [0] , choices=self . recipients ) 3237 self .TxOrRx = wx.RadioBox( self , id=ID TXRX USB0B, choices=self . transmission mode , style=wx.RA HORIZONTAL) 3238 self . source name entry = wx. TextCtrl( self , id=ID SRC NAME USB0B, value=" ID456 . txt ") 253 3239 self . source id entry = wx. TextCtrl( self , id=SRC ID USB0B, value=" 456 ") 3240 self . codec message bits entry = wx. TextCtrl( self , id=ID MSG BITS USB0B, value=" 512 ") 3241 self . codec random bits entry = wx. TextCtrl( self , id=ID RAND BITS USB0B, value="8") 3242 self . codec clamp bits entry = wx. TextCtrl( self , id=ID CLAMP BITS USB0B, value="1") 3243 self . codec fragment bits entry = wx. TextCtrl( self , id=ID FRAG BITS USB0B, value="1") 3244 self . codec stop bits entry = wx. TextCtrl( self , id=ID STOP BITS USB0B, value=" 100 ") 3245 self . codec expansion entry = wx. TextCtrl( self , id=ID EXPANSION USB0B, value=" 100 ") 3246 self . codec packet load entry = wx. TextCtrl( self , id=ID PKT LOAD USB0B, value="2") 3247 self . codec decode limit entry = wx. TextCtrl( self , id=ID DECODE LIM USB0B, value=" 100 ") 3248 self . buffer packets entry = wx. TextCtrl( self , id=ID BUF PKT USB0B, value=" 4.0 ") 3249 self . buffer lambda entry = wx. TextCtrl( self , id=ID BUF LAMBDA USB0B, value=" 0.4 ") 3250 self . modem pkt rate bps entry = wx. TextCtrl( self , id=ID PKT RATE USB0B, value=" 500000 " ) 3251 self . modem samples per bit entry = wx. TextCtrl( self , id=ID SAMPLES PER BIT USB0B, value="4") 3252 self . modem gain db entry = wx. TextCtrl( self , id=ID GAIN USB0B, value=" 80.0 ") 3253 self . modem channel loss db entry = wx. TextCtrl( self , id=ID CHANNEL LOSS USB0B, value=" 3.0 ") 3254 self . modem threshold pct entry = wx. TextCtrl( self , id=ID THRESHOLD PCT USB0B, value=" 46.0 ") 3255 self . modem hysteresis pct entry = wx. TextCtrl( self , id=ID HYSTERESIS USB0B, value=" 5.0 " ) 3256 self . modem jitter bits entry = wx. TextCtrl( self , id=ID JITTER USB0B, value=" 2.0 ") 3257 self . modem cusion pct entry = wx. TextCtrl( self , id=ID CUSHION PCT USB0B, value=" 10.0 ") 3258 self . sink name entry = wx. TextCtrl( self , id=ID SINK NAME USB0B, value=" usrp . srp ") 3259 self . sink sample limit entry = wx. TextCtrl( self , id=ID SINK SAMPLE LIM USB0B, value=" 8000000 ") 3260 3261 elif ( self . x offset==500): 3262 self . updateButton = wx. Button( self , id=ID UPDATE USB1A, label=" Update ") 3263 self . startButton = wx. Button( self , id=ID START USB1A, label=" Start ") 3264 self . stopButton = wx. Button( self , id=ID STOP USB1A, label=" Stop ") 3265 self . radioLabel = wx. StaticText ( self , id=ID RADIO USB1A, label=" USB1A ") 3266 self . recipient combo box = wx.ComboBox( self , id=ID RECIPIENT USB1A, value=self . recipients [0] , choices=self . recipients ) 3267 self .TxOrRx = wx.RadioBox( self , id=ID TXRX USB1A, choices=self . transmission mode , style=wx.RA HORIZONTAL) 3268 self . source name entry = wx. TextCtrl( self , id=ID SRC NAME USB1A, value=" ID456 . txt ") 3269 self . source id entry = wx. TextCtrl( self , id=SRC ID USB1A, value=" 456 ") 3270 self . codec message bits entry = wx. TextCtrl( self , id=ID MSG BITS USB1A, value=" 512 ") 3271 self . codec random bits entry = wx. TextCtrl( self , id=ID RAND BITS USB1A, value="8") 3272 self . codec clamp bits entry = wx. TextCtrl( self , id=ID CLAMP BITS USB1A, value="1") 3273 self . codec fragment bits entry = wx. TextCtrl( self , id=ID FRAG BITS USB1A, value="1") 3274 self . codec stop bits entry = wx. TextCtrl( self , id=ID STOP BITS USB1A, value=" 100 ") 3275 self . codec expansion entry = wx. TextCtrl( self , id=ID EXPANSION USB1A, value=" 100 ") 254 3276 self . codec packet load entry = wx. TextCtrl( self , id=ID PKT LOAD USB1A, value="2") 3277 self . codec decode limit entry = wx. TextCtrl( self , id=ID DECODE LIM USB1A, value=" 100 ") 3278 self . buffer packets entry = wx. TextCtrl( self , id=ID BUF PKT USB1A, value=" 4.0 ") 3279 self . buffer lambda entry = wx. TextCtrl( self , id=ID BUF LAMBDA USB1A, value=" 0.4 ") 3280 self . modem pkt rate bps entry = wx. TextCtrl( self , id=ID PKT RATE USB1A, value=" 500000 " ) 3281 self . modem samples per bit entry = wx. TextCtrl( self , id=ID SAMPLES PER BIT USB1A, value="4") 3282 self . modem gain db entry = wx. TextCtrl( self , id=ID GAIN USB1A, value=" 80.0 ") 3283 self . modem channel loss db entry = wx. TextCtrl( self , id=ID CHANNEL LOSS USB1A, value=" 3.0 ") 3284 self . modem threshold pct entry = wx. TextCtrl( self , id=ID THRESHOLD PCT USB1A, value=" 46.0 ") 3285 self . modem hysteresis pct entry = wx. TextCtrl( self , id=ID HYSTERESIS USB1A, value=" 5.0 " ) 3286 self . modem jitter bits entry = wx. TextCtrl( self , id=ID JITTER USB1A, value=" 2.0 ") 3287 self . modem cusion pct entry = wx. TextCtrl( self , id=ID CUSHION PCT USB1A, value=" 10.0 ") 3288 self . sink name entry = wx. TextCtrl( self , id=ID SINK NAME USB1A, value=" usrp . srp ") 3289 self . sink sample limit entry = wx. TextCtrl( self , id=ID SINK SAMPLE LIM USB1A, value=" 8000000 ") 3290 3291 elif ( self . x offset==750): 3292 self . updateButton = wx. Button( self , id=ID UPDATE USB1B, label=" Update ") 3293 self . startButton = wx. Button( self , id=ID START USB1B, label=" Start ") 3294 self . stopButton = wx. Button( self , id=ID STOP USB1B, label=" Stop ") 3295 self . radioLabel = wx. StaticText ( self , id=ID RADIO USB1B, label=" USB1B ") 3296 self . recipient combo box = wx.ComboBox( self , id=ID RECIPIENT USB1B, value=self . recipients [0] , choices=self . recipients ) 3297 self .TxOrRx = wx.RadioBox( self , id=ID TXRX USB1B, choices=self . transmission mode , style=wx.RA HORIZONTAL) 3298 self . source name entry = wx. TextCtrl( self , id=ID SRC NAME USB1B, value=" ID456 . txt ") 3299 self . source id entry = wx. TextCtrl( self , id=SRC ID USB1B, value=" 456 ") 3300 self . codec message bits entry = wx. TextCtrl( self , id=ID MSG BITS USB1B, value=" 512 ") 3301 self . codec random bits entry = wx. TextCtrl( self , id=ID RAND BITS USB1B, value="8") 3302 self . codec clamp bits entry = wx. TextCtrl( self , id=ID CLAMP BITS USB1B, value="1") 3303 self . codec fragment bits entry = wx. TextCtrl( self , id=ID FRAG BITS USB1B, value="1") 3304 self . codec stop bits entry = wx. TextCtrl( self , id=ID STOP BITS USB1B, value=" 100 ") 3305 self . codec expansion entry = wx. TextCtrl( self , id=ID EXPANSION USB1B, value=" 100 ") 3306 self . codec packet load entry = wx. TextCtrl( self , id=ID PKT LOAD USB1B, value="2") 3307 self . codec decode limit entry = wx. TextCtrl( self , id=ID DECODE LIM USB1B, value=" 100 ") 3308 self . buffer packets entry = wx. TextCtrl( self , id=ID BUF PKT USB1B, value=" 4.0 ") 3309 self . buffer lambda entry = wx. TextCtrl( self , id=ID BUF LAMBDA USB1B, value=" 0.4 ") 3310 self . modem pkt rate bps entry = wx. TextCtrl( self , id=ID PKT RATE USB1B, value=" 500000 " ) 255 3311 self . modem samples per bit entry = wx. TextCtrl( self , id=ID SAMPLES PER BIT USB1B, value="4") 3312 self . modem gain db entry = wx. TextCtrl( self , id=ID GAIN USB1B, value=" 80.0 ") 3313 self . modem channel loss db entry = wx. TextCtrl( self , id=ID CHANNEL LOSS USB1B, value=" 3.0 ") 3314 self . modem threshold pct entry = wx. TextCtrl( self , id=ID THRESHOLD PCT USB1B, value=" 46.0 ") 3315 self . modem hysteresis pct entry = wx. TextCtrl( self , id=ID HYSTERESIS USB1B, value=" 5.0 " ) 3316 self . modem jitter bits entry = wx. TextCtrl( self , id=ID JITTER USB1B, value=" 2.0 ") 3317 self . modem cusion pct entry = wx. TextCtrl( self , id=ID CUSHION PCT USB1B, value=" 10.0 ") 3318 self . sink name entry = wx. TextCtrl( self , id=ID SINK NAME USB1B, value=" usrp . srp ") 3319 self . sink sample limit entry = wx. TextCtrl( self , id=ID SINK SAMPLE LIM USB1B, value=" 8000000 ") 3320 3321 3322 def doLayout( self ) : 3323 for control , x, y, width , height in n 3324 [ 3325 #( self . parameterLabel ,0 , 0, 1, 1) , 3326 ( self . logwindow label 1 ,1000,0, 1, 1) , 3327 ( self . logwindow label 2 ,1000,200, 1, 1) , 3328 ( self . logwindow label 3 ,1000,400, 1, 1) , 3329 ( self . logwindow label 4 ,1000,600, 1, 1) , 3330 ( self . logwindow ,980 , self . y offset +20,420,175) , 3331 ( self . updateButton , self . x offset +20,10, 1, 1) , 3332 ( self . startButton , self . x offset +95,10,50,30) , 3333 ( self . stopButton , self . x offset +150,10,50,30) , 3334 3335 ( self . recipient label , self . x offset +130,40, 1, 1) , 3336 ( self . recipient combo box , self . x offset +145,40,85,30) , 3337 #( self .radioComboBox , self . x offset +10,40, 1, 1) , 3338 ( self . radioLabel , self . x offset ,40, 1, 1) , 3339 #TX or RX 3340 ( self .TxOrRx, self . x offset +40,40,85,30) , 3341 #source configuration 3342 ( self . source name label , self . x offset +20,70, 1, 1) , 3343 ( self . source name entry , self . x offset +100,70, 1, 1) , 3344 ( self . source id label , self . x offset +20,100, 1, 1) , 3345 ( self . source id entry , self . x offset +100,100, 1, 1) , 3346 #codec configuration 3347 ( self . codec label , self . x offset +10,130, 1, 1) , 3348 ( self . codec message bits label , self . x offset +20,160, 1, 1) , 3349 ( self . codec message bits entry , self . x offset +120,160, 1, 1) , 3350 ( self . codec random bits label , self . x offset +20,190, 1, 1) , 256 3351 ( self . codec random bits entry , self . x offset +120,190, 1, 1) , 3352 ( self . codec clamp bits label , self . x offset +20,220, 1, 1) , 3353 ( self . codec clamp bits entry , self . x offset +120,220, 1, 1) , 3354 ( self . codec fragment bits label , self . x offset +20,250, 1, 1) , 3355 ( self . codec fragment bits entry , self . x offset +120,250, 1, 1) , 3356 ( self . codec stop bits label , self . x offset +20,280, 1, 1) , 3357 ( self . codec stop bits entry , self . x offset +120,280, 1, 1) , 3358 ( self . codec expansion label , self . x offset +20,310, 1, 1) , 3359 ( self . codec expansion entry , self . x offset +120,310, 1, 1) , 3360 ( self . codec packet load label , self . x offset +20,340, 1, 1) , 3361 ( self . codec packet load entry , self . x offset +120,340, 1, 1) , 3362 ( self . codec decode limit label , self . x offset +20,370, 1, 1) , 3363 ( self . codec decode limit entry , self . x offset +120,370, 1, 1) , 3364 #buffer configuration 3365 ( self . buffer label , self . x offset +10,400, 1, 1) , 3366 ( self . buffer packets label , self . x offset +20,430, 1, 1) , 3367 ( self . buffer packets entry , self . x offset +120,430, 1, 1) , 3368 ( self . buffer lambda label , self . x offset +20,460, 1, 1) , 3369 ( self . buffer lambda entry , self . x offset +120,460, 1, 1) , 3370 #modem configuration 3371 ( self . modem label , self . x offset +10,490, 1, 1) , 3372 ( self . modem pkt rate bps label , self . x offset +20,520, 1, 1) , 3373 ( self . modem pkt rate bps entry , self . x offset +130,520, 1, 1) , 3374 ( self . modem samples per bit label , self . x offset +20,550, 1, 1) , 3375 ( self . modem samples per bit entry , self . x offset +120,550, 1, 1) , 3376 ( self . modem gain db label , self . x offset +20,580, 1, 1) , 3377 ( self . modem gain db entry , self . x offset +120,580, 1, 1) , 3378 ( self . modem channel loss db label , self . x offset +20,610, 1, 1) , 3379 ( self . modem channel loss db entry , self . x offset +125,610, 1, 1) , 3380 ( self . modem threshold pct label , self . x offset +20,640, 1, 1) , 3381 ( self . modem threshold pct entry , self . x offset +125,640, 1, 1) , 3382 ( self . modem hysteresis pct label , self . x offset +20,670, 1, 1) , 3383 ( self . modem hysteresis pct entry , self . x offset +120,670, 1, 1) , 3384 ( self . modem jitter bits label , self . x offset +20,700, 1, 1) , 3385 ( self . modem jitter bits entry , self . x offset +120,700, 1, 1) , 3386 ( self . modem cusion pct label , self . x offset +20,730, 1, 1) , 3387 ( self . modem cusion pct entry , self . x offset +120,730, 1, 1) , 3388 #sink configuration 3389 ( self . sink label , self . x offset +10,760, 1, 1) , 3390 ( self . sink name label , self . x offset +20,790, 1, 1) , 3391 ( self . sink name entry , self . x offset +120,790, 1, 1) , 3392 ( self . sink sample limit label , self . x offset +20,820, 1, 1) , 3393 ( self . sink sample limit entry , self . x offset +120,820, 1, 1) , 3394 ]: 3395 control . SetDimensions(x=x,y=y, width=width , height=height ) 257 3396 3397 def OnClearWindow( self , event) : 3398 dlg = wx. MessageDialog( self , " Are you sure you want to clear this log window ?" ," Confirm Clear Log " , wx.OKjwx.CANCELjwx.ICON QUESTION) 3399 result = dlg .ShowModal() 3400 dlg . Destroy () 3401 if result == wx.ID OK: 3402 if (event . GetId()==ID CLEAR LOGWIN 1) : 3403 self .FindWindowById(ID LOGWIN USB0A) . Clear () 3404 elif (event . GetId()==ID CLEAR LOGWIN 2) : 3405 self .FindWindowById(ID LOGWIN USB0B) . Clear () 3406 elif (event . GetId()==ID CLEAR LOGWIN 3) : 3407 self .FindWindowById(ID LOGWIN USB1A) . Clear () 3408 elif (event . GetId()==ID CLEAR LOGWIN 4) : 3409 self .FindWindowById(ID LOGWIN USB1B) . Clear () 3410 elif (event . GetId()==ID CLEAR LOGWIN 5) : 3411 self . olsr v1 output="" 3412 elif (event . GetId()==ID CLEAR LOGWIN 6) : 3413 self . olsr v2 output="" 3414 elif (event . GetId()==ID CLEAR LOGWIN 7) : 3415 self . olsr v3 output="" 3416 elif (event . GetId()==ID CLEAR LOGWIN 8) : 3417 self . olsr v4 output="" 3418 elif (event . GetId()==ID CLEAR LOGWIN 9) : 3419 self . olsr v5 output="" 3420 elif (event . GetId()==ID CLEAR LOGWIN 10) : 3421 self . olsr v6 output="" 3422 elif (event . GetId()==ID CLEAR LOGWIN ALL) : 3423 self .FindWindowById(ID LOGWIN USB0A) . Clear () 3424 self .FindWindowById(ID LOGWIN USB0B) . Clear () 3425 self .FindWindowById(ID LOGWIN USB1A) . Clear () 3426 self .FindWindowById(ID LOGWIN USB1B) . Clear () 3427 self . olsr v1 output="" 3428 self . olsr v2 output="" 3429 self . olsr v3 output="" 3430 self . olsr v4 output="" 3431 self . olsr v5 output="" 3432 self . olsr v6 output="" 3433 3434 def OnResetQueue( self , event) : 3435 dlg = wx. MessageDialog( self , " Do you really want to reset all queues in this application ?" ," Confirm Reset " , wx.OKjwx.CANCELjwx.ICON QUESTION) 3436 result = dlg .ShowModal() 3437 dlg . Destroy () 3438 if result == wx.ID OK: 258 3439 self . rx pkt queue usrp0A =[] 3440 self . rx pkt queue usrp0B =[] 3441 self . rx pkt queue usrp1A =[] 3442 self . rx pkt queue usrp1B =[] 3443 self . rx pkt queue virt1 =[] 3444 self . rx pkt queue virt2 =[] 3445 self . rx pkt queue virt3 =[] 3446 self . rx pkt queue virt4 =[] 3447 self . rx pkt queue virt5 =[] 3448 self . rx pkt queue virt6 =[] 3449 self . tx pkt queue usrp0A =[] 3450 self . tx pkt queue usrp0B =[] 3451 self . tx pkt queue usrp1A =[] 3452 self . tx pkt queue usrp1B =[] 3453 self . tx pkt queue virt1 =[] 3454 self . tx pkt queue virt2 =[] 3455 self . tx pkt queue virt3 =[] 3456 self . tx pkt queue virt4 =[] 3457 self . tx pkt queue virt5 =[] 3458 self . tx pkt queue virt6 =[] 3459 self . rx pkt queue historical usrp0A =[] 3460 self . rx pkt queue historical usrp0B =[] 3461 self . rx pkt queue historical usrp1A =[] 3462 self . rx pkt queue historical usrp1B =[] 3463 self . rx pkt queue historical virt1 =[] 3464 self . rx pkt queue historical virt2 =[] 3465 self . rx pkt queue historical virt3 =[] 3466 self . rx pkt queue historical virt4 =[] 3467 self . rx pkt queue historical virt5 =[] 3468 self . rx pkt queue historical virt6 =[] 3469 self . tx pkt queue historical usrp0A =[] 3470 self . tx pkt queue historical usrp0B =[] 3471 self . tx pkt queue historical usrp1A =[] 3472 self . tx pkt queue historical usrp1B =[] 3473 self . tx pkt queue historical virt1 =[] 3474 self . tx pkt queue historical virt2 =[] 3475 self . tx pkt queue historical virt3 =[] 3476 self . tx pkt queue historical virt4 =[] 3477 self . tx pkt queue historical virt5 =[] 3478 self . tx pkt queue historical virt6 =[] 3479 3480 3481 def OnClose( self , event) : 3482 dlg = wx. MessageDialog( self , " Do you really want to close this application ?" ," Confirm Exit " , wx.OKjwx.CANCELjwx.ICON QUESTION) 259 3483 result = dlg .ShowModal() 3484 dlg . Destroy () 3485 if result == wx.ID OK: 3486 self . olsr bring down interfaces () 3487 self . killOLSRProcesses () 3488 self . Destroy () 3489 3490 #raise SystemExit 3491 3492 def OnAbout( self , event) : 3493 dial = wx. MessageDialog( self , ? USRP GUI App v .1.1\ nMark Kuhr ? , ? About ? , wx.OK j wx. ICON INFORMATION) 3494 dial .ShowModal() 3495 3496 3497 if name == ? __main__ ? : 3498 app = wx.App( redirect=True) # Error messages go to popup window 3499 top = Frame(" USRP GUI Control Application ") 3500 top .Show(True) 3501 app.MainLoop() C.1.1 BBC Packet Class 1 2 ############################ 3 ## BEGIN BBC PACKET CLASS ## 4 ############################ 5 6 class packet( object ) : 7 def init ( self , node id=None, node address=None, to address=None, from address=None, 8 filename=None, marks=0, messages found=0, packets lost=0, rssi value=0): 9 self . node id = node id 10 self . node address = node address 11 self . to address=to address 12 self . from address=from address 13 self . filename=filename 14 self .marks=marks 15 self . messages found=messages found 16 self . packets lost=packets lost 17 self . rssi value = rssi value 18 19 20 def IsAckPacket( self ) : 21 if ( self . filename . find (" Ack ")>=0): 22 return True 260 23 else : 24 return False 25 26 def GetNodeAddress( self ) : 27 return self . node address 28 29 def GetToAddress( self ) : 30 return self . to address 31 32 def GetFromAddress( self ) : 33 return self . from address 34 35 def GetNodeId( self ) : 36 return self . node id 37 38 def GetFilename( self ) : 39 return self . filename 40 41 def GetRSSI( self ) : 42 return self . rssi value 43 44 def print pkt ( self ) : 45 print " Node id : "+self . node id 46 print " Node Address : "+self . node address 47 print " To Address : "+self . to address 48 print " From Address : "+self . from address 49 print " Filename : "+self . filename 50 print " Marks : "+self .marks 51 print " Messages Found : "+self . messages found 52 print " Packets lost : "+self . packets lost 53 print " RSSI Value : "+self . rssi value 54 print "\n" C.2 BBC Encoder/Decoder [Bahn 2007] C.2.1 usrp.c 1 / 2 Main TX/RX Module for the Real time BBC Codec/Modem 3 4 Modified By: 5 Mark G. Kuhr 6 Auburn University 7 261 8 Original Author : 9 William L. Bahn 10 Academy Center for Information Security 11 Department of Computer Science 12 United States Air Force Academy 13 USAFA, CO 80840 14 15 16 DESCRIPTION 17 18 19 The basic , high level , flow is as follows : 20 21 TX: The Transmitter 22 23 The transmitter uses the following signal flow : 24 25 SOURCE > ENCODER > BUFFER > MODULATOR > SINK 26 27 28 RX: The Receiver 29 30 The receiver used the following signal flow 31 32 SOURCE > MODEM > BUFFER > CODEC > SINK 33 34 35 // 36 37 the module supports both the transmitter and recevier functions . 38 39 40 / 41 / Real time BBC CODEC 42 43 This program is designed to process the raw USRP output data and decode 44 the resulting packets in real time in a streaming fashion . Since it is 45 a real time application , structural overhead has been minimized and 46 global variables have been used extensively . 47 48 THE DATA BUFFER 49 50 The data is stored in a circular buffer with the following variables : 51 buffer : Pointer to the block of memory where the buffer starts . 52 read : Index of the first byte of the present packet . 262 53 write : Index of the next unused buffer location . 54 f i l l : How many bytes are in buffer beyond the scope of the CODEC. 55 unused : How many unused bytes are available in the buffer . 56 57 The buffer is seen by two functions , the one that is demodulating the 58 data packet and the one that is decoding the resulting data . The 59 demodulating function writes to the buffer at a nominally constant 60 rate dictated by the communications link . In this application , this is 61 simulated by reading the stored waveform data from a file and querying 62 the clock to determine how many bytes to add to the buffer each time 63 the function is called . The decoding function , on the other hand , always 64 to decodes eight packets each time it is called provided sufficient data 65 is available . Specifically , it decodes the eight packets that start with 66 the bits in the byte stored at the "read" pointer . Since it can ?t decode 67 packets that are not completely contained in the buffer , the decoding 68 function first checks to see if " f i l l " is non negative . If it isn ?t , then 69 it returns immediately . At the other end of the spectrum , the MODEM 70 may run out of unused memory to write to . If this happens , data is going 71 to be lost . It is cleaner to throw away old data instead of introducing 72 a gap in present data , therefore the MODEM will push the "read" 73 pointer forward as it overwrites the beginning of the existing packet 74 data . 75 76 / 77 78 // 79 // FILE INCLUSIONS 80 // 81 82 #include // printf () 83 #include // exit () , EXIT SUCCESS, EXIT FAILURE 84 #include 85 #include