├── .gitignore ├── .revision ├── .vimloader ├── CC-Bootloader └── rfcat_bootloader ├── FAQ ├── LICENSE ├── LICENSE.CC-Bootloader ├── README ├── README.immesniff ├── README.msfrelay ├── README.nonroot ├── TODO ├── etc └── udev │ └── rules.d │ └── 20-rfcat.rules ├── firmware ├── CCBootloader │ ├── CCBootloader-rfcat-chronosdongle.hex │ ├── CCBootloader-rfcat-donsdongle.hex │ └── CCBootloader-rfcat-ys1.hex ├── Makefile ├── appCC2531.c ├── appFHSSNIC.c ├── appNIC.c ├── appNetworkTest.c ├── appSniff.c ├── application.c ├── bins │ ├── .placeholder │ ├── RfCatChronos-170802.hex │ ├── RfCatChronosCCBootloader-170802.hex │ ├── RfCatDons-170802.hex │ ├── RfCatDonsCCBootloader-170802.hex │ ├── RfCatYS1-170802.hex │ ├── RfCatYS1CCBootloader-170802.hex │ └── immeSniff-170802.hex ├── bootloader.c ├── bootloader_serial.py ├── buildall.sh ├── cc1111_aes.c ├── cc1111_vcom.c ├── cc1111_vcomdesc.c ├── cc1111rf.c ├── chipcon_dma.c ├── chipcon_usb.c ├── chipcon_usbdebug.c ├── global.c ├── immedisplay.c ├── immefont.c ├── immeio.c ├── immekeys.c ├── include │ ├── FHSS.h │ ├── bits.h │ ├── bootloader.h │ ├── cc1110-ext.h │ ├── cc1111.h │ ├── cc1111_aes.h │ ├── cc1111_vcom.h │ ├── cc1111rf.h │ ├── cc1111usb.h │ ├── cc2530-ext.h │ ├── cc2531.h │ ├── chipcon_dma.h │ ├── chipcon_usb.h │ ├── chipcon_usbdebug.h │ ├── global.h │ ├── imme5x7.h │ ├── immedisplay.h │ ├── immefont.h │ ├── immeio.h │ ├── immekeys.h │ ├── immestring.h │ ├── immeterm.h │ ├── nic.h │ └── types.h ├── new_serial.py └── usbonly.c ├── package.sh ├── revision.sh ├── rfcat ├── rfcat_msfrelay ├── rfcat_server ├── rflib ├── __init__.py ├── bits.py ├── cc1111client.py ├── cc111Xhparser.py ├── ccrecvdump.py ├── ccspecan.py ├── chipcon_nic.py ├── chipcon_usb.py ├── chipcondefs.py ├── intelhex.py ├── rflib_defs.py └── rflib_version.py ├── setup.py └── vstruct ├── __init__.py ├── builder.py ├── defs ├── __init__.py ├── elf.py ├── kdcom.py ├── macho │ ├── __init__.py │ ├── const.py │ ├── fat.py │ └── loader.py ├── pe.py ├── win32.py └── windows │ ├── __init__.py │ ├── win_5_1_i386 │ ├── __init__.py │ ├── ntdll.py │ ├── ntoskrnl.py │ └── win32k.py │ ├── win_6_1_amd64 │ ├── __init__.py │ └── ntdll.py │ └── win_6_1_wow64 │ ├── __init__.py │ └── ntdll.py └── primitives.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | -------------------------------------------------------------------------------- /.revision: -------------------------------------------------------------------------------- 1 | 465 -------------------------------------------------------------------------------- /.vimloader: -------------------------------------------------------------------------------- 1 | :tabnew ./firmware/appFHSSNIC.c 2 | :tabnew ./firmware/cc1111rf.c 3 | :tabnew ./firmware/global.c 4 | :tabnew ./firmware/chipcon_usb.c 5 | :tabnew ./firmware/cc1111_vcom.c 6 | :tabnew ./firmware/cc1111_vcomdesc.c 7 | :tabnew ./firmware/include/global.h 8 | :tabnew ./firmware/include/chipcon_usb.h 9 | :tabnew ./firmware/include/nic.h 10 | :tabnew ./firmware/include/FHSS.h 11 | :tabnew ./firmware/include/cc1111.h 12 | :tabnew ./firmware/include/cc1111rf.h 13 | :tabnew ./firmware/include/cc1110-ext.h 14 | :tabnew ./firmware/include/cc1111_vcom.h 15 | :tabnew ./rfcat 16 | :tabnew ./rfcat_server 17 | :tabnew ./rflib/__init__.py 18 | :tabnew ./rflib/chipcon_nic.py 19 | :tabnew ./rflib/cc1111client.py 20 | :tabnew ./rflib/cc111Xhparser.py 21 | :tabnew ./rflib/chipcondefs.py 22 | :tabnext 23 | :q 24 | -------------------------------------------------------------------------------- /CC-Bootloader/rfcat_bootloader: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import time 5 | import serial 6 | from serial.serialutil import SerialException 7 | 8 | 9 | bootloader_error_codes = { 10 | '0' : "OK", 11 | '1' : "Intel HEX Invalid", 12 | '2' : "Bad Checksum", 13 | '3' : "Bad Address", 14 | '4' : "Bad Record Type", 15 | '5' : "Record Too Long" 16 | } 17 | 18 | def download_code(ihx_file, serial_port): 19 | for line in ihx_file.readlines(): 20 | record_type = int(line[7:9], 16) 21 | if (record_type == 0x00): 22 | print "Writing", line[:-1], 23 | serial_port.write(line) 24 | rc = serial_port.read() 25 | print " RC =", rc, 26 | if rc in bootloader_error_codes: 27 | print "(%s)" % bootloader_error_codes[rc] 28 | else: 29 | print "(Unknown Error)" 30 | if (rc != '0'): 31 | print "Error downloading code!" 32 | return False 33 | else: 34 | print "Skipping non data record: '%s'" % line[:-1] 35 | return True 36 | 37 | def verify_code(ihx_file, serial_port): 38 | can_read_any= None 39 | for line in ihx_file.readlines(): 40 | record_type = int(line[7:9], 16) 41 | if (record_type == 0x00): 42 | length = int(line[1:3], 16) 43 | start_addr = int(line[3:7], 16) 44 | data = line[9:9+(length*2)] 45 | # first time around, check if we can only read 16 byte chunks 46 | if can_read_any == None: 47 | can_read_any = False 48 | do_flash_read(serial_port, start_addr, 1) 49 | for read_data in serial_port: 50 | read_data = read_data.strip() 51 | if not read_data: 52 | continue 53 | if not read_data == ":00000001FF": 54 | can_read_any = True 55 | else: 56 | break 57 | if not can_read_any: 58 | print "*** warning! this version of CC-Bootloader can only read 16 byte blocks!" 59 | print "*** upgrade recommended!" 60 | if can_read_any: 61 | block_length= length 62 | else: 63 | block_length= ((length / 16) + 1) * 16 64 | print "\rVerifying %04d bytes at address: %04X" % (length, start_addr), 65 | do_flash_read(serial_port, start_addr, block_length) 66 | verify_data= '' 67 | for read_data in serial_port: 68 | read_data= read_data.strip() 69 | if (not data or read_data == ":00000001FF"): 70 | break 71 | # strip header and checksum 72 | verify_data += read_data[9:-2] 73 | if (data == verify_data[:length*2]): 74 | print '(OK)', 75 | else: 76 | print 'Failed! Expected:', data, 'Got:', verify_data[:length*2] 77 | exit(1) 78 | sys.stdout.flush() 79 | else: 80 | print "Skipping non data record: '%s'" % line[:-1] 81 | return True 82 | 83 | def run_user_code(serial_port): 84 | # User code is entered on intel HEX EOF record 85 | serial_port.write(":00000001FF\n") 86 | return True 87 | 88 | def reset_bootloader(serial_port): 89 | serial_port.write(":00000022DE\n") 90 | rc = serial_port.read() 91 | print "RC =", rc, 92 | if rc in bootloader_error_codes: 93 | print "(%s)" % bootloader_error_codes[rc] 94 | else: 95 | print "(Unknown Error)" 96 | if (rc != '0'): 97 | print "Error resetting bootloader!" 98 | return False 99 | return True 100 | 101 | def erase_all_user(serial_port): 102 | serial_port.write(":00000023DD\n") 103 | rc = serial_port.read() 104 | print "RC =", rc, 105 | if rc in bootloader_error_codes: 106 | print "(%s)" % bootloader_error_codes[rc] 107 | else: 108 | print "(Unknown Error)" 109 | if (rc != '0'): 110 | print "Error erasing all user flash!" 111 | return False 112 | return True 113 | 114 | def erase_user_page(serial_port, page): 115 | chksum = (0xDB + 0x100 - page) & 0xFF 116 | serial_port.write(":01000024%02X%02X\n" % (page, chksum)) 117 | rc = serial_port.read() 118 | print "RC =", rc, 119 | if rc in bootloader_error_codes: 120 | print "(%s)" % bootloader_error_codes[rc] 121 | else: 122 | print "(Unknown Error)" 123 | if (rc != '0'): 124 | print "Error erasing user flash page!" 125 | return False 126 | return True 127 | 128 | def do_flash_read(serial_port, start_addr, length): 129 | chksum = (0xD9 + 130 | (0x100 - (start_addr & 0xFF)) + 131 | (0x100 - ((start_addr>>8) & 0xFF)) + 132 | (0x100 - (length & 0xFF)) + 133 | (0x100 - ((length>>8) & 0xFF)) 134 | ) & 0xFF 135 | serial_port.write(":02%04X25%04X%02X\n" % (start_addr, length, chksum)) 136 | 137 | 138 | def flash_read(ihx_file, serial_port, start_addr, length): 139 | do_flash_read(serial_port, start_addr, length) 140 | for line in serial_port: 141 | if not line == "\n": 142 | if(ihx_file): 143 | ihx_file.write(line) 144 | else: 145 | print line, 146 | if (line == ":00000001FF\n"): 147 | break 148 | 149 | def print_usage(): 150 | import sys 151 | print """ 152 | CC Bootloader Download Utility 153 | 154 | Usage: %s serial_port command 155 | 156 | Commands: 157 | 158 | download 159 | 160 | Download hex_file to the device. 161 | 162 | run 163 | 164 | Run the user code. 165 | 166 | reset 167 | 168 | The bootloader will not erase pages that have previously been written to 169 | before writing new data to that page. This allows for random access writes 170 | but prevents you from overwriting downloaded code unless the device is 171 | power cycled. This command will reset the bootloader's record of what 172 | pages have been written to, allowing you to overwrite without power 173 | cycling. 174 | 175 | erase_all 176 | 177 | Erases the entire user flash area. 178 | 179 | erage 180 | 181 | Erases page n of the flash memory (organised into 1024 byte pages). The 182 | bootloader occupies the first few pages and the rest are reserved for user 183 | code. Attempting to erase a bootloader page will have no effect. To 184 | determine which page the user code starts on please check the 185 | USER_CODE_BASE setting in main.h. 186 | 187 | read [hex_file] 188 | 189 | Reads len bytes from flash memory starting from start_addr and optionally 190 | write to hex_file. start_addr and len should be specified in hexadecimal 191 | (e.g. 0x1234). 192 | 193 | verify 194 | 195 | Verify hex_file matches device flash memory. 196 | """ % sys.argv[0] 197 | 198 | if __name__ == '__main__': 199 | import sys 200 | if (len(sys.argv) < 3): 201 | print_usage() 202 | sys.exit(1) 203 | 204 | serial_port_name = sys.argv[1] 205 | command = sys.argv[2] 206 | options = sys.argv[3:] 207 | 208 | while True: 209 | try: 210 | serial_port = serial.Serial(serial_port_name, timeout=1) 211 | break 212 | 213 | except SerialException,e: 214 | print "\nSomething is talking to the RfCat dongle (Modem Manager, most likely). Retrying again after 5 seconds. This can take a minute, please be patient." 215 | time.sleep(6) 216 | except KeyboardInterrupt: 217 | print "Caught , exitting..." 218 | exit (-2) 219 | except Exception,e: 220 | sys.excepthook(*sys.exc_info()) 221 | print e 222 | exit (-1) 223 | 224 | try: 225 | if (command == 'download' or command == 'verify'): 226 | if (len(options) < 1): 227 | print_usage() 228 | else: 229 | ihx_filename = options[0] 230 | ihx_file = open(ihx_filename, 'r') 231 | if (command == 'download'): 232 | download_code(ihx_file, serial_port) 233 | else: 234 | verify_code(ihx_file, serial_port) 235 | 236 | elif (command == 'run'): 237 | run_user_code(serial_port) 238 | 239 | elif (command == 'reset'): 240 | reset_bootloader(serial_port) 241 | 242 | elif (command == 'erase_all'): 243 | erase_all_user(serial_port) 244 | 245 | elif (command == 'erase'): 246 | if (len(options) < 1): 247 | print_usage() 248 | else: 249 | erase_user_page(serial_port, int(options[0])) 250 | 251 | elif (command == 'read'): 252 | if (len(options) < 2): 253 | print_usage() 254 | else: 255 | ihx_file = None 256 | if(len(options) == 3): 257 | try: 258 | ihx_filename = options[2] 259 | ihx_file = open(ihx_filename, 'w') 260 | print 'reading to:', ihx_filename 261 | except: 262 | print "couldn't open output file:", ihx_filename 263 | exit(2) 264 | flash_read(ihx_file, serial_port, int(options[0], 16), int(options[1], 16)) 265 | 266 | else: 267 | print_usage() 268 | finally: 269 | serial_port.close() 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /FAQ: -------------------------------------------------------------------------------- 1 | ok, simple stuff: 2 | 3 | Q: why do i get this when i start rfcat: Error in resetup():USBError(110, 'Operation timed out') 4 | A: try starting rfcat *before* plugging in the dongle 5 | A: this has been "fixed" in the latest firmware and client. dongles now only enter RX mode when the client first talks to them, and that is only in "research" mode, so individual tools can control this 6 | 7 | Q: why does it not work! 8 | A: check dependencies (pyusb, libusb) 9 | A: see question above 10 | A: try a different usb port. especially usb3 ports just bomb out. not sure why yet. 11 | A: debian likes to break things. email me if you are trying this on debian. 12 | 13 | 14 | Q: why do i sometimes get an error about "Input/output error" (often when RfCat was working)?? 15 | A: this appears to be a bug between the CC1111 and some USB3 ports. try a different USB port, and then a different computer. i currently get this on two of three ports on my newest laptop (the third is a USB2 port) 16 | 17 | Q: why does my device sometimes not show up in RfCat? 18 | A: see answer to the question above. 19 | 20 | Q: why does my dongle still go into bootloader mode even though i've installed RfCat? 21 | A: if you still have your debugger attached you may be grounding the hardware bootloader request line. detach your debugger! 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012 atlas 2 | 3 | License: BSD 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | 15 | 3. The names of the authors may not be used to endorse or promote 16 | products derived from this software without specific prior 17 | written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 | WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.immesniff: -------------------------------------------------------------------------------- 1 | 2 | Key Bindings 3 | ============ 4 | 5 | q, a - inc/dec highest sync word nibble 6 | w, s - inc/dec high-middle sync word nibble 7 | e, d - inc/dec low-middle sync word nibble 8 | r, f - inc/dec lowest sync word nibble 9 | z - NO sync word matching 10 | 11 | menu - inc Modulation type 12 | bye! - dec Modulation type 13 | 14 | up - inc recv bandwidth 15 | down - dec recv bandwidth 16 | 17 | right - inc baudrate 18 | left - dec baudrate 19 | 20 | p, Enter - inc/dec frequency 21 | o, ',' - faster inc/dec frequency 22 | i, m - even faster inc/dec frequency 23 | l - set freq to 915mhz 24 | k - set freq to 868mhz 25 | j - set freq to 433mhz 26 | h - set freq to 315mhz 27 | t, v - inc/dec channels 28 | g - set channel = 0 29 | 30 | 31 | SPACE - switch screens 32 | SPKR - toggle CARRIER TX mode (good for showing up on a SpecAn, or, umm, jamming?) 33 | 34 | -------------------------------------------------------------------------------- /README.msfrelay: -------------------------------------------------------------------------------- 1 | RfCat MSF Relay 2 | =============== 3 | 4 | The RfCat MSF Relay is a lightweight webserver that provides 5 | Metasploit Hardware Bridge support. Many of the python methods 6 | are available interfactive from either the Metasploit hwbridge 7 | interactive shell or from Metasploit modules written to support 8 | the rftransceiver extension. 9 | 10 | For details on the RFTransceiver extension API see: 11 | http://OpenGarages.org/hwbridge 12 | 13 | To download Metasploit: https://www.metasploit.com/ 14 | 15 | Usage 16 | ===== 17 | 18 | With a RfCat compatiable device plugged into a machine (ie YardStickOne) 19 | run rfcat_msfrelay. It will start a webserver and report 20 | 21 | RfCat MSFRelay running. 22 | 23 | By default it only listens to localhost and has a default username:password 24 | of msf_relay:rfcat_relaypass. All of these options can be altered via 25 | command line arguments for rfcat_msfrelay. Once running can launch Metasploit. 26 | 27 | ``` 28 | ./msfconsole -q 29 | msf > use auxiliary/client/hwbridge/connect 30 | msf auxiliary(connect) > set httpusername msf_relay 31 | httpusername => msf_relay 32 | msf auxiliary(connect) > set httppassword rfcat_relaypass 33 | httppassword => rfcat_relaypass 34 | msf auxiliary(connect) > run 35 | 36 | [*] Attempting to connect to 127.0.0.1... 37 | [*] Hardware bridge interface session 1 opened (127.0.0.1 -> 127.0.0.1) at 2017-03-11 17:16:23 -0800 38 | [+] HWBridge session established 39 | [*] HW Specialty: {"rftransceiver"=>true} Capabilities: {"cc11xx"=>true} 40 | [!] NOTICE: You are about to leave the matrix. All actions performed on this hardware bridge 41 | [!] could have real world consequences. Use this module in a controlled testing 42 | [!] environment and with equipment you are authorized to perform testing on. 43 | [*] Auxiliary module execution completed 44 | msf auxiliary(connect) > sessions 45 | 46 | Active sessions 47 | =============== 48 | 49 | Id Type Information Connection 50 | -- ---- ----------- ---------- 51 | 1 hwbridge cmd/hardware rftransceiver 127.0.0.1 -> 127.0.0.1 (127.0.0.1) 52 | 53 | msf auxiliary(connect) > sessions -i 1 54 | [*] Starting interaction with 1... 55 | 56 | hwbridge > help 57 | 58 | Core Commands 59 | ============= 60 | 61 | Command Description 62 | ------- ----------- 63 | ? Help menu 64 | bgkill Kills a background meterpreter script 65 | bglist Lists running background scripts 66 | bgrun Executes a meterpreter script as a background thread 67 | exit Terminate the hardware bridge session 68 | help Help menu 69 | info Displays information about a Post module 70 | irb Drop into irb scripting mode 71 | load Load one or more meterpreter extensions 72 | load_custom_methods Loads custom HW commands if any 73 | reboot Reboots the device. Usually only supported by stand-alone devices 74 | reset Resets the device. Some devices this is a full factory reset 75 | run Executes a meterpreter script or Post module 76 | specialty Hardware devices specialty 77 | status Fetch bridge status information 78 | 79 | 80 | RFtransceiver Commands 81 | ====================== 82 | 83 | Command Description 84 | ------- ----------- 85 | baud sets the baud rate 86 | channel sets channel 87 | channel_bw sets the channel bandwidth 88 | deviation sets the deviation 89 | enable_crc enables crc 90 | enable_manchester enales manchester encoding 91 | flen sets the fixed length packet size 92 | freq sets the frequency 93 | idx sets an active idx 94 | maxpower sets max power 95 | modulation sets the modulation 96 | power sets the power level 97 | preamble sets the preamble number 98 | recv receive a packet of data 99 | supported_idx suppored USB indexes 100 | sync_word sets the sync word 101 | vlen sets the variable lenght packet size 102 | xmit transmits some data 103 | 104 | hwbridge > run post/hardware/rftransceiver/... 105 | ``` 106 | 107 | Notes 108 | ===== 109 | Not all methods have been ported to Metasploit. The typical workflow 110 | is to do your initial research via rfcat and use Metasploit just 111 | for the results of that research. Metasploit works better as an 112 | exploit framework than a research framework. However, if you feel 113 | that there are some useful methods missing that you would want to see, 114 | please file an issue on the Metasploit github page: 115 | https://github.com/rapid7/metasploit-framework 116 | 117 | -------------------------------------------------------------------------------- /README.nonroot: -------------------------------------------------------------------------------- 1 | many thanks to Adam Laurie (Major Malfunction) for providing an elegant udev 2 | rules file to make a stock RFCAT device have user-permissions. 3 | 4 | this translates as "i don't have to 'sudo rfcat'" 5 | 6 | i had considered making this auto-install, but since i would feel weird about 7 | anyone dumping stuff into my device configuration areas without asking, i'm 8 | simply writing this README. 9 | 10 | to allow automatic non-root access, run: 11 | 12 | sudo cp etc/udev/rules.d/20-rfcat.rules /etc/udev/rules.d 13 | sudo udevadm control --reload-rules 14 | 15 | hack fun! 16 | @ 17 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | create methods to get/set PA_POWER and assist in ASK/OOK modulation. 3 | create method setPktPreambleTX() and change g/setPktPQT to g/setPktPreambleRX(numTimesFour) 4 | 5 | continuous detection mode cleanup and enhancement 6 | 7 | CLEAN UP CODE/PROJECT / UNBORK 8 | make firmware CC25x1-friendly 9 | consolidate chipcon code from cc1111/cc2531/cc2511 code 10 | 11 | rfcat_server 12 | make this more complete and tested! 13 | 14 | all USB firmwares: 15 | * add reset capability to EP0's commands 16 | * add stall recovery to client and EP0 commands (explore this one...) 17 | 18 | documentation! :) yes, i heard you. 19 | -------------------------------------------------------------------------------- /etc/udev/rules.d/20-rfcat.rules: -------------------------------------------------------------------------------- 1 | # legacy RfCats and cc1111usb 2 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="0451" ATTRS{idProduct}=="4715" MODE:="0660" SYMLINK+="RFCAT%n", GROUP="dialout" 3 | 4 | # modern RfCats 5 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="6047" MODE:="0660" SYMLINK+="RFCAT%n", GROUP="dialout" 6 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="6048" MODE:="0660" SYMLINK+="RFCAT%n", GROUP="dialout" 7 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="605b" MODE:="0660" SYMLINK+="RFCAT%n", GROUP="dialout" 8 | 9 | # RfCat bootloader subsystem (uses it's own product id) 10 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="6049" SYMLINK+="RFCAT_BL_C" ENV{ID_MM_DEVICE_IGNORE}="1" 11 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="604a" SYMLINK+="RFCAT_BL_D" ENV{ID_MM_DEVICE_IGNORE}="1" 12 | SUBSYSTEMS=="usb" ATTRS{idVendor}=="1d50" ATTRS{idProduct}=="605c" SYMLINK+="RFCAT_BL_YS1" ENV{ID_MM_DEVICE_IGNORE}="1" 13 | -------------------------------------------------------------------------------- /firmware/appCC2531.c: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | //SFR(WDCTL, 0xc9); 4 | 5 | /************************************************************************************************* 6 | * welcome to the cc1111usb application. 7 | * this lib was designed to be the basis for your usb-app on the cc1111 radio. hack fun! 8 | * 9 | * 10 | * best way to start is to look over the library and get a little familiar with it. 11 | * next, put code as follows: 12 | * * any initialization code that should happen at power up goes in appMainInit() 13 | * * the main application loop code should go in appMainLoop() 14 | * * usb interface code: register a callback using register_Cb_ep5() as demonstrated in appMainInit() 15 | * 16 | * if you should need to change anything about the USB descriptors, do your homework! particularly 17 | * keep in mind, if you change the IN or OUT max packetsize, you *must* change it in the 18 | * EPx_MAX_PACKET_SIZE define, and should correspond to the setting of MAXI and MAXO. 19 | * 20 | * */ 21 | 22 | 23 | 24 | 25 | /************************************************************************************************* 26 | * Application Code - these first few functions are what should get overwritten for your app * 27 | ************************************************************************************************/ 28 | 29 | __xdata u32 loopCnt; 30 | __xdata u8 xmitCnt; 31 | 32 | int appHandleEP5(void); 33 | 34 | /* appMainInit() is called *before Interrupts are enabled* for various initialization things. */ 35 | void appMainInit(void) 36 | { 37 | //registerCb_ep0Vendor( appHandleEP0Vendor ); 38 | registerCb_ep5( appHandleEP5 ); 39 | 40 | loopCnt = 0; 41 | xmitCnt = 1; 42 | 43 | //RxMode(); 44 | } 45 | 46 | /* appMain is the application. it is called every loop through main, as does the USB handler code. 47 | * do not block if you want USB to work. */ 48 | void appMainLoop(void) 49 | { 50 | /* 51 | // this is part of the NIC code to handle received RF packets and may be replaced/modified // 52 | __xdata u8 processbuffer; 53 | 54 | if (rfif) 55 | { 56 | lastCode[0] = LC_MAIN_RFIF; 57 | IEN2 &= ~IEN2_RFIE; 58 | 59 | if(rfif & RFIF_IRQ_DONE) 60 | { 61 | processbuffer = !rfRxCurrentBuffer; 62 | if(rfRxProcessed[processbuffer] == RX_UNPROCESSED) 63 | { 64 | // we've received a packet. deliver it. 65 | if (PKTCTRL0&1) // variable length packets have a leading "length" byte, let's skip it 66 | txdata(APP_NIC, NIC_RECV, (u8)rfrxbuf[processbuffer][0], (u8*)&rfrxbuf[processbuffer][1]); 67 | else 68 | txdata(APP_NIC, NIC_RECV, PKTLEN, (u8*)&rfrxbuf[processbuffer]); 69 | 70 | // Set receive buffer to processed so it can be used again // 71 | rfRxProcessed[processbuffer] = RX_PROCESSED; 72 | } 73 | } 74 | 75 | rfif = 0; 76 | IEN2 |= IEN2_RFIE; 77 | }*/ 78 | ////////////////////////////////////////////////////////////////////////////////////////////// 79 | } 80 | 81 | /* appHandleEP5 gets called when a message is received on endpoint 5 from the host. this is the 82 | * main handler routine for the application as endpoint 0 is normally used for system stuff. 83 | * 84 | * important things to know: 85 | * * your data is in ep5.OUTbuf, the length is ep5.OUTlen, and the first two bytes are 86 | * going to be \x40\xe0. just craft your application to ignore those bytes, as i have ni 87 | * puta idea what they do. 88 | * * transmit data back to the client-side app through txdatai(). this function immediately 89 | * xmits as soon as any previously transmitted data is out of the buffer (ie. it blocks 90 | * while (ep5.flags & EP_INBUF_WRITTEN) and then transmits. this flag is then set, and 91 | * cleared by an interrupt when the data has been received on the host side. */ 92 | int appHandleEP5() 93 | { // not used by VCOM 94 | #ifndef VIRTUAL_COM 95 | __xdata u8 *ptr = &ep5.OUTbuf[0]; 96 | 97 | switch (ep5.OUTcmd) 98 | { 99 | /* 100 | case CMD_RFMODE: 101 | switch (*ptr++) 102 | { 103 | case RF_STATE_RX: 104 | 105 | RxMode(); 106 | break; 107 | case RF_STATE_IDLE: 108 | IdleMode(); 109 | break; 110 | case RF_STATE_TX: 111 | transmit(ptr, ep5.OUTlen); 112 | break; 113 | } 114 | txdata(app,cmd,len,ptr); 115 | break; 116 | */ 117 | default: 118 | break; 119 | } 120 | ep5.flags &= ~EP_OUTBUF_WRITTEN; // this allows the OUTbuf to be rewritten... it's saved until now. 121 | #endif 122 | return 0; 123 | } 124 | 125 | /************************************************************************************************* 126 | * here begins the initialization stuff... this shouldn't change much between firmwares or * 127 | * devices. * 128 | *************************************************************************************************/ 129 | 130 | void appInitRf(void) 131 | { 132 | #if 0 133 | IOCFG2 = 0x00; 134 | IOCFG1 = 0x00; 135 | IOCFG0 = 0x00; 136 | SYNC1 = 0x0c; 137 | SYNC0 = 0x4e; 138 | PKTLEN = 0xff; 139 | PKTCTRL1 = 0x40; // PQT threshold - was 0x00 140 | PKTCTRL0 = 0x01; 141 | ADDR = 0x00; 142 | CHANNR = 0x00; 143 | FSCTRL1 = 0x06; 144 | FSCTRL0 = 0x00; 145 | FREQ2 = 0x24; 146 | FREQ1 = 0x3a; 147 | FREQ0 = 0xf1; 148 | MDMCFG4 = 0xca; 149 | MDMCFG3 = 0xa3; 150 | MDMCFG2 = 0x03; 151 | MDMCFG1 = 0x23; 152 | MDMCFG0 = 0x11; 153 | DEVIATN = 0x36; 154 | MCSM2 = 0x07; // RX_TIMEOUT 155 | MCSM1 = 0x3f; // CCA_MODE RSSI below threshold unless currently recvg pkt - always end up in RX mode 156 | MCSM0 = 0x18; // fsautosync when going from idle to rx/tx/fstxon 157 | FOCCFG = 0x17; 158 | BSCFG = 0x6c; 159 | AGCCTRL2 = 0x03; 160 | AGCCTRL1 = 0x40; 161 | AGCCTRL0 = 0x91; 162 | FREND1 = 0x56; 163 | FREND0 = 0x10; 164 | FSCAL3 = 0xe9; 165 | FSCAL2 = 0x2a; 166 | FSCAL1 = 0x00; 167 | FSCAL0 = 0x1f; 168 | TEST2 = 0x88; // low data rates, increased sensitivity - was 0x88 169 | TEST1 = 0x31; // always 0x31 in tx-mode, for low data rates, increased sensitivity - was 0x31 170 | TEST0 = 0x09; 171 | PA_TABLE0 = 0x50; 172 | 173 | 174 | #ifndef RADIO_EU 175 | //PKTCTRL1 = 0x04; // APPEND_STATUS 176 | //PKTCTRL1 = 0x40; // PQT threshold 177 | //PKTCTRL0 = 0x01; // VARIABLE LENGTH, no crc, no whitening 178 | //PKTCTRL0 = 0x00; // FIXED LENGTH, no crc, no whitening 179 | FSCTRL1 = 0x0c; // Intermediate Frequency 180 | //FSCTRL0 = 0x00; 181 | FREQ2 = 0x25; 182 | FREQ1 = 0x95; 183 | FREQ0 = 0x55; 184 | //MDMCFG4 = 0x1d; // chan_bw and drate_e 185 | //MDMCFG3 = 0x55; // drate_m 186 | //MDMCFG2 = 0x13; // gfsk, 30/32+carrier sense sync 187 | //MDMCFG1 = 0x23; // 4-preamble-bytes, chanspc_e 188 | //MDMCFG0 = 0x11; // chanspc_m 189 | //DEVIATN = 0x63; 190 | //FOCCFG = 0x1d; 191 | //BSCFG = 0x1c; // bit sync config 192 | //AGCCTRL2 = 0xc7; 193 | //AGCCTRL1 = 0x00; 194 | //AGCCTRL0 = 0xb0; 195 | FREND1 = 0xb6; 196 | FREND0 = 0x10; 197 | FSCAL3 = 0xea; 198 | FSCAL2 = 0x2a; 199 | FSCAL1 = 0x00; 200 | FSCAL0 = 0x1f; 201 | //TEST2 = 0x88; 202 | //TEST1 = 0x31; 203 | //TEST0 = 0x09; 204 | //PA_TABLE0 = 0x83; 205 | #endif 206 | #endif 207 | } 208 | 209 | /* initialize the IO subsystems for the appropriate dongles */ 210 | 211 | /************************************************************************************************* 212 | * main startup code * 213 | *************************************************************************************************/ 214 | void initBoard(void) 215 | { 216 | // in global.c 217 | clock_init(); 218 | io_init(); 219 | } 220 | 221 | 222 | void main (void) 223 | { 224 | initBoard(); 225 | initUSB(); 226 | //init_RF(); 227 | appMainInit(); 228 | 229 | 230 | /* Enable interrupts */ 231 | EA = 1; 232 | usb_up(); 233 | 234 | 235 | // wait until the host identifies the usb device (the host timeouts are awfully fast) 236 | waitForUSBsetup(); 237 | 238 | while (1) 239 | { 240 | usbProcessEvents(); 241 | appMainLoop(); 242 | } 243 | 244 | } 245 | 246 | -------------------------------------------------------------------------------- /firmware/appNIC.c: -------------------------------------------------------------------------------- 1 | #include "cc1111rf.h" 2 | #include "global.h" 3 | #include "nic.h" 4 | 5 | #ifdef VIRTUAL_COM 6 | #include "cc1111.h" 7 | #include "cc1111_vcom.h" 8 | #else 9 | #include "cc1111usb.h" 10 | #endif 11 | 12 | /************************************************************************************************* 13 | * welcome to the cc1111usb application. 14 | * this lib was designed to be the basis for your usb-app on the cc1111 radio. hack fun! 15 | * 16 | * 17 | * best way to start is to look over the library and get a little familiar with it. 18 | * next, put code as follows: 19 | * * any initialization code that should happen at power up goes in appMainInit() 20 | * * the main application loop code should go in appMainLoop() 21 | * * usb interface code should go into appHandleEP5. this includes a switch statement for any 22 | * verbs you want to create between the client on this firmware. 23 | * 24 | * if you should need to change anything about the USB descriptors, do your homework! particularly 25 | * keep in mind, if you change the IN or OUT max packetsize, you *must* change it in the 26 | * EPx_MAX_PACKET_SIZE define, the desciptor definition (be sure to get the right one!) and should 27 | * correspond to the setting of MAXI and MAXO. 28 | * 29 | * */ 30 | 31 | 32 | #define APP_NIC 0x42 33 | #define NIC_RECV 0x1 34 | #define NIC_XMIT 0x2 35 | 36 | /************************************************************************************************* 37 | * Application Code - these first few functions are what should get overwritten for your app * 38 | ************************************************************************************************/ 39 | 40 | __xdata u32 loopCnt; 41 | __xdata u8 xmitCnt; 42 | 43 | /* appMainInit() is called *before Interrupts are enabled* for various initialization things. */ 44 | void appMainInit(void) 45 | { 46 | loopCnt = 0; 47 | xmitCnt = 1; 48 | 49 | RxMode(); 50 | //startRX(); 51 | } 52 | 53 | /* appMain is the application. it is called every loop through main, as does the USB handler code. 54 | * do not block if you want USB to work. */ 55 | void appMainLoop(void) 56 | { 57 | __xdata u8 processbuffer; 58 | 59 | if (rfif) 60 | { 61 | lastCode[0] = 0xd; 62 | IEN2 &= ~IEN2_RFIE; 63 | 64 | if(rfif & RFIF_IRQ_DONE) 65 | { 66 | processbuffer = !rfRxCurrentBuffer; 67 | if(rfRxProcessed[processbuffer] == RX_UNPROCESSED) 68 | { 69 | // we've received a packet. deliver it. 70 | if (PKTCTRL0&1) // variable length packets have a leading "length" byte, let's skip it 71 | txdata(APP_NIC, NIC_RECV, (u8)rfrxbuf[processbuffer][0], (u8*)&rfrxbuf[processbuffer][1]); 72 | else 73 | txdata(APP_NIC, NIC_RECV, PKTLEN, (u8*)&rfrxbuf[processbuffer]); 74 | 75 | /* Set receive buffer to processed so it can be used again */ 76 | rfRxProcessed[processbuffer] = RX_PROCESSED; 77 | } 78 | } 79 | 80 | rfif = 0; 81 | IEN2 |= IEN2_RFIE; 82 | } 83 | } 84 | 85 | /* appHandleEP5 gets called when a message is received on endpoint 5 from the host. this is the 86 | * main handler routine for the application as endpoint 0 is normally used for system stuff. 87 | * 88 | * important things to know: 89 | * * your data is in ep5.OUTbuf, the length is ep5.OUTlen, and the first two bytes are 90 | * going to be \x40\xe0. just craft your application to ignore those bytes, as i have ni 91 | * puta idea what they do. 92 | * * transmit data back to the client-side app through txdatai(). this function immediately 93 | * xmits as soon as any previously transmitted data is out of the buffer (ie. it blocks 94 | * while (ep5.flags & EP_INBUF_WRITTEN) and then transmits. this flag is then set, and 95 | * cleared by an interrupt when the data has been received on the host side. */ 96 | int appHandleEP5() 97 | { // not used by VCOM 98 | #ifndef VIRTUAL_COM 99 | __xdata u8 *ptr = &ep5.OUTbuf[0]; 100 | 101 | switch (ep5.OUTapp) 102 | { 103 | case APP_NIC: 104 | 105 | switch (ep5.OUTcmd) 106 | { 107 | case NIC_XMIT: 108 | transmit(ptr, ep5.OUTlen-1, 0, 0); 109 | { LED=1; sleepMillis(2); LED=0; sleepMillis(1); } 110 | txdata(ep5.OUTapp, ep5.OUTcmd, 1, (__xdata u8*)"0"); 111 | break; 112 | default: 113 | break; 114 | } 115 | break; 116 | } 117 | ep5.flags &= ~EP_OUTBUF_WRITTEN; // this allows the OUTbuf to be rewritten... it's saved until now. 118 | #endif 119 | return 0; 120 | } 121 | 122 | 123 | 124 | /************************************************************************************************* 125 | * here begins the initialization stuff... this shouldn't change much between firmwares or * 126 | * devices. * 127 | *************************************************************************************************/ 128 | 129 | void appInitRf(void) 130 | { 131 | IOCFG2 = 0x00; 132 | IOCFG1 = 0x00; 133 | IOCFG0 = 0x00; 134 | SYNC1 = 0x0c; 135 | SYNC0 = 0x4e; 136 | PKTLEN = 0xff; 137 | PKTCTRL1 = 0x40; // PQT threshold - was 0x00 138 | PKTCTRL0 = 0x01; 139 | ADDR = 0x00; 140 | CHANNR = 0x00; 141 | FSCTRL1 = 0x06; 142 | FSCTRL0 = 0x00; 143 | FREQ2 = 0x24; 144 | FREQ1 = 0x3a; 145 | FREQ0 = 0xf1; 146 | MDMCFG4 = 0xca; 147 | MDMCFG3 = 0xa3; 148 | MDMCFG2 = 0x03; 149 | MDMCFG1 = 0x23; 150 | MDMCFG0 = 0x11; 151 | DEVIATN = 0x36; 152 | MCSM2 = 0x07; // RX_TIMEOUT 153 | MCSM1 = 0x3f; // CCA_MODE RSSI below threshold unless currently recvg pkt - always end up in RX mode 154 | MCSM0 = 0x18; // fsautosync when going from idle to rx/tx/fstxon 155 | FOCCFG = 0x17; 156 | BSCFG = 0x6c; 157 | AGCCTRL2 = 0x03; 158 | AGCCTRL1 = 0x40; 159 | AGCCTRL0 = 0x91; 160 | FREND1 = 0x56; 161 | FREND0 = 0x10; 162 | FSCAL3 = 0xe9; 163 | FSCAL2 = 0x2a; 164 | FSCAL1 = 0x00; 165 | FSCAL0 = 0x1f; 166 | TEST2 = 0x88; // low data rates, increased sensitivity provided by 0x81- was 0x88 167 | TEST1 = 0x31; // always 0x31 in tx-mode, for low data rates 0x35 provides increased sensitivity - was 0x31 168 | TEST0 = 0x09; 169 | PA_TABLE0 = 0x50; 170 | 171 | 172 | #ifndef RADIO_EU 173 | //PKTCTRL1 = 0x04; // APPEND_STATUS 174 | //PKTCTRL1 = 0x40; // PQT threshold 175 | //PKTCTRL0 = 0x01; // VARIABLE LENGTH, no crc, no whitening 176 | //PKTCTRL0 = 0x00; // FIXED LENGTH, no crc, no whitening 177 | FSCTRL1 = 0x0c; // Intermediate Frequency 178 | //FSCTRL0 = 0x00; 179 | FREQ2 = 0x25; 180 | FREQ1 = 0x95; 181 | FREQ0 = 0x55; 182 | //MDMCFG4 = 0x1d; // chan_bw and drate_e 183 | //MDMCFG3 = 0x55; // drate_m 184 | //MDMCFG2 = 0x13; // gfsk, 30/32+carrier sense sync 185 | //MDMCFG1 = 0x23; // 4-preamble-bytes, chanspc_e 186 | //MDMCFG0 = 0x11; // chanspc_m 187 | //DEVIATN = 0x63; 188 | //FOCCFG = 0x1d; 189 | //BSCFG = 0x1c; // bit sync config 190 | //AGCCTRL2 = 0xc7; 191 | //AGCCTRL1 = 0x00; 192 | //AGCCTRL0 = 0xb0; 193 | FREND1 = 0xb6; 194 | FREND0 = 0x10; 195 | FSCAL3 = 0xea; 196 | FSCAL2 = 0x2a; 197 | FSCAL1 = 0x00; 198 | FSCAL0 = 0x1f; 199 | //TEST2 = 0x88; 200 | //TEST1 = 0x31; 201 | //TEST0 = 0x09; 202 | //PA_TABLE0 = 0x83; 203 | #endif 204 | 205 | } 206 | 207 | 208 | /************************************************************************************************* 209 | * main startup code * 210 | *************************************************************************************************/ 211 | void initBoard(void) 212 | { 213 | clock_init(); 214 | io_init(); 215 | } 216 | 217 | 218 | void main (void) 219 | { 220 | initBoard(); 221 | initUSB(); 222 | blink(300,300); 223 | 224 | init_RF(); 225 | appMainInit(); 226 | 227 | usb_up(); 228 | 229 | /* Enable interrupts */ 230 | EA = 1; 231 | 232 | while (1) 233 | { 234 | usbProcessEvents(); 235 | appMainLoop(); 236 | } 237 | 238 | } 239 | 240 | -------------------------------------------------------------------------------- /firmware/appNetworkTest.c: -------------------------------------------------------------------------------- 1 | #include "cc1111rf.h" 2 | #include "cc1111_aes.h" 3 | #include "chipcon_dma.h" 4 | #include "global.h" 5 | #include "nic.h" 6 | 7 | #ifdef VIRTUAL_COM 8 | #include "cc1111.h" 9 | #include "cc1111_vcom.h" 10 | #else 11 | #include "cc1111usb.h" 12 | #endif 13 | 14 | /************************************************************************************************* 15 | * welcome to the cc1111usb application. 16 | * this lib was designed to be the basis for your usb-app on the cc1111 radio. hack fun! 17 | * 18 | * 19 | * best way to start is to look over the library and get a little familiar with it. 20 | * next, put code as follows: 21 | * * any initialization code that should happen at power up goes in appMainInit() 22 | * * the main application loop code should go in appMainLoop() 23 | * * usb interface code should go into appHandleEP5. this includes a switch statement for any 24 | * verbs you want to create between the client on this firmware. 25 | * 26 | * if you should need to change anything about the USB descriptors, do your homework! particularly 27 | * keep in mind, if you change the IN or OUT max packetsize, you *must* change it in the 28 | * EPx_MAX_PACKET_SIZE define, the desciptor definition (be sure to get the right one!) and should 29 | * correspond to the setting of MAXI and MAXO. 30 | * 31 | * */ 32 | 33 | 34 | 35 | 36 | /************************************************************************************************* 37 | * Application Code - these first few functions are what should get overwritten for your app * 38 | ************************************************************************************************/ 39 | 40 | __xdata u32 loopCnt; 41 | __xdata u8 xmitCnt; 42 | 43 | /* appMainInit() is called *before Interrupts are enabled* for various initialization things. */ 44 | void appMainInit(void) 45 | { 46 | loopCnt = 0; 47 | xmitCnt = 1; 48 | 49 | #ifdef RECEIVE_TEST 50 | RxMode(); 51 | //startRX(); 52 | #endif 53 | } 54 | 55 | /* appMain is the application. it is called every loop through main, as does the USB handler code. 56 | * do not block if you want USB to work. */ 57 | void appMainLoop(void) 58 | { 59 | __xdata u8 processbuffer; 60 | #ifdef TRANSMIT_TEST 61 | __xdata u8 testPacket[14]; 62 | 63 | 64 | if (loopCnt++ == 90000) 65 | { 66 | /* Send a packet */ 67 | testPacket[0] = 0x0D; 68 | testPacket[1] = xmitCnt++; 69 | testPacket[2] = 0x48; 70 | testPacket[3] = 0x41; 71 | testPacket[4] = 0x4C; 72 | testPacket[5] = 0x4C; 73 | testPacket[6] = 0x4F; 74 | //testPacket[6] = 0x43; 75 | //testPacket[7] = 0x43; 76 | testPacket[7] = lastCode[0]; 77 | testPacket[8] = lastCode[1]; 78 | testPacket[9] = 0x31; 79 | testPacket[10] = 0x31; 80 | testPacket[11] = 0x31; 81 | testPacket[12] = 0x31; 82 | 83 | transmit(testPacket, 13, 0, 0); 84 | //blink(400,400); 85 | REALLYFASTBLINK(); 86 | #ifndef VIRTUAL_COM 87 | debug("sent packet..."); 88 | #endif 89 | loopCnt = 0; 90 | } 91 | #endif 92 | 93 | if (rfif) 94 | { 95 | lastCode[0] = 0xd; 96 | IEN2 &= ~IEN2_RFIE; 97 | 98 | if(rfif & RFIF_IRQ_DONE) 99 | { 100 | processbuffer = !rfRxCurrentBuffer; 101 | if(rfRxProcessed[processbuffer] == RX_UNPROCESSED) 102 | { 103 | if (PKTCTRL0&1) // variable length packets have a leading "length" byte, let's skip it 104 | txdata(APP_NIC, NIC_RECV, (u8)rfrxbuf[processbuffer][0], (u8*)&rfrxbuf[processbuffer][1]); 105 | else 106 | txdata(APP_NIC, NIC_RECV, PKTLEN, (u8*)&rfrxbuf[processbuffer]); 107 | 108 | /* Set receive buffer to processed so it can be used again */ 109 | rfRxProcessed[processbuffer] = RX_PROCESSED; 110 | } 111 | } 112 | 113 | rfif = 0; 114 | IEN2 |= IEN2_RFIE; 115 | } 116 | } 117 | 118 | /* appHandleEP5 gets called when a message is received on endpoint 5 from the host. this is the 119 | * main handler routine for the application as endpoint 0 is normally used for system stuff. 120 | * 121 | * important things to know: 122 | * * your data is in ep5.OUTbuf, the length is ep5.OUTlen, and the first two bytes are 123 | * going to be \x40\xe0. just craft your application to ignore those bytes, as i have ni 124 | * puta idea what they do. 125 | * * transmit data back to the client-side app through txdatai(). this function immediately 126 | * xmits as soon as any previously transmitted data is out of the buffer (ie. it blocks 127 | * while (ep5.flags & EP_INBUF_WRITTEN) and then transmits. this flag is then set, and 128 | * cleared by an interrupt when the data has been received on the host side. */ 129 | int appHandleEP5() 130 | { // not used by VCOM 131 | #ifndef VIRTUAL_COM 132 | __xdata u8 *ptr = &ep5.OUTbuf[0]; 133 | 134 | switch (ep5.OUTcmd) 135 | { 136 | default: 137 | break; 138 | } 139 | ep5.flags &= ~EP_OUTBUF_WRITTEN; // this allows the OUTbuf to be rewritten... it's saved until now. 140 | #endif 141 | return 0; 142 | } 143 | 144 | 145 | /************************************************************************************************* 146 | * here begins the initialization stuff... this shouldn't change much between firmwares or * 147 | * devices. * 148 | *************************************************************************************************/ 149 | 150 | void appInitRf(void) 151 | { 152 | // initial radio state. this is easily changed from the client, but 153 | // most cases it's far superior to have a sane initial rf config. 154 | // customize as desired, keeping in mind the impact any changes may 155 | // have on the function of the firmware (assumptions abound) 156 | IOCFG2 = 0x00; 157 | IOCFG1 = 0x00; 158 | IOCFG0 = 0x00; 159 | SYNC1 = 0x0c; 160 | SYNC0 = 0x4e; 161 | PKTLEN = 0xff; 162 | PKTCTRL1 = 0x40; // PQT threshold - was 0x00 163 | PKTCTRL0 = 0x01; 164 | ADDR = 0x00; 165 | CHANNR = 0x00; 166 | FSCTRL1 = 0x06; 167 | FSCTRL0 = 0x00; 168 | FREQ2 = 0x24; 169 | FREQ1 = 0x3a; 170 | FREQ0 = 0xf1; 171 | MDMCFG4 = 0xca; 172 | MDMCFG3 = 0xa3; 173 | MDMCFG2 = 0x03; 174 | MDMCFG1 = 0x23; 175 | MDMCFG0 = 0x11; 176 | DEVIATN = 0x36; 177 | MCSM2 = 0x07; // RX_TIMEOUT 178 | MCSM1 = 0x3f; // CCA_MODE RSSI below threshold unless currently recvg pkt - always end up in RX mode 179 | MCSM0 = 0x18; // fsautosync when going from idle to rx/tx/fstxon 180 | FOCCFG = 0x17; 181 | BSCFG = 0x6c; 182 | AGCCTRL2 = 0x03; 183 | AGCCTRL1 = 0x40; 184 | AGCCTRL0 = 0x91; 185 | FREND1 = 0x56; 186 | FREND0 = 0x10; 187 | FSCAL3 = 0xe9; 188 | FSCAL2 = 0x2a; 189 | FSCAL1 = 0x00; 190 | FSCAL0 = 0x1f; 191 | TEST2 = 0x88; // low data rates, increased sensitivity provided by 0x81- was 0x88 192 | TEST1 = 0x31; // always 0x31 in tx-mode, for low data rates 0x35 provides increased sensitivity - was 0x31 193 | TEST0 = 0x09; 194 | PA_TABLE0 = 0x50; 195 | 196 | 197 | #ifndef RADIO_EU 198 | //PKTCTRL1 = 0x04; // APPEND_STATUS 199 | //PKTCTRL1 = 0x40; // PQT threshold 200 | //PKTCTRL0 = 0x01; // VARIABLE LENGTH, no crc, no whitening 201 | //PKTCTRL0 = 0x00; // FIXED LENGTH, no crc, no whitening 202 | FSCTRL1 = 0x0c; // Intermediate Frequency 203 | //FSCTRL0 = 0x00; 204 | FREQ2 = 0x25; 205 | FREQ1 = 0x95; 206 | FREQ0 = 0x55; 207 | //MDMCFG4 = 0x1d; // chan_bw and drate_e 208 | //MDMCFG3 = 0x55; // drate_m 209 | //MDMCFG2 = 0x13; // gfsk, 30/32+carrier sense sync 210 | //MDMCFG1 = 0x23; // 4-preamble-bytes, chanspc_e 211 | //MDMCFG0 = 0x11; // chanspc_m 212 | //DEVIATN = 0x63; 213 | //FOCCFG = 0x1d; 214 | //BSCFG = 0x1c; // bit sync config 215 | //AGCCTRL2 = 0xc7; 216 | //AGCCTRL1 = 0x00; 217 | //AGCCTRL0 = 0xb0; 218 | FREND1 = 0xb6; 219 | FREND0 = 0x10; 220 | FSCAL3 = 0xea; 221 | FSCAL2 = 0x2a; 222 | FSCAL1 = 0x00; 223 | FSCAL0 = 0x1f; 224 | //TEST2 = 0x88; 225 | //TEST1 = 0x31; 226 | //TEST0 = 0x09; 227 | //PA_TABLE0 = 0x83; 228 | #endif 229 | 230 | } 231 | 232 | /************************************************************************************************* 233 | * main startup code * 234 | *************************************************************************************************/ 235 | void initBoard(void) 236 | { 237 | clock_init(); 238 | io_init(); 239 | } 240 | 241 | 242 | void main (void) 243 | { 244 | initBoard(); 245 | initDMA(); // do this early so peripherals that use DMA can allocate channels correctly 246 | initAES(); 247 | initUSB(); 248 | blink(300,300); 249 | 250 | init_RF(); 251 | appMainInit(); 252 | 253 | usb_up(); 254 | 255 | /* Enable interrupts */ 256 | EA = 1; 257 | 258 | while (1) 259 | { 260 | usbProcessEvents(); 261 | appMainLoop(); 262 | } 263 | 264 | } 265 | 266 | -------------------------------------------------------------------------------- /firmware/bins/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas0fd00m/rfcat-firsttry/ec89f57a35777acb48c59eaf4f9fa8356b93dbd3/firmware/bins/.placeholder -------------------------------------------------------------------------------- /firmware/bootloader.c: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "bootloader.h" 3 | 4 | void run_bootloader(void) 5 | { 6 | // check that our bootloader is present & if so, tell it we want it to run... 7 | // we use the otherwise unused I2S SFRs as semaphores. 8 | if(I2SCLKF0 == 0xf0 && I2SCLKF1 == 0x0d) 9 | I2SCLKF2= 0x69; 10 | // disable all interrupts 11 | EA = 0; 12 | IEN0 = IEN1 = IEN2 = 0; 13 | usb_down(); 14 | // reset USB controller 15 | SLEEP &= ~SLEEP_USB_EN; 16 | // abort and disarm all DMA 17 | DMAARM = 0x9F; 18 | LED = 0; 19 | // Jump to bootloader (if there isn't one this will just cause a reset) 20 | __asm 21 | ljmp 0x00 22 | __endasm; 23 | } 24 | -------------------------------------------------------------------------------- /firmware/bootloader_serial.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | from rflib.intelhex import IntelHex 5 | 6 | WRITEBACK = True 7 | if len(sys.argv) > 1: 8 | WRITEBACK = False 9 | ser = int(sys.argv[1]) 10 | else: 11 | try: 12 | ser = int(file(".serial", 'rb').read(), 16) + 1 13 | except IOError: 14 | ser = 0 15 | 16 | print >>sys.stderr,("[--- new serial number: %.4x ---]" % ser) 17 | 18 | if WRITEBACK: 19 | file(".serial", 'wb').write("%.13x" % ser) 20 | 21 | sertxt = '' 22 | sertmp = "%.13x" % ser 23 | for c in sertmp: 24 | sertxt += "%s\x00" % c 25 | 26 | ihc=IntelHex('CCBootloader/CCBootloader-rfcat-chronosdongle.hex') 27 | ihd=IntelHex('CCBootloader/CCBootloader-rfcat-donsdongle.hex') 28 | ihy=IntelHex('CCBootloader/CCBootloader-rfcat-ys1.hex') 29 | ihc.puts(0x13e0, "@las\x1c\x03" + sertxt) 30 | ihd.puts(0x13e0, "@las\x1c\x03" + sertxt) 31 | ihy.puts(0x13e0, "@las\x1c\x03" + sertxt) 32 | ihc.write_hex_file('CCBootloader/CCBootloader-rfcat-chronosdongle-serial.hex') 33 | ihd.write_hex_file('CCBootloader/CCBootloader-rfcat-donsdongle-serial.hex') 34 | ihy.write_hex_file('CCBootloader/CCBootloader-rfcat-ys1-serial.hex') 35 | 36 | -------------------------------------------------------------------------------- /firmware/buildall.sh: -------------------------------------------------------------------------------- 1 | 2 | DATESTAMP=`date +%y%m%d` 3 | cp .serial /tmp/ 4 | make clean RfCatChronos 5 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 6 | mv bins/RfCatChronos.hex bins/RfCatChronos-$DATESTAMP.hex 7 | 8 | cp /tmp/.serial . 9 | make RfCatChronosCCBootloader 10 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 11 | mv bins/RfCatChronosCCBootloader.hex bins/RfCatChronosCCBootloader-$DATESTAMP.hex 12 | 13 | cp /tmp/.serial . 14 | make clean RfCatDons 15 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 16 | mv bins/RfCatDons.hex bins/RfCatDons-$DATESTAMP.hex 17 | 18 | cp /tmp/.serial . 19 | make RfCatDonsCCBootloader 20 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 21 | mv bins/RfCatDonsCCBootloader.hex bins/RfCatDonsCCBootloader-$DATESTAMP.hex 22 | 23 | cp /tmp/.serial . 24 | make clean RfCatYS1 25 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 26 | mv bins/RfCatYS1.hex bins/RfCatYS1-$DATESTAMP.hex 27 | 28 | cp /tmp/.serial . 29 | make RfCatYS1CCBootloader 30 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 31 | mv bins/RfCatYS1CCBootloader.hex bins/RfCatYS1CCBootloader-$DATESTAMP.hex 32 | 33 | cp /tmp/.serial . 34 | make clean immeSniff 35 | [ $? -ne 0 ] && printf "\n\n\n FAILURE TO BUILD!!! \n\n\n" && exit 36 | mv bins/immeSniff.hex bins/immeSniff-$DATESTAMP.hex 37 | -------------------------------------------------------------------------------- /firmware/cc1111_aes.c: -------------------------------------------------------------------------------- 1 | #include "cc1110-ext.h" 2 | #include "cc1111_aes.h" 3 | #include "cc1111rf.h" 4 | 5 | /************************************************************************************************* 6 | * AES helpers * 7 | ************************************************************************************************/ 8 | 9 | __xdata DMA_DESC * __xdata aesdmai, * __xdata aesdmao; 10 | __xdata u8 aesdmachani, aesdmaarmi, aesdmachano, aesdmaarmo; 11 | 12 | // initialise DMA 13 | void initAES(void) 14 | { 15 | // input to crypto co-processor 16 | // note that to save code memory we don't bother setting anything to 0 17 | // as it's initialised to 0 anyway 18 | aesdmachani= getDMA(); // allocate a DMA channel 19 | aesdmaarmi= (DMAARM0 << aesdmachani); // pre-calculate arming bit 20 | aesdmai= &dma_configs[aesdmachani]; // point our DMA descriptor at allocated channel descriptor 21 | aesdmai->destAddrH = 0xdf; // ENCDI == 0xdfb1 - AES Input SFR 22 | aesdmai->destAddrL = 0xb1; 23 | aesdmai->lenL = 16; // always 128 bit operations 24 | aesdmai->trig = DMA_CFG0_TRIGGER_ENC_DW; // trigger when co-processor requests data 25 | aesdmai->srcInc = 1; 26 | aesdmai->priority = 1; 27 | 28 | // output from crypto co-processor 29 | aesdmachano= getDMA(); 30 | aesdmaarmo= (DMAARM0 << aesdmachano); 31 | aesdmao= &dma_configs[aesdmachano]; 32 | aesdmao->srcAddrH = 0xdf; // ENCDO == 0xdfb2 - AES Output SFR 33 | aesdmao->srcAddrL = 0xb2; 34 | aesdmao->lenL = 16; 35 | aesdmao->trig = DMA_CFG0_TRIGGER_DNC_UP; // trigger when co-processor signals upload ready 36 | aesdmao->destInc = 1; 37 | aesdmao->priority = 1; 38 | 39 | // set interrupt priority for group 4 to "11" (3 - highest) 40 | IP0 |= BIT4; 41 | IP1 |= BIT4; 42 | } 43 | 44 | // set the AES 128 bit key or IV 45 | void setAES(__xdata u8* __xdata buf, __xdata u8 command, __xdata u8 mode) 46 | { 47 | // wait for co-processor to be ready 48 | while(!(ENCCS & ENCCS_RDY)) 49 | ; 50 | 51 | // prepare DMA for transfer 52 | aesdmai->srcAddrH = (u8) ((u16) buf >> 8); 53 | aesdmai->srcAddrL = (u8) ((u16) buf & 0xff); 54 | DMAARM |= aesdmaarmi; 55 | NOP(); 56 | 57 | // start co-processor 58 | ENCCS = mode | command | ENCCS_ST; 59 | 60 | // wait for co-processor to finish 61 | while(!(ENCCS & ENCCS_RDY)) 62 | ; 63 | } 64 | 65 | // pad a buffer to multiple of 16 bytes. caller must ensure 66 | // enough space exists in buffer. returns new length. 67 | __xdata u16 padAES(__xdata u8* __xdata buf, __xdata u16 len) 68 | { 69 | while(len % 16) 70 | buf[len++]= '\0'; 71 | 72 | return len; 73 | } 74 | 75 | // encrypt a buffer 76 | void encAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 mode) 77 | { 78 | doAES(inbuf, outbuf, len, ENCCS_CMD_ENC, mode); 79 | } 80 | 81 | // decrypt a buffer 82 | void decAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 mode) 83 | { 84 | doAES(inbuf, outbuf, len, ENCCS_CMD_DEC, mode); 85 | } 86 | 87 | // process a buffer 88 | void doAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 command, __xdata u8 mode) 89 | { 90 | __xdata u16 bufp; 91 | 92 | // wait for co-processor to be ready 93 | while(!(ENCCS & ENCCS_RDY)) 94 | ; 95 | 96 | for(bufp= 0 ; bufp < len ; bufp += 16) 97 | { 98 | // prepare DMA for transfer 99 | aesdmai->srcAddrH = (u8) ((u16) (inbuf + bufp) >> 8); 100 | aesdmai->srcAddrL = (u8) ((u16) (inbuf + bufp) & 0xff); 101 | aesdmao->destAddrH = (u8) ((u16) (outbuf + bufp) >> 8); 102 | aesdmao->destAddrL = (u8) ((u16) (outbuf + bufp) & 0xff); 103 | DMAARM |= (aesdmaarmi | aesdmaarmo); 104 | NOP(); NOP(); 105 | 106 | // start co-processor 107 | // CBC-MAC is special - do last block as CBC to generate the final MAC 108 | // (note that all preceding blocks do not generate any output, so only 109 | // the first output block is significant. care should also be taken not 110 | // to transmit any other blocks as they may contain original plaintext 111 | // e.g. if encryption is being done in-place). 112 | // for clarity: the output of CBC-MAC will always only be the initial 113 | // 128 bits of the output buffer, regardless of message length. 114 | if((mode & ENCCS_MODE_CBCMAC) && bufp == len - 16) 115 | ENCCS = ENCCS_MODE_CBC | command | ENCCS_ST; 116 | else 117 | ENCCS = mode | command | ENCCS_ST; 118 | 119 | // wait for co-processor to finish 120 | while(!(ENCCS & ENCCS_RDY)) 121 | ; 122 | } 123 | } 124 | 125 | -------------------------------------------------------------------------------- /firmware/cc1111_vcomdesc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - USB descriptors 3 | * 4 | * Adapted from AltOS code by Fergus Noble (c) 2011 5 | * AltOS code Copyright © 2009 Keith Packard 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 2 of the License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 | */ 20 | 21 | #include "cc1111.h" 22 | #include "cc1111_vcom.h" 23 | 24 | // USB descriptors in one giant block of bytes 25 | __code __at(0x00aa) u8 usb_descriptors [] = 26 | { 27 | // Device descriptor 28 | 0x12, 29 | USB_DESC_DEVICE, 30 | LE_WORD(0x0110), // bcdUSB 31 | 0x02, // bDeviceClass 32 | 0x00, // bDeviceSubClass 33 | 0x00, // bDeviceProtocol 34 | USB_CONTROL_SIZE, // bMaxPacketSize 35 | LE_WORD(USB_VID), // idVendor 36 | LE_WORD(USB_PID), // idProduct 37 | LE_WORD(0x010), // bcdDevice 38 | 0x01, // iManufacturer 39 | 0x02, // iProduct 40 | 0x03, // iSerialNumber 41 | 0x01, // bNumConfigurations 42 | 43 | // Configuration descriptor 44 | 0x09, 45 | USB_DESC_CONFIGURATION, 46 | LE_WORD(67), // wTotalLength 47 | 0x02, // bNumInterfaces 48 | 0x01, // bConfigurationValue 49 | 0x00, // iConfiguration 50 | 0xC0, // bmAttributes 51 | 0x32, // bMaxPower 52 | 53 | // Control class interface 54 | 0x09, 55 | USB_DESC_INTERFACE, 56 | 0x00, // bInterfaceNumber 57 | 0x00, // bAlternateSetting 58 | 0x01, // bNumEndPoints 59 | 0x02, // bInterfaceClass 60 | 0x02, // bInterfaceSubClass 61 | 0x01, // bInterfaceProtocol, linux requires value of 1 for the cdc_acm module 62 | 0x00, // iInterface 63 | 64 | // Header functional descriptor 65 | 0x05, 66 | CS_INTERFACE, 67 | 0x00, // bDescriptor SubType Header 68 | LE_WORD(0x0110), // CDC version 1.1 69 | 70 | // Call management functional descriptor 71 | 0x05, 72 | CS_INTERFACE, 73 | 0x01, // bDescriptor SubType Call Management 74 | 0x01, // bmCapabilities = device handles call management 75 | 0x01, // bDataInterface call management interface number 76 | 77 | // ACM functional descriptor 78 | 0x04, 79 | CS_INTERFACE, 80 | 0x02, // bDescriptor SubType Abstract Control Management 81 | 0x02, // bmCapabilities = D1 (Set_line_Coding, Set_Control_Line_State, Get_Line_Coding and Serial_State) 82 | 83 | // Union functional descriptor 84 | 0x05, 85 | CS_INTERFACE, 86 | 0x06, // bDescriptor SubType Union Functional descriptor 87 | 0x00, // bMasterInterface 88 | 0x01, // bSlaveInterface0 89 | 90 | // Notification EP 91 | 0x07, 92 | USB_DESC_ENDPOINT, 93 | USB_INT_EP|0x80, // bEndpointAddress 94 | 0x03, // bmAttributes = intr 95 | LE_WORD(8), // wMaxPacketSize 96 | 0x0A, // bInterval 97 | 98 | // Data class interface descriptor 99 | 0x09, 100 | USB_DESC_INTERFACE, 101 | 0x01, // bInterfaceNumber 102 | 0x00, // bAlternateSetting 103 | 0x02, // bNumEndPoints 104 | 0x0A, // bInterfaceClass = data 105 | 0x00, // bInterfaceSubClass 106 | 0x00, // bInterfaceProtocol 107 | 0x00, // iInterface 108 | 109 | // Data EP OUT 110 | 0x07, 111 | USB_DESC_ENDPOINT, 112 | USB_OUT_EP, // bEndpointAddress 113 | 0x02, // bmAttributes = bulk 114 | LE_WORD(USB_OUT_SIZE), // wMaxPacketSize 115 | 0x00, // bInterval 116 | 117 | // Data EP in 118 | 0x07, 119 | USB_DESC_ENDPOINT, 120 | USB_IN_EP|0x80, // bEndpointAddress 121 | 0x02, // bmAttributes = bulk 122 | LE_WORD(USB_IN_SIZE), // wMaxPacketSize 123 | 0x00, // bInterval 124 | 125 | // String descriptors 126 | 0x04, 127 | USB_DESC_STRING, 128 | LE_WORD(0x0409), 129 | 130 | // iManufacturer 131 | USB_iManufacturer_LEN, 132 | USB_DESC_STRING, 133 | USB_iManufacturer_UCS2, 134 | 135 | // iProduct 136 | USB_iProduct_LEN, 137 | USB_DESC_STRING, 138 | USB_iProduct_UCS2, 139 | 140 | // iSerial 141 | USB_iSerial_LEN, 142 | USB_DESC_STRING, 143 | USB_iSerial_UCS2, 144 | 145 | // Terminating zero 146 | 0 147 | }; 148 | -------------------------------------------------------------------------------- /firmware/chipcon_dma.c: -------------------------------------------------------------------------------- 1 | #include "cc1110-ext.h" 2 | #include "chipcon_dma.h" 3 | #include "global.h" 4 | #include 5 | 6 | // Because the CC1111 only has two sets of SFRs for pointing at DMA configs (DMA0CFG for DMA channel 0 7 | // and DMA1CFG for DMA channels 1-4), 1-4 must be allocated in contiguous memory so the DMA controller 8 | // can find them based on their offsets. We therefore allocate memory for the desired number of channels 9 | // here and then point at them in the main code. For consistency we include channel 0 even though this 10 | // isn't strictly necessary. 11 | // 12 | // example: 13 | // 14 | // __xdata u8 my_dma_usb_chan, my_dma_usb_arm; 15 | // __xdata DMA_DESC *my_dma_usb_desc; 16 | // 17 | // my_dma_usb_chan= getDMA(); 18 | // my_dma_usb_arm= (DMAARM0 << my_dma_usb_chan); 19 | // my_dma_usb_desc= &dma_configs[my_dma_usb_chan]; 20 | // my_dma_usb_desc->srcAddrH= 0xde; //USBF5 == 0xde2a 21 | // my_dma_usb_desc->srcAddrL= 0x2a; 22 | // DMAARM |= my_dma_usb_arm; 23 | // etc. 24 | // 25 | 26 | __xdata DMA_DESC dma_configs[DMA_CHANNELS]; 27 | __data u8 dma_channels= 0; 28 | 29 | void initDMA(void) 30 | { 31 | if(DMA_CHANNELS) 32 | { 33 | DMA0CFGH = ((u16)(&dma_configs[0]))>>8; 34 | DMA0CFGL = ((u16)(&dma_configs[0]))&0xff; 35 | } 36 | if(DMA_CHANNELS > 1) 37 | { 38 | DMA1CFGH = ((u16)(&dma_configs[1]))>>8; 39 | DMA1CFGL = ((u16)(&dma_configs[1]))&0xff; 40 | } 41 | // FIXME: is this necessary or is new memory already 0 filled? 42 | memset(dma_configs,'\0',sizeof(DMA_DESC)*DMA_CHANNELS); 43 | } 44 | 45 | // allocate next DMA channel. return 0xff if none left. 46 | u8 getDMA(void) 47 | { 48 | if(dma_channels == DMA_CHANNELS) 49 | return 0xff; 50 | else 51 | return dma_channels++; 52 | } 53 | -------------------------------------------------------------------------------- /firmware/chipcon_usbdebug.c: -------------------------------------------------------------------------------- 1 | #include "chipcon_usb.h" 2 | 3 | /************************************************************************************************* 4 | * debug stuff. slows executions. * 5 | ************************************************************************************************/ 6 | /* sends a debug message up to the python code to be spit out on stderr */ 7 | void debugx(__xdata u8* __xdata text) 8 | { 9 | u16 len = 0; 10 | __xdata u8* __xdata ptr = text; 11 | while (*ptr++ != 0) 12 | len ++; 13 | txdata(0xfe, 0xf0, len, (__xdata u8*)text); 14 | } 15 | 16 | void debug(__code u8* __xdata text) 17 | { 18 | u16 len = 0; 19 | __code u8* __xdata ptr = text; 20 | while (*ptr++ != 0) 21 | len ++; 22 | txdata(0xfe, 0xf0, len, (__xdata u8*)text); 23 | } 24 | 25 | void debughex(__xdata u8 num) 26 | { 27 | txdata(0xfe, DEBUG_CMD_HEX, 1, (__xdata u8*)&num); 28 | } 29 | 30 | void debughex16(__xdata u16 num) 31 | { 32 | txdata(0xfe, DEBUG_CMD_HEX16, 2, (__xdata u8*)&num); 33 | } 34 | 35 | void debughex32(__xdata u32 num) 36 | { 37 | txdata(0xfe, DEBUG_CMD_HEX32, 4, (__xdata u8*)&num); 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /firmware/global.c: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | // used for debugging and tracing execution. see client's ".getDebugCodes()" 4 | __xdata u8 lastCode[2]; 5 | __xdata u32 clock; 6 | 7 | 8 | 9 | void sleepMillis(int ms) 10 | { 11 | int j; 12 | while (--ms > 0) 13 | { 14 | for (j=0; j 0) ; 25 | } 26 | 27 | void blink_binary_baby_lsb(u16 num, char bits) 28 | { 29 | LED = 1; 30 | sleepMillis(1000); 31 | LED = 0; 32 | sleepMillis(500); 33 | bits -= 1; // 16 bit numbers needs to start on bit 15, etc.... 34 | 35 | for (; bits>=0; bits--) 36 | { 37 | if (num & 1) 38 | { 39 | sleepMillis(25); 40 | LED = 1; 41 | sleepMillis(550); 42 | LED = 0; 43 | sleepMillis(25); 44 | } 45 | else 46 | { 47 | sleepMillis(275); 48 | LED = 1; 49 | sleepMillis(50); 50 | LED = 0; 51 | sleepMillis(275); 52 | } 53 | num = num >> 1; 54 | } 55 | LED = 0; 56 | sleepMillis(1000); 57 | } 58 | 59 | /* 60 | void blink_binary_baby_msb(u16 num, char bits) 61 | { 62 | LED = 1; 63 | sleepMillis(1500); 64 | LED = 0; 65 | sleepMillis(100); 66 | bits -= 1; // 16 bit numbers needs to start on bit 15, etc.... 67 | 68 | for (; bits>=0; bits--) 69 | { 70 | if (num & (1<0;n--) 93 | { 94 | tst = *s1 - *s2; 95 | if (tst) 96 | return tst; 97 | s1++; 98 | s2++; 99 | } 100 | return 0; 101 | } 102 | 103 | void clock_init(void) 104 | { 105 | // SET UP CPU SPEED! USE 26MHz for CC1110 and 24MHz for CC1111 106 | // Set the system clock source to HS XOSC and max CPU speed, 107 | // ref. [clk]=>[clk_xosc.c] 108 | SLEEP &= ~SLEEP_OSC_PD; 109 | while( !(SLEEP & SLEEP_XOSC_S) ); 110 | CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1; 111 | while (CLKCON & CLKCON_OSC); 112 | SLEEP |= SLEEP_OSC_PD; 113 | while (!IS_XOSC_STABLE()); 114 | 115 | // FIXME: this should be defined so it works with 24/26mhz 116 | // setup TIMER 1 117 | // free running mode 118 | // time freq: 187.50 for cc1111 / 203.125kHz for cc1110 119 | CLKCON &= 0xc7; //( ~ 0b00111000); - clearing out TICKSPD freq = 24mhz on cc1111, 26mhz on cc1110 120 | 121 | T1CTL |= T1CTL_DIV_128; // T1 running at 187.500 kHz 122 | T1CTL |= T1CTL_MODE_FREERUN; 123 | T1IE = 1; 124 | 125 | } 126 | 127 | 128 | 129 | /* initialize the IO subsystems for the appropriate dongles */ 130 | void io_init(void) 131 | { 132 | #ifdef IMME 133 | 134 | #ifdef IMMEDONGLE // CC1110 on IMME pink dongle 135 | // IM-ME Dongle. It's a CC1110, so no USB stuffs. Still, a bit of stuff to init for talking 136 | // to it's own Cypress USB chip 137 | P0SEL |= (BIT5 | BIT3); // Select SCK and MOSI as SPI 138 | P0DIR |= BIT4 | BIT6; // SSEL and LED as output 139 | P0 &= ~(BIT4 | BIT2); // Drive SSEL and MISO low 140 | 141 | P1IF = 0; // clear P1 interrupt flag 142 | IEN2 |= IEN2_P1IE; // enable P1 interrupt 143 | P1IEN |= BIT1; // enable interrupt for P1.1 144 | 145 | P1DIR |= BIT0; // P1.0 as output, attention line to cypress 146 | P1 &= ~BIT0; // not ready to receive 147 | #else // full blown IMME with screen and keyboard 148 | 149 | //Disable WDT 150 | IEN2&=~IEN2_WDTIE; 151 | IEN0&=~EA; 152 | setIOPorts(); 153 | configureSPI(); 154 | LCDReset(); 155 | 156 | //Startup display. 157 | setDisplayStart(0); 158 | SSN = LOW; 159 | setNormalReverse(0); 160 | erasescreen(); 161 | drawstr(0,0, "IMME SNIFF v0.1"); 162 | SSN = HIGH; 163 | 164 | //immeLCDInitScreen(); 165 | //sleepMillis(100); 166 | 167 | #endif 168 | #else // CC1111 169 | #ifdef DONSDONGLES 170 | // CC1111 USB Dongle 171 | // turn on LED and BUTTON 172 | P1DIR |= 3; 173 | // Activate BUTTON - Do we need this? 174 | //CC1111EM_BUTTON = 1; 175 | 176 | #elif defined YARDSTICKONE 177 | // USB, LED1, LED2, and LED3 178 | P1DIR |= 0xf; 179 | // amplifer configuration pins 180 | P2DIR |= 0x19; 181 | // initial states 182 | LED2 = 0; 183 | LED3 = 0; 184 | TX_AMP_EN = 0; 185 | RX_AMP_EN = 0; 186 | AMP_BYPASS_EN = 1; 187 | 188 | #else 189 | // CC1111 USB (ala Chronos watch dongle), we just need LED 190 | P1DIR |= 3; 191 | 192 | #endif // CC1111 193 | 194 | #ifndef VIRTUAL_COM 195 | // Turn off LED 196 | LED = 0; 197 | #endif 198 | 199 | #endif // conditional 200 | } 201 | 202 | 203 | void t1IntHandler(void) __interrupt T1_VECTOR // interrupt handler should trigger on T1 overflow 204 | { 205 | clock ++; 206 | } 207 | 208 | -------------------------------------------------------------------------------- /firmware/immedisplay.c: -------------------------------------------------------------------------------- 1 | /* 2 | * IM-Me display functions 3 | * 4 | * Copyright 2010 Dave 5 | * http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html 6 | * 7 | * Copyright 2010 Michael Ossmann 8 | * 9 | * Copyright 2011 atlas 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2, or (at your option) 14 | * any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program; see the file COPYING. If not, write to 23 | * the Free Software Foundation, Inc., 51 Franklin Street, 24 | * Boston, MA 02110-1301, USA. 25 | */ 26 | 27 | #include 28 | #include "cc1110-ext.h" 29 | #include "bits.h" 30 | #include "immedisplay.h" 31 | #include "immekeys.h" 32 | #include "imme5x7.h" 33 | 34 | 35 | void setIOPorts() { 36 | //No need to set PERCFG or P2DIR as default values on reset are fine 37 | P0SEL |= (BIT5 | BIT3 ); // set SCK and MOSI as peripheral outputs 38 | P0DIR |= BIT4 | BIT2; // set SSN and A0 as outputs 39 | P1DIR |= BIT1; // set LCDRst as output 40 | P2DIR = BIT3 | BIT4; // set LEDs as outputs 41 | //LED_GREEN = LOW; // Turn the Green LED on (LEDs driven by reverse logic: 0 is ON) 42 | } 43 | 44 | void configureSPI() { 45 | U0CSR = 0; //Set SPI Master operation 46 | U0BAUD = SPI_BAUD_M; // set Mantissa 47 | U0GCR = U0GCR_ORDER | SPI_BAUD_E; // set clock on 1st edge, -ve clock polarity, MSB first, and exponent 48 | } 49 | void tx(unsigned char ch) { 50 | U0DBUF = ch; 51 | while(!(U0CSR & U0CSR_TX_BYTE)); // wait for byte to be transmitted 52 | U0CSR &= ~U0CSR_TX_BYTE; // Clear transmit byte status 53 | } 54 | 55 | void txData(unsigned char ch) { 56 | A0 = HIGH; 57 | tx(ch); 58 | } 59 | 60 | void txCtl(unsigned char ch){ 61 | A0 = LOW; 62 | tx(ch); 63 | } 64 | 65 | void LCDReset(void) { 66 | LCDRst = LOW; // hold down the RESET line to reset the display 67 | sleepMillis(1); 68 | LCDRst = HIGH; 69 | SSN = LOW; 70 | // send the initialisation commands to the LCD display 71 | txCtl(0xe2); // RESET cmd 72 | txCtl(0x24); // set internal resistor ratio 73 | txCtl(0x81); // set Vol Control 74 | txCtl(0x60); // set Vol Control - ctd 75 | txCtl(0xe6); // ?? -- don't know what this command is 76 | txCtl(0x00); // ?? -- don't know what this command is 77 | txCtl(0x2f); // set internal PSU operating mode 78 | txCtl(0xa1); // LCD bias set 79 | txCtl(0xaf); // Display ON 80 | txCtl(0xa4); // Normal (not all pixels) mode 81 | SSN = HIGH; 82 | } 83 | 84 | void LCDPowerSave() { // not tested yet; taken from spi trace 85 | txCtl(0xac); // static indicator off cmd 86 | txCtl(0xae); // LCD off 87 | txCtl(0xa5); // Display all Points on cmd = Power Save when following LCD off 88 | } 89 | 90 | void setCursor(unsigned char row, unsigned char col) { 91 | txCtl(0xb0 + row); // set cursor row 92 | txCtl(0x00 + (col & 0x0f)); // set cursor col low 93 | txCtl(0x10 + ( (col>>4) & 0x0f)); // set cursor col high 94 | } 95 | 96 | void setDisplayStart(unsigned char start) { 97 | txCtl(0x40 | (start & 0x3f)); // set Display start address 98 | } 99 | 100 | void setNormalReverse(unsigned char normal) { // 0 = Normal, 1 = Reverse 101 | txCtl(0xa6 | (normal & 0x01) ); 102 | } 103 | 104 | /* clear all LCD pixels */ 105 | void clear() { 106 | u8 row; 107 | u8 col; 108 | 109 | SSN = LOW; 110 | setDisplayStart(0); 111 | 112 | /* normal display mode (not inverted) */ 113 | setNormalReverse(0); 114 | 115 | for (row = 0; row <= 9; row++) { 116 | setCursor(row, 0); 117 | for (col = 0; col < WIDTH; col++) 118 | txData(0x00); 119 | } 120 | 121 | SSN = HIGH; 122 | } 123 | 124 | /* sdcc provides printf if we provide this */ 125 | void putchar(char c) { 126 | u8 i; 127 | 128 | c &= 0x7f; 129 | 130 | if (c >= FONT_OFFSET) { 131 | for (i = 0; i < FONT_WIDTH; i++) 132 | txData(font[c - FONT_OFFSET][i]); 133 | txData(0x00); 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /firmware/immefont.c: -------------------------------------------------------------------------------- 1 | #include "immeterm.h" 2 | 3 | 4 | static const u8 font[fontSIZE]={ 5 | //0x20 is a space, handy 6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //space 7 | 0x00, 0x5f, 0x5f, 0x00, 0x00, 0x00, //! 8 | 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, //" 9 | 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00, //# 10 | 0,0,0,0,0,0, 11 | 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, //% 12 | 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, //' 13 | 0,0,0,0,0,0, 14 | //28 15 | 0,0,0,0,0,0, 16 | 0,0,0,0,0,0, 17 | 0,0,0,0,0,0, 18 | 0,0,0,0,0,0, 19 | 0,0,0,0,0,0, 20 | 0,0,0,0,0,0, 21 | 0,0,0,0,0,0, 22 | 0,0,0,0,0,0, 23 | 24 | //0x30 in ASCII 25 | //0 26 | 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00, //0 27 | 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, //1 28 | 0x42, 0x61, 0x51, 0x49, 0x46, 0x00, //2 29 | 0x21, 0x41, 0x45, 0x4b, 0x31, 0x00, //3 30 | 0x18, 0x14, 0x12, 0x7f, 0x10, 0x00, //4 31 | 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, //5 32 | 0x3c, 0x4a, 0x49, 0x49, 0x30, 0x00, //6 33 | 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, //7 34 | 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, //8 35 | 0x06, 0x49, 0x49, 0x29, 0x1e, 0x00, //9 36 | 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, //: 37 | 0x00, 0x56, 0x36, 0x00, 0x00, 0x00, //; 38 | 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, //< 39 | 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, //= 40 | 0x41, 0x22, 0x14, 0x08, 0x00, 0x00, //> 41 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 42 | 0x3e, 0x41, 0x5d, 0x49, 0x4f, 0x00, //@ 43 | 44 | //Uppercase letters begin at 0x41 45 | 0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00, //A 46 | 0x7f, 0x49, 0x49, 0x49, 0x36, 0x00, //B 47 | 0x3e, 0x41, 0x41, 0x41, 0x22, 0x00, //C 48 | 0x7f, 0x41, 0x41, 0x41, 0x3e, 0x00, //D 49 | 0x7f, 0x49, 0x49, 0x49, 0x41, 0x00, //E 50 | 0x7f, 0x09, 0x09, 0x09, 0x01, 0x00, //F 51 | 0x3e, 0x41, 0x49, 0x49, 0x79, 0x00, //G 52 | 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, //H 53 | 0x00, 0x41, 0x7f, 0x41, 0x00, 0x00, //I 54 | 0x30, 0x40, 0x40, 0x40, 0x3f, 0x00, //J 55 | 0x7f, 0x08, 0x14, 0x22, 0x41, 0x00, //K 56 | 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, //L 57 | 0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00, //M 58 | 0x7f, 0x04, 0x08, 0x10, 0x7f, 0x00, //N 59 | 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00, //O 60 | 0x7f, 0x09, 0x09, 0x09, 0x06, 0x00, //P 61 | 0x3c, 0x42, 0x52, 0x3c, 0x40, 0x00, //Q 62 | 0x7f, 0x09, 0x19, 0x29, 0x46, 0x00, //R 63 | 0x46, 0x49, 0x49, 0x49, 0x31, 0x00, //S 64 | 0x01, 0x01, 0x7f, 0x01, 0x01, 0x00, //T 65 | 0x7f, 0x40, 0x40, 0x40, 0x7f, 0x00, //U 66 | 0x07, 0x18, 0x60, 0x18, 0x07, 0x00, //V 67 | 0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00, //W 68 | 0x63, 0x1c, 0x08, 0x1c, 0x63, 0x00, //X 69 | 0x03, 0x04, 0x7c, 0x04, 0x03, 0x00, //Y 70 | 0x61, 0x61, 0x51, 0x49, 0x47, 0x00, //Z FIXME 71 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 72 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //\ 73 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //] 74 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //^ 75 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //_ 76 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //` 77 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //a 78 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //b 79 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //c 80 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //d 81 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //e 82 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //f 83 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //g 84 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //h 85 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //i 86 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //j 87 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //k 88 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //l 89 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //m 90 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //n 91 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //o 92 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //p 93 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //q 94 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //r 95 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //s 96 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //t 97 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //u 98 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //v 99 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //w 100 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //x 101 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //y 102 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //z 103 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //{ 104 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //| 105 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //} 106 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //~ 107 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 108 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 109 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 110 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 111 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 112 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 113 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 114 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 115 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 116 | 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, //? 117 | 118 | 119 | 0 120 | }; 121 | 122 | 123 | 124 | void putch(char ch){ 125 | u16 start; 126 | u8 i; 127 | 128 | if(!ch){ 129 | for(i=0;i<7;i++) 130 | txData(0x00); 131 | return; 132 | } 133 | 134 | //uppercase 135 | if(ch>='a' && ch<='z') 136 | ch-=('a'-'A'); 137 | 138 | start=ch-ASCIIOFFSET; 139 | start*=6; 140 | for(i=0;i<6;i++) 141 | txData(font[start+i]); 142 | } 143 | -------------------------------------------------------------------------------- /firmware/immekeys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2010 Travis Goodspeed, Michael Ossmann 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2, or (at your option) 7 | * any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; see the file COPYING. If not, write to 16 | * the Free Software Foundation, Inc., 51 Franklin Street, 17 | * Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #include 21 | #include "cc1110-ext.h" 22 | #include "immekeys.h" 23 | #include "bits.h" 24 | 25 | static u8 active_key; 26 | 27 | //8 rows, 10 columns 28 | const u8 keychars[]={ 29 | //gnd 0_1 1_2 1_3 1_4 1_5 1_6 1_7 0_6 0_7 30 | 31 | //row 0, gnd 32 | 0x00, 0x00, 'O', 'K', 'N', 'M', KPWR, 'P', 0x00, 0x00, 33 | //row 1 34 | 0x00, 0x00, 'Y', 'G', 'C', ' ', '<', ',', KMNU, '>', 35 | //row 2 36 | 0x00, 0x00, 0x00, 'Q', 'W', 'E', 'R', 'T', 'U', 'I', 37 | //row 3 38 | 0x00, 0x00, 0x00, 0x00, 'A', 'S', 'D', 'F', 'H', 'J', 39 | //row 4 40 | 0x00, 0x00, 0x00, 0x00, 0x00, KCAP, 'Z', 'X', 'V', 'B', 41 | //row 5 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KSPK, KALT, KONL, KBACK, 43 | //row 6 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KBYE, KDWN, '^', 45 | //row 7 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '\n', 'L' 47 | }; 48 | 49 | #define KEY(row,col) keychars[row*10+col] 50 | 51 | u8 realkeyscan(){ 52 | u8 row, col; 53 | 54 | //All input 55 | P0DIR &= ~(BIT1+BIT6+BIT7); 56 | P1DIR &= ~(BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); 57 | P0 |= BIT1+BIT6+BIT7; 58 | P1 |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; 59 | 60 | for(row=0;row<8;row++){ 61 | col=row;//nothing 62 | switch(row){ 63 | case 0://ground 64 | default: 65 | break; 66 | case 1: //P0_1 67 | P0DIR|=BIT1; 68 | P0&=~BIT1; 69 | break; 70 | case 2: //P1_2 71 | P1DIR|=BIT2; 72 | P1&=~BIT2; 73 | break; 74 | case 3: //P1_3 75 | P1DIR|=BIT3; 76 | P1&=~BIT3; 77 | break; 78 | case 4: //p1_4 79 | P1DIR|=BIT4; 80 | P1&=~BIT4; 81 | break; 82 | case 5: //p1_5 83 | P1DIR|=BIT5; 84 | P1&=~BIT5; 85 | break; 86 | case 6: //P1_6 87 | P1DIR|=BIT6; 88 | P1&=~BIT6; 89 | break; 90 | case 7: //P1_7 91 | P1DIR|=BIT7; 92 | P1&=~BIT7; 93 | break; 94 | } 95 | 96 | if(~P0&BIT1) col=1; 97 | if(~P1&BIT2) col=2; 98 | if(~P1&BIT3) col=3; 99 | if(~P1&BIT4) col=4; 100 | if(~P1&BIT5) col=5; 101 | if(~P1&BIT6) col=6; 102 | if(~P1&BIT7) col=7; 103 | if(~P0&BIT6) col=8; 104 | if(~P0&BIT7) col=9; 105 | 106 | if(col!=row) return KEY(row,col); 107 | } 108 | 109 | return '\0'; 110 | } 111 | 112 | //! Returns the debounced character press. 113 | u8 keyscan(){ 114 | u8 key=realkeyscan(); 115 | //debounce 116 | while(key!=realkeyscan()) 117 | key=realkeyscan(); 118 | 119 | //All input 120 | P0DIR &= ~(BIT1+BIT6+BIT7); 121 | P1DIR &= ~(BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); 122 | P0 |= BIT1+BIT6+BIT7; 123 | P1 |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; 124 | 125 | return key; 126 | } 127 | 128 | /* non-blocking check for a keypress */ 129 | u8 getkey() { 130 | u8 key = keyscan(); 131 | 132 | /* keep track of key currently pressed to avoid rapid repeating */ 133 | if (key != active_key) 134 | active_key = key; 135 | else 136 | key = 0x00; 137 | 138 | return key; 139 | } 140 | -------------------------------------------------------------------------------- /firmware/include/FHSS.h: -------------------------------------------------------------------------------- 1 | #ifndef FHSS_H 2 | #define FHSS_H 3 | 4 | #define FHSS_SET_CHANNELS 0x10 5 | #define FHSS_NEXT_CHANNEL 0x11 6 | #define FHSS_CHANGE_CHANNEL 0x12 7 | #define FHSS_SET_MAC_THRESHOLD 0x13 8 | #define FHSS_GET_MAC_THRESHOLD 0x14 9 | #define FHSS_SET_MAC_DATA 0x15 10 | #define FHSS_GET_MAC_DATA 0x16 11 | #define FHSS_XMIT 0x17 12 | #define FHSS_GET_CHANNELS 0x18 13 | 14 | #define FHSS_SET_STATE 0x20 15 | #define FHSS_GET_STATE 0x21 16 | #define FHSS_START_SYNC 0x22 17 | #define FHSS_START_HOPPING 0x23 18 | #define FHSS_STOP_HOPPING 0x24 19 | #define FHSS_SET_MAC_PERIOD 0x25 20 | 21 | #define MAC_STATE_NONHOPPING 0 22 | #define MAC_STATE_DISCOVERY 1 23 | #define MAC_STATE_SYNCHING 2 24 | #define MAC_LAST_NONHOPPING_STATE MAC_STATE_SYNCHING 25 | 26 | #define MAC_STATE_SYNCHED 3 27 | #define MAC_STATE_SYNC_MASTER 4 28 | #define MAC_STATE_SYNCINGMASTER 5 29 | #define MAC_STATE_LONG_XMIT 6 30 | #define MAC_STATE_LONG_XMIT_FAIL 7 31 | 32 | 33 | // spectrum analysis defines 34 | // application and command 35 | #define APP_SPECAN 0x43 36 | #define SPECAN_QUEUE 0x1 37 | 38 | // FHSSNIC commands to start and stop SPECAN mode 39 | #define RFCAT_START_SPECAN 0x40 40 | #define RFCAT_STOP_SPECAN 0x41 41 | 42 | // MAC_STATEs for SPECAN 43 | #define MAC_STATE_PREP_SPECAN 0x40 44 | #define MAC_STATE_SPECAN 0x41 45 | 46 | 47 | // MAC layer defines 48 | #define MAX_CHANNELS 880 49 | #define MAX_TX_MSGS 2 50 | #define MAX_TX_MSGLEN 240 // must match RF_MAX_TX_CHUNK in rflib/chipcon_nic.py 51 | // and be divisible by 16 for crypto operations 52 | #define MAX_SYNC_WAIT 10 //seconds... need to true up with T1/clock 53 | 54 | #define MAC_TIMER_STATIC_DIFF 6 55 | #define FHSS_TX_SLEEP_DELAY 25 56 | 57 | #define DEFAULT_NUM_CHANS 83 58 | #define DEFAULT_NUM_CHANHOPS 83 59 | 60 | void begin_hopping(__xdata u8 T2_offset); 61 | void stop_hopping(void); 62 | 63 | void PHY_set_channel(__xdata u16 chan); 64 | void MAC_initChannels(); 65 | void MAC_sync(__xdata u16 netID); 66 | void MAC_set_chanidx(__xdata u16 chanidx); 67 | u8 MAC_tx(__xdata u8* __xdata message, __xdata u8 len); 68 | void MAC_rx_handle(__xdata u8 len, __xdata u8* __xdata message); 69 | u8 MAC_getNextChannel(); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /firmware/include/bits.h: -------------------------------------------------------------------------------- 1 | #define BIT0 0x01 2 | #define BIT1 0x02 3 | #define BIT2 0x04 4 | #define BIT3 0x08 5 | #define BIT4 0x10 6 | #define BIT5 0x20 7 | #define BIT6 0x40 8 | #define BIT7 0x80 9 | -------------------------------------------------------------------------------- /firmware/include/bootloader.h: -------------------------------------------------------------------------------- 1 | void run_bootloader(void); 2 | -------------------------------------------------------------------------------- /firmware/include/cc1111.h: -------------------------------------------------------------------------------- 1 | #ifndef CC1111_H 2 | #define CC1111_H 3 | 4 | #include "cc1110-ext.h" 5 | #include 6 | 7 | 8 | 9 | 10 | SFRX(USBADDR, 0xDE00); // Function Address 11 | SFRX(USBPOW, 0xDE01); // Power / Control Register 12 | SFRX(USBIIF, 0xDE02); // IN Endpoints and EP0 Interrupt Flags 13 | SFRX(USBOIF, 0xDE04); // OUT Endpoints Interrupt Flags 14 | SFRX(USBCIF, 0xDE06); // Common USB Interrupt Flags 15 | SFRX(USBIIE, 0xDE07); // IN Endpoints and EP0 Interrupt Enable Mask 16 | SFRX(USBOIE, 0xDE09); // Out Endpoints Interrupt Enable Mask 17 | SFRX(USBCIE, 0xDE0B); // Common USB Interrupt Enable Mask 18 | SFRX(USBFRML, 0xDE0C); // Current Frame Number (Low byte) 19 | SFRX(USBFRMH, 0xDE0D); // Current Frame Number (High byte) 20 | SFRX(USBINDEX, 0xDE0E); // Selects current endpoint. Make sure this register has the required value before any of the following registers are accessed. This register must be set to a value in the range 0 - 5. 21 | 22 | SFRX(USBMAXI, 0xDE10); // Max. packet size for IN endpoint, 1-5 23 | SFRX(USBCS0, 0xDE11); // EP0 Control and Status (USBINDEX = 0), 0 24 | SFRX(USBCSIL, 0xDE11); // IN EP{1 - 5} Control and Status Low, 1-5 25 | SFRX(USBCSIH, 0xDE12); // IN EP{1 - 5} Control and Status High, 1-5 26 | SFRX(USBMAXO, 0xDE13); // Max. packet size for OUT endpoint, 1-5 27 | SFRX(USBCSOL, 0xDE14); // OUT EP{1 - 5} Control and Status Low, 1-5 28 | SFRX(USBCSOH, 0xDE15); // OUT EP{1 - 5} Control and Status High, 1-5 29 | SFRX(USBCNT0, 0xDE16); // Number of received bytes in EP0 FIFO (USBINDEX = 0), 0 30 | SFRX(USBCNTL, 0xDE16); // Number of bytes in OUT FIFO Low, 1-5 31 | SFRX(USBCNTH, 0xDE17); // Number of bytes in OUT FIFO High, 1-5 32 | 33 | 34 | SFRX(USBF0, 0xDE20); // Endpoint 0 FIFO 35 | SFRX(USBF1, 0xDE22); // Endpoint 1 FIFO 36 | SFRX(USBF2, 0xDE24); // Endpoint 2 FIFO 37 | SFRX(USBF3, 0xDE26); // Endpoint 3 FIFO 38 | SFRX(USBF4, 0xDE28); // Endpoint 4 FIFO 39 | SFRX(USBF5, 0xDE2A); // Endpoint 5 FIFO 40 | 41 | 42 | 43 | 44 | //#define P0IFG_USB_RESUME 0x80 //rw0 45 | 46 | // SBIT(USBIF, 0xE8, 0); // USB Interrupt Flag 47 | 48 | #include "chipcon_usb.h" 49 | #include "chipcon_dma.h" 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /firmware/include/cc1111_aes.h: -------------------------------------------------------------------------------- 1 | #ifndef CC1111AES_H 2 | #define CC1111AES_H 3 | /************************************************************************************************* 4 | * AES helpers * 5 | ************************************************************************************************/ 6 | 7 | #include 8 | 9 | void initAES(void); 10 | void setAES(__xdata u8* __xdata buf, __xdata u8 command, __xdata u8 mode); 11 | __xdata u16 padAES(__xdata u8* __xdata inbuf, __xdata u16 len); 12 | void encAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 mode); 13 | void decAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 mode); 14 | void doAES(__xdata u8* __xdata inbuf, __xdata u8* __xdata outbuf, __xdata u16 len, __xdata u8 command, __xdata u8 mode); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /firmware/include/cc1111_vcom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CC Bootloader - USB CDC class (serial) driver 3 | * 4 | * Adapted from AltOS code by Fergus Noble (c) 2011 5 | * AltOS code Copyright © 2009 Keith Packard 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; version 2 of the License. 10 | * 11 | * This program is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 | */ 20 | 21 | #ifndef _USB_H_ 22 | #define _USB_H_ 23 | 24 | #include "cc1111.h" 25 | #include "types.h" 26 | 27 | // External interface 28 | 29 | void initUSB(); 30 | void usbProcessEvents(); 31 | void vcom_disable(); 32 | void vcom_enable(); 33 | char vcom_getchar(); 34 | void vcom_putchar(char c); 35 | void vcom_flush(); 36 | 37 | void vcom_putstr(char* __xdata buff); 38 | void vcom(char* __xdata buff); 39 | //void vcom_up(); 40 | //void vcom_down(); 41 | void usb_up(void); 42 | void usb_down(void); 43 | 44 | //void txdata(u8 app, u8 cmd, u16 len, __xdata u8* dataptr); 45 | 46 | // End external interface 47 | 48 | #define USB_SETUP_DIR_MASK (0x01 << 7) 49 | #define USB_SETUP_TYPE_MASK (0x03 << 5) 50 | #define USB_SETUP_RECIP_MASK (0x1f) 51 | 52 | #define USB_DIR_OUT 0 53 | #define USB_DIR_IN (1 << 7) 54 | 55 | #define USB_TYPE_STANDARD 0 56 | #define USB_TYPE_CLASS (1 << 5) 57 | #define USB_TYPE_VENDOR (2 << 5) 58 | #define USB_TYPE_RESERVED (3 << 5) 59 | 60 | #define USB_RECIP_DEVICE 0 61 | #define USB_RECIP_INTERFACE 1 62 | #define USB_RECIP_ENDPOINT 2 63 | #define USB_RECIP_OTHER 3 64 | 65 | // Standard requests 66 | #define USB_REQ_GET_STATUS 0x00 67 | #define USB_REQ_CLEAR_FEATURE 0x01 68 | #define USB_REQ_SET_FEATURE 0x03 69 | #define USB_REQ_SET_ADDRESS 0x05 70 | #define USB_REQ_GET_DESCRIPTOR 0x06 71 | #define USB_REQ_SET_DESCRIPTOR 0x07 72 | #define USB_REQ_GET_CONFIGURATION 0x08 73 | #define USB_REQ_SET_CONFIGURATION 0x09 74 | #define USB_REQ_GET_INTERFACE 0x0A 75 | #define USB_REQ_SET_INTERFACE 0x0B 76 | #define USB_REQ_SYNCH_FRAME 0x0C 77 | 78 | //#define USB_DESC_DEVICE 1 79 | #define USB_DESC_CONFIGURATION 2 80 | //#define USB_DESC_STRING 3 81 | //#define USB_DESC_INTERFACE 4 82 | //#define USB_DESC_ENDPOINT 5 83 | //#define USB_DESC_DEVICE_QUALIFIER 6 84 | #define USB_DESC_OTHER_SPEED 7 85 | #define USB_DESC_INTERFACE_POWER 8 86 | 87 | #define USB_GET_DESC_TYPE(x) (((x)>>8)&0xFF) 88 | #define USB_GET_DESC_INDEX(x) ((x)&0xFF) 89 | 90 | #define USB_CONTROL_EP 0 91 | #define USB_INT_EP 1 92 | #define USB_OUT_EP 4 93 | #define USB_IN_EP 5 94 | #define USB_CONTROL_SIZE 32 95 | 96 | // Double buffer IN and OUT EPs, so each 97 | // gets half of the available space 98 | // 99 | // Ah, but USB bulk packets can only come in 8, 16, 32 and 64 100 | // byte sizes, so we'll use 64 for everything 101 | #define USB_IN_SIZE 64 102 | #define USB_OUT_SIZE 64 103 | 104 | #define USB_EP0_IDLE 0 105 | #define USB_EP0_DATA_IN 1 106 | #define USB_EP0_DATA_OUT 2 107 | 108 | #define LE_WORD(x) ((x)&0xFF),((u8) (((u16) (x))>>8)) 109 | 110 | // CDC definitions 111 | #define CS_INTERFACE 0x24 112 | #define CS_ENDPOINT 0x25 113 | 114 | #define SET_LINE_CODING 0x20 115 | #define GET_LINE_CODING 0x21 116 | #define SET_CONTROL_LINE_STATE 0x22 117 | 118 | // Data structure for GET_LINE_CODING / SET_LINE_CODING class requests 119 | struct usb_line_coding { 120 | unsigned long rate; 121 | unsigned char char_format; 122 | unsigned char parity; 123 | unsigned char data_bits; 124 | }; 125 | 126 | #define USB_READ_AGAIN ((char) -1) 127 | 128 | #define USB_VID 0xFFFE 129 | #define USB_PID 0x000A 130 | 131 | // iManufacturer 132 | #define USB_iManufacturer_LEN 0x10 133 | #define USB_iManufacturer_STRING "JobyGPS" 134 | #define USB_iManufacturer_UCS2 'J', 0, 'o', 0, 'b', 0, 'y', 0, 'G', 0, 'P', 0, 'S', 0 135 | // iProduct 136 | #define USB_iProduct_LEN 0x1C 137 | #define USB_iProduct_STRING "CC Bootloader" 138 | #define USB_iProduct_UCS2 'C', 0, 'C', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 139 | // iSerial 140 | #define USB_iSerial_LEN 0x0e 141 | #define USB_iSerial_STRING "000001" 142 | #define USB_iSerial_UCS2 '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '1', 0 143 | 144 | extern __code __at(0x00aa) unsigned char usb_descriptors[]; 145 | 146 | #endif // _USB_H_ 147 | -------------------------------------------------------------------------------- /firmware/include/cc1111rf.h: -------------------------------------------------------------------------------- 1 | #ifndef CC1111RF_H 2 | #define CC1111RF_H 3 | 4 | #include "cc1111.h" 5 | #include "global.h" 6 | 7 | // use DMA for RF? 8 | //#define RFDMA - nope. this has now died for InfiniteMode TX/RX. we need to 9 | // switch buffers mid-stream 10 | 11 | #define DMA_CFG_SIZE 8 12 | // BUFFER size must match RF_MAX_RX_BLOCK defined in rflib/cc1111client.py 13 | #define BUFFER_SIZE 512 14 | #define BUFFER_AMOUNT 2 15 | 16 | #define PKTCTRL0_LENGTH_CONFIG_INF (0x02) 17 | #define RF_MAX_TX_BLOCK (u16) 255 18 | 19 | #define RSSI_TIMEOUT_US 1500 20 | 21 | #define RF_STATE_RX 1 22 | #define RF_STATE_TX 2 23 | #define RF_STATE_IDLE 3 24 | 25 | #define RF_SUCCESS 0 26 | 27 | #define RF_DMA_VLEN_1 1<<5 28 | #define RF_DMA_VLEN_3 4<<5 29 | #define RF_DMA_LEN 0xfe 30 | #define RF_DMA_WORDSIZE16 1<<7 31 | #define RF_DMA_WORDSIZE8 0<<7 32 | #define RF_DMA_TMODE 0 33 | #define RF_DMA_TRIGGER 19 34 | #define RF_DMA_DST_INC 1<<4 35 | #define RF_DMA_SRC_INC 1<<6 36 | #define RF_DMA_IRQMASK_DI 0<<3 37 | #define RF_DMA_IRQMASK_EN 1<<3 38 | #define RF_DMA_M8 0<<2 39 | #define RF_DMA_M7 1<<2 40 | #define RF_DMA_PRIO_LOW 0<<1 41 | #define RF_DMA_PRIO_NOR 1<<1 42 | #define RF_DMA_PRIO_HIGH 1<<2 43 | 44 | #define FIRST_BUFFER 0 45 | #define SECOND_BUFFER 1 46 | #define RX_UNPROCESSED 0 47 | #define RX_PROCESSED 1 48 | 49 | /* Type for registers: 50 | NORMAL: registers are configured by client 51 | RECV: registers are set for receive 52 | XMIT: registers are set for transmit 53 | */ 54 | typedef enum{NORMAL,RECV,XMIT} register_e; 55 | 56 | /* Rx buffers */ 57 | extern volatile __xdata u8 rfRxCurrentBuffer; 58 | extern volatile __xdata u8 rfrxbuf[BUFFER_AMOUNT][BUFFER_SIZE]; 59 | extern volatile __xdata u16 rfRxCounter[BUFFER_AMOUNT]; 60 | extern volatile __xdata u8 rfRxProcessed[BUFFER_AMOUNT]; 61 | extern volatile __xdata u8 rfRxInfMode; 62 | extern volatile __xdata u16 rfRxTotalRXLen; 63 | extern volatile __xdata u16 rfRxLargeLen; 64 | /* Tx buffers */ 65 | extern volatile __xdata u8 *__xdata rftxbuf; 66 | extern volatile __xdata u8 rfTxBufCount; 67 | extern volatile __xdata u8 rfTxCurBufIdx; 68 | extern volatile __xdata u16 rfTxCounter; 69 | extern volatile __xdata u16 rfTxRepeatCounter; 70 | extern volatile __xdata u16 rfTxBufferEnd; 71 | extern volatile __xdata u16 rfTxRepeatLen; 72 | extern volatile __xdata u16 rfTxRepeatOffset; 73 | extern volatile __xdata u16 rfTxTotalTXLen; 74 | extern volatile __xdata u8 rfTxInfMode; 75 | 76 | extern volatile __xdata u16 rf_MAC_timer; 77 | extern volatile __xdata u16 rf_tLastRecv; 78 | 79 | // AES 80 | extern volatile __xdata u8 rfAESMode; 81 | 82 | extern volatile __xdata u8 rfAmpMode; 83 | extern __xdata u16 txTotal; // debugger 84 | 85 | extern volatile u8 rfif; 86 | 87 | void rfTxRxIntHandler(void) __interrupt RFTXRX_VECTOR; // interrupt handler should transmit or receive the next byte 88 | void rfIntHandler(void) __interrupt RF_VECTOR; // interrupt handler should trigger on rf events 89 | 90 | // set semi-permanent states 91 | void RxMode(void); // set defaults to return to RX and calls RFRX 92 | void TxMode(void); // set defaults to return to TX and calls RFTX 93 | void IdleMode(void); // set defaults to return to IDLE and calls RFOFF 94 | 95 | // set transient RF mode (like. NOW!) 96 | #ifdef YARDSTICKONE 97 | // enable or disable front-end amplifiers on YARD Stick One 98 | #define SET_TX_AMP_ON do { TX_AMP_EN = 1; RX_AMP_EN = 0; AMP_BYPASS_EN = 0; } while (0) 99 | #define SET_RX_AMP_ON do { TX_AMP_EN = 0; RX_AMP_EN = 1; AMP_BYPASS_EN = 0; } while (0) 100 | #define SET_AMP_OFF do { TX_AMP_EN = 0; RX_AMP_EN = 0; AMP_BYPASS_EN = 1; } while (0) 101 | #define SET_TX_AMP do { TX_AMP_EN = rfAmpMode; RX_AMP_EN = 0; AMP_BYPASS_EN = rfAmpMode^1; } while (0) 102 | #define SET_RX_AMP do { TX_AMP_EN = 0; RX_AMP_EN = rfAmpMode; AMP_BYPASS_EN = rfAmpMode^1; } while (0) 103 | // set RF mode to RX and wait until MARCSTATE shows it's there 104 | #define RFTX do { SET_TX_AMP; RFST = RFST_STX; while ((MARCSTATE) != MARC_STATE_TX); } while (0) 105 | // set RF mode to TX and wait until MARCSTATE shows it's there 106 | #define RFRX do { SET_RX_AMP; RFST = RFST_SRX; while ((MARCSTATE) != MARC_STATE_RX); } while (0) 107 | // set RF mode to CAL and wait until MARCSTATE shows it's done (in IDLE) 108 | #define RFCAL do { SET_AMP_OFF; RFST=RFST_SCAL; while ((MARCSTATE) != MARC_STATE_IDLE); } while (0) 109 | // set RF mode to IDLE and wait until MARCSTATE shows it's there 110 | #define RFOFF do { SET_AMP_OFF; RFST=RFST_SIDLE; while ((MARCSTATE) != MARC_STATE_IDLE); } while (0) 111 | #else 112 | // set RF mode to RX and wait until MARCSTATE shows it's there 113 | #define RFTX do { RFST = RFST_STX; while ((MARCSTATE) != MARC_STATE_TX); } while (0) 114 | // set RF mode to TX and wait until MARCSTATE shows it's there 115 | #define RFRX do { RFST = RFST_SRX; while ((MARCSTATE) != MARC_STATE_RX); } while (0) 116 | // set RF mode to CAL and wait until MARCSTATE shows it's done (in IDLE) 117 | #define RFCAL do { RFST = RFST_SCAL; while ((MARCSTATE) != MARC_STATE_IDLE); } while (0) 118 | // set RF mode to IDLE and wait until MARCSTATE shows it's there 119 | #define RFOFF do { RFST = RFST_SIDLE; while ((MARCSTATE) != MARC_STATE_IDLE); } while (0) 120 | #endif 121 | 122 | 123 | int waitRSSI(void); 124 | 125 | u8 transmit(__xdata u8* __xdata buf, __xdata u16 len, __xdata u16 repeat, __xdata u16 offset); // sends data out the radio using the current RF settings 126 | void appInitRf(void); // in application.c (provided by the application and called from init_RF() 127 | void init_RF(void); 128 | void byte_shuffle(__xdata u8* __xdata buf, __xdata u16 len, __xdata u16 offset); 129 | void startRX(void); 130 | void resetRFSTATE(void); 131 | 132 | typedef struct MAC_DATA_s 133 | { 134 | u8 mac_state; 135 | // MAC parameters (FIXME: make this all cc1111fhssmac.c/h?) 136 | u16 MAC_threshold; // when the T2 clock as overflowed this many times, change channel 137 | u16 MAC_timer; // this tracks how many times it's overflowed (really? 32-bits for these two?!?) 138 | u16 NumChannels; // in case of multiple paths through the available channels 139 | u16 NumChannelHops; // total number of channels in pattern (>= g_MaxChannels) 140 | u16 curChanIdx; // indicates current channel index of the hopping pattern 141 | u16 tLastStateChange; 142 | u16 tLastHop; 143 | u16 desperatelySeeking; // this should be unnecessary, and should instead use mac_state? 144 | u8 txMsgIdx; 145 | u8 txMsgIdxDone; 146 | u16 synched_chans; 147 | } MAC_DATA_t; 148 | 149 | extern __xdata MAC_DATA_t macdata; 150 | 151 | #endif 152 | -------------------------------------------------------------------------------- /firmware/include/cc1111usb.h: -------------------------------------------------------------------------------- 1 | #ifndef CC1111USB_H 2 | #define CC1111USB_H 3 | 4 | #include "chipcon_usb.h" 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /firmware/include/cc2531.h: -------------------------------------------------------------------------------- 1 | #ifndef CC2531_H 2 | #define CC2531_H 3 | 4 | #include 5 | #include "cc2530-ext.h" 6 | 7 | 8 | 9 | SFRX(USBADDR, 0x6200); // Function Address 10 | SFRX(USBPOW, 0x6201); // Power / Control Register 11 | SFRX(USBIIF, 0x6202); // IN Endpoints and EP0 Interrupt Flags 12 | SFRX(USBOIF, 0x6204); // OUT Endpoints Interrupt Flags 13 | SFRX(USBCIF, 0x6206); // Common USB Interrupt Flags 14 | SFRX(USBIIE, 0x6207); // IN Endpoints and EP0 Interrupt Enable Mask 15 | SFRX(USBOIE, 0x6209); // Out Endpoints Interrupt Enable Mask 16 | SFRX(USBCIE, 0x620B); // Common USB Interrupt Enable Mask 17 | SFRX(USBFRML, 0x620C); // Current Frame Number (Low byte) 18 | SFRX(USBFRMH, 0x620D); // Current Frame Number (High byte) 19 | SFRX(USBINDEX, 0x620E); // Selects current endpoint. Make sure this register has the required value before any of the following registers are accessed. This register must be set to a value in the range 0 - 5. 20 | 21 | SFRX(USBMAXI, 0x6210); // Max. packet size for IN endpoint, 1-5 22 | SFRX(USBCS0, 0x6211); // EP0 Control and Status (USBINDEX = 0), 0 23 | SFRX(USBCSIL, 0x6211); // IN EP{1 - 5} Control and Status Low, 1-5 24 | SFRX(USBCSIH, 0x6212); // IN EP{1 - 5} Control and Status High, 1-5 25 | SFRX(USBMAXO, 0x6213); // Max. packet size for OUT endpoint, 1-5 26 | SFRX(USBCSOL, 0x6214); // OUT EP{1 - 5} Control and Status Low, 1-5 27 | SFRX(USBCSOH, 0x6215); // OUT EP{1 - 5} Control and Status High, 1-5 28 | SFRX(USBCNT0, 0x6216); // Number of received bytes in EP0 FIFO (USBINDEX = 0), 0 29 | SFRX(USBCNTL, 0x6216); // Number of bytes in OUT FIFO Low, 1-5 30 | SFRX(USBCNTH, 0x6217); // Number of bytes in OUT FIFO High, 1-5 31 | 32 | 33 | SFRX(USBF0, 0x6220); // Endpoint 0 FIFO 34 | SFRX(USBF1, 0x6222); // Endpoint 1 FIFO 35 | SFRX(USBF2, 0x6224); // Endpoint 2 FIFO 36 | SFRX(USBF3, 0x6226); // Endpoint 3 FIFO 37 | SFRX(USBF4, 0x6228); // Endpoint 4 FIFO 38 | SFRX(USBF5, 0x622A); // Endpoint 5 FIFO 39 | 40 | 41 | 42 | //#define P0IFG_USB_RESUME 0x80 //rw0 43 | 44 | // SBIT(USBIF, 0xE8, 0); // USB Interrupt Flag 45 | 46 | // USB activities 47 | #define USB_ENABLE_PIN P1_0 48 | //#define USB_ENABLE_PIN P1_1 49 | #define NOP() __asm; nop; __endasm; 50 | #define USB_DISABLE() SLEEP &= ~SLEEP_USB_EN; 51 | #define USB_ENABLE() SLEEP |= SLEEP_USB_EN; 52 | #define USB_RESET() USB_DISABLE(); NOP(); USB_ENABLE(); 53 | #define USB_INT_ENABLE() IEN2|= 0x02; 54 | #define USB_INT_DISABLE() IEN2&= ~0x02; 55 | #define USB_INT_CLEAR() P2IFG= 0; P2IF= 0; 56 | 57 | #define USB_PULLUP_ENABLE() USB_ENABLE_PIN = 1; 58 | #define USB_PULLUP_DISABLE() USB_ENABLE_PIN = 0; 59 | 60 | #define USB_RESUME_INT_ENABLE() P0IE= 1 61 | #define USB_RESUME_INT_DISABLE() P0IE= 0 62 | #define USB_RESUME_INT_CLEAR() P0IFG= 0; P0IF= 0 63 | #define PM1() SLEEP |= 1 64 | 65 | #include "chipcon_usb.h" 66 | #include "chipcon_dma.h" 67 | #endif 68 | -------------------------------------------------------------------------------- /firmware/include/chipcon_dma.h: -------------------------------------------------------------------------------- 1 | #ifndef CHIPCON_DMA_H 2 | #define CHIPCON_DMA_H 3 | 4 | #include "types.h" 5 | #include "cc1111.h" 6 | #include "cc1111rf.h" 7 | 8 | // define number of required DMA channels here 9 | // RF (maybe) 10 | // USB 11 | // AES x 2 12 | #ifdef RFDMA 13 | #define DMA_CHANNELS 4 14 | #else 15 | #define DMA_CHANNELS 3 16 | #endif 17 | 18 | // prototypes 19 | 20 | void initDMA(void); 21 | u8 getDMA(void); 22 | 23 | // defines 24 | 25 | typedef union 26 | { 27 | u16 ui16; 28 | u8 ui8[2]; 29 | } U16_U8; 30 | 31 | // sdcc requires this bit ordering. this struct appears differently from the IAR version, which uses "#pragma bitfields=reversed" 32 | typedef struct DMA_DESC_S { 33 | uint8 srcAddrH; 34 | uint8 srcAddrL; 35 | uint8 destAddrH; 36 | uint8 destAddrL; 37 | uint8 lenH : 5; 38 | uint8 vlen : 3; 39 | uint8 lenL : 8; 40 | uint8 trig : 5; 41 | uint8 tMode : 2; 42 | uint8 wordSize : 1; 43 | 44 | uint8 priority : 2; 45 | uint8 m8 : 1; 46 | uint8 irqMask : 1; 47 | uint8 destInc : 2; 48 | uint8 srcInc : 2; 49 | } DMA_DESC; 50 | 51 | #define DMA_LEN_HIGH_VLEN_MASK (7 << 5) 52 | #define DMA_LEN_HIGH_VLEN_LEN (0 << 5) 53 | #define DMA_LEN_HIGH_VLEN_PLUS_1 (1 << 5) 54 | #define DMA_LEN_HIGH_VLEN (2 << 5) 55 | #define DMA_LEN_HIGH_VLEN_PLUS_2 (3 << 5) 56 | #define DMA_LEN_HIGH_VLEN_PLUS_3 (4 << 5) 57 | #define DMA_LEN_HIGH_MASK (0x1f) 58 | extern __xdata DMA_DESC dma_configs[DMA_CHANNELS]; 59 | 60 | #define DMA_CFG0_WORDSIZE_8 (0 << 7) 61 | #define DMA_CFG0_WORDSIZE_16 (1 << 7) 62 | #define DMA_CFG0_TMODE_MASK (3 << 5) 63 | #define DMA_CFG0_TMODE_SINGLE (0 << 5) 64 | #define DMA_CFG0_TMODE_BLOCK (1 << 5) 65 | #define DMA_CFG0_TMODE_REPEATED_SINGLE (2 << 5) 66 | #define DMA_CFG0_TMODE_REPEATED_BLOCK (3 << 5) 67 | #define DMA_CFG0_TRIGGER_ENC_DW 29 68 | #define DMA_CFG0_TRIGGER_DNC_UP 30 69 | 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /firmware/include/chipcon_usbdebug.h: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | #ifndef CC1111USBDEBUG_H 4 | #define CC1111USBDEBUG_H 5 | 6 | void debugEP0Req(u8 * __xdata pReq); 7 | void debug(__code u8* __xdata text); 8 | void debugx(__xdata u8* __xdata text); 9 | void debughex(__xdata u8 num); 10 | void debughex16(__xdata u16 num); 11 | void debughex32(__xdata u32 num); 12 | 13 | #endif 14 | 15 | -------------------------------------------------------------------------------- /firmware/include/global.h: -------------------------------------------------------------------------------- 1 | #ifndef GLOBAL_H 2 | #define GLOBAL_H 3 | 4 | #include "types.h" 5 | 6 | #ifdef CC1111 7 | #include "cc1111.h" 8 | #elif defined CC2511 9 | #include "cc1111.h" 10 | #elif defined CC2531 11 | #include "cc2531.h" 12 | #elif defined IMME 13 | #include 14 | #include "cc1110-ext.h" 15 | #endif 16 | 17 | #include "bits.h" 18 | 19 | // used for debugging and tracing execution. see client's ".getDebugCodes()" 20 | extern __xdata u8 lastCode[2]; 21 | extern __xdata u32 clock; 22 | 23 | ////////////// DEBUG ////////////// 24 | //#define VIRTUAL_COM 25 | //#define RADIO_EU 26 | //#define TRANSMIT_TEST 27 | //#define RECEIVE_TEST 28 | ////////////////////////////////////// 29 | 30 | // lastCode[0]: locations 31 | #define LC_USB_INITUSB 0x2 32 | #define LC_MAIN_RFIF 0xd 33 | #define LC_USB_DATA_RESET_RESUME 0xa 34 | #define LC_USB_RESET 0xb 35 | #define LC_USB_EP5OUT 0xc 36 | 37 | #define LC_RF_VECTOR 0x10 38 | #define LC_RFTXRX_VECTOR 0x11 39 | #define LC_TXDATA_START 0x12 40 | #define LC_TXDATA_COMPLETED_FRAME 0x13 41 | #define LC_TXDATA_COMPLETED_MESSAGE 0x14 42 | 43 | 44 | // lastCode[1]: Errors 45 | #define LCE_NO_ERROR 0x0 46 | 47 | #define LCE_USB_EP5_TX_WHILE_INBUF_WRITTEN 0x1 48 | #define LCE_USB_EP0_SENT_STALL 0x4 49 | #define LCE_USB_EP5_OUT_WHILE_OUTBUF_WRITTEN 0x5 50 | #define LCE_USB_EP5_LEN_TOO_BIG 0x6 51 | #define LCE_USB_EP5_GOT_CRAP 0x7 52 | #define LCE_USB_EP5_STALL 0x8 53 | #define LCE_USB_DATA_LEFTOVER_FLAGS 0x9 54 | 55 | #define LCE_RF_RXOVF 0x10 56 | #define LCE_RF_TXUNF 0x11 57 | #define LCE_DROPPED_PACKET 0x12 58 | #define LCE_RFTX_NEVER_TX 0x13 59 | #define LCE_RFTX_NEVER_LEAVE_TX 0x14 60 | #define LCE_RF_MODE_INCOMPAT 0x15 61 | #define LCE_RF_BLOCKSIZE_INCOMPAT 0x16 62 | #define LCE_RF_MULTI_BUFFER_NOT_INIT 0x17 63 | #define LCE_RF_MULTI_BUFFER_NOT_FREE 0x18 64 | 65 | // Return Codes 66 | #define RC_NO_ERROR 0x0 67 | #define RC_TX_DROPPED_PACKET 0xec 68 | #define RC_TX_ERROR 0xed 69 | #define RC_RF_BLOCKSIZE_INCOMPAT 0xee 70 | #define RC_RF_MODE_INCOMPAT 0xef 71 | #define RC_ERR_BUFFER_NOT_AVAILABLE 0xfe 72 | #define RC_ERR_BUFFER_SIZE_EXCEEDED 0xff 73 | 74 | // USB activities 75 | #ifdef CHRONOSDONGLE 76 | #define USB_ENABLE_PIN P1_1 77 | #else 78 | #define USB_ENABLE_PIN P1_0 79 | #endif 80 | #define NOP() __asm; nop; __endasm; 81 | 82 | // USB data buffer 83 | #define BUFFER_AVAILABLE 0x00 84 | #define BUFFER_FILLING 0xff 85 | #define ERR_BUFFER_SIZE_EXCEEDED -1 86 | #define ERR_BUFFER_NOT_AVAILABLE -2 87 | 88 | // Checks 89 | #define IS_XOSC_STABLE() (SLEEP & SLEEP_XOSC_S) 90 | 91 | // AES 92 | // defines for specifying desired crypto operations. 93 | // AES_CRYPTO is in two halves: 94 | // upper 4 bits mirror CC1111 mode (ENCCS_MODE_CBC etc.) 95 | // lower 4 bits are switches 96 | // AES_CRYPTO[7:4] ENCCS_MODE... 97 | // AES_CRYPTO[3] OUTBOUND 0 == OFF, 1 == ON 98 | // AES_CRYPTO[2] OUTBOUND 0 == Decrypt, 1 == Encrypt 99 | // AES_CRYPTO[1] INBOUND 0 == OFF, 1 == ON 100 | // AES_CRYPTO[0] INBOUND 0 == Decrypt, 1 == Encrypt 101 | // bitfields 102 | #define AES_CRYPTO_MODE 0xF0 103 | #define AES_CRYPTO_OUT 0x0C 104 | #define AES_CRYPTO_OUT_ENABLE 0x08 105 | #define AES_CRYPTO_OUT_ON (0x01 << 3) 106 | #define AES_CRYPTO_OUT_OFF (0x00 << 3) 107 | #define AES_CRYPTO_OUT_TYPE 0x04 108 | #define AES_CRYPTO_OUT_DECRYPT (0x00 << 2) 109 | #define AES_CRYPTO_OUT_ENCRYPT (0x01 << 2) 110 | #define AES_CRYPTO_IN 0x03 111 | #define AES_CRYPTO_IN_ENABLE 0x02 112 | #define AES_CRYPTO_IN_ON (0x01 << 1) 113 | #define AES_CRYPTO_IN_OFF (0x00 << 1) 114 | #define AES_CRYPTO_IN_TYPE 0x01 115 | #define AES_CRYPTO_IN_DECRYPT (0x00 << 0) 116 | #define AES_CRYPTO_IN_ENCRYPT (0x01 << 0) 117 | #define AES_CRYPTO_NONE 0x00 118 | // flags 119 | #define AES_DISABLE 0x00 120 | #define AES_ENABLE 0x01 121 | #define AES_DECRYPT 0x00 122 | #define AES_ENCRYPT 0x01 123 | 124 | /* board-specific defines */ 125 | #ifdef IMME 126 | // CC1110 IMME pink dongle - 26mhz 127 | #define LED_RED P2_3 128 | #define LED_GREEN P2_4 129 | #define SLEEPTIMER 1200 130 | #define PLATFORM_CLOCK_FREQ 26 131 | 132 | #include "immedisplay.h" 133 | #include "immekeys.h" 134 | #include "immeio.h" 135 | //#include "pm.h" 136 | 137 | #else 138 | #define SLEEPTIMER 1100 139 | #define PLATFORM_CLOCK_FREQ 24 140 | void usbIntHandler(void) __interrupt P2INT_VECTOR; 141 | void p0IntHandler(void) __interrupt P0INT_VECTOR; 142 | 143 | #if defined DONSDONGLES 144 | // CC1111 USB Dongle with breakout debugging pins (EMK?) - 24mhz 145 | #define LED_RED P1_1 146 | #define LED_GREEN P1_1 147 | #define CC1111EM_BUTTON P1_2 148 | 149 | #elif defined YARDSTICKONE 150 | #define LED1 P1_1 151 | #define LED_GREEN P1_1 152 | #define LED2 P1_2 153 | #define LED_RED P1_2 154 | #define LED3 P1_3 155 | #define LED_YELLOW P1_3 156 | #define TX_AMP_EN P2_0 157 | #define RX_AMP_EN P2_4 158 | #define AMP_BYPASS_EN P2_3 159 | 160 | #elif defined CHRONOSDONGLE 161 | // CC1111 USB Chronos watch dongle - 24mhz 162 | #define LED_RED P1_0 163 | #define LED_GREEN P1_0 164 | 165 | #elif defined CC2531 166 | // CC2531 USB 802.15.4 emk - 24mhz 167 | #define LED_RED P1_0 //?? 168 | #define LED_GREEN P1_0 //?? 169 | #endif 170 | #endif 171 | 172 | #define LED LED_GREEN 173 | 174 | 175 | #define REALLYFASTBLINK() { LED=1; sleepMillis(2); LED=0; sleepMillis(10); } 176 | #define blink( on_cycles, off_cycles) {LED=1; sleepMillis(on_cycles); LED=0; sleepMillis(off_cycles);} 177 | #define BLOCK() { while (1) { REALLYFASTBLINK() ; usbProcessEvents(); } } 178 | #define LE_WORD(x) ((x)&0xFF),((u8) (((u16) (x))>>8)) 179 | #define ASCII_LONG(x) '0' + x / 1000 % 10,'0' + x / 100 % 10, '0' + x / 10 % 10, '0' + x % 10 180 | #define QUOTE(x) XQUOTE(x) 181 | #define XQUOTE(x) #x 182 | 183 | /* function declarations */ 184 | void sleepMillis(int ms); 185 | void sleepMicros(int us); 186 | void t1IntHandler(void) __interrupt T1_VECTOR; // interrupt handler should trigger on T1 overflow 187 | void clock_init(void); 188 | void io_init(void); 189 | //void blink(u16 on_cycles, u16 off_cycles); 190 | void blink_binary_baby_lsb(u16 num, char bits); 191 | int strncmp(const char * __xdata s1, const char * __xdata s2, u16 n); 192 | #endif 193 | -------------------------------------------------------------------------------- /firmware/include/imme5x7.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 5x7 fixed font taken from http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html 3 | * "Public domain font. Share and enjoy." 4 | */ 5 | 6 | #define FONT_WIDTH 5 7 | #define FONT_HEIGHT 7 8 | #define FONT_OFFSET 32 9 | #define FONT_MAX 127 10 | 11 | const unsigned char font[][FONT_WIDTH] = { 12 | {0x00, 0x00, 0x00, 0x00, 0x00}, /* space */ 13 | {0x00, 0x00, 0x5e, 0x00, 0x00}, /* exclam */ 14 | {0x00, 0x0e, 0x00, 0x0e, 0x00}, /* quotedbl */ 15 | {0x28, 0x7c, 0x28, 0x7c, 0x28}, /* numbersign */ 16 | {0x08, 0x54, 0x7c, 0x54, 0x20}, /* dollar */ 17 | {0x26, 0x10, 0x08, 0x64, 0x00}, /* percent */ 18 | {0x28, 0x54, 0x28, 0x40, 0x00}, /* ampersand */ 19 | {0x00, 0x00, 0x0e, 0x00, 0x00}, /* quotesingle */ 20 | {0x00, 0x3c, 0x42, 0x00, 0x00}, /* parenleft */ 21 | {0x00, 0x42, 0x3c, 0x00, 0x00}, /* parenright */ 22 | {0x00, 0x54, 0x38, 0x54, 0x00}, /* asterisk */ 23 | {0x10, 0x10, 0x7c, 0x10, 0x10}, /* plus */ 24 | {0x00, 0x80, 0x60, 0x20, 0x00}, /* comma */ 25 | {0x10, 0x10, 0x10, 0x10, 0x00}, /* hyphen */ 26 | {0x00, 0x60, 0x60, 0x00, 0x00}, /* period */ 27 | {0x20, 0x10, 0x08, 0x04, 0x00}, /* slash */ 28 | {0x00, 0x3c, 0x42, 0x3c, 0x00}, /* zero */ 29 | {0x00, 0x44, 0x7e, 0x40, 0x00}, /* one */ 30 | {0x44, 0x62, 0x52, 0x4c, 0x00}, /* two */ 31 | {0x22, 0x4a, 0x4a, 0x36, 0x00}, /* three */ 32 | {0x18, 0x14, 0x7e, 0x10, 0x00}, /* four */ 33 | {0x2e, 0x4a, 0x4a, 0x32, 0x00}, /* five */ 34 | {0x3c, 0x4a, 0x4a, 0x30, 0x00}, /* six */ 35 | {0x02, 0x62, 0x1a, 0x06, 0x00}, /* seven */ 36 | {0x34, 0x4a, 0x4a, 0x34, 0x00}, /* eight */ 37 | {0x0c, 0x52, 0x52, 0x3c, 0x00}, /* nine */ 38 | {0x00, 0x6c, 0x6c, 0x00, 0x00}, /* colon */ 39 | {0x80, 0x6c, 0x2c, 0x00, 0x00}, /* semicolon */ 40 | {0x00, 0x10, 0x28, 0x44, 0x00}, /* less */ 41 | {0x28, 0x28, 0x28, 0x28, 0x00}, /* equal */ 42 | {0x00, 0x44, 0x28, 0x10, 0x00}, /* greater */ 43 | {0x00, 0x04, 0x52, 0x0c, 0x00}, /* question */ 44 | {0x3c, 0x42, 0x5a, 0x1c, 0x00}, /* at */ 45 | {0x7c, 0x12, 0x12, 0x7c, 0x00}, /* A */ 46 | {0x7e, 0x4a, 0x4a, 0x34, 0x00}, /* B */ 47 | {0x3c, 0x42, 0x42, 0x24, 0x00}, /* C */ 48 | {0x7e, 0x42, 0x42, 0x3c, 0x00}, /* D */ 49 | {0x7e, 0x4a, 0x4a, 0x42, 0x00}, /* E */ 50 | {0x7e, 0x0a, 0x0a, 0x02, 0x00}, /* F */ 51 | {0x3c, 0x42, 0x52, 0x74, 0x00}, /* G */ 52 | {0x7e, 0x08, 0x08, 0x7e, 0x00}, /* H */ 53 | {0x00, 0x42, 0x7e, 0x42, 0x00}, /* I */ 54 | {0x20, 0x40, 0x40, 0x3e, 0x00}, /* J */ 55 | {0x7e, 0x18, 0x24, 0x42, 0x00}, /* K */ 56 | {0x7e, 0x40, 0x40, 0x40, 0x00}, /* L */ 57 | {0x7e, 0x0c, 0x0c, 0x7e, 0x00}, /* M */ 58 | {0x7e, 0x0c, 0x30, 0x7e, 0x00}, /* N */ 59 | {0x3c, 0x42, 0x42, 0x3c, 0x00}, /* O */ 60 | {0x7e, 0x12, 0x12, 0x0c, 0x00}, /* P */ 61 | {0x3c, 0x62, 0x42, 0xbc, 0x00}, /* Q */ 62 | {0x7e, 0x12, 0x32, 0x4c, 0x00}, /* R */ 63 | {0x24, 0x4a, 0x52, 0x24, 0x00}, /* S */ 64 | {0x00, 0x02, 0x7e, 0x02, 0x00}, /* T */ 65 | {0x3e, 0x40, 0x40, 0x3e, 0x00}, /* U */ 66 | {0x1e, 0x60, 0x60, 0x1e, 0x00}, /* V */ 67 | {0x7e, 0x30, 0x30, 0x7e, 0x00}, /* W */ 68 | {0x66, 0x18, 0x18, 0x66, 0x00}, /* X */ 69 | {0x00, 0x0e, 0x70, 0x0e, 0x00}, /* Y */ 70 | {0x62, 0x52, 0x4a, 0x46, 0x00}, /* Z */ 71 | {0x00, 0x7e, 0x42, 0x42, 0x00}, /* bracketleft */ 72 | {0x04, 0x08, 0x10, 0x20, 0x00}, /* backslash */ 73 | {0x00, 0x42, 0x42, 0x7e, 0x00}, /* bracketright */ 74 | {0x00, 0x04, 0x02, 0x04, 0x00}, /* asciicircum */ 75 | {0x40, 0x40, 0x40, 0x40, 0x00}, /* underscore */ 76 | {0x00, 0x02, 0x04, 0x00, 0x00}, /* grave */ 77 | {0x30, 0x48, 0x28, 0x78, 0x00}, /* a */ 78 | {0x7e, 0x48, 0x48, 0x30, 0x00}, /* b */ 79 | {0x30, 0x48, 0x48, 0x00, 0x00}, /* c */ 80 | {0x30, 0x48, 0x48, 0x7e, 0x00}, /* d */ 81 | {0x30, 0x68, 0x58, 0x10, 0x00}, /* e */ 82 | {0x10, 0x7c, 0x12, 0x04, 0x00}, /* f */ 83 | {0x50, 0xa8, 0xa8, 0x98, 0x00}, /* g */ 84 | {0x7e, 0x08, 0x08, 0x70, 0x00}, /* h */ 85 | {0x00, 0x48, 0x7a, 0x40, 0x00}, /* i */ 86 | {0x00, 0x40, 0x80, 0x7a, 0x00}, /* j */ 87 | {0x7e, 0x10, 0x28, 0x40, 0x00}, /* k */ 88 | {0x00, 0x42, 0x7e, 0x40, 0x00}, /* l */ 89 | {0x78, 0x10, 0x18, 0x70, 0x00}, /* m */ 90 | {0x78, 0x08, 0x08, 0x70, 0x00}, /* n */ 91 | {0x30, 0x48, 0x48, 0x30, 0x00}, /* o */ 92 | {0xf8, 0x48, 0x48, 0x30, 0x00}, /* p */ 93 | {0x30, 0x48, 0x48, 0xf8, 0x00}, /* q */ 94 | {0x78, 0x08, 0x08, 0x10, 0x00}, /* r */ 95 | {0x50, 0x58, 0x68, 0x28, 0x00}, /* s */ 96 | {0x08, 0x3e, 0x48, 0x40, 0x00}, /* t */ 97 | {0x38, 0x40, 0x40, 0x78, 0x00}, /* u */ 98 | {0x00, 0x38, 0x40, 0x38, 0x00}, /* v */ 99 | {0x78, 0x60, 0x60, 0x78, 0x00}, /* w */ 100 | {0x48, 0x30, 0x30, 0x48, 0x00}, /* x */ 101 | {0x18, 0xa0, 0x40, 0x38, 0x00}, /* y */ 102 | {0x48, 0x68, 0x58, 0x48, 0x00}, /* z */ 103 | {0x00, 0x08, 0x3c, 0x42, 0x00}, /* braceleft */ 104 | {0x00, 0x00, 0x7e, 0x00, 0x00}, /* bar */ 105 | {0x00, 0x42, 0x3c, 0x08, 0x00}, /* braceright */ 106 | }; 107 | -------------------------------------------------------------------------------- /firmware/include/immedisplay.h: -------------------------------------------------------------------------------- 1 | /* 2 | * IM-Me display functions 3 | * 4 | * Copyright 2010 Dave 5 | * http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html 6 | * 7 | * Copyright 2010 Michael Ossmann 8 | * 9 | * Copyright 2011 atlas 10 | * 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2, or (at your option) 14 | * any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program; see the file COPYING. If not, write to 23 | * the Free Software Foundation, Inc., 51 Franklin Street, 24 | * Boston, MA 02110-1301, USA. 25 | */ 26 | 27 | #define LOW 0 28 | #define HIGH 1 29 | 30 | #define WIDTH 132 31 | #define HEIGHT 65 32 | 33 | void sleepMillis(int ms); 34 | 35 | void xtalClock(); 36 | 37 | // IO Port Definitions: 38 | #define A0 P0_2 39 | #define SSN P0_4 40 | #define LCDRst P1_1 41 | //#define LED_RED P2_3 42 | //#define LED_GREEN P2_4 43 | // plus SPI ports driven from USART0 are: 44 | // MOSI P0_3 45 | // SCK P0_5 46 | 47 | void setIOPorts(); 48 | 49 | void configureSPI(); 50 | 51 | void tx(unsigned char ch); 52 | 53 | void txData(unsigned char ch); 54 | 55 | void txCtl(unsigned char ch); 56 | 57 | void LCDReset(void); 58 | 59 | void LCDPowerSave(); 60 | 61 | void setCursor(unsigned char row, unsigned char col); 62 | 63 | void setDisplayStart(unsigned char start); 64 | 65 | void setNormalReverse(unsigned char normal); 66 | 67 | void clear(); 68 | 69 | void putchar(char c); 70 | -------------------------------------------------------------------------------- /firmware/include/immefont.h: -------------------------------------------------------------------------------- 1 | 2 | #define ASCIIOFFSET 0x20 3 | 4 | //6 bytes wide 5 | //Each byte is 8 pixels tall 6 | 7 | #define fontSIZE 768 8 | 9 | void putch(char ch); 10 | -------------------------------------------------------------------------------- /firmware/include/immeio.h: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | 3 | void immeLCDUpdateState(void); 4 | void immeLCDShowRFConfig(void); 5 | void immeLCDInitScreen(void); 6 | void immeLCDShowPacket(void); 7 | 8 | void eraserow(u8 row); 9 | void erasescreen(); 10 | void drawstr(u8 row, u8 col, char *str); 11 | void drawint(u8 row, u8 col, u16 val); 12 | void drawhex(u8 row, u8 col, u16 val); 13 | void poll_keyboard(); 14 | void usb_up(void); 15 | void initIMME(void); 16 | 17 | // provided by firmware ////////// 18 | void immeLCDInitialState(void); 19 | ////////////////////////////////// 20 | 21 | // Set a clock rate of approx. 2.5 Mbps for 26 MHz Xtal clock 22 | #define SPI_BAUD_M 170 23 | #define SPI_BAUD_E 16 24 | 25 | #define IMME_STATE_CONFIG_SCREEN 1 26 | #define IMME_STATE_SNIFF 0 27 | 28 | #define MOD_2FSK 0 29 | #define MOD_GFSK 1 30 | #define MOD_ASKOOK 3 31 | #define MOD_MSK 7 32 | 33 | extern char __xdata rxbuf[30]; 34 | extern u8 modulations[]; 35 | extern u8 current_modulation; 36 | extern char __code fsk2[]; 37 | extern char __code gfsk[]; 38 | extern char __code ask[]; 39 | extern char __code msk[]; 40 | extern char* __code modstrings[]; 41 | 42 | 43 | -------------------------------------------------------------------------------- /firmware/include/immekeys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 atlas 3 | * adapted from code by Travis Goodspeed, Michael Ossmann 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2, or (at your option) 8 | * any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; see the file COPYING. If not, write to 17 | * the Free Software Foundation, Inc., 51 Franklin Street, 18 | * Boston, MA 02110-1301, USA. 19 | */ 20 | #include "types.h" 21 | 22 | u8 keyscan(void); 23 | u8 getkey(void); 24 | 25 | //Special keys. 26 | //#define KPWR 0x01 27 | //#define KMNU 0x03 28 | //#define KCAP 0x82 29 | //#define KSPK 0x83 30 | //#define KALT 0x84 31 | //#define KONL 0x85 32 | //#define KBACK 0x86 33 | //#define KDWN 0x87 34 | //#define KBYE 0x02 35 | #define KPWR 0x01 36 | #define KMNU 0x03 37 | #define KCAP 0x82 38 | #define KSPK 0x83 39 | #define KALT 0x84 40 | #define KONL 0x85 41 | #define KBACK 0x86 42 | #define KUP 0x87 43 | #define KDWN 0x5e 44 | #define KBYE 0x02 45 | #define KRIGHT 0x3e 46 | #define KLEFT 0x3c 47 | #define KENTER 0xa 48 | 49 | -------------------------------------------------------------------------------- /firmware/include/immestring.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | //! Find the length of a string. 4 | u16 strlen(char * __xdata str); 5 | -------------------------------------------------------------------------------- /firmware/include/immeterm.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "cc1110-ext.h" 4 | //#include "hal_cc8051.h" 5 | 6 | #include "bits.h" 7 | 8 | #include "immefont.h" 9 | #include "immeio.h" 10 | //#include "string.h" 11 | #include "immekeys.h" 12 | //#include "power.h" 13 | 14 | 15 | //Apps 16 | #define LOW 0; 17 | #define HIGH 1; 18 | 19 | //times.c 20 | void sleepMillis(int ms); 21 | void xtalClock(); 22 | 23 | //io.c 24 | // IO Port Definitions: 25 | #define A0 P0_2 26 | #define SSN P0_4 27 | #define LCDRst P1_1 28 | #define LED_RED P2_3 29 | #define LED_GREEN P2_4 30 | // plus SPI ports driven from USART0 are: 31 | // MOSI P0_3 32 | // SCK P0_5 33 | 34 | //! Sets not !normal 35 | void setNormalReverse(unsigned char normal); 36 | //! Start the display. 37 | void setDisplayStart(unsigned char start); 38 | 39 | //! Initialize the IO ports. 40 | void setIOPorts(); 41 | 42 | // Set a clock rate of approx. 2.5 Mbps for 26 MHz Xtal clock 43 | #define SPI_BAUD_M 170 44 | #define SPI_BAUD_E 16 45 | 46 | void configureSPI(); 47 | void tx(unsigned char ch); 48 | void txData(unsigned char ch); 49 | void txCtl(unsigned char ch); 50 | 51 | //! Reset the LCD display. 52 | void LCDReset(void); 53 | 54 | //! Power save, not yet tested. 55 | void LCDPowerSave(); 56 | 57 | //! Set the cursor position. 58 | void setCursor(unsigned char row, unsigned char col) ; 59 | 60 | 61 | void fail(char * __xdata msg); 62 | -------------------------------------------------------------------------------- /firmware/include/nic.h: -------------------------------------------------------------------------------- 1 | #ifndef _NIC_H_ 2 | #define _NIC_H_ 3 | 4 | #define APP_NIC 0x42 5 | #define NIC_RECV 0x1 6 | #define NIC_XMIT 0x2 7 | 8 | #define NIC_SET_ID 0x3 9 | #define NIC_SET_RECV_LARGE 0x5 10 | 11 | #define NIC_SET_AES_MODE 0x6 12 | #define NIC_GET_AES_MODE 0x7 13 | #define NIC_SET_AES_IV 0x8 14 | #define NIC_SET_AES_KEY 0x9 15 | #define NIC_SET_AMP_MODE 0xa 16 | #define NIC_GET_AMP_MODE 0xb 17 | 18 | #define NIC_LONG_XMIT 0xc 19 | #define NIC_LONG_XMIT_MORE 0xd 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /firmware/include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | #define u8 unsigned char 5 | #define u16 unsigned int 6 | #define uint8 unsigned char 7 | #define uint16 unsigned int 8 | #define u32 unsigned long 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /firmware/new_serial.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | 4 | sn_header = """// Serial number 5 | 10, // bLength 6 | USB_DESC_STRING, // bDescriptorType 7 | """ 8 | 9 | try: 10 | ser = int(file(".serial", 'rb').read(), 16) #+ 1 11 | except IOError: 12 | ser = 0 13 | 14 | print >>sys.stderr,("[--- new serial number: %.4x ---]" % ser) 15 | 16 | file(".serial", 'wb').write("%.4x" % ser) 17 | sertxt = "%.4x" % ser 18 | 19 | for c in sertxt: 20 | n = ord(c) 21 | sys.stdout.write("%s,0," % n) 22 | 23 | -------------------------------------------------------------------------------- /firmware/usbonly.c: -------------------------------------------------------------------------------- 1 | #include "cc1111usb.h" 2 | 3 | void main(void) 4 | { 5 | } 6 | 7 | -------------------------------------------------------------------------------- /package.sh: -------------------------------------------------------------------------------- 1 | echo "=== set revision: `./revision.sh` ===" 2 | 3 | echo "=== build firmwares ===" 4 | cd firmware 5 | ./buildall.sh 6 | cd .. 7 | 8 | DATESTAMP=`date +%y%m%d` 9 | TARGETDIR="rfcat_$DATESTAMP" 10 | TARGETPATH="../$TARGETDIR" 11 | echo "=== make archive ===" 12 | rm -rf $TARGETPATH 13 | hg archive -r tip $TARGETPATH 14 | 15 | echo "=== touch up archive ===" 16 | cp .revision $TARGETPATH 17 | cp firmware/bins/*$DATESTAMP.hex $TARGETPATH/firmware/bins/ 18 | 19 | echo "=== package up archive $TARGETDIR.tgz ===" 20 | cd .. 21 | tar zcf $TARGETDIR.tgz $TARGETDIR 22 | -------------------------------------------------------------------------------- /revision.sh: -------------------------------------------------------------------------------- 1 | 2 | hg parent >/dev/null 2>&1 3 | if [ $? -eq 0 ]; then 4 | hg parent --template '{rev}' | tee .revision 5 | else 6 | [ -e .revision ] && cat .revision || echo '65535' 7 | fi 8 | 9 | -------------------------------------------------------------------------------- /rfcat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import readline 5 | import rlcompleter 6 | readline.parse_and_bind("tab: complete") 7 | 8 | from rflib import * 9 | 10 | 11 | 12 | intro = """'RfCat, the greatest thing since Frequency Hopping!' 13 | 14 | Research Mode: enjoy the raw power of rflib 15 | 16 | currently your environment has an object called "d" for dongle. this is how 17 | you interact with the rfcat dongle: 18 | >>> d.ping() 19 | >>> d.setFreq(433000000) 20 | >>> d.setMdmModulation(MOD_ASK_OOK) 21 | >>> d.makePktFLEN(250) 22 | >>> d.RFxmit("HALLO") 23 | >>> d.RFrecv() 24 | >>> print d.reprRadioConfig() 25 | 26 | """ 27 | 28 | if __name__ == "__main__": 29 | import argparse 30 | 31 | parser = argparse.ArgumentParser() 32 | parser.add_argument('-r', '--research', default=False, action="store_true", help='Interactive Python and the "d" instance to talk to your dongle. melikey longtime.') 33 | parser.add_argument('-i', '--index', default=0, type=int) 34 | parser.add_argument('-s', '--specan', default=False, action="store_true", help='start spectrum analyzer') 35 | parser.add_argument('-f', '--centfreq', default=902e6, type=float) 36 | parser.add_argument('-c', '--inc', default=250e3, type=float) 37 | parser.add_argument('-n', '--specchans', default=104, type=int) 38 | parser.add_argument('--bootloader', default=False, action="store_true", help='trigger the bootloader (use in order to flash the dongle)') 39 | parser.add_argument('--force', default=False, action="store_true", help='use this to make sure you want to set bootloader mode (you *must* flash after setting --bootloader)') 40 | 41 | ifo = parser.parse_args() 42 | 43 | if ifo.bootloader: 44 | if not ifo.force: 45 | print "Protecting you from yourself. If you want to trigger Bootloader mode (you will then *have* to flash a new RfCat image on it) use the --force argument as well" 46 | exit(-1) 47 | 48 | print "Entering RfCat Bootloader mode, ready for new image..." 49 | RfCat(ifo.index).bootloader() 50 | exit(0) 51 | 52 | elif ifo.specan: 53 | RfCat(ifo.index).specan(ifo.centfreq,ifo.inc,ifo.specchans) 54 | 55 | elif ifo.research: 56 | interactive(ifo.index, DongleClass=RfCat, intro=intro) 57 | 58 | else: 59 | # do the full-rfcat thing 60 | d = RfCat(ifo.index, debug=False) 61 | d.rf_redirection((sys.stdin, sys.stdout)) 62 | 63 | -------------------------------------------------------------------------------- /rflib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ipython -i --no-banner 2 | from chipcon_nic import * 3 | import rflib.bits as rfbits 4 | 5 | RFCAT_START_SPECAN = 0x40 6 | RFCAT_STOP_SPECAN = 0x41 7 | 8 | MAX_FREQ = 936e6 9 | 10 | class RfCat(FHSSNIC): 11 | def RFdump(self, msg="Receiving", maxnum=100, timeoutms=1000): 12 | try: 13 | for x in xrange(maxnum): 14 | y, t = self.RFrecv(timeoutms) 15 | print "(%5.3f) %s: %s" % (t, msg, y.encode('hex')) 16 | except ChipconUsbTimeoutException: 17 | pass 18 | 19 | def scan(self, basefreq=902e6, inc=250e3, count=104, delaysec=2, drate=38400, lowball=1): 20 | ''' 21 | scan for signal over a range of frequencies 22 | ''' 23 | self.RFdump("Clearing") 24 | self.lowball(lowball) 25 | self.setMdmDRate(drate) 26 | print "Scanning range: " 27 | while not keystop(): 28 | try: 29 | print "(press Enter to quit)" 30 | for freq in xrange(int(basefreq), int(basefreq+(inc*count)), int(inc)): 31 | print "Scanning for frequency %d..." % freq 32 | self.setFreq(freq) 33 | self.RFdump(timeoutms=delaysec*1000) 34 | if keystop(): 35 | break 36 | except KeyboardInterrupt: 37 | print "Please press to stop" 38 | 39 | sys.stdin.read(1) 40 | self.lowballRestore() 41 | 42 | def specan(self, centfreq=915e6, inc=250e3, count=104): 43 | ''' 44 | Enter Spectrum Analyzer mode. 45 | this sets the mode of the dongle to send data, and brings up the GUI. 46 | 47 | centfreq is the center frequency 48 | ''' 49 | freq, delta = self._doSpecAn(centfreq, inc, count) 50 | 51 | import rflib.ccspecan as rfspecan 52 | rfspecan.ensureQapp() 53 | 54 | fhigh = freq + (delta*(count+1)) 55 | 56 | window = rfspecan.Window(self, freq, fhigh, delta, 0) 57 | window.show() 58 | rfspecan._qt_app.exec_() 59 | 60 | def _doSpecAn(self, centfreq, inc, count): 61 | ''' 62 | store radio config and start sending spectrum analysis data 63 | 64 | centfreq = Center Frequency 65 | ''' 66 | if count>255: 67 | raise Exception("sorry, only 255 samples per pass... (count)") 68 | 69 | spectrum = (count * inc) 70 | halfspec = spectrum / 2.0 71 | basefreq = centfreq - halfspec 72 | if (count * inc) + basefreq > MAX_FREQ: 73 | raise Exception("Sorry, %1.3f + (%1.3f * %1.3f) is higher than %1.3f" % 74 | (basefreq, count, inc)) 75 | self.getRadioConfig() 76 | self._specan_backup_radiocfg = self.radiocfg 77 | 78 | self.setFreq(basefreq) 79 | self.setMdmChanSpc(inc) 80 | 81 | freq, fbytes = self.getFreq() 82 | delta = self.getMdmChanSpc() 83 | 84 | self.send(APP_NIC, RFCAT_START_SPECAN, "%c" % (count) ) 85 | return freq, delta 86 | 87 | def _stopSpecAn(self): 88 | ''' 89 | stop sending rfdata and return radio to original config 90 | ''' 91 | self.send(APP_NIC, RFCAT_STOP_SPECAN, '') 92 | self.radiocfg = self._specan_backup_radiocfg 93 | self.setRadioConfig() 94 | 95 | 96 | def rf_configure(*args, **kwargs): 97 | self.setRFparameters(*args, **kwargs) 98 | 99 | def rf_redirection(self, fdtup, use_rawinput=False, printable=False): 100 | buf = '' 101 | 102 | if len(fdtup)>1: 103 | fd0i, fd0o = fdtup 104 | else: 105 | fd0i, = fdtup 106 | fd0o, = fdtup 107 | 108 | fdsock = False # socket or fileio? 109 | if hasattr(fd0i, 'recv'): 110 | fdsock = True 111 | 112 | try: 113 | while True: 114 | #if self._pause: 115 | # continue 116 | 117 | try: 118 | x,y,z = select.select([fd0i ], [], [], .1) 119 | if fd0i in x: 120 | # FIXME: make this aware of VLEN/FLEN and the proper length 121 | if fdsock: 122 | data = fd0i.recv(self.max_packet_size) 123 | else: 124 | data = fd0i.read(self.max_packet_size) 125 | 126 | if not len(data): # terminated socket 127 | break 128 | 129 | buf += data 130 | pktlen, vlen = self.getPktLEN() 131 | if vlen: 132 | pktlen = ord(buf[0]) 133 | 134 | #FIXME: probably want to take in a length struct here and then only send when we have that many bytes... 135 | data = buf[:pktlen] 136 | if use_rawinput: 137 | data = eval('"%s"'%data) 138 | 139 | if len(buf) >= pktlen: 140 | self.RFxmit(data) 141 | 142 | except ChipconUsbTimeoutException: 143 | pass 144 | 145 | try: 146 | data, time = self.RFrecv(1) 147 | 148 | if printable: 149 | data = "\n"+str(time)+": "+repr(data) 150 | else: 151 | data = struct.pack(" 1: 240 | idx = int(sys.argv.pop()) 241 | 242 | interactive(idx) 243 | -------------------------------------------------------------------------------- /rflib/cc1111client.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas0fd00m/rfcat-firsttry/ec89f57a35777acb48c59eaf4f9fa8356b93dbd3/rflib/cc1111client.py -------------------------------------------------------------------------------- /rflib/cc111Xhparser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | #include 4 | /* ------------------------------------------------------------------------------------------------ 5 | * Interrupt Vectors 6 | * ------------------------------------------------------------------------------------------------ 7 | */ 8 | #define RFTXRX_VECTOR 0 /* RF TX done / RX ready */ 9 | #define ADC_VECTOR 1 /* ADC End of Conversion */ 10 | #define URX0_VECTOR 2 /* USART0 RX Complete */ 11 | #define URX1_VECTOR 3 /* USART1 RX Complete */ 12 | #define ENC_VECTOR 4 /* AES Encryption/Decryption Complete */ 13 | #define ST_VECTOR 5 /* Sleep Timer Compare */ 14 | #define P2INT_VECTOR 6 /* Port 2 Inputs */ 15 | #define UTX0_VECTOR 7 /* USART0 TX Complete */ 16 | #define DMA_VECTOR 8 /* DMA Transfer Complete */ 17 | #define T1_VECTOR 9 /* Timer 1 (16-bit) Capture/Compare/Overflow */ 18 | #define T2_VECTOR 10 /* Timer 2 (MAC Timer) Overflow */ 19 | #define T3_VECTOR 11 /* Timer 3 (8-bit) Capture/Compare/Overflow */ 20 | #define T4_VECTOR 12 /* Timer 4 (8-bit) Capture/Compare/Overflow */ 21 | #define P0INT_VECTOR 13 /* Port 0 Inputs */ 22 | #define UTX1_VECTOR 14 /* USART1 TX Complete */ 23 | #define P1INT_VECTOR 15 /* Port 1 Inputs */ 24 | #define RF_VECTOR 16 /* RF General Interrupts */ 25 | #define WDT_VECTOR 17 /* Watchdog Overflow in Timer Mode */ 26 | 27 | SFR(P0, 0x80); // Port 0 28 | SBIT(P0_0, 0x80, 0); // Port 0 bit 0 29 | SBIT(P0_1, 0x80, 1); // Port 0 bit 1 30 | SBIT(P0_2, 0x80, 2); // Port 0 bit 2 31 | SBIT(P0_3, 0x80, 3); // Port 0 bit 3 32 | SBIT(P0_4, 0x80, 4); // Port 0 bit 4 33 | SBIT(P0_5, 0x80, 5); // Port 0 bit 5 34 | SBIT(P0_6, 0x80, 6); // Port 0 bit 6 35 | SBIT(P0_7, 0x80, 7); // Port 0 bit 7 36 | 37 | SFR(SP, 0x81); // Stack Pointer 38 | SFR(DPL0, 0x82); // Data Pointer 0 Low Byte 39 | SFR(DPH0, 0x83); // Data Pointer 0 High Byte 40 | SFR(DPL1, 0x84); // Data Pointer 1 Low Byte 41 | SFR(DPH1, 0x85); // Data Pointer 1 High Byte 42 | """ 43 | import sys 44 | 45 | 46 | def parseLines(lines): 47 | defs = {} 48 | incomment = False 49 | for line in lines: 50 | # find single-line comments 51 | slc = line.find("//") 52 | if (slc > -1): 53 | line = line[:slc] + "#" + line[slc+2:] 54 | # find /* */ comments 55 | mlcs = line.find("/*") 56 | mlce = line.find("*/") 57 | if (mlcs>-1): 58 | if (mlce>-1): # both are in this line 59 | if (mlce>mlcs): # they are "together" 60 | if (mlce >= len(line.strip())-3): 61 | line = line[:mlcs] + '#' + line[mlcs+2:mlce] 62 | else: 63 | line = line[:mlcs] + '"""' + line[mlcs+2:mlce] + '"""' + line[mlce+2:] 64 | else: # they are *not* together 65 | line = line[mlce+2:mlcs] 66 | else: # only the beginning is in this line, treat like a single-line comment for now 67 | line = line[:mlcs] 68 | incomment = True 69 | elif incomment: # no mlc-starter found... are we incomment? then ignore until the end of comment 70 | if (mlce>-1): 71 | line = line[mlce+2:] 72 | incomment = False 73 | else: 74 | line = '' 75 | if incomment: # if we're still incomment, this whole line is comment 76 | continue 77 | 78 | # chop initial and trailing whitespace 79 | line = line.strip() 80 | 81 | # now we can actually parse the line 82 | if (line.startswith("#define ")): 83 | line = line[8:].strip() # peel off any additional spaces after the #define 84 | pieces = line.split(" ", 1) 85 | if len(pieces)<2: 86 | continue 87 | name, value = pieces 88 | if "(" in name: 89 | print >>sys.stderr,("SKIPPING: %s"%(line)) 90 | continue # skip adding "function" defines 91 | defs[name.strip()] = value.strip() 92 | 93 | elif (line.startswith("SFR(")): 94 | endparen = line.find(")") 95 | if (endparen == -1): 96 | print >>sys.stderr,("ERROR: SFR without end parens: '%s'"%(line)) 97 | continue 98 | line = line[4:endparen].strip() 99 | name, value = line.split(",", 1) 100 | defs[name.strip()] = value.strip() 101 | elif (line.startswith("SFRX(")): 102 | endparen = line.find(")") 103 | if (endparen == -1): 104 | print >>sys.stderr,("ERROR: SFRX without end parens: '%s'"%(line)) 105 | continue 106 | line = line[5:endparen].strip() 107 | name, value = line.split(",", 1) 108 | defs[name.strip()] = value.strip() 109 | elif (line.startswith("SBIT")): 110 | endparen = line.find(")") 111 | if (endparen == -1): 112 | print >>sys.stderr,("ERROR: SBIT without end parens: '%s'"%(line)) 113 | continue 114 | line = line[5:endparen].strip() 115 | name, val1, val2 = line.split(",", 2) 116 | defs[name.strip()] = 1 << (int(val2.strip())) 117 | 118 | return defs 119 | 120 | 121 | if __name__ == '__main__': 122 | defs = {} 123 | defs.update(parseLines(file('../includes/cc1110-ext.h'))) 124 | defs.update(parseLines(file('../includes/cc1111.h'))) 125 | defs.update(parseLines(file('/usr/share/sdcc/include/mcs51/cc1110.h'))) 126 | 127 | skeys = defs.keys() 128 | skeys.sort() 129 | out = ["%-30s = %s"%(key,defs[key]) for key in skeys] 130 | 131 | trueout = [] 132 | for x in out: 133 | try: 134 | compile(x,'stdin','exec') 135 | trueout.append(x) 136 | print(x) 137 | except: 138 | sys.excepthook(*sys.exc_info()) 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /rflib/ccrecvdump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys, serial 3 | 4 | port = "ACM0" 5 | if len(sys.argv) > 1: 6 | port = sys.argv.pop() 7 | 8 | dport = "/dev/tty" + port 9 | 10 | print "Opening serial port %s for listening..." % dport 11 | s=serial.Serial(dport, 115200) 12 | 13 | counter = 0 14 | while True: 15 | print ("%d: %s" % (counter, repr(s.read(12)))) 16 | counter += 1 17 | #sys.stdout.write(s.read(1)) 18 | #sys.stdout.flush() 19 | -------------------------------------------------------------------------------- /rflib/rflib_defs.py: -------------------------------------------------------------------------------- 1 | # firmware errors 2 | LCE_NO_ERROR = 0x00 3 | LCE_USB_EP5_TX_WHILE_INBUF_WRITTEN = 0x01 4 | LCE_USB_EP0_SENT_STALL = 0x04 5 | LCE_USB_EP5_OUT_WHILE_OUTBUF_WRITTEN = 0x05 6 | LCE_USB_EP5_LEN_TOO_BIG = 0x06 7 | LCE_USB_EP5_GOT_CRAP = 0x07 8 | LCE_USB_EP5_STALL = 0x08 9 | LCE_USB_DATA_LEFTOVER_FLAGS = 0x09 10 | 11 | LCE_RF_RXOVF = 0x10 12 | LCE_RF_TXUNF = 0x11 13 | LCE_DROPPED_PACKET = 0x12 14 | LCE_RFTX_NEVER_TX = 0x13 15 | LCE_RFTX_NEVER_LEAVE_TX = 0x14 16 | LCE_RF_MODE_INCOMPAT = 0x15 17 | LCE_RF_BLOCKSIZE_INCOMPAT = 0x16 18 | LCE_RF_MULTI_BUFFER_NOT_INIT = 0x17 19 | LCE_RF_MULTI_BUFFER_NOT_FREE = 0x18 20 | 21 | RC_NO_ERROR = 0x00 22 | RC_TX_DROPPED_PACKET = 0xec 23 | RC_TX_ERROR = 0xed 24 | RC_RF_BLOCKSIZE_INCOMPAT = 0xee 25 | RC_RF_MODE_INCOMPAT = 0xef 26 | RC_TEMP_ERR_BUFFER_NOT_AVAILABLE = 0xfe # temporary error - retry! 27 | RC_ERR_BUFFER_SIZE_EXCEEDED = 0xff 28 | RC_FAIL_TRANSMIT_LONG = 0xffff 29 | 30 | # python client only errors 31 | PY_NO_ERROR = 0x00 32 | PY_TX_BLOCKSIZE_INCOMPAT = 0xd0 # block > 255 bytes but with with repeat or offset specified 33 | PY_TX_BLOCKSIZE_TOO_LARGE = 0xda # block > 65535 (we could make this bigger by using a u32 for size) 34 | -------------------------------------------------------------------------------- /rflib/rflib_version.py: -------------------------------------------------------------------------------- 1 | RFLIB_VERSION=397 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | from distutils.core import setup, Extension 4 | 5 | packages = ['rflib', 'vstruct', 'vstruct.defs'] 6 | mods = [] 7 | pkgdata = {} 8 | scripts = ['rfcat', 'rfcat_server', 'rfcat_msfrelay', 'CC-Bootloader/rfcat_bootloader', 9 | ] 10 | 11 | # store the HG revision in an rflib python file 12 | try: 13 | REV = os.popen('./revision.sh').readline() 14 | if len(REV): 15 | file('rflib/rflib_version.py', 'wb').write( "RFLIB_VERSION=%s" % REV) 16 | except: 17 | sys.excepthook(*sys.exc_info()) 18 | 19 | setup (name = 'rfcat', 20 | version = '1.0', 21 | description = "the swiss army knife of subGHz", 22 | author = 'atlas of d00m', 23 | author_email = 'atlas@r4780y.com', 24 | #include_dirs = [], 25 | packages = packages, 26 | package_data = pkgdata, 27 | ext_modules = mods, 28 | scripts = scripts 29 | ) 30 | 31 | 32 | -------------------------------------------------------------------------------- /vstruct/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | import struct 3 | from StringIO import StringIO 4 | 5 | import vstruct.primitives as vs_prims 6 | 7 | def isVstructType(x): 8 | return isinstance(x, vs_prims.v_base) 9 | 10 | class VStruct(vs_prims.v_base): 11 | 12 | def __init__(self, bigend=False): 13 | # A tiny bit of evil... 14 | object.__setattr__(self, "_vs_values", {}) 15 | vs_prims.v_base.__init__(self) 16 | self._vs_name = self.__class__.__name__ 17 | self._vs_fields = [] 18 | self._vs_field_align = False # To toggle visual studio style packing 19 | self._vs_padnum = 0 20 | self._vs_fmtbase = '<' 21 | if bigend: 22 | self._vs_fmtbase = '>' 23 | 24 | def vsGetClassPath(self): 25 | ''' 26 | Return the entire class name (including module path). 27 | ''' 28 | return '%s.%s' % (self.__module__, self._vs_name) 29 | 30 | def vsParse(self, bytes, offset=0): 31 | """ 32 | For all the primitives contained within, allow them 33 | an opportunity to parse the given data and return the 34 | total offset... 35 | """ 36 | plist = self.vsGetPrims() 37 | fmt = self.vsGetFormat() 38 | size = struct.calcsize(fmt) 39 | vals = struct.unpack(fmt, bytes[offset:offset+size]) 40 | for i in range(len(plist)): 41 | plist[i].vsSetParsedValue(vals[i]) 42 | 43 | def vsEmit(self): 44 | """ 45 | Get back the byte sequence associated with this structure. 46 | """ 47 | fmt = self.vsGetFormat() 48 | r = [] 49 | for p in self.vsGetPrims(): 50 | r.append(p.vsGetFmtValue()) 51 | return struct.pack(fmt, *r) 52 | 53 | def vsGetFormat(self): 54 | """ 55 | Return the format specifier which would then be used 56 | """ 57 | # Unpack everything little endian, let vsParseValue deal... 58 | ret = self._vs_fmtbase 59 | for p in self.vsGetPrims(): 60 | ret += p.vsGetFormat() 61 | return ret 62 | 63 | def vsIsPrim(self): 64 | return False 65 | 66 | def vsGetFields(self): 67 | ret = [] 68 | for fname in self._vs_fields: 69 | fobj = self._vs_values.get(fname) 70 | ret.append((fname,fobj)) 71 | return ret 72 | 73 | def vsGetField(self, name): 74 | x = self._vs_values.get(name) 75 | if x == None: 76 | raise Exception("Invalid field: %s" % name) 77 | return x 78 | 79 | def vsHasField(self, name): 80 | return self._vs_values.get(name) != None 81 | 82 | def vsSetField(self, name, value): 83 | if isVstructType(value): 84 | self._vs_values[name] = value 85 | return 86 | x = self._vs_values.get(name) 87 | return x.vsSetValue(value) 88 | 89 | # FIXME implement more arithmetic for structs... 90 | def __ixor__(self, other): 91 | for name,value in other._vs_values.items(): 92 | self._vs_values[name] ^= value 93 | return self 94 | 95 | def vsAddField(self, name, value): 96 | if not isVstructType(value): 97 | raise Exception("Added fields MUST be vstruct types!") 98 | 99 | # Do optional field alignment... 100 | if self._vs_field_align: 101 | 102 | # If it's a primitive, all is well, if not, pad to size of 103 | # the first element of the VStruct/VArray... 104 | if value.vsIsPrim(): 105 | align = len(value) 106 | else: 107 | fname = value._vs_fields[0] 108 | align = len(value._vs_values.get(fname)) 109 | 110 | delta = len(self) % align 111 | if delta != 0: 112 | print "PADDING %s by %d" % (name,align-delta) 113 | pname = "_pad%d" % self._vs_padnum 114 | self._vs_padnum += 1 115 | self._vs_fields.append(pname) 116 | self._vs_values[pname] = vs_prims.v_bytes(align-delta) 117 | 118 | self._vs_fields.append(name) 119 | self._vs_values[name] = value 120 | 121 | def vsGetPrims(self): 122 | """ 123 | return an order'd list of the primitive fields in this 124 | structure definition. This is recursive and will return 125 | the sub fields of all nested structures. 126 | """ 127 | ret = [] 128 | for name, field in self.vsGetFields(): 129 | if field.vsIsPrim(): 130 | ret.append(field) 131 | else: 132 | ret.extend(field.vsGetPrims()) 133 | 134 | return ret 135 | 136 | def vsGetTypeName(self): 137 | return self._vs_name 138 | 139 | def vsGetOffset(self, name): 140 | """ 141 | Return the offset of a member. 142 | """ 143 | offset = 0 144 | for fname in self._vs_fields: 145 | if name == fname: 146 | return offset 147 | x = self._vs_values.get(fname) 148 | offset += len(x) 149 | raise Exception("Invalid Field Specified!") 150 | 151 | def vsGetPrintInfo(self, offset=0, indent=0, top=True): 152 | ret = [] 153 | if top: 154 | ret.append((offset, indent, self._vs_name, self)) 155 | indent += 1 156 | for fname in self._vs_fields: 157 | x = self._vs_values.get(fname) 158 | off = offset + self.vsGetOffset(fname) 159 | if isinstance(x, VStruct): 160 | ret.append((off, indent, fname, x)) 161 | ret.extend(x.vsGetPrintInfo(offset=off, indent=indent, top=False)) 162 | else: 163 | ret.append((off, indent, fname, x)) 164 | return ret 165 | 166 | def __len__(self): 167 | fmt = self.vsGetFormat() 168 | return struct.calcsize(fmt) 169 | 170 | def __getattr__(self, name): 171 | # Gotta do this for pickle issues... 172 | vsvals = self.__dict__.get("_vs_values") 173 | if vsvals == None: 174 | vsvals = {} 175 | self.__dict__["_vs_values"] = vsvals 176 | r = vsvals.get(name) 177 | if r is None: 178 | raise AttributeError(name) 179 | if isinstance(r, vs_prims.v_prim): 180 | return r.vsGetValue() 181 | return r 182 | 183 | def __setattr__(self, name, value): 184 | # If we have this field, asign to it 185 | x = self._vs_values.get(name, None) 186 | if x != None: 187 | return self.vsSetField(name, value) 188 | 189 | # If it's a vstruct type, create a new field 190 | if isVstructType(value): 191 | return self.vsAddField(name, value) 192 | 193 | # Fail over to standard object attribute behavior 194 | return object.__setattr__(self, name, value) 195 | 196 | def __iter__(self): 197 | # Our iteration returns name,field pairs 198 | ret = [] 199 | for name in self._vs_fields: 200 | ret.append((name, self._vs_values.get(name))) 201 | return iter(ret) 202 | 203 | def __repr__(self): 204 | return self._vs_name 205 | 206 | def tree(self, va=0, reprmax=None): 207 | ret = "" 208 | for off, indent, name, field in self.vsGetPrintInfo(): 209 | rstr = field.vsGetTypeName() 210 | if isinstance(field, vs_prims.v_number): 211 | val = field.vsGetValue() 212 | rstr = '0x%.8x (%d)' % (val,val) 213 | elif isinstance(field, vs_prims.v_prim): 214 | rstr = repr(field) 215 | if reprmax != None and len(rstr) > reprmax: 216 | rstr = rstr[:reprmax] + '...' 217 | ret += "%.8x (%.2d)%s %s: %s\n" % (va+off, len(field), " "*(indent*2),name,rstr) 218 | return ret 219 | 220 | class VArray(VStruct): 221 | 222 | def __init__(self, elems=()): 223 | VStruct.__init__(self) 224 | for e in elems: 225 | self.vsAddElement(e) 226 | 227 | def vsAddElement(self, elem): 228 | """ 229 | Used to add elements to an array 230 | """ 231 | idx = len(self._vs_fields) 232 | self.vsAddField("%d" % idx, elem) 233 | 234 | def __getitem__(self, index): 235 | return self.vsGetField("%d" % index) 236 | 237 | #FIXME slice asignment 238 | 239 | def resolve(impmod, nameparts): 240 | """ 241 | Resolve the given (potentially nested) object 242 | from within a module. 243 | """ 244 | if not nameparts: 245 | return None 246 | 247 | m = impmod 248 | for nname in nameparts: 249 | m = getattr(m, nname, None) 250 | if m == None: 251 | break 252 | 253 | return m 254 | 255 | # NOTE: Gotta import this *after* VStruct/VSArray defined 256 | import vstruct.defs as vs_defs 257 | 258 | def getStructure(sname): 259 | """ 260 | Return an instance of the specified structure. The 261 | structure name may be a definition that was added with 262 | addStructure() or a python path (ie. win32.TEB) of a 263 | definition from within vstruct.defs. 264 | """ 265 | x = resolve(vs_defs, sname.split(".")) 266 | if x != None: 267 | return x() 268 | 269 | return None 270 | 271 | def getModuleNames(): 272 | return [x for x in dir(vs_defs) if not x.startswith("__")] 273 | 274 | def getStructNames(modname): 275 | ret = [] 276 | mod = resolve(vs_defs, modname) 277 | if mod == None: 278 | return ret 279 | 280 | for n in dir(mod): 281 | x = getattr(mod, n) 282 | if issubclass(x, VStruct): 283 | ret.append(n) 284 | 285 | return ret 286 | 287 | -------------------------------------------------------------------------------- /vstruct/builder.py: -------------------------------------------------------------------------------- 1 | ''' 2 | 3 | VStruct builder! Used to serialize structure definitions etc... 4 | 5 | ''' 6 | 7 | import types 8 | import inspect 9 | import vstruct 10 | import vstruct.primitives as vs_prim 11 | 12 | prim_types = [ None, 13 | vs_prim.v_uint8, 14 | vs_prim.v_uint16, 15 | None, 16 | vs_prim.v_uint32, 17 | None, None, None, 18 | vs_prim.v_uint64 19 | ] 20 | 21 | # VStruct Field Flags 22 | VSFF_ARRAY = 1 23 | VSFF_POINTER = 2 24 | 25 | class VStructConstructor: 26 | def __init__(self, builder, vsname): 27 | self.builder = builder 28 | self.vsname = vsname 29 | 30 | def __call__(self, *args, **kwargs): 31 | return self.builder.buildVStruct(self.vsname) 32 | 33 | class VStructBuilder: 34 | 35 | def __init__(self, defs=(), enums=()): 36 | self._vs_defs = {} 37 | self._vs_enums = {} 38 | self._vs_namespaces = {} 39 | for vsdef in defs: 40 | self.addVStructDef(vsdef) 41 | for enum in enums: 42 | self.addVStructEnumeration(enum) 43 | 44 | def __getattr__(self, name): 45 | ns = self._vs_namespaces.get(name) 46 | if ns != None: 47 | return ns 48 | 49 | vsdef = self._vs_defs.get(name) 50 | if vsdef != None: 51 | return VStructConstructor(self, name) 52 | 53 | raise AttributeError, name 54 | 55 | def addVStructEnumeration(self, enum): 56 | self._vs_enums[enum[0]] = enum 57 | 58 | def addVStructNamespace(self, name, builder): 59 | self._vs_namespaces[name] = builder 60 | 61 | def getVStructNamespaces(self): 62 | return self._vs_namespaces.items() 63 | 64 | def getVStructNamespaceNames(self): 65 | return self._vs_namespaces.keys() 66 | 67 | def hasVStructNamespace(self, namespace): 68 | return self._vs_namespaces.get(namespace, None) != None 69 | 70 | def getVStructNames(self, namespace=None): 71 | if namespace == None: 72 | return self._vs_defs.keys() 73 | nsmod = self._vs_namespaces.get(namespace) 74 | ret = [] 75 | for name in dir(nsmod): 76 | nobj = getattr(nsmod, name) 77 | if not inspect.isclass(nobj): 78 | continue 79 | if issubclass(nobj, vstruct.VStruct): 80 | ret.append(name) 81 | return ret 82 | 83 | def addVStructDef(self, vsdef): 84 | vsname = vsdef[0] 85 | self._vs_defs[vsname] = vsdef 86 | 87 | def buildVStruct(self, vsname): 88 | # Check for a namespace 89 | parts = vsname.split('.', 1) 90 | if len(parts) == 2: 91 | ns = self._vs_namespaces.get(parts[0]) 92 | if ns == None: 93 | raise Exception('Namespace %s is not present! (need symbols?)' % parts[0]) 94 | 95 | # If a module gets added as a namespace, assume it has a class def... 96 | if isinstance(ns, types.ModuleType): 97 | cls = getattr(ns, parts[1]) 98 | if cls == None: 99 | raise Exception('Unknown VStruct Definition: %s' % vsname) 100 | return cls() 101 | 102 | return ns.buildVStruct(parts[1]) 103 | 104 | vsdef = self._vs_defs.get(vsname) 105 | if vsdef == None: 106 | raise Exception('Unknown VStruct Definition: %s' % vsname) 107 | 108 | vsname, vssize, vskids = vsdef 109 | 110 | vs = vstruct.VStruct() 111 | vs._vs_name = vsname 112 | 113 | for fname, foffset, fsize, ftypename, fflags in vskids: 114 | 115 | if fflags & VSFF_POINTER: 116 | # FIXME support pointers with types! 117 | if fsize == 4: 118 | fieldval = vs_prim.v_ptr32() 119 | 120 | elif fsize == 8: 121 | fieldval = vs_prim.v_ptr64() 122 | 123 | else: 124 | raise Exception('Invalid Pointer Width: %d' % fsize) 125 | 126 | elif fflags & VSFF_ARRAY: 127 | if ftypename != None: 128 | fieldval = vstruct.VArray() 129 | while len(fieldval) < fsize: 130 | fieldval.vsAddElement( self.buildVStruct(ftypename) ) 131 | else: 132 | # FIXME actually handle arrays! 133 | fieldval = vs_prim.v_bytes(size=fsize) 134 | 135 | elif ftypename == None: 136 | 137 | if fsize not in [1,2,4,8]: 138 | #print 'Primitive Field Size: %d' % fsize 139 | fieldval = v_bytes(size=fsize) 140 | 141 | else: 142 | fieldval = prim_types[fsize]() 143 | 144 | else: 145 | fieldval = self.buildVStruct(ftypename) 146 | 147 | cursize = len(vs) 148 | if foffset < cursize: 149 | #print 'FIXME handle unions, overlaps, etc...' 150 | continue 151 | 152 | if foffset > cursize: 153 | setattr(vs, '_pad%.4x' % foffset, vs_prim.v_bytes(size=(foffset-cursize))) 154 | 155 | setattr(vs, fname, fieldval) 156 | 157 | return vs 158 | 159 | def genVStructPyCode(self): 160 | ret = 'import vstruct\n' 161 | ret += 'from vstruct.primitives import *' 162 | ret += '\n\n' 163 | 164 | for ename, esize, ekids in self._vs_enums.values(): 165 | ret += '%s = v_enum()\n' % ename 166 | for kname, kval in ekids: 167 | ret += '%s.%s = %d\n' % (ename,kname,kval) 168 | ret += '\n\n' 169 | 170 | 171 | for vsname, vsize, vskids in self._vs_defs.values(): 172 | ret += 'class %s(vstruct.VStruct):\n' % vsname 173 | ret += ' def __init__(self):\n' 174 | ret += ' vstruct.VStruct.__init__(self)\n' 175 | offset = 0 176 | for fname, foffset, fsize, ftypename, fflags in vskids: 177 | 178 | if foffset < offset: 179 | continue 180 | 181 | if foffset > offset: 182 | ret += ' self._pad%.4x = v_bytes(size=%d)\n' % (foffset, foffset-offset) 183 | offset += (foffset - offset) 184 | 185 | if fflags & VSFF_POINTER: 186 | if fsize == 4: 187 | fconst = 'v_ptr32()' 188 | elif fsize == 8: 189 | fconst = 'v_ptr64()' 190 | else: 191 | fconst = 'v_bytes(size=%d) # FIXME should be pointer!' % fsize 192 | 193 | elif fflags & VSFF_ARRAY: 194 | if ftypename != None: 195 | '[ %s() for i in xrange( %d / len(%s())) ]' % (ftypename, fsize, ftypename) 196 | else: 197 | fconst = 'v_bytes(size=%d) # FIXME Unknown Array Type' % fsize 198 | 199 | elif ftypename == None: 200 | if fsize == 1: 201 | fconst = 'v_uint8()' 202 | elif fsize == 2: 203 | fconst = 'v_uint16()' 204 | elif fsize == 4: 205 | fconst = 'v_uint32()' 206 | elif fsize == 8: 207 | fconst = 'v_uint64()' 208 | else: 209 | fconst = 'v_bytes(size=%d)' % fsize 210 | else: 211 | fconst = '%s()' % ftypename 212 | 213 | 214 | ret += ' self.%s = %s\n' % (fname, fconst) 215 | offset += fsize 216 | ret += '\n\n' 217 | 218 | return ret 219 | 220 | if __name__ == '__main__': 221 | # Parse windows structures from dll symbols... 222 | import os 223 | import sys 224 | import platform 225 | 226 | from pprint import pprint 227 | 228 | import PE 229 | import vtrace.platforms.win32 as vt_win32 230 | 231 | p = PE.PE(file(sys.argv[1], 'rb')) 232 | baseaddr = p.IMAGE_NT_HEADERS.OptionalHeader.ImageBase 233 | osmajor = p.IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion 234 | osminor = p.IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion 235 | machine = p.IMAGE_NT_HEADERS.FileHeader.Machine 236 | 237 | archname = PE.machine_names.get(machine) 238 | 239 | parser = vt_win32.Win32SymbolParser(0xffffffff, sys.argv[1], baseaddr) 240 | parser.parse() 241 | 242 | t = parser._sym_types.values() 243 | e = parser._sym_enums.values() 244 | builder = VStructBuilder(defs=t, enums=e) 245 | 246 | print '# Version: %d.%d' % (osmajor, osminor) 247 | print '# Architecture: %s' % archname 248 | print builder.genVStructPyCode() 249 | 250 | -------------------------------------------------------------------------------- /vstruct/defs/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # Import all local structure modules 3 | import elf 4 | import pe 5 | import win32 6 | 7 | -------------------------------------------------------------------------------- /vstruct/defs/elf.py: -------------------------------------------------------------------------------- 1 | import vstruct 2 | from vstruct.primitives import * 3 | 4 | EI_NIDENT = 4 5 | EI_PADLEN = 7 6 | 7 | class Elf32(vstruct.VStruct): 8 | def __init__(self): 9 | vstruct.VStruct.__init__(self) 10 | self.e_ident = v_bytes(EI_NIDENT) 11 | self.e_class = v_uint8() 12 | self.e_data = v_uint8() 13 | self.e_fileversion = v_uint8() 14 | self.e_osabi = v_uint8() 15 | self.e_abiversio = v_uint8() 16 | self.e_pad = v_bytes(EI_PADLEN) 17 | self.e_type = v_uint16() 18 | self.e_machine = v_uint16() 19 | self.e_version = v_uint32() 20 | self.e_entry = v_uint32() 21 | self.e_phoff = v_uint32() 22 | self.e_shoff = v_uint32() 23 | self.e_flags = v_uint32() 24 | self.e_ehsize = v_uint16() 25 | self.e_phentsize = v_uint16() 26 | self.e_phnum = v_uint16() 27 | self.e_shentsize = v_uint16() 28 | self.e_shnum = v_uint16() 29 | self.e_shstrndx = v_uint16() 30 | 31 | class Elf32Section(vstruct.VStruct): 32 | def __init__(self): 33 | vstruct.VStruct.__init__(self) 34 | self.sh_name = v_uint32() 35 | self.sh_type = v_uint32() 36 | self.sh_flags = v_uint32() 37 | self.sh_addr = v_uint32() 38 | self.sh_offset = v_uint32() 39 | self.sh_size = v_uint32() 40 | self.sh_link = v_uint32() 41 | self.sh_info = v_uint32() 42 | self.sh_addralign = v_uint32() 43 | self.sh_entsize = v_uint32() 44 | 45 | class Elf32Pheader(vstruct.VStruct): 46 | def __init__(self): 47 | vstruct.VStruct.__init__(self) 48 | self.p_type = v_uint32() 49 | self.p_offset = v_uint32() 50 | self.p_vaddr = v_uint32() 51 | self.p_paddr = v_uint32() 52 | self.p_filesz = v_uint32() 53 | self.p_memsz = v_uint32() 54 | self.p_flags = v_uint32() 55 | self.p_align = v_uint32() 56 | 57 | class Elf32Reloc(vstruct.VStruct): 58 | def __init__(self): 59 | vstruct.VStruct.__init__(self) 60 | self.r_offset = v_ptr32() 61 | self.r_info = v_uint32() 62 | 63 | class Elf32Reloca(Elf32Reloc): 64 | def __init__(self): 65 | Elf32Reloc.__init__(self) 66 | self.r_addend = v_uint32() 67 | 68 | class Elf32Symbol(vstruct.VStruct): 69 | def __init__(self): 70 | vstruct.VStruct.__init__(self) 71 | self.st_name = v_uint32() 72 | self.st_value = v_uint32() 73 | self.st_size = v_uint32() 74 | self.st_info = v_uint8() 75 | self.st_other = v_uint8() 76 | self.st_shndx = v_uint16() 77 | 78 | class Elf32Dynamic(vstruct.VStruct): 79 | def __init__(self): 80 | vstruct.VStruct.__init__(self) 81 | self.d_tag = v_uint32() 82 | self.d_value = v_uint32() 83 | 84 | 85 | class Elf64(vstruct.VStruct): 86 | def __init__(self): 87 | vstruct.VStruct.__init__(self) 88 | self.e_ident = v_bytes(EI_NIDENT) 89 | self.e_class = v_uint8() 90 | self.e_data = v_uint8() 91 | self.e_fileversion = v_uint8() 92 | self.e_osabi = v_uint8() 93 | self.e_abiversio = v_uint8() 94 | self.e_pad = v_bytes(EI_PADLEN) 95 | self.e_type = v_uint16() 96 | self.e_machine = v_uint16() 97 | self.e_version = v_uint32() 98 | self.e_entry = v_uint64() 99 | self.e_phoff = v_uint64() 100 | self.e_shoff = v_uint64() 101 | self.e_flags = v_uint32() 102 | self.e_ehsize = v_uint16() 103 | self.e_phentsize = v_uint16() 104 | self.e_phnum = v_uint16() 105 | self.e_shentsize = v_uint16() 106 | self.e_shnum = v_uint16() 107 | self.e_shstrndx = v_uint16() 108 | 109 | class Elf64Section(Elf32Section): 110 | def __init__(self): 111 | vstruct.VStruct.__init__(self) 112 | self.sh_name = v_uint32() 113 | self.sh_type = v_uint32() 114 | self.sh_flags = v_uint64() 115 | self.sh_addr = v_uint64() 116 | self.sh_offset = v_uint64() 117 | self.sh_size = v_uint64() 118 | self.sh_link = v_uint32() 119 | self.sh_info = v_uint32() 120 | self.sh_addralign = v_uint64() 121 | self.sh_entsize = v_uint64() 122 | 123 | class Elf64Pheader(Elf32Pheader): 124 | def __init__(self): 125 | vstruct.VStruct.__init__(self) 126 | self.p_type = v_uint32() 127 | self.p_flags = v_uint32() 128 | self.p_offset = v_uint64() 129 | self.p_vaddr = v_uint64() 130 | self.p_paddr = v_uint64() 131 | self.p_filesz = v_uint64() 132 | self.p_memsz = v_uint64() 133 | self.p_align = v_uint64() 134 | 135 | 136 | class Elf64Reloc(vstruct.VStruct): 137 | def __init__(self): 138 | vstruct.VStruct.__init__(self) 139 | self.r_offset = v_ptr64() 140 | self.r_info = v_uint64() 141 | 142 | class Elf64Reloca(Elf64Reloc): 143 | def __init__(self): 144 | #Elf64Reloc.__init__(self) 145 | vstruct.VStruct.__init__(self) 146 | self.r_offset = v_uint64() 147 | self.r_info = v_uint64() 148 | self.r_addend = v_uint64() 149 | 150 | class Elf64Symbol(vstruct.VStruct): 151 | def __init__(self): 152 | vstruct.VStruct.__init__(self) 153 | self.st_name = v_uint32() 154 | self.st_info = v_uint8() 155 | self.st_other = v_uint8() 156 | self.st_shndx = v_uint16() 157 | self.st_value = v_uint64() 158 | self.st_size = v_uint64() 159 | 160 | class Elf64Dynamic(Elf32Dynamic): 161 | pass 162 | 163 | -------------------------------------------------------------------------------- /vstruct/defs/kdcom.py: -------------------------------------------------------------------------------- 1 | """ 2 | Initial module with supporting structures for windows 3 | kernel serial debugging. 4 | """ 5 | 6 | import vstruct 7 | from vstruct.primitives import * 8 | 9 | # Main packet magic bytes and such 10 | BREAKIN_PACKET = 0x62626262 11 | BREAKIN_PACKET_BYTE = 0x62 12 | PACKET_LEADER = 0x30303030 13 | PACKET_LEADER_BYTE = 0x30 14 | CONTROL_PACKET_LEADER = 0x69696969 15 | CONTROL_PACKET_LEADER_BYTE = 0x69 16 | PACKET_TRAILING_BYTE = 0xAA 17 | 18 | pkt_magic_names = { 19 | BREAKIN_PACKET:"Break Packet", 20 | PACKET_LEADER:"Packet", 21 | CONTROL_PACKET_LEADER:"Control Packet", 22 | } 23 | 24 | # Primary "packet types" 25 | PACKET_TYPE_UNUSED = 0 26 | PACKET_TYPE_KD_STATE_CHANGE32 = 1 27 | PACKET_TYPE_KD_STATE_MANIPULATE = 2 28 | PACKET_TYPE_KD_DEBUG_IO = 3 29 | PACKET_TYPE_KD_ACKNOWLEDGE = 4 30 | PACKET_TYPE_KD_RESEND = 5 31 | PACKET_TYPE_KD_RESET = 6 32 | PACKET_TYPE_KD_STATE_CHANGE64 = 7 33 | PACKET_TYPE_KD_POLL_BREAKIN = 8 34 | PACKET_TYPE_KD_TRACE_IO = 9 35 | PACKET_TYPE_KD_CONTROL_REQUEST = 10 36 | PACKET_TYPE_KD_FILE_IO = 11 37 | PACKET_TYPE_MAX = 12 38 | 39 | pkt_type_names = { 40 | PACKET_TYPE_UNUSED:"Unused", 41 | PACKET_TYPE_KD_STATE_CHANGE32:"State Change32", 42 | PACKET_TYPE_KD_STATE_MANIPULATE:"Manipulate", 43 | PACKET_TYPE_KD_DEBUG_IO:"Debug IO", 44 | PACKET_TYPE_KD_ACKNOWLEDGE:"Ack", 45 | PACKET_TYPE_KD_RESEND:"Resend", 46 | PACKET_TYPE_KD_RESET:"Reset", 47 | PACKET_TYPE_KD_STATE_CHANGE64:"State Change64", 48 | PACKET_TYPE_KD_POLL_BREAKIN:"Breakin", 49 | PACKET_TYPE_KD_TRACE_IO:"Trace IO", 50 | PACKET_TYPE_KD_CONTROL_REQUEST:"Control Request", 51 | PACKET_TYPE_KD_FILE_IO:"File IO", 52 | PACKET_TYPE_MAX:"Max", 53 | } 54 | 55 | # Wait State Change Types 56 | DbgKdMinimumStateChange = 0x00003030 57 | DbgKdExceptionStateChange = 0x00003030 58 | DbgKdLoadSymbolsStateChange = 0x00003031 59 | DbgKdCommandStringStateChange = 0x00003032 60 | DbgKdMaximumStateChange = 0x00003033 61 | 62 | pkt_sub_wait_state_change = { 63 | DbgKdMinimumStateChange:"DbgKdMinimumStateChange", 64 | DbgKdExceptionStateChange:"DbgKdExceptionStateChange", 65 | DbgKdLoadSymbolsStateChange:"DbgKdLoadSymbolsStateChange", 66 | DbgKdCommandStringStateChange:"DbgKdCommandStringStateChange", 67 | DbgKdMaximumStateChange:"DbgKdMaximumStateChange", 68 | } 69 | 70 | # Manipulate Types 71 | DbgKdMinimumManipulate = 0x00003130 72 | DbgKdReadVirtualMemoryApi = 0x00003130 73 | DbgKdWriteVirtualMemoryApi = 0x00003131 74 | DbgKdGetContextApi = 0x00003132 75 | DbgKdSetContextApi = 0x00003133 76 | DbgKdWriteBreakPointApi = 0x00003134 77 | DbgKdRestoreBreakPointApi = 0x00003135 78 | DbgKdContinueApi = 0x00003136 79 | DbgKdReadControlSpaceApi = 0x00003137 80 | DbgKdWriteControlSpaceApi = 0x00003138 81 | DbgKdReadIoSpaceApi = 0x00003139 82 | DbgKdWriteIoSpaceApi = 0x0000313A 83 | DbgKdRebootApi = 0x0000313B 84 | DbgKdContinueApi2 = 0x0000313C 85 | DbgKdReadPhysicalMemoryApi = 0x0000313D 86 | DbgKdWritePhysicalMemoryApi = 0x0000313E 87 | DbgKdQuerySpecialCallsApi = 0x0000313F 88 | DbgKdSetSpecialCallApi = 0x00003140 89 | DbgKdClearSpecialCallsApi = 0x00003141 90 | DbgKdSetInternalBreakPointApi = 0x00003142 91 | DbgKdGetInternalBreakPointApi = 0x00003143 92 | DbgKdReadIoSpaceExtendedApi = 0x00003144 93 | DbgKdWriteIoSpaceExtendedApi = 0x00003145 94 | DbgKdGetVersionApi = 0x00003146 95 | DbgKdWriteBreakPointExApi = 0x00003147 96 | DbgKdRestoreBreakPointExApi = 0x00003148 97 | DbgKdCauseBugCheckApi = 0x00003149 98 | DbgKdSwitchProcessor = 0x00003150 99 | DbgKdPageInApi = 0x00003151 100 | DbgKdReadMachineSpecificRegister = 0x00003152 101 | DbgKdWriteMachineSpecificRegister = 0x00003153 102 | OldVlm1 = 0x00003154 103 | OldVlm2 = 0x00003155 104 | DbgKdSearchMemoryApi = 0x00003156 105 | DbgKdGetBusDataApi = 0x00003157 106 | DbgKdSetBusDataApi = 0x00003158 107 | DbgKdCheckLowMemoryApi = 0x00003159 108 | DbgKdClearAllInternalBreakpointsApi = 0x0000315A 109 | DbgKdFillMemoryApi = 0x0000315B 110 | DbgKdQueryMemoryApi = 0x0000315C 111 | DbgKdSwitchPartition = 0x0000315D 112 | DbgKdMaximumManipulate = 0x0000315E 113 | 114 | pkt_sub_manipulate = { 115 | DbgKdMinimumManipulate:"DbgKdMinimumManipulate", 116 | DbgKdReadVirtualMemoryApi:"DbgKdReadVirtualMemoryApi", 117 | DbgKdWriteVirtualMemoryApi:"DbgKdWriteVirtualMemoryApi", 118 | DbgKdGetContextApi:"DbgKdGetContextApi", 119 | DbgKdSetContextApi:"DbgKdSetContextApi", 120 | DbgKdWriteBreakPointApi:"DbgKdWriteBreakPointApi", 121 | DbgKdRestoreBreakPointApi:"DbgKdRestoreBreakPointApi", 122 | DbgKdContinueApi:"DbgKdContinueApi", 123 | DbgKdReadControlSpaceApi:"DbgKdReadControlSpaceApi", 124 | DbgKdWriteControlSpaceApi:"DbgKdWriteControlSpaceApi", 125 | DbgKdReadIoSpaceApi:"DbgKdReadIoSpaceApi", 126 | DbgKdWriteIoSpaceApi:"DbgKdWriteIoSpaceApi", 127 | DbgKdRebootApi:"DbgKdRebootApi", 128 | DbgKdContinueApi2:"DbgKdContinueApi2", 129 | DbgKdReadPhysicalMemoryApi:"DbgKdReadPhysicalMemoryApi", 130 | DbgKdWritePhysicalMemoryApi:"DbgKdWritePhysicalMemoryApi", 131 | DbgKdQuerySpecialCallsApi:"DbgKdQuerySpecialCallsApi", 132 | DbgKdSetSpecialCallApi:"DbgKdSetSpecialCallApi", 133 | DbgKdClearSpecialCallsApi:"DbgKdClearSpecialCallsApi", 134 | DbgKdSetInternalBreakPointApi:"DbgKdSetInternalBreakPointApi", 135 | DbgKdGetInternalBreakPointApi:"DbgKdGetInternalBreakPointApi", 136 | DbgKdReadIoSpaceExtendedApi:"DbgKdReadIoSpaceExtendedApi", 137 | DbgKdWriteIoSpaceExtendedApi:"DbgKdWriteIoSpaceExtendedApi", 138 | DbgKdGetVersionApi:"DbgKdGetVersionApi", 139 | DbgKdWriteBreakPointExApi:"DbgKdWriteBreakPointExApi", 140 | DbgKdRestoreBreakPointExApi:"DbgKdRestoreBreakPointExApi", 141 | DbgKdCauseBugCheckApi:"DbgKdCauseBugCheckApi", 142 | DbgKdSwitchProcessor:"DbgKdSwitchProcessor", 143 | DbgKdPageInApi:"DbgKdPageInApi", 144 | DbgKdReadMachineSpecificRegister:"DbgKdReadMachineSpecificRegister", 145 | DbgKdWriteMachineSpecificRegister:"DbgKdWriteMachineSpecificRegister", 146 | OldVlm1:"OldVlm1", 147 | OldVlm2:"OldVlm2", 148 | DbgKdSearchMemoryApi:"DbgKdSearchMemoryApi", 149 | DbgKdGetBusDataApi:"DbgKdGetBusDataApi", 150 | DbgKdSetBusDataApi:"DbgKdSetBusDataApi", 151 | DbgKdCheckLowMemoryApi:"DbgKdCheckLowMemoryApi", 152 | DbgKdClearAllInternalBreakpointsApi:"DbgKdClearAllInternalBreakpointsApi", 153 | DbgKdFillMemoryApi:"DbgKdFillMemoryApi", 154 | DbgKdQueryMemoryApi:"DbgKdQueryMemoryApi", 155 | DbgKdSwitchPartition:"DbgKdSwitchPartition", 156 | DbgKdMaximumManipulate:"DbgKdMaximumManipulate", 157 | } 158 | 159 | # Debug I/O Types 160 | DbgKdPrintStringApi = 0x00003230 161 | DbgKdGetStringApi = 0x00003231 162 | 163 | # Control Report Flags 164 | REPORT_INCLUDES_SEGS = 0x0001 165 | REPORT_INCLUDES_CS = 0x0002 166 | 167 | # Protocol Versions 168 | DBGKD_64BIT_PROTOCOL_VERSION1 = 5 169 | DBGKD_64BIT_PROTOCOL_VERSION2 = 6 170 | 171 | # Query Memory Address Spaces 172 | DBGKD_QUERY_MEMORY_VIRTUAL = 0 173 | DBGKD_QUERY_MEMORY_PROCESS = 0 174 | DBGKD_QUERY_MEMORY_SESSION = 1 175 | DBGKD_QUERY_MEMORY_KERNEL = 2 176 | 177 | # Query Memory Flags 178 | DBGKD_QUERY_MEMORY_READ = 0x01 179 | DBGKD_QUERY_MEMORY_WRITE = 0x02 180 | DBGKD_QUERY_MEMORY_EXECUTE = 0x04 181 | DBGKD_QUERY_MEMORY_FIXED = 0x08 182 | 183 | ULONG = v_uint32 184 | ULONG64 = v_uint64 185 | BOOLEAN = v_uint32 186 | 187 | class DBGKD_LOAD_SYMBOLS64(vstruct.VStruct): 188 | def __init__(self): 189 | vstruct.VStruct.__init__(self) 190 | self._vs_field_align = True 191 | self.PathNameLength = v_uint32() 192 | self.BaseOfDll = v_uint64() 193 | self.ProcessId = v_uint64() 194 | self.CheckSum = v_uint32() 195 | self.SizeOfImage = v_uint32() 196 | #self.UnloadSymbols = v_uint8() 197 | self.UnloadSymbols = v_uint32() # HACK must be 32 bit aligned 198 | 199 | class DBGKD_WAIT_STATE_CHANGE64(vstruct.VStruct): 200 | def __init__(self): 201 | vstruct.VStruct.__init__(self) 202 | self._vs_field_align = True 203 | self.NewState = v_uint32() 204 | self.ProcessorLevel = v_uint16() 205 | self.Processor = v_uint16() 206 | self.NumberProcessors = v_uint32() 207 | self.Thread = v_uint64() 208 | self.ProgramCounter = v_uint64() 209 | 210 | -------------------------------------------------------------------------------- /vstruct/defs/macho/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Structure definitions for the OSX MachO binary format. 3 | ''' 4 | 5 | import vstruct 6 | import vstruct.primitives as vs_prim 7 | 8 | from vstruct.defs.macho.const import * 9 | 10 | from vstruct.defs.macho.fat import * 11 | from vstruct.defs.macho.loader import * 12 | 13 | -------------------------------------------------------------------------------- /vstruct/defs/macho/const.py: -------------------------------------------------------------------------------- 1 | 2 | # Fat Defines... 3 | FAT_MAGIC = 0xcafebabe 4 | FAT_CIGAM = 0xbebafec #NXSwapLong(FAT_MAGIC) 5 | 6 | MH_MAGIC = 0xfeedface # the mach magic number 7 | MH_CIGAM = 0xcefaedfe # NXSwapInt(MH_MAGIC) 8 | MH_MAGIC_64 = 0xfeedfacf # the 64-bit mach magic number 9 | MH_CIGAM_64 = 0xcffaedfe # NXSwapInt(MH_MAGIC_64) 10 | MH_OBJECT = 0x1 # relocatable object file 11 | MH_EXECUTE = 0x2 # demand paged executable file 12 | MH_FVMLIB = 0x3 # fixed VM shared library file 13 | MH_CORE = 0x4 # core file 14 | MH_PRELOAD = 0x5 # preloaded executable file 15 | MH_DYLIB = 0x6 # dynamically bound shared library 16 | MH_DYLINKER = 0x7 # dynamic link editor 17 | MH_BUNDLE = 0x8 # dynamically bound bundle file 18 | MH_DYLIB_STUB = 0x9 # shared library stub for static 19 | MH_DSYM = 0xa # companion file with only debug 20 | MH_NOUNDEFS = 0x1 # the object file has no undefinedreferences 21 | MH_INCRLINK = 0x2 # the object file is the output of anincremental link against a base fileand can't be link edited again 22 | MH_DYLDLINK = 0x4 # the object file is input for thedynamic linker and can't be staticlylink edited again 23 | MH_BINDATLOAD = 0x8 # the object file's undefinedreferences are bound by the dynamiclinker when loaded. 24 | MH_PREBOUND = 0x10 # the file has its dynamic undefinedreferences prebound. 25 | MH_SPLIT_SEGS = 0x20 # the file has its read-only andread-write segments split 26 | MH_LAZY_INIT = 0x40 # the shared library init routine isto be run lazily via catching memoryfaults to its writeable segments(obsolete) 27 | MH_TWOLEVEL = 0x80 # the image is using two-level namespace bindings 28 | MH_FORCE_FLAT = 0x100 # the executable is forcing all imagesto use flat name space bindings 29 | MH_NOMULTIDEFS = 0x200 # this umbrella guarantees no multipledefintions of symbols in itssub-images so the two-level namespacehints can always be used. 30 | MH_NOFIXPREBINDING = 0x400 # do not have dyld notify theprebinding agent about thisexecutable 31 | MH_PREBINDABLE = 0x800 # the binary is not prebound but canhave its prebinding redone. only usedwhen MH_PREBOUND is not set. 32 | MH_ALLMODSBOUND = 0x1000 # this binary binds toall two-level namespace modules ofits dependent libraries. only usedwhen MH_PREBINDABLE and MH_TWOLEVELare both set. 33 | MH_CANONICAL = 0x4000 # the binary has been canonicalizedvia the unprebind operation 34 | MH_WEAK_DEFINES = 0x8000 # the final linked image containsexternal weak symbols 35 | MH_BINDS_TO_WEAK = 0x10000 # the final linked image usesweak symbols 36 | MH_ROOT_SAFE = 0x40000 # When this bit is set, the binarydeclares it is safe for use inprocesses with uid zero 37 | MH_SETUID_SAFE = 0x80000 # When this bit is set, the binarydeclares it is safe for use inprocesses when issetugid() is true 38 | MH_NO_REEXPORTED_DYLIBS = 0x100000 # When this bit is set on a dylib,the static linker does not need toexamine dependent dylibs to seeif any are re-exported 39 | MH_PIE = 0x200000 # When this bit is set, the OS willload the main executable at arandom address. Only used inMH_EXECUTE filetypes. 40 | 41 | # Constants for the cmd field of all load commands, the type 42 | LC_REQ_DYLD = 0x80000000 # When this bit is set, the OS willload the main executable at arandom address. Only used inMH_EXECUTE filetypes. 43 | LC_SEGMENT = 0x1 # segment of this file to be mapped 44 | LC_SYMTAB = 0x2 # link-edit stab symbol table info 45 | LC_SYMSEG = 0x3 # link-edit gdb symbol table info (obsolete) 46 | LC_THREAD = 0x4 # thread 47 | LC_UNIXTHREAD = 0x5 # unix thread (includes a stack) 48 | LC_LOADFVMLIB = 0x6 # load a specified fixed VM shared library 49 | LC_IDFVMLIB = 0x7 # fixed VM shared library identification 50 | LC_IDENT = 0x8 # object identification info (obsolete) 51 | LC_FVMFILE = 0x9 # fixed VM file inclusion (internal use) 52 | LC_PREPAGE = 0xa # prepage command (internal use) 53 | LC_DYSYMTAB = 0xb # dynamic link-edit symbol table info 54 | LC_LOAD_DYLIB = 0xc # load a dynamically linked shared library 55 | LC_ID_DYLIB = 0xd # dynamically linked shared lib ident 56 | LC_LOAD_DYLINKER = 0xe # load a dynamic linker 57 | LC_ID_DYLINKER = 0xf # dynamic linker identification 58 | LC_PREBOUND_DYLIB = 0x10 # modules prebound for a dynamically 59 | LC_ROUTINES = 0x11 # image routines 60 | LC_SUB_FRAMEWORK = 0x12 # sub framework 61 | LC_SUB_UMBRELLA = 0x13 # sub umbrella 62 | LC_SUB_CLIENT = 0x14 # sub client 63 | LC_SUB_LIBRARY = 0x15 # sub library 64 | LC_TWOLEVEL_HINTS = 0x16 # two-level namespace lookup hints 65 | LC_PREBIND_CKSUM = 0x17 # prebind checksum 66 | LC_SEGMENT_64 = 0x19 # 64-bit segment of this file to bemapped 67 | LC_ROUTINES_64 = 0x1a # 64-bit image routines 68 | LC_UUID = 0x1b # the uuid 69 | LC_CODE_SIGNATURE = 0x1d # local of code signature 70 | LC_SEGMENT_SPLIT_INFO = 0x1e # local of info to split segments 71 | LC_LAZY_LOAD_DYLIB = 0x20 # delay load of dylib until first use 72 | LC_ENCRYPTION_INFO = 0x21 # encrypted segment information 73 | SG_HIGHVM = 0x1 # the file contents for this segment is forthe high part of the VM space, the low partis zero filled (for stacks in core files) 74 | SG_FVMLIB = 0x2 # this segment is the VM that is allocated bya fixed VM library, for overlap checking inthe link editor 75 | SG_NORELOC = 0x4 # this segment has nothing that was relocatedin it and nothing relocated to it, that isit maybe safely replaced without relocation 76 | SG_PROTECTED_VERSION_1 = 0x8 # This segment is protected. If thesegment starts at file offset 0, thefirst page of the segment is notprotected. All other pages of thesegment are protected. 77 | 78 | 79 | SECTION_TYPE = 0x000000ff # 256 section types 80 | SECTION_ATTRIBUTES = 0xffffff00 # 24 section attributes 81 | S_REGULAR = 0x0 # regular section 82 | S_ZEROFILL = 0x1 # zero fill on demand section 83 | S_CSTRING_LITERALS = 0x2 # section with only literal C strings 84 | S_4BYTE_LITERALS = 0x3 # section with only 4 byte literals 85 | S_8BYTE_LITERALS = 0x4 # section with only 8 byte literals 86 | S_LITERAL_POINTERS = 0x5 # section with only pointers to 87 | S_NON_LAZY_SYMBOL_POINTERS = 0x6 # section with only non-lazysymbol pointers 88 | S_LAZY_SYMBOL_POINTERS = 0x7 # section with only lazy symbolpointers 89 | S_SYMBOL_STUBS = 0x8 # section with only symbolstubs, byte size of stub inthe reserved2 field 90 | S_MOD_INIT_FUNC_POINTERS = 0x9 # section with only functionpointers for initialization 91 | S_MOD_TERM_FUNC_POINTERS = 0xa # section with only functionpointers for termination 92 | S_COALESCED = 0xb # section contains symbols thatare to be coalesced 93 | S_GB_ZEROFILL = 0xc # zero fill on demand section(that can be larger than 4gigabytes) 94 | S_INTERPOSING = 0xd # section with only pairs offunction pointers forinterposing 95 | S_16BYTE_LITERALS = 0xe # section with only 16 byteliterals 96 | S_DTRACE_DOF = 0xf # section containsDTrace Object Format 97 | S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10 # section with only lazysymbol pointers to lazyloaded dylibs 98 | SECTION_ATTRIBUTES_USR = 0xff000000 # User setable attributes 99 | S_ATTR_PURE_INSTRUCTIONS = 0x80000000 # section contains only truemachine instructions 100 | S_ATTR_NO_TOC = 0x40000000 # section contains coalescedsymbols that are not to bein a ranlib table ofcontents 101 | S_ATTR_STRIP_STATIC_SYMS = 0x20000000 # ok to strip static symbolsin this section in fileswith the MH_DYLDLINK flag 102 | S_ATTR_NO_DEAD_STRIP = 0x10000000 # no dead stripping 103 | S_ATTR_LIVE_SUPPORT = 0x08000000 # blocks are live if theyreference live blocks 104 | S_ATTR_SELF_MODIFYING_CODE = 0x04000000 # Used with i386 code stubswritten on by dyld 105 | S_ATTR_DEBUG = 0x02000000 # a debug section 106 | SECTION_ATTRIBUTES_SYS = 0x00ffff00 # system setable attributes 107 | S_ATTR_SOME_INSTRUCTIONS = 0x00000400 # section contains somemachine instructions 108 | S_ATTR_EXT_RELOC = 0x00000200 # section has externalrelocation entries 109 | S_ATTR_LOC_RELOC = 0x00000100 # section has localrelocation entries 110 | INDIRECT_SYMBOL_LOCAL = 0x80000000 # section has localrelocation entries 111 | INDIRECT_SYMBOL_ABS = 0x40000000 # section has localrelocation entries 112 | 113 | CPU_TYPE_ANY = -1 114 | CPU_TYPE_VAX = 1 115 | CPU_TYPE_MC680 = 6 116 | CPU_TYPE_X86 = 7 117 | CPU_TYPE_X86_64 = 0x01000007 118 | #CPU_TYPE_MIPS ((cpu_type_t) 8) */ 119 | #CPU_TYPE_MC98000 ((cpu_type_t) 10) 120 | #CPU_TYPE_HPPA ((cpu_type_t) 11) 121 | #CPU_TYPE_ARM ((cpu_type_t) 12) 122 | #CPU_TYPE_MC88000 ((cpu_type_t) 13) 123 | #CPU_TYPE_SPARC ((cpu_type_t) 14) 124 | #CPU_TYPE_I860 ((cpu_type_t) 15) 125 | #CPU_TYPE_ALPHA ((cpu_type_t) 16) */ 126 | #CPU_TYPE_POWERPC ((cpu_type_t) 18) 127 | #CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) 128 | 129 | -------------------------------------------------------------------------------- /vstruct/defs/macho/fat.py: -------------------------------------------------------------------------------- 1 | 2 | import vstruct 3 | import vstruct.primitives as vs_prim 4 | 5 | class fat_header(vstruct.VStruct): 6 | def __init__(self): 7 | vstruct.VStruct.__init__(self, bigend=True) 8 | self.magic = vs_prim.v_uint32() 9 | self.nfat_arch = vs_prim.v_uint32() 10 | 11 | class fat_arch(vstruct.VStruct): 12 | def __init__(self): 13 | vstruct.VStruct.__init__(self, bigend=True) 14 | self.cputype = vs_prim.v_uint32() # cpu specifier (int) */ 15 | self.cpusubtype = vs_prim.v_uint32() # machine specifier (int) */ 16 | self.offset = vs_prim.v_uint32() # file offset to this object file */ 17 | self.size = vs_prim.v_uint32() # size of this object file */ 18 | self.align = vs_prim.v_uint32() # alignment as a power of 2 */ 19 | 20 | -------------------------------------------------------------------------------- /vstruct/defs/pe.py: -------------------------------------------------------------------------------- 1 | 2 | import vstruct 3 | from vstruct.primitives import * 4 | 5 | class IMAGE_BASE_RELOCATION(vstruct.VStruct): 6 | def __init__(self): 7 | vstruct.VStruct.__init__(self) 8 | self.VirtualAddress = v_uint32() 9 | self.SizeOfBlock = v_uint32() 10 | 11 | class IMAGE_DATA_DIRECTORY(vstruct.VStruct): 12 | def __init__(self): 13 | vstruct.VStruct.__init__(self) 14 | self.VirtualAddress = v_uint32() 15 | self.Size = v_uint32() 16 | 17 | class IMAGE_DOS_HEADER(vstruct.VStruct): 18 | def __init__(self): 19 | vstruct.VStruct.__init__(self) 20 | self.e_magic = v_uint16() 21 | self.e_cblp = v_uint16() 22 | self.e_cp = v_uint16() 23 | self.e_crlc = v_uint16() 24 | self.e_cparhdr = v_uint16() 25 | self.e_minalloc = v_uint16() 26 | self.e_maxalloc = v_uint16() 27 | self.e_ss = v_uint16() 28 | self.e_sp = v_uint16() 29 | self.e_csum = v_uint16() 30 | self.e_ip = v_uint16() 31 | self.e_cs = v_uint16() 32 | self.e_lfarlc = v_uint16() 33 | self.e_ovno = v_uint16() 34 | self.e_res = vstruct.VArray([v_uint16() for i in range(4)]) 35 | self.e_oemid = v_uint16() 36 | self.e_oeminfo = v_uint16() 37 | self.e_res2 = vstruct.VArray([v_uint16() for i in range(10)]) 38 | self.e_lfanew = v_uint32() 39 | 40 | class IMAGE_EXPORT_DIRECTORY(vstruct.VStruct): 41 | def __init__(self): 42 | vstruct.VStruct.__init__(self) 43 | self.Characteristics = v_uint32() 44 | self.TimeDateStamp = v_uint32() 45 | self.MajorVersion = v_uint16() 46 | self.MinorVersion = v_uint16() 47 | self.Name = v_uint32() 48 | self.Base = v_uint32() 49 | self.NumberOfFunctions = v_uint32() 50 | self.NumberOfNames = v_uint32() 51 | self.AddressOfFunctions = v_uint32() 52 | self.AddressOfNames = v_uint32() 53 | self.AddressOfOrdinals = v_uint32() 54 | 55 | class IMAGE_FILE_HEADER(vstruct.VStruct): 56 | def __init__(self): 57 | vstruct.VStruct.__init__(self) 58 | self.Machine = v_uint16() 59 | self.NumberOfSections = v_uint16() 60 | self.TimeDateStamp = v_uint32() 61 | self.PointerToSymbolTable = v_uint32() 62 | self.NumberOfSymbols = v_uint32() 63 | self.SizeOfOptionalHeader = v_uint16() 64 | self.Ccharacteristics = v_uint16() 65 | 66 | class IMAGE_IMPORT_DIRECTORY(vstruct.VStruct): 67 | def __init__(self): 68 | vstruct.VStruct.__init__(self) 69 | self.OriginalFirstThunk = v_uint32() 70 | self.TimeDateStamp = v_uint32() 71 | self.ForwarderChain = v_uint32() 72 | self.Name = v_uint32() 73 | self.FirstThunk = v_uint32() 74 | 75 | class IMAGE_LOAD_CONFIG_DIRECTORY(vstruct.VStruct): 76 | def __init__(self): 77 | vstruct.VStruct.__init__(self) 78 | self.Size = v_uint32() 79 | self.TimeDateStamp = v_uint32() 80 | self.MajorVersion = v_uint16() 81 | self.MinorVersion = v_uint16() 82 | self.GlobalFlagsClear = v_uint32() 83 | self.GlobalFlagsSet = v_uint32() 84 | self.CriticalSectionDefaultTimeout = v_uint32() 85 | self.DeCommitFreeBlockThreshold = v_uint32() 86 | self.DeCommitTotalFreeThreshold = v_uint32() 87 | self.LockPrefixTable = v_uint32() 88 | self.MaximumAllocationSize = v_uint32() 89 | self.VirtualMemoryThreshold = v_uint32() 90 | self.ProcessHeapFlags = v_uint32() 91 | self.ProcessAffinityMask = v_uint32() 92 | self.CSDVersion = v_uint16() 93 | self.Reserved1 = v_uint16() 94 | self.EditList = v_uint32() 95 | self.SecurityCookie = v_uint32() 96 | self.SEHandlerTable = v_uint32() 97 | self.SEHandlerCount = v_uint32() 98 | 99 | class IMAGE_NT_HEADERS(vstruct.VStruct): 100 | def __init__(self): 101 | vstruct.VStruct.__init__(self) 102 | self.Signature = v_bytes(4) 103 | self.FileHeader = IMAGE_FILE_HEADER() 104 | self.OptionalHeader = IMAGE_OPTIONAL_HEADER() 105 | 106 | class IMAGE_NT_HEADERS64(vstruct.VStruct): 107 | def __init__(self): 108 | vstruct.VStruct.__init__(self) 109 | self.Signature = v_bytes(4) 110 | self.FileHeader = IMAGE_FILE_HEADER() 111 | self.OptionalHeader = IMAGE_OPTIONAL_HEADER64() 112 | 113 | class IMAGE_OPTIONAL_HEADER(vstruct.VStruct): 114 | def __init__(self): 115 | vstruct.VStruct.__init__(self) 116 | self.Magic = v_bytes(2) 117 | self.MajorLinkerVersion = v_uint8() 118 | self.MinorLinkerVersion = v_uint8() 119 | self.SizeOfCode = v_uint32() 120 | self.SizeOfInitializedData = v_uint32() 121 | self.SizeOfUninitializedData = v_uint32() 122 | self.AddressOfEntryPoint = v_uint32() 123 | self.BaseOfCode = v_uint32() 124 | self.BaseOfData = v_uint32() 125 | self.ImageBase = v_uint32() 126 | self.SectionAlignment = v_uint32() 127 | self.FileAlignment = v_uint32() 128 | self.MajorOperatingSystemVersion = v_uint16() 129 | self.MinorOperatingSystemVersion = v_uint16() 130 | self.MajorImageVersion = v_uint16() 131 | self.MinorImageVersion = v_uint16() 132 | self.MajorSubsystemVersion = v_uint16() 133 | self.MinorSubsystemVersion = v_uint16() 134 | self.Win32VersionValue = v_uint32() 135 | self.SizeOfImage = v_uint32() 136 | self.SizeOfHeaders = v_uint32() 137 | self.CheckSum = v_uint32() 138 | self.Subsystem = v_uint16() 139 | self.DllCharacteristics = v_uint16() 140 | self.SizeOfStackReserve = v_uint32() 141 | self.SizeOfStackCommit = v_uint32() 142 | self.SizeOfHeapReserve = v_uint32() 143 | self.SizeOfHeapCommit = v_uint32() 144 | self.LoaderFlags = v_uint32() 145 | self.NumberOfRvaAndSizes = v_uint32() 146 | self.DataDirectory = vstruct.VArray([IMAGE_DATA_DIRECTORY() for i in range(16)]) 147 | 148 | class IMAGE_OPTIONAL_HEADER64(vstruct.VStruct): 149 | def __init__(self): 150 | vstruct.VStruct.__init__(self) 151 | self.Magic = v_bytes(2) 152 | self.MajorLinkerVersion = v_uint8() 153 | self.MinorLinkerVersion = v_uint8() 154 | self.SizeOfCode = v_uint32() 155 | self.SizeOfInitializedData = v_uint32() 156 | self.SizeOfUninitializedData = v_uint32() 157 | self.AddressOfEntryPoint = v_uint32() 158 | self.BaseOfCode = v_uint32() 159 | self.ImageBase = v_uint64() 160 | self.SectionAlignment = v_uint32() 161 | self.FileAlignment = v_uint32() 162 | self.MajorOperatingSystemVersion = v_uint16() 163 | self.MinorOperatingSystemVersion = v_uint16() 164 | self.MajorImageVersion = v_uint16() 165 | self.MinorImageVersion = v_uint16() 166 | self.MajorSubsystemVersion = v_uint16() 167 | self.MinorSubsystemVersion = v_uint16() 168 | self.Win32VersionValue = v_uint32() 169 | self.SizeOfImage = v_uint32() 170 | self.SizeOfHeaders = v_uint32() 171 | self.CheckSum = v_uint32() 172 | self.Subsystem = v_uint16() 173 | self.DllCharacteristics = v_uint16() 174 | self.SizeOfStackReserve = v_uint64() 175 | self.SizeOfStackCommit = v_uint64() 176 | self.SizeOfHeapReserve = v_uint64() 177 | self.SizeOfHeapCommit = v_uint64() 178 | self.LoaderFlags = v_uint32() 179 | self.NumberOfRvaAndSizes = v_uint32() 180 | self.DataDirectory = vstruct.VArray([IMAGE_DATA_DIRECTORY() for i in range(16)]) 181 | 182 | class IMAGE_RESOURCE_DIRECTORY(vstruct.VStruct): 183 | def __init__(self): 184 | vstruct.VStruct.__init__(self) 185 | self.Characteristics = v_uint32() 186 | self.TimeDateStamp = v_uint32() 187 | self.MajorVersion = v_uint16() 188 | self.MinorVersion = v_uint16() 189 | self.NumberOfNamedEntries = v_uint16() 190 | self.NumberOfIdEntries = v_uint16() 191 | 192 | class IMAGE_SECTION_HEADER(vstruct.VStruct): 193 | 194 | def __init__(self): 195 | vstruct.VStruct.__init__(self) 196 | self.Name = v_str(8) 197 | self.VirtualSize = v_uint32() 198 | self.VirtualAddress = v_uint32() 199 | self.SizeOfRawData = v_uint32() 200 | self.PointerToRawData = v_uint32() 201 | self.PointerToRelocations = v_uint32() 202 | self.PointerToLineNumbers = v_uint32() 203 | self.NumberOfRelocations = v_uint16() 204 | self.NumberOfLineNumbers = v_uint16() 205 | self.Characteristics = v_uint32() 206 | 207 | 208 | class IMAGE_RUNTIME_FUNCTION_ENTRY(vstruct.VStruct): 209 | """ 210 | Used in the .pdata section of a PE32+ for all non 211 | leaf functions. 212 | """ 213 | def __init__(self): 214 | vstruct.VStruct.__init__(self) 215 | self.BeginAddress = v_uint32() 216 | self.EndAddress = v_uint32() 217 | self.UnwindInfoAddress = v_uint32() 218 | 219 | -------------------------------------------------------------------------------- /vstruct/defs/win32.py: -------------------------------------------------------------------------------- 1 | 2 | # FIXME this is named wrong! 3 | 4 | import vstruct 5 | from vstruct.primitives import * 6 | 7 | class CLIENT_ID(vstruct.VStruct): 8 | def __init__(self): 9 | vstruct.VStruct.__init__(self) 10 | self.UniqueProcess = v_ptr() 11 | self.UniqueThread = v_ptr() 12 | 13 | class EXCEPTION_RECORD(vstruct.VStruct): 14 | def __init__(self): 15 | vstruct.VStruct.__init__(self) 16 | self.ExceptionCode = v_uint32() 17 | self.ExceptionFlags = v_uint32() 18 | self.ExceptionRecord = v_ptr() 19 | self.ExceptionAddress = v_ptr() 20 | self.NumberParameters = v_uint32() 21 | 22 | class EXCEPTION_REGISTRATION(vstruct.VStruct): 23 | def __init__(self): 24 | vstruct.VStruct.__init__(self) 25 | self.prev = v_ptr() 26 | self.handler = v_ptr() 27 | 28 | class HEAP(vstruct.VStruct): 29 | def __init__(self): 30 | vstruct.VStruct.__init__(self) 31 | self.Entry = HEAP_ENTRY() 32 | self.Signature = v_uint32() 33 | self.Flags = v_uint32() 34 | self.ForceFlags = v_uint32() 35 | self.VirtualMemoryThreshold = v_uint32() 36 | self.SegmentReserve = v_uint32() 37 | self.SegmentCommit = v_uint32() 38 | self.DeCommitFreeBlockThreshold = v_uint32() 39 | self.DeCommitTotalFreeThreshold = v_uint32() 40 | self.TotalFreeSize = v_uint32() 41 | self.MaximumAllocationSize = v_uint32() 42 | self.ProcessHeapsListIndex = v_uint16() 43 | self.HeaderValidateLength = v_uint16() 44 | self.HeaderValidateCopy = v_ptr() 45 | self.NextAvailableTagIndex = v_uint16() 46 | self.MaximumTagIndex = v_uint16() 47 | self.TagEntries = v_ptr() 48 | self.UCRSegments = v_ptr() 49 | self.UnusedUnCommittedRanges = v_ptr() 50 | self.AlignRound = v_uint32() 51 | self.AlignMask = v_uint32() 52 | self.VirtualAllocBlocks = ListEntry() 53 | self.Segments = vstruct.VArray([v_uint32() for i in range(64)]) 54 | self.u = vstruct.VArray([v_uint8() for i in range(16)]) 55 | self.u2 = vstruct.VArray([v_uint8() for i in range(2)]) 56 | self.AllocatorBackTraceIndex = v_uint16() 57 | self.NonDedicatedListLength = v_uint32() 58 | self.LargeBlocksIndex = v_ptr() 59 | self.PseudoTagEntries = v_ptr() 60 | self.FreeLists = vstruct.VArray([ListEntry() for i in range(128)]) 61 | self.LockVariable = v_uint32() 62 | self.CommitRoutine = v_ptr() 63 | self.FrontEndHeap = v_ptr() 64 | self.FrontEndHeapLockCount = v_uint16() 65 | self.FrontEndHeapType = v_uint8() 66 | self.LastSegmentIndex = v_uint8() 67 | 68 | class HEAP_SEGMENT(vstruct.VStruct): 69 | def __init__(self): 70 | vstruct.VStruct.__init__(self) 71 | self.Entry = HEAP_ENTRY() 72 | self.SegmentSignature = v_uint32() 73 | self.SegmentFlags = v_uint32() 74 | self.Heap = v_ptr() 75 | self.LargestUncommitedRange = v_uint32() 76 | self.BaseAddress = v_ptr() 77 | self.NumberOfPages = v_uint32() 78 | self.FirstEntry = v_ptr() 79 | self.LastValidEntry = v_ptr() 80 | self.NumberOfUnCommittedPages = v_uint32() 81 | self.NumberOfUnCommittedRanges = v_uint32() 82 | self.UncommittedRanges = v_ptr() 83 | self.SegmentAllocatorBackTraceIndex = v_uint16() 84 | self.Reserved = v_uint16() 85 | self.LastEntryInSegment = v_ptr() 86 | 87 | class HEAP_ENTRY(vstruct.VStruct): 88 | def __init__(self): 89 | vstruct.VStruct.__init__(self) 90 | self.Size = v_uint16() 91 | self.PrevSize = v_uint16() 92 | self.SegmentIndex = v_uint8() 93 | self.Flags = v_uint8() 94 | self.Unused = v_uint8() 95 | self.TagIndex = v_uint8() 96 | 97 | class ListEntry(vstruct.VStruct): 98 | def __init__(self): 99 | vstruct.VStruct.__init__(self) 100 | self.Flink = v_ptr() 101 | self.Blink = v_ptr() 102 | 103 | class NT_TIB(vstruct.VStruct): 104 | def __init__(self): 105 | vstruct.VStruct.__init__(self) 106 | self.ExceptionList = v_ptr() 107 | self.StackBase = v_ptr() 108 | self.StackLimit = v_ptr() 109 | self.SubSystemTib = v_ptr() 110 | self.FiberData = v_ptr() 111 | #x.Version = v_ptr() # This is a union field 112 | self.ArbitraryUserPtr = v_ptr() 113 | self.Self = v_ptr() 114 | 115 | class PEB(vstruct.VStruct): 116 | def __init__(self): 117 | vstruct.VStruct.__init__(self) 118 | self.InheritedAddressSpace = v_uint8() 119 | self.ReadImageFileExecOptions = v_uint8() 120 | self.BeingDebugged = v_uint8() 121 | self.SpareBool = v_uint8() 122 | self.Mutant = v_ptr() 123 | self.ImageBaseAddress = v_ptr() 124 | self.Ldr = v_ptr() 125 | self.ProcessParameters = v_ptr() 126 | self.SubSystemData = v_ptr() 127 | self.ProcessHeap = v_ptr() 128 | self.FastPebLock = v_ptr() 129 | self.FastPebLockRoutine = v_ptr() 130 | self.FastPebUnlockRoutine = v_ptr() 131 | self.EnvironmentUpdateCount = v_uint32() 132 | self.KernelCallbackTable = v_ptr() 133 | self.SystemReserved = v_uint32() 134 | self.AtlThunkSListPtr32 = v_ptr() 135 | self.FreeList = v_ptr() 136 | self.TlsExpansionCounter = v_uint32() 137 | self.TlsBitmap = v_ptr() 138 | self.TlsBitmapBits = vstruct.VArray([v_uint32() for i in range(2)]) 139 | self.ReadOnlySharedMemoryBase = v_ptr() 140 | self.ReadOnlySharedMemoryHeap = v_ptr() 141 | self.ReadOnlyStaticServerData = v_ptr() 142 | self.AnsiCodePageData = v_ptr() 143 | self.OemCodePageData = v_ptr() 144 | self.UnicodeCaseTableData = v_ptr() 145 | self.NumberOfProcessors = v_uint32() 146 | self.NtGlobalFlag = v_uint64() 147 | self.CriticalSectionTimeout = v_uint64() 148 | self.HeapSegmentReserve = v_uint32() 149 | self.HeapSegmentCommit = v_uint32() 150 | self.HeapDeCommitTotalFreeThreshold = v_uint32() 151 | self.HeapDeCommitFreeBlockThreshold = v_uint32() 152 | self.NumberOfHeaps = v_uint32() 153 | self.MaximumNumberOfHeaps = v_uint32() 154 | self.ProcessHeaps = v_ptr() 155 | self.GdiSharedHandleTable = v_ptr() 156 | self.ProcessStarterHelper = v_ptr() 157 | self.GdiDCAttributeList = v_uint32() 158 | self.LoaderLock = v_ptr() 159 | self.OSMajorVersion = v_uint32() 160 | self.OSMinorVersion = v_uint32() 161 | self.OSBuildNumber = v_uint16() 162 | self.OSCSDVersion = v_uint16() 163 | self.OSPlatformId = v_uint32() 164 | self.ImageSubsystem = v_uint32() 165 | self.ImageSubsystemMajorVersion = v_uint32() 166 | self.ImageSubsystemMinorVersion = v_uint32() 167 | self.ImageProcessAffinityMask = v_uint32() 168 | self.GdiHandleBuffer = vstruct.VArray([v_ptr() for i in range(34)]) 169 | self.PostProcessInitRoutine = v_ptr() 170 | self.TlsExpansionBitmap = v_ptr() 171 | self.TlsExpansionBitmapBits = vstruct.VArray([v_uint32() for i in range(32)]) 172 | self.SessionId = v_uint32() 173 | self.AppCompatFlags = v_uint64() 174 | self.AppCompatFlagsUser = v_uint64() 175 | self.pShimData = v_ptr() 176 | self.AppCompatInfo = v_ptr() 177 | self.CSDVersion = v_ptr() 178 | self.UNKNOWN = v_uint32() 179 | self.ActivationContextData = v_ptr() 180 | self.ProcessAssemblyStorageMap = v_ptr() 181 | self.SystemDefaultActivationContextData = v_ptr() 182 | self.SystemAssemblyStorageMap = v_ptr() 183 | self.MinimumStackCommit = v_uint32() 184 | 185 | class SEH3_SCOPETABLE(vstruct.VStruct): 186 | def __init__(self): 187 | vstruct.VStruct.__init__(self) 188 | self.EnclosingLevel = v_int32() 189 | self.FilterFunction = v_ptr() 190 | self.HandlerFunction = v_ptr() 191 | 192 | class SEH4_SCOPETABLE(vstruct.VStruct): 193 | def __init__(self): 194 | vstruct.VStruct.__init__(self) 195 | self.GSCookieOffset = v_int32() 196 | self.GSCookieXOROffset = v_int32() 197 | self.EHCookieOffset = v_int32() 198 | self.EHCookieXOROffset = v_int32() 199 | self.EnclosingLevel = v_int32() 200 | self.FilterFunction = v_ptr() 201 | self.HandlerFunction = v_ptr() 202 | 203 | class TEB(vstruct.VStruct): 204 | def __init__(self): 205 | vstruct.VStruct.__init__(self) 206 | self.TIB = NT_TIB() 207 | self.EnvironmentPointer = v_ptr() 208 | self.ClientId = CLIENT_ID() 209 | self.ActiveRpcHandle = v_ptr() 210 | self.ThreadLocalStorage = v_ptr() 211 | self.ProcessEnvironmentBlock = v_ptr() 212 | self.LastErrorValue = v_uint32() 213 | self.CountOfOwnedCriticalSections = v_uint32() 214 | self.CsrClientThread = v_ptr() 215 | self.Win32ThreadInfo = v_ptr() 216 | self.User32Reserved = vstruct.VArray([v_uint32() for i in range(26)]) 217 | self.UserReserved = vstruct.VArray([v_uint32() for i in range(5)]) 218 | self.WOW32Reserved = v_ptr() 219 | self.CurrentLocale = v_uint32() 220 | self.FpSoftwareStatusRegister = v_uint32() 221 | 222 | class CLSID(vstruct.VStruct): 223 | def __init__(self): 224 | vstruct.VStruct.__init__(self) 225 | self.uuid = GUID() 226 | 227 | class IID(vstruct.VStruct): 228 | def __init__(self): 229 | vstruct.VStruct.__init__(self) 230 | self.uuid = GUID() 231 | 232 | -------------------------------------------------------------------------------- /vstruct/defs/windows/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | The pre-made windows structure defs (extracted from pdb syms) 3 | ''' 4 | 5 | import envi 6 | import ctypes 7 | import platform 8 | 9 | def isSysWow64(): 10 | k32 = ctypes.windll.kernel32 11 | if not hasattr(k32, 'IsWow64Process'): 12 | return False 13 | ret = ctypes.c_ulong(0) 14 | myproc = ctypes.c_size_t(-1) 15 | if not k32.IsWow64Process(myproc, ctypes.addressof(ret)): 16 | return False 17 | return bool(ret.value) 18 | 19 | def getCurrentDef(normname): 20 | bname, wver, stuff, whichkern = platform.win32_ver() 21 | wvertup = wver.split('.') 22 | arch = envi.getCurrentArch() 23 | if isSysWow64(): 24 | arch = 'wow64' 25 | 26 | modname = 'vstruct.defs.windows.win_%s_%s_%s.%s' % (wvertup[0], wvertup[1], arch, normname) 27 | 28 | try: 29 | mod = __import__(modname, {}, {}, 1) 30 | except ImportError, e: 31 | mod = None 32 | return mod 33 | 34 | if __name__ == '__main__': 35 | print getCurrentDef('ntdll') 36 | 37 | -------------------------------------------------------------------------------- /vstruct/defs/windows/win_5_1_i386/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vstruct/defs/windows/win_6_1_amd64/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas0fd00m/rfcat-firsttry/ec89f57a35777acb48c59eaf4f9fa8356b93dbd3/vstruct/defs/windows/win_6_1_amd64/__init__.py -------------------------------------------------------------------------------- /vstruct/defs/windows/win_6_1_wow64/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------