Table Of Contents

 Gateway Visual Feedback System Formal ReportSubnet MasqueRAIDers - Matthew Baskharion, Colby Brunner, Alex RollickTable Of Contents TOC \h \u \z Table Of Contents PAGEREF _c3rkloj29v8w \h 1Executive Summary PAGEREF _kx2jfd9k1cmp \h 3Project Scope PAGEREF _we2l659wbnol \h 4Out of Scope PAGEREF _cw7g5luqa7m \h 5Project Problems PAGEREF _df4yq4rg103n \h 6ODBC Driver configuration and connection PAGEREF _maihdevj2lxt \h 6Outfile Encryption PAGEREF _gfo81d3fqf0n \h 6Router PAGEREF _flu4ghu8w55j \h 6Project Members PAGEREF _5ebv74w1mx12 \h 7Colby Brunner PAGEREF _86rod01gnc1m \h 7Alex Rollick PAGEREF _ltf0g5t4s2g1 \h 7Matt Baskharion PAGEREF _4bn04ghxwmqz \h 7Planned Budget PAGEREF _p89zkj3gv330 \h 8Materials PAGEREF _8b3w9bdcerbe \h 9References PAGEREF _ifbn4u6d5w1 \h 10Appendix PAGEREF _kthkmwux2tgc \h 11A.Source Code PAGEREF _abf8q61v970m \h 11pyDBAllOrOne.py PAGEREF _uc6ljgbepiba \h 11clearPin5and6.py PAGEREF _gh4hr44i6v9 \h 14LEDControl.py PAGEREF _g8sekqvrp192 \h 14B.User And Administrative Manual PAGEREF _kkddwpvhjf3q \h 18Hardware Administrative Guide PAGEREF _mfk9zlf70tcm \h 19Materials PAGEREF _wejetkjwj0ic \h 19Hardware Schematics PAGEREF _zcvaqlfuxqfe \h 19Procedure PAGEREF _a34ny2i7g0oz \h 20Hardware User Guide PAGEREF _uhb6g1s8q323 \h 22Software Administrative Guide: PAGEREF _x1h6b9ncs8er \h 23LEDControl.py PAGEREF _1fbpygs9hs81 \h 23pyDBAllorOne.py PAGEREF _sq3p418mtgab \h 23ODBC Driver Configuration[1] PAGEREF _deuqaw281ek3 \h 25Software User Guide PAGEREF _mhv4zeowbi2z \h 28pyDBAllorOne.py PAGEREF _i8tm8laxtggz \h 28LEDControl.py PAGEREF _jxaehzxp7juo \h 28C.Glossary PAGEREF _pn0kv7v2z8xn \h 30D.Actual Budget PAGEREF _bd5renfep7pp \h 31Hardware PAGEREF _1y70i2j21g6a \h 31Software PAGEREF _2o0n4bsyle8j \h 32Labour PAGEREF _75towtz64k0h \h 32Executive SummaryContained in this document are the details of the Gateway Visual Feedback project. We were able to create a functioning proof of concept device as part of a sponsorship with Shaw. This project evolved several times over the duration of its lifetime, but has come to a point where both the client, and us as a team, are satisfied with what we have created.Project ScopeThe scope of this project was to create a visual way to monitor the status of several tests performed on gateway devices. As this project is sponsored by Shaw, we were able to create a proof of concept device for their distribution center. However, we were not given access to actual Shaw gateway devices, so we were required to emulate how one would interact with our scripts.The project includes elements of software (scripts and applications), hardware (breadboard, LEDs, wiring), networking (secure wifi network, file server), security (encryption for files), as well as clear and concise documentation for each part of the project.Out of ScopeWhile we tried to include as much development into our project as possible, there were some aspects that we were either unable to complete in the time allowed, or were too difficult for the proof of concept idea. Some of these out of scope ideas included:Virtualizing the entire network infrastructure to pull serial numbers fromCreating a permanent/visually appealing case for the LEDsAdding more colours of LEDs to represent additional errorsSecurely encrypting the file so that it can be accessed at NO time while it is encryptedGiven more time, it is likely that we could have implemented many of these ideas. However, as only a proof of concept, it is a rough, working product that Shaw could use to increase efficiency within its distribution center. Project Problems We had four main issues for this project:ODBC Driver configuration and connection.Outfile EncryptionRouter and IP Address AssignmentODBC Driver configuration and connectionEnabling the script to connect to the Microsoft Access database involved a good amount of trial and error. The documentation Matt had consulted had provided simple connection parameters which hadn’t worked. After a decent amount of experimentation with different parameters and research, he had found the solution. The connection function required a series of specific values provided by the database itself. In order to retrieve these parameters, Matt had to use Data Sources(ODBC) to load the Microsoft Access Driver, then load the database itself.Outfile EncryptionThe LED Control script had generated outfile based on the results it had parsed. Matt had attempted to encrypt the outfile after it was written to. This caused a problem as the encrypted outfile could not be written to. After a few weeks of trial and error, the working script had managed to decrypt the outfile, store the plaintext in a temporary file, and append to that. The temporary file was then encrypted and renamed, while the old outfile was deleted.RouterAccording to the router’s documentation, there was no way to assign static IP addresses. Requesting static IP addresses on either the Raspberry Pi 2 or our Laptop resulted in no IP address being assigned and the connection had failed. Matt went into the DHCP settings and set the number of possible of clients to 2, and set the first available address to the desired address for the Pi.Project MembersColby BrunnerSome titles Colby held over the course of the project were: website developer, Python initiator, hardware assistant, script reviewer, and team lead. He worked with both Alex and Matt assist them in their tasks. When helping Alex, Colby gathered materials, wires, and LEDs for the hardware aspect of the project. He also gave input into the design and creation of the team banner. He also assisted Matt with the development of the initial Python scripts, and took time to discuss Matt’s progress with his following scripts. Colby, on his own, oversaw the development of the team website and ensured that everyone provided the required documents and organized them appropriately.Alex RollickSome titles Alex held over the course of the project were: hardware lead, documentation reviewer, banner developer, and team lead. Alex was in charge of both developing and wiring the hardware aspects of the project. He was able to connect the GPIO to the correct pins, and position the multicolour LEDs appropriately. He then was able to work with Matt to create a script that would adequately power the required LEDs at a specified time. Alex also led several meetings and was mainly in charge of editing and updating the team documents so they remained current and relevant.Matt BaskharionSome titles Matt held over the course of the project were: lead software developer, script analyst, operations supervisor, and team lead. Matt took over control of creating and developing the required Python scripts needed for the project to function. He worked closely with Alex and Colby to ensure the scripts behaved as expected when connected to the hardware. Matt led the majority of the project, ensured each team member remained on task, and personally saw to it that the code and project functioned properly.Planned BudgetItemDescriptionNumber of ItemsCostRaspberry Pi 2 Model BOur mock server1$120.00LED LightsGateway identifiers8$2.00WiringThe power input connections120$11.00Fibre CableConnects with ethernet1$5.00Ethernet CableConnects to internet1$11.00Fibre to Ethernet ConverterConnects fibre and ethernet1$150.00Contingency fundsA safety netN/A$500.00Total Equipment Costs:$799.00ItemHoursRateCostAlex Rollick78$40.00$3120.00Matthew Baskharion80$40.00$3200.00Colby Brunner71$40.00$2840.00Total Operating Costs:$9160.00MaterialsWe were able to complete our project with minimal materials required. In the end, the only items we required were: a router, breadboard, several multicoloured LEDs, colour-coded wires, a Raspberry Pi and peripherals, GPIO connector, and a wire crimper. Most of our project was software based, so it ended up being economical and very portable. Most materials, such as the peripherals, were rentals from SAIT and are also really easy to come by. The materials required to implement this in the Shaw environment may differ slightly however, as we would need more materials to actually test the gateways.References[1]P. paradox, "Pyodbc error Data source name not found and no default driver specified paradox", , 2017. [Online]. Available: . [Accessed: 06- Apr- 2017].[2]"Gateway HDPVR Terminal and Portals | Gateway - Shaw.ca", Shaw.ca, 2017. [Online]. Available: . [Accessed: 10- Apr- 2017].[3]"Microsoft Open Database Connectivity (ODBC)", Docs., 2017. [Online]. Available: . [Accessed: 10- Apr- 2017].[4]"Toshiba Tecra Z50-A1503", PCMAG, 2017. [Online]. Available: . [Accessed: 10- Apr- 2017].[5]"Buy Access 2016 - Microsoft Store Canada", Microsoft Store, 2017. [Online]. Available: . [Accessed: 11- Apr- 2017].AppendixA.Source CodepyDBAllOrOne.py#This is different version of the database iterating script that includes the original PyDB script. This script has two modes: read(-r), and original functionality (-n). -n requires serial number from CLI.# pyodbc #Python module to interact with ODBC databases. ODBC is a standard API, which serves as the base for Microsoft Accessimport os #Module to interact with Operating System and for file managementimport sys #Module to retrieve command line parameters #The following functions contains try..excepts to attempt to open the necessary files. Which files are opened depends on the serialNumSwitch.#serialNumSwitch is the first CLI parameter and must be -n or -r.#this function is called within databaseScanner(), which is where the serialNumSwitch is actually retrieveddef fileHandling(serialNumSwitch):#net use /user:raspberry\pi \\192.168.1.100\PiShare\VisualFeedbackLogs raspberry#the above is a working command to connect to the windows share on the raspberry piif serialNumSwitch in ["-r","-R","-n","-N"] and len(sys.argv)>=4 and len(sys.argv)<=5:#this block will not run unless the user has inputted a total of 5 or 6 CLI parameters.#An example of the parameters for this block to run are: pyDBFileIteration.py -r username passwordnetfilePathBackSlash="\\192.168.29.2\PiShare\VisualFeedbackLogs" #remote path where the GPIOInFile will be written to. This path includes backslashes to accomadate the Windows NET USE filePathForSlash="//192.168.29.2/PiShare/VisualFeedbackLogs" #same as above but with forward slashes as to work with python file handlingusername=sys.argv[2] #retrieve SMB share username from the second CLI parameter. password=sys.argv[3] #retrieve SMB share password from the third CLI parametermountCommand="net use /user:" + username +" \\"+netfilePathBackSlash+" "+passwordos.system(mountCommand)outfilePath=netfilePathForSlash+"//GPIOInFile.txt"try:gpioInFile = open(outfilePath,'w')return gpioInFileexcept OSError as error:print("File Error. Error Code:",error.errno)print(error)sys.exit(1)except:print("Unknown Error")raisesys.exit(1)else:print("There was a problem with your CLI arguments",sys.argv)#print(sys.argv)print("First parameter is infile switch which must be -r or -g. Second Parameter must be username, and third is password. Consult user manual ")sys.exit(1)def databaseScanner():serialNumSwitch=sys.argv[1]odbcConnectionFile = open('C:\DSN\ODBC.dsn','r')odbcConnectionString = odbcConnectionFile.readline()#DB_CONNECTION=pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};UID=admin;UserCommitSync=Yes;Threads=3;SafeTransactions=0;PageTimeout=5;MaxScanRows=8;MaxBufferSize=2048;FIL=MS Access;DriverId=25;DefaultDir=C:\Users\716203\Documents\school\sem4\proj354\testDB;DBQ=C:\Users\716203\Documents\school\sem4\proj354\testDB\GatewayCleanAndScreenDB.accdb') #Hardcoded connection string to connect to databaseDB_CONNECTION=pyodbc.connect(odbcConnectionString) #Connection string to connect to Database. This was generated by the ODBC drivercursor = DB_CONNECTION.cursor()#serialNum=repr(sys.argv[4])gpioInFile = fileHandling(serialNumSwitch)if serialNumSwitch in ["-r","-R"]:i=0sqlQuery= "SELECT TestResult.[PING Test], TestResult.[DOCSIS Tuner Test], TestResult.[PWAN Test], TestResult.[docsDevResetNow]FROM TestResult;"#beginning of code sourced from: = cursor.execute(sqlQuery)for row in rows:#end of code sourced from: of working SQL query:#SELECT TestResult.[PING Test], TestResult.[DOCSIS Tuner Test], TestResult.[PWAN Test], TestResult.[docsDevResetNow]FROM TestResult WHERE SN=A1A1A1A1A1A1A1A;rowLen = len(row)while i < rowLen:rowStr=str(row[i])rowStr=rowStr+"\n"i+=1gpioInFile.write(rowStr)cursor.close()DB_CONNECTION.close()elif serialNumSwitch in ["-n","-N"] and len(sys.argv)==5:serialNum=repr(sys.argv[4])sqlQuery = 'SELECT TestResult.[PING Test], TestResult.[DOCSIS Tuner Test], TestResult.[PWAN Test], TestResult.[docsDevResetNow]FROM TestResult WHERE SN='+ serialNum +';'#SELECT TestResult.[PING Test], TestResult.[DOCSIS Tuner Test], TestResult.[PWAN Test], TestResult.[docsDevResetNow]FROM TestResult WHERE SN=DBTBR6AED949309;i=0;cursor.execute(sqlQuery)row = cursor.fetchone()rowLen = len(row)while i < rowLen:rowStr=str(row[i])rowStr=rowStr+"\n"i+=1gpioInFile.write(rowStr)cursor.close()DB_CONNECTION.close()else:print("Error CLI parameter 0 must be:%s",serialNumSwitch)print("There must be a total of 6 CLI parameters.",sys.argv)cursor.close()DB_CONNECTION.close()sys.exit(1)def main():databaseScanner()main()clearPin5and6.pyimport gpiozeroledPin5 = gpiozero.LED(5,True,False)ledPin6 = gpiozero.LED(6,True,False)ledPin5.close()ledPin6.close()LEDControl.py'''1st Test: GPIO 5,6,132nd Test: GPIO 17,27,223rd Test: GPIO 23,24,254th Test: GPIO 12,16,26The order of the LEDs are RBG respectively'''import gpiozeroimport timeimport subprocessimport sysimport osdef main():outfilePath = "/home/pi/share/VisualFeedbackLogs/GPIOOutFile.txt"encOutfilePath = "/home/pi/share/VisualFeedbackLogs/GPIOOutFile.txt.gpg"tmpPath = "/tmp/LEDFeedback.txt"infile = open("/home/pi/share/VisualFeedbackLogs/GPIOInFile.txt", 'r')tmp= open(tmpPath,'a+')encSwitch = sys.argv[1]if encSwitch in ["-e","-E"]:if os.path.exists(encOutfilePath):print("DECRYPTION") encFileText = subprocess.check_output(["gpg","-d",encOutfilePath],universal_newlines=True) #decrypts the encrypted file using gpg and stores the output in encFileTexttmp.write(encFileText) #write the decrypted text to tmpfileledControl(tmp, infile)tmp.close()infile.close()os.remove(encOutfilePath) #delete the old encrypted fileos.rename("/tmp/LEDFeedback.txt","/home/pi/share/VisualFeedbackLogs/GPIOOutFile.txt") #rename and move temp file to the old outfile's pathprint("ENCRYPTION")encString = "gpg -c --force-mdc " + outfilePath #encrypt the tempfile we moved hereos.system(encString)os.remove(outfilePath) #delete the plaintext temp fileelse:outfile = open("/home/pi/share/VisualFeedbackLogs/GPIOOutFile.txt", 'a')ledControl(outfile, infile)infile.close()outfile.close()print("ENCRYPTION")encString = "gpg -c --force-mdc " + outfilePathos.system(encString)os.remove(outfilePath) #delete the plaintext temp fileelif encSwitch in ["-d","-D"]:decString= "gpg -o " + outfilePath+ " "+ outfilePath + ".gpg"os.system(decString)elif encSwitch in ["-n","-N"]:outfile = open("/home/pi/share/VisualFeedbackLogs/GPIOOutFile.txt", 'a')ledControl(outfile, infile)infile.close()outfile.close()else:print("Error. Must be run with CLI parameter -e or -d")delString = "rm " + outfilePathos.system(delString)def tabCheck(testNames, i):if len(testNames[i]) > 15: #If a string has more than 15 characters then the tab after it will be misalignedtab ="\t"else:tab="\t\t"return tabdef ledControl(outfile, infile):outfile.write("-------------------------")currentTime=str(time.ctime()) #retrieves current date in human readable formatoutfile.write(currentTime)outfile.write("-------------------------\n")testNames=['PING Test','DOCSIS Tuner Test','PWAN Test','docsDevResetNow']i=0ledTime=1gpioPins=[[5,13], [17,22], [23,25], [12,26]] #GPIO Pins as listed abovefor line in infile:if "PASS" in line:pinNum=gpioPins[i][1] #row i and column 1. Column 1 are the GPIO Pins controlling Green LEDled=gpiozero.LED(pinNum,True,False) #this powers the green light on the multicolour LEDled.on()tab=tabCheck(testNames, i)testAndResult=testNames[i]+tab+lineoutfile.write(testAndResult)#print(testAndResult) # This line is for debug purposestime.sleep(ledTime)led.off()else:pinNum=gpioPins[i][0]led=gpiozero.LED(pinNum,True,False) #this powers the red light on the multicolour LEDled.on()tab=tabCheck(testNames, i)testAndResult=testNames[i]+tab+lineoutfile.write(testAndResult)##print(testAndResult) # This line is for debug purposestime.sleep(ledTime)led.off()led.close()i+=1if i >= 4:i=0return outfilemain()B.User And Administrative ManualHardware Administrative GuideMaterialsRaspberry PiBreadboardTri-colour LEDs/Green & Red LEDsNetwork CableWiring KitRaspberry Pi GPIO CableDatabaseMonitorKeyboardMouseComputer SystemHardware SchematicsFigure 1: Shows the process of where the information travels through the hardware.Figure 2: Shows the Tri-colour LEDs in relation to the coloursFigure 3: Shows the Tri-colour LEDs from a different angle to show the 4 prongs on each LEDProcedureGather all required materials.Plug in network cables and power cables to both Raspberry Pi and Computer System.Determine which pins will be used for the Tri-colour LEDs.Hook up ground wire to the negative flow on breadboard (Figure 2).Ensure there are enough pins to support the amount of tests you will perform. For this project, we ran four different tests to test our database, which means 8 pins would be used for red and green. Blue may be used as well if there was a third option for these tests.Connect LEDs and wires to board as shown in figure 3.Plug in peripherals for both the Raspberry Pi and the computer system (mouse, keyboard, monitor).Connect GPIO cable to the breadboard as a connection between the Pi and the wires.Power on system and move onto the software portion of running the project.Hardware User GuideEach LED lights up corresponding to the test shown on the screen. As it iterates through the script, the screen should say what each test is as the LEDs light up. Green shows that the test is a pass, and red shows that the test is a fail. The first test LED shows the results of the PING test. The second LED shows the result of the DOCSIS Tuner test. The third LED shows the result of the PWAN test. The fourth LED shows the result of the docsDevResetNow test.Software Administrative Guide:NOTE: All python scripts are written in python 3.LEDControl.pyDescription: This script controls the LEDs and is the actual code that allows them to light up the appropriate colour in response to the results of the gateway tests.The first function this script steps into is the main() function. In this function, the program determines where to find the infile that was generated by the pyDBAllorOne.py script, along with where to store the encrypted results outfile.If the program receives either an “e” or “E” from the CLI, it will encrypt the results of the gateway tests. This is done using gpg and stores the results in a temporary, decrypted file. The old encrypted text is then deleted so the user is able to view the results. After the user finishes, the file is then encrypted again and moved back to its original location.If the program is run with the CLI parameter “d” or “D”, it will decrypt the resulting text file with gpg. If neither the “E” or “D” parameters are used, the program will return an error.In order to print the results to the user in a neat and ordered way, the tabCheck function is run. This function tests if a string contains more than 15 characters. If it does, it will only be tabbed twice, so as to remain in line with the strings that had to be tabbed twice.The actual ledControl function writes to an outfile what the user is able to see on screen. It prints out the names of the tests that were run and uses the results of the generated infile to determine whether a certain LED should turn green or red.The outfile is then closed and the program finishes.pyDBAllorOne.pyDescription: This script provides one method of connecting to the access database and processing the information. If -n is specified via CLI then it prints the results for the specified Gateway to the GPIO infile by using the device’s serial number from the CLI. In order to connect, the program needs to be run with the parameters: username, password, serial number. This script uses the “pyodbc” module that allows access to the Microsoft Access database. The other modules, “os” and “sys” are used to to interact with the operating system for file management, and retrieve command line parameters, respectively. If -r is specified vs CLI then it prints the results for all gateways to the GPIO infile.The program first enters the main function. The main functions then directs to the databaseScanner function. The purpose of the databaseScanner function is to open the connection to the access database and take the user-entered parameters and place them into an SQL query.Just before the script inserts the options into the SQL query, it opens the fileHandling function. This function helps the program distinguish between forward slashes and backslashes to differentiate Windows and Unix file paths. It then takes the command line parameters the user entered for username and password and adds them to a variable. Using these values, the data is then written to an outfile, using the correct facing slashes for the script that will be using them.The program then finishes writing the SQL query by opening the database, using the “cursor” function to allow for the program to send queries to the database. The program then executes the query and iterates through until there are no more variables to add to the infile that will be used to control the LEDs.The connection to the database is then closed and the program finishes.ODBC Driver Configuration[1]Open C:\Windows\SysWOW64\odbcad32.exe.Select File DSN Tab.Click “Add”Select Microsoft Access Driver (*.mdb,*.accdb)Specify that the file will be saved to C:\DSN\ODBC.dsnClick Finish.Select the Database that will be used.Navigate to the directory containing the DSN file that was just generated.Open the DSN File in notepad.Delete the line containing [ODBC]Add a semicolon at end of every line, except the last one.Put an opening curly brace ({) right after ‘DRIVER=’ and a closing curly brace (}) right before the semicolon.Make it so that all text is on one line.Example:Software User GuidepyDBAllorOne.pyDescription: Prints results of all gateway’s or just one gateway specified by Serial Number via CLI parameter.Usage: python pyDBAllOrOne.py <SerialNumberSwitch> <username> <password> <SN>Python - Python 3 InterpreterpyDBAllOrOne.py - Script being runSerialNumberSwitch - Switch to determine if the results of all gateways will printed to the GPIOInFile or just one specified gateway.If -r is specified, then the test results of all gateways is sent to GPIOInfileIf -n is specified, alongside the serial number, the the results of the specified gateway are sent to GPIOInfileUsername - SMB Share UsernamePassword - SMB Share Password SN - serial numberExample - python pyDBAllOrOne.py -r admin 12345ORpython pyDBAllOrOne.py -n admin 12345 A1A1A1A1A1A1A1ALEDControl.pyDescription: This python script is the piece of code that actually controls how the LEDs react to various inputs.Process: The script takes an infile, generated through the access database, and parses it for the terms “pass” and “fail”. If the term “pass” is found, the GPIO will output a current to pin 13. On the multicolour LEDs we have in place, this will turn on the green light. If the program finds the term “fail”, it will provide a current to pin 5, turning on the red light.Usage: python LEDControl.py <EncryptionParameter>Python - Python 3 InterpreterLEDControl.py - Script being run<EncryptionParameter> - Switch to determine if outfile will be encryptedIf -e is specified, the outfile will be encrypted. You will be prompted for a password to decrypt the outfile, and then later re-encrypt it. If -d is specified, nothing will happen to the LEDs, but you will be prompted for a password to decrypt the outfile. Successfully inputting the password will result in the outfile being present as plaintext in /home/pi/share/VisualFeedbackLogs.If -n is specified, the LEDs will be controlled as usual, and a new plaintext outfile will be generated. No encryption is used with this optionNote: when prompted for a password, the characters you type will not appear on screen. This is for security reasons.Example - python3 LEDControl.py -eORpython3 LEDControl.py -dpython3 LEDControl.py -nC.GlossaryGatewayHDPVR Consumer TV device from Shaw [2] ODBCOpen DataBase Connectivity. It is an API to allow for data transmission between programs and various databases. [3]D.Actual BudgetHardwareItemDescriptionNumber of ItemsCostRaspberry Pi 2 Model BSmall device capable of running linux. This kit includes an HDMI cable and 8 GB SD card to load an OS onto.1$120.00Tri-colour LED LightsGateway identifiers4$3.00WiringThe power input connections120$11.00KeyboardAllows user input to device1$25.00MonitorAllows the screen to display1$50.00MousePeripheral device to navigate the GUI1$15.00Laptop Tecra Z50-ALaptop with i7 processor and 16 GB of ram. Includes Windows 7 and hosts Microsoft Access Database.1$1600.00[4]Microsoft AccessDatabase Management system from Microsoft. Gateway test results are stored in a database managed through Access.1$119.00[5]Total Equipment Costs:$1943.00SoftwareItemDescriptionNumber of ItemsCostMicrosoft AccessDatabase Management system from Microsoft. Gateway test results are stored in a database managed through Access.1$119.00[5]LabourItemHoursRateCostAlex Rollick66$40.00$2640.00Matthew Baskharion75$40.00$2880.00Colby Brunner64$40.00$2560.00Total Operating Costs:$8080.00 ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download