| Line 2... |
Line 2... |
| 2 |
#
|
2 |
#
|
| 3 |
#
|
3 |
#
|
| 4 |
# Copyright 2010 TheSeven, benedikt93, Farthen
|
4 |
# Copyright 2010 TheSeven, benedikt93, Farthen
|
| 5 |
#
|
5 |
#
|
| 6 |
#
|
6 |
#
|
| 7 |
# This file is part of emBIOS.
|
7 |
# This file is part of emCORE.
|
| 8 |
#
|
8 |
#
|
| 9 |
# emBIOS is free software: you can redistribute it and/or
|
9 |
# emCORE is free software: you can redistribute it and/or
|
| 10 |
# modify it under the terms of the GNU General Public License as
|
10 |
# modify it under the terms of the GNU General Public License as
|
| 11 |
# published by the Free Software Foundation, either version 2 of the
|
11 |
# published by the Free Software Foundation, either version 2 of the
|
| 12 |
# License, or (at your option) any later version.
|
12 |
# License, or (at your option) any later version.
|
| 13 |
#
|
13 |
#
|
| 14 |
# emBIOS is distributed in the hope that it will be useful,
|
14 |
# emCORE is distributed in the hope that it will be useful,
|
| 15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
16 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 |
# See the GNU General Public License for more details.
|
17 |
# See the GNU General Public License for more details.
|
| 18 |
#
|
18 |
#
|
| 19 |
# You should have received a copy of the GNU General Public License
|
19 |
# You should have received a copy of the GNU General Public License
|
| 20 |
# along with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
20 |
# along with emCORE. If not, see <http://www.gnu.org/licenses/>.
|
| 21 |
#
|
21 |
#
|
| 22 |
#
|
22 |
#
|
| 23 |
|
23 |
|
| 24 |
"""
|
24 |
"""
|
| 25 |
emBIOS client library.
|
25 |
emCORE client library.
|
| 26 |
Provides functions to communicate with emBIOS devices via the USB bus.
|
26 |
Provides functions to communicate with emCORE devices via the USB bus.
|
| 27 |
"""
|
27 |
"""
|
| 28 |
|
28 |
|
| 29 |
import sys
|
29 |
import sys
|
| 30 |
import struct
|
30 |
import struct
|
| 31 |
import usb.core
|
31 |
import usb.core
|
| 32 |
import libembiosdata
|
32 |
import libemcoredata
|
| 33 |
|
33 |
|
| 34 |
from misc import Logger, Bunch, Error, gethwname
|
34 |
from misc import Logger, Bunch, Error, gethwname
|
| 35 |
from functools import wraps
|
35 |
from functools import wraps
|
| 36 |
|
36 |
|
| 37 |
class ArgumentError(Error):
|
37 |
class ArgumentError(Error):
|
| Line 85... |
Line 85... |
| 85 |
wrapper.func = func
|
85 |
wrapper.func = func
|
| 86 |
return wrapper
|
86 |
return wrapper
|
| 87 |
return decorator
|
87 |
return decorator
|
| 88 |
|
88 |
|
| 89 |
|
89 |
|
| 90 |
class Embios(object):
|
90 |
class Emcore(object):
|
| 91 |
"""
|
91 |
"""
|
| 92 |
Class for all embios functions.
|
92 |
Class for all emcore functions.
|
| 93 |
They all get the "@command()" decorator.
|
93 |
They all get the "@command()" decorator.
|
| 94 |
This decorator has a timeout variable that can be set to change the
|
94 |
This decorator has a timeout variable that can be set to change the
|
| 95 |
device timeout for the duration of the function.
|
95 |
device timeout for the duration of the function.
|
| 96 |
It also adds a "timeout" argument to every function to access this
|
96 |
It also adds a "timeout" argument to every function to access this
|
| 97 |
feature from external. So DON'T EVER use a parameter called 'timeout'
|
97 |
feature from external. So DON'T EVER use a parameter called 'timeout'
|
| 98 |
in your commands. Variables are ok.
|
98 |
in your commands. Variables are ok.
|
| 99 |
"""
|
99 |
"""
|
| 100 |
def __init__(self, loglevel = 2, logtarget = "stdout", logfile = "tools.log"):
|
100 |
def __init__(self, loglevel = 2, logtarget = "stdout", logfile = "tools.log"):
|
| 101 |
self.logger = Logger(loglevel, logtarget, logfile)
|
101 |
self.logger = Logger(loglevel, logtarget, logfile)
|
| 102 |
self.logger.debug("Initializing Embios object\n")
|
102 |
self.logger.debug("Initializing Emcore object\n")
|
| 103 |
self.lib = Lib(self.logger)
|
103 |
self.lib = Lib(self.logger)
|
| 104 |
|
104 |
|
| 105 |
self.getversioninfo()
|
105 |
self.getversioninfo()
|
| 106 |
self.getpacketsizeinfo()
|
106 |
self.getpacketsizeinfo()
|
| 107 |
self.getusermemrange()
|
107 |
self.getusermemrange()
|
| Line 151... |
Line 151... |
| 151 |
self.lib.monitorcommand(struct.pack("IIII", 7, addr, len(data), 0), "III", (None, None, None))
|
151 |
self.lib.monitorcommand(struct.pack("IIII", 7, addr, len(data), 0), "III", (None, None, None))
|
| 152 |
return self.lib.dev.dout(data)
|
152 |
return self.lib.dev.dout(data)
|
| 153 |
|
153 |
|
| 154 |
@command()
|
154 |
@command()
|
| 155 |
def getversioninfo(self):
|
155 |
def getversioninfo(self):
|
| 156 |
""" This returns the emBIOS version and device information. """
|
156 |
""" This returns the emCORE version and device information. """
|
| 157 |
resp = self.lib.monitorcommand(struct.pack("IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
|
157 |
resp = self.lib.monitorcommand(struct.pack("IIII", 1, 0, 0, 0), "IBBBBI", ("revision", "majorv", "minorv", "patchv", "swtypeid", "hwtypeid"))
|
| 158 |
self.lib.dev.version.revision = resp.revision
|
158 |
self.lib.dev.version.revision = resp.revision
|
| 159 |
self.lib.dev.version.majorv = resp.majorv
|
159 |
self.lib.dev.version.majorv = resp.majorv
|
| 160 |
self.lib.dev.version.minorv = resp.minorv
|
160 |
self.lib.dev.version.minorv = resp.minorv
|
| 161 |
self.lib.dev.version.patchv = resp.patchv
|
161 |
self.lib.dev.version.patchv = resp.patchv
|
| Line 165... |
Line 165... |
| 165 |
self.lib.dev.hwtypeid = resp.hwtypeid
|
165 |
self.lib.dev.hwtypeid = resp.hwtypeid
|
| 166 |
return resp
|
166 |
return resp
|
| 167 |
|
167 |
|
| 168 |
@command()
|
168 |
@command()
|
| 169 |
def getpacketsizeinfo(self):
|
169 |
def getpacketsizeinfo(self):
|
| 170 |
""" This returns the emBIOS max packet size information.
|
170 |
""" This returns the emCORE max packet size information.
|
| 171 |
It also sets the properties of the device object accordingly.
|
171 |
It also sets the properties of the device object accordingly.
|
| 172 |
"""
|
172 |
"""
|
| 173 |
resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
|
173 |
resp = self.lib.monitorcommand(struct.pack("IIII", 1, 1, 0, 0), "HHII", ("coutmax", "cinmax", "doutmax", "dinmax"))
|
| 174 |
self.logger.debug("Device cout packet size limit = " + str(resp.coutmax) + "\n")
|
174 |
self.logger.debug("Device cout packet size limit = " + str(resp.coutmax) + "\n")
|
| 175 |
self.lib.dev.packetsizelimit.cout = resp.coutmax
|
175 |
self.lib.dev.packetsizelimit.cout = resp.coutmax
|
| Line 379... |
Line 379... |
| 379 |
offset = threadstructsize * thread
|
379 |
offset = threadstructsize * thread
|
| 380 |
threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
|
380 |
threaddata = struct.unpack("<16IIIIIQIIIIIIIBBBB", data[offset:offset+threadstructsize])
|
| 381 |
info = Bunch()
|
381 |
info = Bunch()
|
| 382 |
info.id = id
|
382 |
info.id = id
|
| 383 |
state = threaddata[17]
|
383 |
state = threaddata[17]
|
| 384 |
info.state = libembiosdata.thread_state[state]
|
384 |
info.state = libemcoredata.thread_state[state]
|
| 385 |
if info.state == "THREAD_FREE":
|
385 |
if info.state == "THREAD_FREE":
|
| 386 |
id += 1
|
386 |
id += 1
|
| 387 |
continue
|
387 |
continue
|
| 388 |
info.regs = Bunch()
|
388 |
info.regs = Bunch()
|
| 389 |
for register in range(16):
|
389 |
for register in range(16):
|
| Line 401... |
Line 401... |
| 401 |
info.timeout = threaddata[23]
|
401 |
info.timeout = threaddata[23]
|
| 402 |
info.blocked_since = threaddata[24]
|
402 |
info.blocked_since = threaddata[24]
|
| 403 |
info.blocked_by_ptr = threaddata[25]
|
403 |
info.blocked_by_ptr = threaddata[25]
|
| 404 |
info.stackaddr = threaddata[26]
|
404 |
info.stackaddr = threaddata[26]
|
| 405 |
info.err_no = threaddata[27]
|
405 |
info.err_no = threaddata[27]
|
| 406 |
info.block_type = libembiosdata.thread_block[threaddata[28]]
|
406 |
info.block_type = libemcoredata.thread_block[threaddata[28]]
|
| 407 |
info.type = libembiosdata.thread_type[threaddata[29]]
|
407 |
info.type = libemcoredata.thread_type[threaddata[29]]
|
| 408 |
info.priority = threaddata[30]
|
408 |
info.priority = threaddata[30]
|
| 409 |
info.cpuload = threaddata[31]
|
409 |
info.cpuload = threaddata[31]
|
| 410 |
threads.append(info)
|
410 |
threads.append(info)
|
| 411 |
id += 1
|
411 |
id += 1
|
| 412 |
return threads
|
412 |
return threads
|
| Line 465... |
Line 465... |
| 465 |
""" Flushes the CPU instruction and data cache """
|
465 |
""" Flushes the CPU instruction and data cache """
|
| 466 |
return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
|
466 |
return self.lib.monitorcommand(struct.pack("IIII", 20, 0, 0, 0), "III", (None, None, None))
|
| 467 |
|
467 |
|
| 468 |
@command()
|
468 |
@command()
|
| 469 |
def execimage(self, addr):
|
469 |
def execimage(self, addr):
|
| 470 |
""" Runs the emBIOS app at 'addr' """
|
470 |
""" Runs the emCORE app at 'addr' """
|
| 471 |
return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("rc", None, None))
|
471 |
return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("rc", None, None))
|
| 472 |
|
472 |
|
| 473 |
@command()
|
473 |
@command()
|
| 474 |
def run(self, app):
|
474 |
def run(self, app):
|
| 475 |
""" Uploads and runs the emBIOS app in the string 'app' """
|
475 |
""" Uploads and runs the emCORE app in the string 'app' """
|
| 476 |
try:
|
476 |
try:
|
| 477 |
appheader = struct.unpack("<8sIIIIIIIIII", app[:48])
|
477 |
appheader = struct.unpack("<8sIIIIIIIIII", app[:48])
|
| 478 |
except struct.error:
|
478 |
except struct.error:
|
| 479 |
raise ArgumentError("The specified app is not an emBIOS application")
|
479 |
raise ArgumentError("The specified app is not an emCORE application")
|
| 480 |
header = appheader[0]
|
480 |
header = appheader[0]
|
| 481 |
if header != "emBIexec":
|
481 |
if header != "emBIexec":
|
| 482 |
raise ArgumentError("The specified app is not an emBIOS application")
|
482 |
raise ArgumentError("The specified app is not an emCORE application")
|
| 483 |
baseaddr = appheader[2]
|
483 |
baseaddr = appheader[2]
|
| 484 |
threadnameptr = appheader[8]
|
484 |
threadnameptr = appheader[8]
|
| 485 |
nameptr = threadnameptr - baseaddr
|
485 |
nameptr = threadnameptr - baseaddr
|
| 486 |
name = ""
|
486 |
name = ""
|
| 487 |
while True:
|
487 |
while True:
|
| 488 |
char = app[nameptr:nameptr+1]
|
488 |
char = app[nameptr:nameptr+1]
|
| 489 |
try:
|
489 |
try:
|
| 490 |
if ord(char) == 0:
|
490 |
if ord(char) == 0:
|
| 491 |
break
|
491 |
break
|
| 492 |
except TypeError:
|
492 |
except TypeError:
|
| 493 |
raise ArgumentError("The specified app is not an emBIOS application")
|
493 |
raise ArgumentError("The specified app is not an emCORE application")
|
| 494 |
name += char
|
494 |
name += char
|
| 495 |
nameptr += 1
|
495 |
nameptr += 1
|
| 496 |
usermem = self.getusermemrange()
|
496 |
usermem = self.getusermemrange()
|
| 497 |
if usermem.lower > baseaddr or usermem.upper < baseaddr + len(app):
|
497 |
if usermem.lower > baseaddr or usermem.upper < baseaddr + len(app):
|
| 498 |
raise ArgumentError("The baseaddress of the specified emBIOS application is out of range of the user memory range on the device. Are you sure that this application is compatible with your device?")
|
498 |
raise ArgumentError("The baseaddress of the specified emCORE application is out of range of the user memory range on the device. Are you sure that this application is compatible with your device?")
|
| 499 |
self.write(baseaddr, app)
|
499 |
self.write(baseaddr, app)
|
| 500 |
self.execimage(baseaddr)
|
500 |
self.execimage(baseaddr)
|
| 501 |
return Bunch(baseaddr=baseaddr, name=name)
|
501 |
return Bunch(baseaddr=baseaddr, name=name)
|
| 502 |
|
502 |
|
| 503 |
@command(timeout = 5000)
|
503 |
@command(timeout = 5000)
|
| Line 588... |
Line 588... |
| 588 |
Write hard drive bad block table
|
588 |
Write hard drive bad block table
|
| 589 |
"""
|
589 |
"""
|
| 590 |
try:
|
590 |
try:
|
| 591 |
bbtheader = struct.unpack("<8s2024sQII512I", bbt[:4096])
|
591 |
bbtheader = struct.unpack("<8s2024sQII512I", bbt[:4096])
|
| 592 |
except struct.error:
|
592 |
except struct.error:
|
| 593 |
raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
593 |
raise ArgumentError("The specified file is not an emCORE hard disk BBT")
|
| 594 |
if bbtheader[0] != "emBIbbth":
|
594 |
if bbtheader[0] != "emBIbbth":
|
| 595 |
raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
595 |
raise ArgumentError("The specified file is not an emCORE hard disk BBT")
|
| 596 |
virtualsectors = bbtheader[2]
|
596 |
virtualsectors = bbtheader[2]
|
| 597 |
bbtsectors = bbtheader[3]
|
597 |
bbtsectors = bbtheader[3]
|
| 598 |
self.write(tempaddr, bbt)
|
598 |
self.write(tempaddr, bbt)
|
| 599 |
sector = 0
|
599 |
sector = 0
|
| 600 |
count = 1
|
600 |
count = 1
|
| Line 836... |
Line 836... |
| 836 |
if rcvdatatypes:
|
836 |
if rcvdatatypes:
|
| 837 |
rcvdatatypes = "I" + rcvdatatypes # add the response
|
837 |
rcvdatatypes = "I" + rcvdatatypes # add the response
|
| 838 |
data = self.dev.cin(struct.calcsize(rcvdatatypes))
|
838 |
data = self.dev.cin(struct.calcsize(rcvdatatypes))
|
| 839 |
data = struct.unpack(rcvdatatypes, data)
|
839 |
data = struct.unpack(rcvdatatypes, data)
|
| 840 |
response = data[0]
|
840 |
response = data[0]
|
| 841 |
if libembiosdata.responsecodes[response] == "ok":
|
841 |
if libemcoredata.responsecodes[response] == "ok":
|
| 842 |
self.logger.debug("Response: OK\n")
|
842 |
self.logger.debug("Response: OK\n")
|
| 843 |
if rcvstruct:
|
843 |
if rcvstruct:
|
| 844 |
datadict = Bunch()
|
844 |
datadict = Bunch()
|
| 845 |
counter = 1 # start with 1, 0 is the id
|
845 |
counter = 1 # start with 1, 0 is the id
|
| 846 |
for item in rcvstruct:
|
846 |
for item in rcvstruct:
|
| Line 848... |
Line 848... |
| 848 |
datadict[item] = data[counter]
|
848 |
datadict[item] = data[counter]
|
| 849 |
counter += 1
|
849 |
counter += 1
|
| 850 |
return datadict
|
850 |
return datadict
|
| 851 |
else:
|
851 |
else:
|
| 852 |
return data
|
852 |
return data
|
| 853 |
elif libembiosdata.responsecodes[response] == "unsupported":
|
853 |
elif libemcoredata.responsecodes[response] == "unsupported":
|
| 854 |
self.logger.debug("Response: UNSUPPORTED\n")
|
854 |
self.logger.debug("Response: UNSUPPORTED\n")
|
| 855 |
raise DeviceError("The device does not support this command.")
|
855 |
raise DeviceError("The device does not support this command.")
|
| 856 |
elif libembiosdata.responsecodes[response] == "invalid":
|
856 |
elif libemcoredata.responsecodes[response] == "invalid":
|
| 857 |
self.logger.debug("Response: INVALID\n")
|
857 |
self.logger.debug("Response: INVALID\n")
|
| 858 |
raise DeviceError("Invalid command! This should NOT happen!")
|
858 |
raise DeviceError("Invalid command! This should NOT happen!")
|
| 859 |
elif libembiosdata.responsecodes[response] == "busy":
|
859 |
elif libemcoredata.responsecodes[response] == "busy":
|
| 860 |
self.logger.debug("Response: BUSY\n")
|
860 |
self.logger.debug("Response: BUSY\n")
|
| 861 |
raise DeviceError("Device busy")
|
861 |
raise DeviceError("Device busy")
|
| 862 |
else:
|
862 |
else:
|
| 863 |
self.logger.debug("Response: UNKOWN\n")
|
863 |
self.logger.debug("Response: UNKOWN\n")
|
| 864 |
raise DeviceError("Invalid response! This should NOT happen!")
|
864 |
raise DeviceError("Invalid response! This should NOT happen!")
|
| Line 926... |
Line 926... |
| 926 |
epcounter += 1
|
926 |
epcounter += 1
|
| 927 |
if epcounter <= 3:
|
927 |
if epcounter <= 3:
|
| 928 |
raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
|
928 |
raise DeviceError("Not all endpoints found in the descriptor. Only "+str(epcounter)+" found, we need 4")
|
| 929 |
|
929 |
|
| 930 |
def connect(self):
|
930 |
def connect(self):
|
| 931 |
self.logger.debug("Looking for emBIOS device\n")
|
931 |
self.logger.debug("Looking for emCORE device\n")
|
| 932 |
self.dev = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
|
932 |
self.dev = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
|
| 933 |
if self.dev is None:
|
933 |
if self.dev is None:
|
| 934 |
raise DeviceNotFoundError()
|
934 |
raise DeviceNotFoundError()
|
| 935 |
self.logger.debug("Device Found!\n")
|
935 |
self.logger.debug("Device Found!\n")
|
| 936 |
self.logger.debug("Setting first configuration\n")
|
936 |
self.logger.debug("Setting first configuration\n")
|
| Line 980... |
Line 980... |
| 980 |
from misc import Logger
|
980 |
from misc import Logger
|
| 981 |
logger = Logger()
|
981 |
logger = Logger()
|
| 982 |
if sys.argv[1] == "test":
|
982 |
if sys.argv[1] == "test":
|
| 983 |
# Some tests
|
983 |
# Some tests
|
| 984 |
import sys
|
984 |
import sys
|
| 985 |
embios = Embios()
|
985 |
emcore = Emcore()
|
| 986 |
resp = embios.getversioninfo()
|
986 |
resp = emcore.getversioninfo()
|
| 987 |
logger.log("Embios device version information: " + libembiosdata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) +
|
987 |
logger.log("Emcore device version information: " + libemcoredata.swtypes[resp.swtypeid] + " v" + str(resp.majorv) + "." + str(resp.minorv) +
|
| 988 |
"." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libembiosdata.hwtypes[resp.hwtypeid] + "\n")
|
988 |
"." + str(resp.patchv) + " r" + str(resp.revision) + " running on " + libemcoredata.hwtypes[resp.hwtypeid] + "\n")
|
| 989 |
resp = embios.getusermemrange()
|
989 |
resp = emcore.getusermemrange()
|
| 990 |
logger.log("Usermemrange: "+hex(resp.lower)+" - "+hex(resp.upper)+"\n")
|
990 |
logger.log("Usermemrange: "+hex(resp.lower)+" - "+hex(resp.upper)+"\n")
|
| 991 |
memaddr = resp.lower
|
991 |
memaddr = resp.lower
|
| 992 |
maxlen = resp.upper - resp.lower
|
992 |
maxlen = resp.upper - resp.lower
|
| 993 |
f = open("./embios.py", "rb")
|
993 |
f = open("./emcore.py", "rb")
|
| 994 |
logger.log("Loading test file (embios.py) to send over USB...\n")
|
994 |
logger.log("Loading test file (emcore.py) to send over USB...\n")
|
| 995 |
datastr = f.read()[:maxlen]
|
995 |
datastr = f.read()[:maxlen]
|
| 996 |
logger.log("Sending data...\n")
|
996 |
logger.log("Sending data...\n")
|
| 997 |
embios.write(memaddr, datastr)
|
997 |
emcore.write(memaddr, datastr)
|
| 998 |
logger.log("Encrypting data with the hardware key...\n")
|
998 |
logger.log("Encrypting data with the hardware key...\n")
|
| 999 |
embios.aesencrypt(memaddr, len(datastr), 0)
|
999 |
emcore.aesencrypt(memaddr, len(datastr), 0)
|
| 1000 |
logger.log("Reading data back and saving it to 'libembios-test-encrypted.bin'...\n")
|
1000 |
logger.log("Reading data back and saving it to 'libemcore-test-encrypted.bin'...\n")
|
| 1001 |
f = open("./libembios-test-encrypted.bin", "wb")
|
1001 |
f = open("./libemcore-test-encrypted.bin", "wb")
|
| 1002 |
f.write(embios.read(memaddr, len(datastr)))
|
1002 |
f.write(emcore.read(memaddr, len(datastr)))
|
| 1003 |
logger.log("Decrypting the data again...\n")
|
1003 |
logger.log("Decrypting the data again...\n")
|
| 1004 |
embios.aesdecrypt(memaddr, len(datastr), 0)
|
1004 |
emcore.aesdecrypt(memaddr, len(datastr), 0)
|
| 1005 |
logger.log("Reading data back from device...\n")
|
1005 |
logger.log("Reading data back from device...\n")
|
| 1006 |
readdata = embios.read(memaddr, len(datastr))
|
1006 |
readdata = emcore.read(memaddr, len(datastr))
|
| 1007 |
if readdata == datastr:
|
1007 |
if readdata == datastr:
|
| 1008 |
logger.log("Data matches!")
|
1008 |
logger.log("Data matches!")
|
| 1009 |
else:
|
1009 |
else:
|
| 1010 |
logger.log("Data does NOT match. Something went wrong")
|
1010 |
logger.log("Data does NOT match. Something went wrong")
|
| 1011 |
|
1011 |
|
| 1012 |
elif sys.argv[1] == "gendoc":
|
1012 |
elif sys.argv[1] == "gendoc":
|
| 1013 |
# Generates Documentation
|
1013 |
# Generates Documentation
|
| 1014 |
from misc import gendoc
|
1014 |
from misc import gendoc
|
| 1015 |
logger.log("Generating documentation\n")
|
1015 |
logger.log("Generating documentation\n")
|
| 1016 |
cmddict = {}
|
1016 |
cmddict = {}
|
| 1017 |
for attr, value in Embios.__dict__.iteritems():
|
1017 |
for attr, value in Emcore.__dict__.iteritems():
|
| 1018 |
if getattr(value, 'func', False):
|
1018 |
if getattr(value, 'func', False):
|
| 1019 |
if getattr(value.func, '_command', False):
|
1019 |
if getattr(value.func, '_command', False):
|
| 1020 |
cmddict[value.func.__name__] = value
|
1020 |
cmddict[value.func.__name__] = value
|
| 1021 |
logger.log(gendoc(cmddict))
|
1021 |
logger.log(gendoc(cmddict))
|
| 1022 |
|
1022 |
|