[1568] | 1 | # WARPnet Client<->Server Architecture |
---|
| 2 | # WARPnet Parameter Definitions |
---|
| 3 | # |
---|
| 4 | # Author: Siddharth Gupta |
---|
| 5 | |
---|
| 6 | import struct, time |
---|
| 7 | from warpnet_common_params import * |
---|
| 8 | from warpnet_client_definitions import * |
---|
| 9 | from twisted.internet import reactor |
---|
| 10 | import binascii |
---|
| 11 | |
---|
| 12 | # Struct IDs |
---|
| 13 | |
---|
| 14 | STRUCTID_CONTROL = 0x13 |
---|
| 15 | STRUCTID_CONTROL_ACK = 0x14 |
---|
| 16 | STRUCTID_COMMAND = 0x17 |
---|
| 17 | STRUCTID_COMMAND_ACK = 0x18 |
---|
[1569] | 18 | STRUCTID_OBSERVE_BER = 0x24 |
---|
| 19 | STRUCTID_OBSERVE_BER_REQ = 0x25 |
---|
[1568] | 20 | STRUCTID_OBSERVE_PER = 0x26 |
---|
| 21 | STRUCTID_OBSERVE_PER_REQ = 0x27 |
---|
| 22 | |
---|
| 23 | # Command IDs |
---|
| 24 | COMMANDID_STARTTRIAL = 0x40 |
---|
| 25 | COMMANDID_STOPTRIAL = 0x41 |
---|
| 26 | COMMANDID_RESET_PER = 0x50 |
---|
| 27 | COMMANDID_ENABLE_BER_TESTING = 0x51 |
---|
| 28 | COMMANDID_DISABLE_BER_TESTING = 0x52 |
---|
| 29 | |
---|
| 30 | ######################## |
---|
| 31 | ## Struct Definitions ## |
---|
| 32 | ######################## |
---|
| 33 | |
---|
| 34 | # ControlStruct is a ClientStruct that stores some basic parameters to pass to the WARP board. The local variable can be accessed |
---|
| 35 | # globally by calling ControlStruct.txPower etc. The struct must also understand the conversion from integer values to binary |
---|
| 36 | # using the prepToSend function; it will be provided with the nodeID. |
---|
| 37 | # typedef struct { |
---|
| 38 | # char structID; |
---|
| 39 | # char nodeID; |
---|
| 40 | # char txPower; |
---|
| 41 | # char channel; |
---|
| 42 | # char modOrderHeader; |
---|
| 43 | # char modOrderPayload; |
---|
| 44 | # short reserved; |
---|
| 45 | # int pktGen_period; |
---|
| 46 | # int pktGen_length; |
---|
| 47 | # } warpnetControl; |
---|
| 48 | class ControlStruct(ClientStruct): |
---|
| 49 | txPower = -1 |
---|
| 50 | channel = -1 |
---|
| 51 | modOrderHeader = -1 |
---|
| 52 | modOrderPayload = -1 |
---|
| 53 | reserved = 0 |
---|
| 54 | packetGeneratorPeriod = 0 |
---|
| 55 | packetGeneratorLength = 0 |
---|
| 56 | |
---|
| 57 | def __init__(self): |
---|
| 58 | self.structID = STRUCTID_CONTROL |
---|
| 59 | self.txPower = 63 |
---|
| 60 | self.channel = 4 |
---|
| 61 | self.modOrderHeader = 0 |
---|
| 62 | self.modOrderPayload = 2 |
---|
| 63 | self.packetGeneratorPeriod = 0 |
---|
| 64 | self.packetGeneratorLength = 1300 |
---|
| 65 | self.expectedReturnStructID = STRUCTID_CONTROL_ACK |
---|
| 66 | |
---|
| 67 | def prepToSend(self, nodeID): |
---|
| 68 | self.updateDone = False |
---|
| 69 | return struct.pack('!6BHII', self.structID, nodeID, self.txPower, self.channel, self.modOrderHeader, self.modOrderPayload, self.reserved, self.packetGeneratorPeriod, self.packetGeneratorLength) |
---|
| 70 | |
---|
| 71 | def updateFromNode(self, rawData, pcapts): |
---|
| 72 | dataTuple = struct.unpack('!BBH', rawData[0:4]) |
---|
| 73 | #print "Control struct successfully applied at node %d" % dataTuple[1] |
---|
| 74 | |
---|
| 75 | |
---|
| 76 | #CommandStruct is used to send commands or requests to the WARP nodes |
---|
| 77 | # The cmdIDs are defined above |
---|
| 78 | # Matching C code definition: |
---|
| 79 | # typedef struct { |
---|
| 80 | # char structID; |
---|
| 81 | # char nodeID; |
---|
| 82 | # char cmdID; |
---|
| 83 | # char cmdParam; |
---|
| 84 | # } warpnetCommand; |
---|
| 85 | class CommandStruct(ClientStruct): |
---|
| 86 | cmdID = -1 |
---|
| 87 | cmdParam = -1 |
---|
| 88 | |
---|
| 89 | def __init__(self, cmdID, cmdParam): |
---|
| 90 | self.structID = STRUCTID_COMMAND |
---|
| 91 | self.expectedReturnStructID = STRUCTID_COMMAND_ACK |
---|
| 92 | self.cmdID = cmdID |
---|
| 93 | self.cmdParam = cmdParam |
---|
| 94 | |
---|
| 95 | def prepToSend(self, nodeID): |
---|
| 96 | self.updateDone = False |
---|
| 97 | return struct.pack('!4B', self.structID, nodeID, self.cmdID, self.cmdParam) |
---|
| 98 | |
---|
| 99 | def updateFromNode(self, rawData, pcapts): |
---|
| 100 | pass |
---|
| 101 | #print "Successfully executed command %d" % self.cmdID |
---|
| 102 | |
---|
| 103 | #ObservePERStruct collects packet error rate (PER) data from WARP nodes |
---|
| 104 | # Matching C code definition: |
---|
| 105 | # typedef struct { |
---|
| 106 | # unsigned char structID; |
---|
| 107 | # unsigned char nodeID; |
---|
| 108 | # unsigned char reqNum; |
---|
| 109 | # unsigned char reqType; |
---|
| 110 | # unsigned int numPkts_tx; |
---|
| 111 | # unsigned int numPkts_rx_good; |
---|
| 112 | # unsigned int numPkts_rx_goodHdrBadPyld; |
---|
| 113 | # unsigned int numPkts_rx_badHdr; |
---|
| 114 | # } warpnetObservePER; |
---|
| 115 | class ObservePERStruct(ClientStruct): |
---|
| 116 | numPkts_tx = -1 |
---|
| 117 | numPkts_rx_good = -1 |
---|
| 118 | numPkts_rx_goodHdrBadPyld = -1 |
---|
| 119 | numPkts_rx_badHdr = -1 |
---|
| 120 | reqNum = -1 |
---|
| 121 | reqType = -1 |
---|
| 122 | |
---|
| 123 | def __init__(self, logger=None): |
---|
| 124 | ClientStruct.__init__(self, logger) |
---|
| 125 | |
---|
| 126 | self.structID = STRUCTID_OBSERVE_PER_REQ |
---|
| 127 | self.expectedReturnStructID = STRUCTID_OBSERVE_PER |
---|
| 128 | |
---|
| 129 | self.numPkts_tx = 0 |
---|
| 130 | self.numPkts_rx_good = 0 |
---|
| 131 | self.numPkts_rx_goodHdrBadPyld = 0 |
---|
| 132 | self.numPkts_rx_badHdr = 0 |
---|
| 133 | self.reqNum = 0 |
---|
| 134 | self.reqType = 0 |
---|
| 135 | |
---|
| 136 | def prepToSend(self, nodeID): |
---|
| 137 | self.updateDone = False |
---|
| 138 | return struct.pack('!4B', self.structID, nodeID, self.reqNum, self.reqType) |
---|
| 139 | |
---|
| 140 | def updateFromNode(self, rawData, pcapts): |
---|
| 141 | dataTuple = struct.unpack('!2B 2B 4I', rawData[0:20]) |
---|
| 142 | self.reqNum = dataTuple[2] |
---|
| 143 | self.reqType = dataTuple[3] |
---|
| 144 | self.numPkts_tx = dataTuple[4] |
---|
| 145 | self.numPkts_rx_good = dataTuple[5] |
---|
| 146 | self.numPkts_rx_goodHdrBadPyld = dataTuple[6] |
---|
| 147 | self.numPkts_rx_badHdr = dataTuple[7] |
---|
| 148 | |
---|
| 149 | |
---|
| 150 | #Client struct for collecting BER updates from the ber_processor program |
---|
| 151 | # Matching C code struct: |
---|
| 152 | # typedef struct { |
---|
| 153 | # unsigned char structID; |
---|
| 154 | # unsigned char nodeID; |
---|
| 155 | # unsigned short sequenceNumber; |
---|
| 156 | # unsigned char nodeID_tx; |
---|
| 157 | # unsigned char nodeID_rx; |
---|
| 158 | # unsigned short mac_seqNum; |
---|
| 159 | # unsigned char mac_pktType; |
---|
| 160 | # unsigned char reserved0; |
---|
| 161 | # unsigned char reserved1; |
---|
| 162 | # unsigned char reserved2; |
---|
| 163 | # unsigned int bits_rx; |
---|
| 164 | # unsigned int bits_errors; |
---|
| 165 | # } warpnetObserveBER; |
---|
| 166 | class ObserveBERStruct(ClientStruct): |
---|
| 167 | totalBitsReceived = 0 |
---|
| 168 | totalBitErrors = 0 |
---|
| 169 | nodeID_tx = -1 |
---|
| 170 | nodeID_rx = -1 |
---|
| 171 | |
---|
| 172 | def __init__(self, logger=None): |
---|
| 173 | ClientStruct.__init__(self, logger) |
---|
| 174 | |
---|
| 175 | self.structID = STRUCTID_OBSERVE_BER_REQ |
---|
| 176 | self.expectedReturnStructID = STRUCTID_OBSERVE_BER |
---|
| 177 | |
---|
| 178 | self.totalBitsReceived = 0 |
---|
| 179 | self.totalBitErrors = 0 |
---|
| 180 | |
---|
| 181 | def prepToSend(self, nodeID): |
---|
| 182 | self.updateDone = False |
---|
| 183 | return struct.pack('!BBH', self.structID, nodeID, 0) |
---|
| 184 | |
---|
| 185 | def updateFromNode(self, rawData, pcapts): |
---|
| 186 | dataTuple = struct.unpack('!2B H 2B H 2I', rawData[0:16]) |
---|
| 187 | self.nodeID_tx = dataTuple[3] |
---|
| 188 | self.nodeID_rx = dataTuple[4] |
---|
| 189 | self.totalBitsReceived += dataTuple[6] |
---|
| 190 | self.totalBitErrors += dataTuple[7] |
---|
| 191 | |
---|
| 192 | def clearBitCounts(self): |
---|
| 193 | self.totalBitsReceived = 0 |
---|
| 194 | self.totalBitErrors = 0 |
---|
[1569] | 195 | |
---|