Added a lot of comments to fully describe alot of the methods we have created.
authorchrishoder <chrishoder@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 19 Feb 2013 23:11:05 +0000 (23:11 +0000)
committerchrishoder <chrishoder@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 19 Feb 2013 23:11:05 +0000 (23:11 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1510 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/FordExperiments.py
client/GoodFETMCPCAN.py
client/GoodFETMCPCANCommunication.py
client/experiments.py

index e826bca..ad1b8b9 100644 (file)
@@ -19,9 +19,6 @@ class FordExperiments(GoodFETMCPCANCommunication, dataLocation):
         #super(FordExperiments,self).__init__(self) #initialize chip
         self.freq = 500;
 
-    
-
-
     def mimic1056(self,packetData,runTime):
         #setup chip
         self.client.serInit()
@@ -118,7 +115,7 @@ class FordExperiments(GoodFETMCPCANCommunication, dataLocation):
         while( (time.time()-recieveTime) < runTime):
             #care about db3 or packet[8] that we want to count at the rate that it is
             dT = time.time()-tpast
-            packetValue += 1
+            packetValue += 10
             pV = packetValue%255
             #temp = ((packetValue+1))%2
             #if( temp == 1):
index 304b747..39faace 100644 (file)
@@ -234,7 +234,22 @@ class GoodFETMCPCAN(GoodFETSPI):
         
         self.SPItrans([0x40|(packbuf<<1)]+packet);
 
+   
+    def txpacket(self,packet):
+        """Transmits a packet through one of the outbound buffers.
+        As usual, the packet should begin with SIDH.
+        For now, only TXB0 is supported."""
+
+        self.writetxbuffer(packet,0);
+        self.MCPrts(TXB0=True);
+
+                
+    ###############   UTILITY FUNCTIONS  #################
+     
     def simpleParse(self,packet):
+        """ 
+        This will print a simple parsing of the data with the standard Id and the extended id parsed.
+        """
         dataPt = ord(packet[0]);
         dataPt2 = ord(packet[1]);
         # check if we have a standard frame, the msb of the second
@@ -256,9 +271,9 @@ class GoodFETMCPCAN(GoodFETSPI):
         #find the dataLength
         dataPt5 = packet[4]
         dataLength = dataPt5 & 0x0e
-        print "Data Length: "+("%d"%dataLength)
+        #print "Data Length: "+("%d"%dataLength)
         # Print the data packet
-        print "Data:"
+        #print "Data:"
         # Temporary, until correct packets are read
         if( dataLength > 8 ):
             dataLength = 8
@@ -272,16 +287,6 @@ class GoodFETMCPCAN(GoodFETSPI):
        # toprint =  self.pcket2str(packet[5:(5+dataLength)])
        # print toprint
 
-    def txpacket(self,packet):
-        """Transmits a packet through one of the outbound buffers.
-        As usual, the packet should begin with SIDH.
-        For now, only TXB0 is supported."""
-
-        self.writetxbuffer(packet,0);
-        self.MCPrts(TXB0=True);
-
-                
-    ###############   UTILITY FUNCTIONS  #################
             
     def packet2str(self,packet):
         """Converts a packet from the internal format to a string."""
@@ -291,8 +296,29 @@ class GoodFETMCPCAN(GoodFETSPI):
         return toprint;
     
     
-    ## This code could be drastica
+    
     def packet2parsed(self,data):
+        """
+        This method will parse the packet that was received via L{rxpacket}.
+        
+        @type data: List
+        @param data: data packet read off of the MCP2515 from the CAN bus. format will be
+                     14 bytes where each element is a character whose unicode integer value corresponds
+                     to the hex value of the byte (use the ord() method).
+        
+        @rtype: Dictionary
+        @return: Dictionary of the packet parsed into various components. The key values will be as follows
+                     
+                     1. ide : 1 if the message is an extended frame. 0 otherwise
+                     2. eID : extended ID. Not included if not an extended frame
+                     3. rtr : 1 if the message is a remote transmission request (RTR)
+                     4. sID : Standard ID. 
+                     5. length: packet length (between 0 and 8)
+                     6. db0 : Data byte 0 (not included if RTR message)
+                         
+                         ---
+                     7. db7 : Data byte 7 (not included if RTR message)
+        """
         dp1 = ord(data[0])
         dp2 = ord(data[1])
         dp5 = ord(data[4])
@@ -327,6 +353,17 @@ class GoodFETMCPCAN(GoodFETSPI):
         return packet
     
     def packet2parsedstr(self,data):
+        """
+        This will return a string that is the parsed CAN message. The bytes will be parsed
+        for the standard ID, extended ID (if one is present), rtr, length and databytes (if present).
+        The message will be placed into a string as decimal integers not hex values. This method 
+        calls L{packet2parsed} to do the packet parsing.
+        
+        @type data: List
+        @param data: Data packet as returned by the L{rxpacket}
+        @rtype: String
+        @return: String that shows the data message in decimal format, parsed.
+        """
         packet = self.packet2parsed(data)
         msg = "sID: %04d" %packet['sId']
         if( packetParsed.get('eID')):
@@ -337,9 +374,9 @@ class GoodFETMCPCAN(GoodFETSPI):
         msg += " data:"
         for i in range(0,length):
             dbidx = 'db%d'%i
-            msg +=" %03d"% ord(packetParsed[dbidx])
+            msg +=" %03d"% ord(packetParsed[dbidx])  # could change this to HEX
         #msg = self.client.packet2parsedstr(packet)
-        print msg
+        return msg
         
         
     def peek8(self,adr):
index f5fc9c9..e29d977 100644 (file)
@@ -25,17 +25,24 @@ import Queue
 class GoodFETMCPCANCommunication:
     
     def __init__(self, dataLocation):
-       self.client=GoodFETMCPCAN(); """ Communication with the bus"""
+       self.client=GoodFETMCPCAN();
+        """ Communication with the bus"""
        self.client.serInit()
        self.client.MCPsetup();
        #self.DATA_LOCATION = "../../contrib/ThayerData/"
-       self.DATA_LOCATION = dataLocation; """ Stores file data location. This is the root folder where basic sniffs will be stored"""
-       self.INJECT_DATA_LOCATION  = self.DATA_LOCATION+"InjectedData/" """ stores the sub folder path where injected data will be stored"""
+       self.DATA_LOCATION = dataLocation; 
+       """ Stores file data location. This is the root folder where basic sniffs will be stored"""
+       self.INJECT_DATA_LOCATION  = self.DATA_LOCATION+"InjectedData/" 
+       """ stores the sub folder path where injected data will be stored"""
        
 
     
     def printInfo(self):
-        """ This method will print information about the board to the termina. It is usefull for diagnostics"""
+        """ 
+        This method will print information about the board to the terminal. 
+        It is good for diagnostics
+        """
+        
         self.client.MCPreqstatConfiguration();
         
         print "MCP2515 Info:\n\n";
@@ -298,7 +305,12 @@ class GoodFETMCPCANCommunication:
 #        return msgIDs, ids
     
     def sniffTest(self, freq):
+        """
+        This method will preform a test to see if we can sniff corretly formed packets from the CAN bus.
         
+        @type freq: number
+        @param freq: frequency of the CAN bus
+        """
         rate = freq;
         
         print "Calling MCPsetrate for %i." %rate;
@@ -322,7 +334,13 @@ class GoodFETMCPCANCommunication:
    
     
     def freqtest(self,freq):
+        """
+        This method will test the frequency provided to see if it is the correct frequency for this CAN bus.
+        
+        @type freq: Number
+        @param freq: The frequency to listen to the CAN bus.
         
+        """
         self.client.MCPsetup();
 
         self.client.MCPsetrate(freq);
@@ -420,6 +438,7 @@ class GoodFETMCPCANCommunication:
         
         @rtype: None
         @return: This method does not return anything
+        @todo: rename setFilters
         """
        
         ### ON-CHIP FILTERING
@@ -468,19 +487,22 @@ class GoodFETMCPCANCommunication:
         self.client.MCPreqstatNormal();
     
     def filterForPacket(self, standardid, DB0, DB1, verbose= True):
-        """ This method will configure filters on the board to listen for a specific packet originating from standardid with data bytes 0 and 1. It will configure all six filters, so you will not recieve any other packets.
-            @type standardid: integer
-            @param standardid: standardID to listen for
-            @type DB0: integer
-            @param standardid: DB0 contents to filter for
-            @type DB1: integer
-            @param standardid: DB1 contents to filter for
-            @type verbose: Boolean
-            @param verbose: If true it will print out messages and diagnostics to terminal.
-            
-            @rtype: None
-            @return: This method does not return anything
-            """
+        """ 
+        This method will configure filters on the board to listen for a specific packet originating 
+        from standardid with data bytes 0 and 1. It will configure all six filters, so you will not receive any other packets.
+        
+        @type standardid: integer
+        @param standardid: standardID to listen for
+        @type DB0: integer
+        @param standardid: DB0 contents to filter for
+        @type DB1: integer
+        @param standardid: DB1 contents to filter for
+        @type verbose: Boolean
+        @param verbose: If true it will print out messages and diagnostics to terminal.
+        
+        @rtype: None
+        @return: This method does not return anything
+        """
         
         ### ON-CHIP FILTERING
        
index 54bb823..9c07643 100644 (file)
@@ -39,7 +39,7 @@ class experiments(GoodFETMCPCANCommunication):
         This will actively filter for 6 ids at a time and sniff for the given amount of
         time in seconds. If at least one message is read in then it will go individually
         through the 6 ids and sniff only for that id for the given amount of time. All the
-        data gathered will be saved. 
+        data gathered will be saved.  This does not save any sniffed packets.
         
         @type  freq: number
         @param freq: The frequency at which the bus is communicating
@@ -78,7 +78,7 @@ class experiments(GoodFETMCPCANCommunication):
         This method will choose random values to listen out of all the possible standard ids up to
         the given number. It will sniff for the given amount of time on each set of ids on the given 
         frequency. Sniffs in groups of 6 but when at least one message is read in it will go through all
-        six individually before continuing.
+        six individually before continuing. This does not save any sniffed packets.
         
         @type  freq: number
         @param freq: The frequency at which the bus is communicating
@@ -123,6 +123,19 @@ class experiments(GoodFETMCPCANCommunication):
         The RTR will be repeated in the given number of attempts and will sniff for the given duration
         continuing to the next id.
         
+        Any messages that are sniffed will be saved to a csv file. The filename will be stored in the DATA_LOCATION folder
+        with a filename that is the date (YYYYMMDD)_rtr.csv. If the file already exists it will append to the end of the file
+        The format will follow that of L{GoodFETMCPCANCommunication.sniff} in that the columns will be as follows:
+            1. timestamp:     as floating point number
+            2. error boolean: 1 if there was an error detected of packet formatting (not exhaustive check). 0 otherwise
+            3. comment tag:   comment about experiments as String
+            4. duration:      Length of overall sniff
+            5. filtering:     1 if there was filtering. 0 otherwise
+            6. db0:           Integer
+            
+                ---
+            7. db7:           Integer
+        
         @type  freq: number
         @param freq: The frequency at which the bus is communicating
         @type   lowID: integer
@@ -307,7 +320,7 @@ class experiments(GoodFETMCPCANCommunication):
                 packet[i+5] = value
             print packet
             #put a rough time stamp on the data and get all the data bytes    
-            row = [time.tT(), id_new,8]
+            row = [time.tT(), id_new,8] # could make this 8 a variable 
             msg = "Injecting: "
             for i in range(5,13):
                 row.append(packet[i])
@@ -326,6 +339,29 @@ class experiments(GoodFETMCPCANCommunication):
         outfile.close()
             
     def generalFuzz(self,freq, Fuzzes, period, writesPerFuzz):
+        """
+        The method will inject properly formatted, randomly generated messages at a given period for a I{writesPerFuzz} 
+        number of times. A new random standard id will be chosen with each newly generated packet. IDs will be chosen from the full
+        range of potential ids ranging from 0 to 4095. The packets that are injected into the bus will all be saved in the following path
+        DATALOCATION/InjectedData/(today's date (YYYYMMDD))_GenerationFuzzedPackets.csv. An example filename would be 20130222_GenerationFuzzedPackets.csv
+        Where DATALOCATION is provided when the class is initiated. The data will be saved as integers.
+        Each row will be formatted in the following form::
+                     row = [time of injection, standardID, 8, db0, db1, db2, db3, db4, db5, db6, db7]
+        
+        @type  freq: number
+        @param freq: The frequency at which the bus is communicating
+        @type period: number
+        @param period: The time gap between packet inejctions given in milliseconds
+        @type writesPerFuzz: integer
+        @param writesPerFuzz: This will be the number of times that each randomly generated packet will be injected onto the bus
+                              before a new packet is generated
+        @type Fuzzes: integer
+        @param Fuzzes: The number of packets to be generated and injected onto bus
+        
+        @rtype: None
+        @return: This method does not return anything
+                         
+        """
         #print "Fuzzing on standard ID: %d" %standardId
         self.client.serInit()
         self.spitSetup(freq)
@@ -343,7 +379,8 @@ class experiments(GoodFETMCPCANCommunication):
             
         fuzzNumber = 0; #: counts the number of packets we have generated
         while( fuzzNumber < Fuzzes):
-            id_new = random.randint(0,4095)
+            #generate new random standard id in the full range of possible values
+            id_new = random.randint(0,4095) 
             #print id_new
             #### split SID into different regs
             SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
@@ -359,7 +396,8 @@ class experiments(GoodFETMCPCANCommunication):
                 packet[i+5] = value
             print packet
             #put a rough time stamp on the data and get all the data bytes    
-            row = [time.time(), id_new,8]
+            row = [time.time(), id_new,8] 
+            """@todo: allow for varied packet lengths"""
             msg = "Injecting: "
             for i in range(5,13):
                 row.append(packet[i])
@@ -379,6 +417,37 @@ class experiments(GoodFETMCPCANCommunication):
     
     # assumes 8 byte packets
     def packetRespond(self,freq, time, repeats, period,  responseID, respondPacket,listenID, listenPacket = None):
+        """
+        This method will allow the user to listen for a specific packet and then respond with a given message.
+        If no listening packet is included then the method will only listen for the id and respond with the specified
+        packet when it receives a message from that id. This process will continue for the given amount of time (in seconds). 
+        and with each message received that matches the listenPacket and ID the transmit message will be sent the I{repeats} number
+        of times at the specified I{period}. This message assumes a packet length of 8 for both messages, although the listenPacket can be None
+        
+        @type freq: number
+        @param freq: Frequency of the CAN bus
+        @type time: number
+        @param time: Length of time to perform the packet listen/response in seconds.
+        @type repeats: Integer
+        @param repeats: The number of times the response packet will be injected onto the bus after the listening 
+                        criteria has been met.
+        @type period: number
+        @param period: The time interval between messages being injected onto the CAN bus. This will be specified in milliseconds
+        @type responseID: Integer
+        @param responseID: The standard ID of the message that we want to inject
+        @type respondPacket: List of integers
+        @param respondPacket: The data we wish to inject into the bus. In the format where respondPacket[0] = databyte 0 ... respondPacket[7] = databyte 7
+                              This assumes a packet length of 8.
+        @type listenID: Integer
+        @param listenID: The standard ID of the messages that we are listening for. When we read the correct message from this ID off of the bus, the method will
+                         begin re-injecting the responsePacket on the responseID
+        @type listenPacket: List of Integers
+        @param listenPacket: The data we wish to listen for before we inject packets. This will be a list of the databytes, stored as integers such that
+                             listenPacket[0] = data byte 0, ..., listenPacket[7] = databyte 7. This assumes a packet length of 8. This input can be None and this
+                             will lead to the program only listening for the standardID and injecting the response as soon as any message from that ID is given
+        """
+        
+        
         self.client.serInit()
         self.spitSetup(freq)
         
@@ -394,7 +463,7 @@ class experiments(GoodFETMCPCANCommunication):
         #load packet/send once
         """@todo: make this only load the data onto the chip and not send """
         self.client.txpacket(resPacket) 
-        self.addFilter([listenID,listenID,listenID,listenID]) #listen only for this packet
+        self.addFilter([listenID,listenID,listenID,listenID, listenID, listenID]) #listen only for this packet
         startTime = tT.time()
         packet = None
         while( (tT.time() - startTime) < time):
@@ -409,6 +478,8 @@ class experiments(GoodFETMCPCANCommunication):
                         self.client.MCPrts(TXB0=True)
                         tT.sleep(period/1000)
                 else: #compare packets
+                    sid =  ord(packet[0])<< | ord(packet[1])>>5
+                    print "standard id of packet recieved: ", sid #standard ID
                     for i in range(0,8):
                         idx = 5 + i
                         byteIn = ord(packet[idx])