moved stuff + scanner com/hid edits
This commit is contained in:
2
extensions/golang/ScannerHID/.gitignore
vendored
Normal file
2
extensions/golang/ScannerHID/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
config.json
|
||||
HIDScannerGO-*
|
||||
18
extensions/golang/ScannerHID/build.sh
Executable file
18
extensions/golang/ScannerHID/build.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
LINUX_BIN="HIDScannerGO-linux"
|
||||
WINDOWS_BIN="HIDScannerGO-windows.exe"
|
||||
|
||||
echo "Starting build process..."
|
||||
|
||||
# 1. Build for Linux (Host)
|
||||
echo "Building for Linux (64-bit)..."
|
||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o "$LINUX_BIN" .
|
||||
|
||||
# 2. Build for Windows (Needs MinGW)
|
||||
echo "Building for Windows (64-bit)..."
|
||||
# We must point to the mingw gcc and enable CGO
|
||||
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc \
|
||||
go build -ldflags="-H=windowsgui" -o "$WINDOWS_BIN" .
|
||||
|
||||
echo "Build complete."
|
||||
46
extensions/golang/ScannerHID/go.mod
Normal file
46
extensions/golang/ScannerHID/go.mod
Normal file
@@ -0,0 +1,46 @@
|
||||
module ScannerGO
|
||||
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.7.3
|
||||
gioui.org v0.9.0
|
||||
github.com/google/gousb v1.1.3
|
||||
)
|
||||
|
||||
require (
|
||||
fyne.io/systray v1.12.0 // indirect
|
||||
gioui.org/shader v1.0.8 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fredbi/uri v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fyne-io/gl-js v0.2.0 // indirect
|
||||
github.com/fyne-io/glfw-js v0.3.0 // indirect
|
||||
github.com/fyne-io/image v0.1.1 // indirect
|
||||
github.com/fyne-io/oksvg v0.2.0 // indirect
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||
github.com/go-text/render v0.2.0 // indirect
|
||||
github.com/go-text/typesetting v0.3.3 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 // indirect
|
||||
github.com/hack-pad/safejs v0.1.0 // indirect
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade // indirect
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rymdport/portal v0.4.2 // indirect
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/image v0.26.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
93
extensions/golang/ScannerHID/go.sum
Normal file
93
extensions/golang/ScannerHID/go.sum
Normal file
@@ -0,0 +1,93 @@
|
||||
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY=
|
||||
eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA=
|
||||
fyne.io/fyne/v2 v2.7.3 h1:xBT/iYbdnNHONWO38fZMBrVBiJG8rV/Jypmy4tVfRWE=
|
||||
fyne.io/fyne/v2 v2.7.3/go.mod h1:gu+dlIcZWSzKZmnrY8Fbnj2Hirabv2ek+AKsfQ2bBlw=
|
||||
fyne.io/systray v1.12.0 h1:CA1Kk0e2zwFlxtc02L3QFSiIbxJ/P0n582YrZHT7aTM=
|
||||
fyne.io/systray v1.12.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||
gioui.org v0.9.0 h1:4u7XZwnb5kzQW91Nz/vR0wKD6LdW9CaVF96r3rfy4kc=
|
||||
gioui.org v0.9.0/go.mod h1:CjNig0wAhLt9WZxOPAusgFD8x8IRvqt26LdDBa3Jvao=
|
||||
gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ=
|
||||
gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA=
|
||||
gioui.org/shader v1.0.8/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/fredbi/uri v1.1.1 h1:xZHJC08GZNIUhbP5ImTHnt5Ya0T8FI2VAwI/37kh2Ko=
|
||||
github.com/fredbi/uri v1.1.1/go.mod h1:4+DZQ5zBjEwQCDmXW5JdIjz0PUA+yJbvtBv+u+adr5o=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fyne-io/gl-js v0.2.0 h1:+EXMLVEa18EfkXBVKhifYB6OGs3HwKO3lUElA0LlAjs=
|
||||
github.com/fyne-io/gl-js v0.2.0/go.mod h1:ZcepK8vmOYLu96JoxbCKJy2ybr+g1pTnaBDdl7c3ajI=
|
||||
github.com/fyne-io/glfw-js v0.3.0 h1:d8k2+Y7l+zy2pc7wlGRyPfTgZoqDf3AI4G+2zOWhWUk=
|
||||
github.com/fyne-io/glfw-js v0.3.0/go.mod h1:Ri6te7rdZtBgBpxLW19uBpp3Dl6K9K/bRaYdJ22G8Jk=
|
||||
github.com/fyne-io/image v0.1.1 h1:WH0z4H7qfvNUw5l4p3bC1q70sa5+YWVt6HCj7y4VNyA=
|
||||
github.com/fyne-io/image v0.1.1/go.mod h1:xrfYBh6yspc+KjkgdZU/ifUC9sPA5Iv7WYUBzQKK7JM=
|
||||
github.com/fyne-io/oksvg v0.2.0 h1:mxcGU2dx6nwjJsSA9PCYZDuoAcsZ/OuJlvg/Q9Njfo8=
|
||||
github.com/fyne-io/oksvg v0.2.0/go.mod h1:dJ9oEkPiWhnTFNCmRgEze+YNprJF7YRbpjgpWS4kzoI=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
||||
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
||||
github.com/go-text/typesetting v0.3.3 h1:ihGNJU9KzdK2QRDy1Bm7FT5RFQoYb+3n3EIhI/4eaQc=
|
||||
github.com/go-text/typesetting v0.3.3/go.mod h1:vIRUT25mLQaSh4C8H/lIsKppQz/Gdb8Pu/tNwpi52ts=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20250618110550-c820a94c77b8 h1:4KCscI9qYWMGTuz6BpJtbUSRzcBrUSSE0ENMJbNSrFs=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20250618110550-c820a94c77b8/go.mod h1:3/62I4La/HBRX9TcTpBj4eipLiwzf+vhI+7whTc9V7o=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/gousb v1.1.3 h1:xt6M5TDsGSZ+rlomz5Si5Hmd/Fvbmo2YCJHN+yGaK4o=
|
||||
github.com/google/gousb v1.1.3/go.mod h1:GGWUkK0gAXDzxhwrzetW592aOmkkqSGcj5KLEgmCVUg=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2 h1:DTqeJJYc1usa45Q5r52t01KhvlSN02+Oq+tQbSBI91A=
|
||||
github.com/hack-pad/go-indexeddb v0.3.2/go.mod h1:QvfTevpDVlkfomY498LhstjwbPW6QC4VC/lxYb0Kom0=
|
||||
github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8=
|
||||
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade h1:FmusiCI1wHw+XQbvL9M+1r/C3SPqKrmBaIOYwVfQoDE=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20250612000132-0ef82f21eade/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1 h1:IxtPxYsR9Gp60cGXjfuR/llTqV8aYMsC472zD0D1vHk=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.5.1/go.mod h1:DrhgsSDZxoAfvVrBVLXoxZn/pN5TXqaDbq7ju94viiQ=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rymdport/portal v0.4.2 h1:7jKRSemwlTyVHHrTGgQg7gmNPJs88xkbKcIL3NlcmSU=
|
||||
github.com/rymdport/portal v0.4.2/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0 h1:tMSqXTK+AQdW3LpCbfatHSRPHeW6+2WuxaVQuHftn80=
|
||||
golang.org/x/exp/shiny v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:ygj7T6vSGhhm/9yTpOQQNvuAUFziTH7RUiH74EoE2C8=
|
||||
golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
|
||||
golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
246
extensions/golang/ScannerHID/main.go
Normal file
246
extensions/golang/ScannerHID/main.go
Normal file
@@ -0,0 +1,246 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/app"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/google/gousb"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
TargetURL string `json:"target_url"`
|
||||
VendorID uint16 `json:"vendor_id"`
|
||||
ProductID uint16 `json:"product_id"`
|
||||
}
|
||||
|
||||
var hidMap = map[byte]string{
|
||||
4: "a", 5: "b", 6: "c", 7: "d", 8: "e", 9: "f", 10: "g", 11: "h", 12: "i",
|
||||
13: "j", 14: "k", 15: "l", 16: "m", 17: "n", 18: "o", 19: "p", 20: "q",
|
||||
21: "r", 22: "s", 23: "t", 24: "u", 25: "v", 26: "w", 27: "x", 28: "y", 29: "z",
|
||||
30: "1", 31: "2", 32: "3", 33: "4", 34: "5", 35: "6", 36: "7", 37: "8", 38: "9", 39: "0",
|
||||
44: " ", 45: "-", 46: "=", 55: ".", 56: "/",
|
||||
}
|
||||
|
||||
type BridgeApp struct {
|
||||
urlEntry *widget.Entry
|
||||
status *canvas.Text
|
||||
logList *widget.List
|
||||
logs []string
|
||||
window fyne.Window
|
||||
config Config
|
||||
isCLI bool
|
||||
}
|
||||
|
||||
func (b *BridgeApp) saveConfig() {
|
||||
b.config.TargetURL = b.urlEntry.Text
|
||||
data, _ := json.MarshalIndent(b.config, "", " ")
|
||||
_ = os.WriteFile("config.json", data, 0644)
|
||||
}
|
||||
|
||||
func loadConfig() Config {
|
||||
conf := Config{
|
||||
TargetURL: "https://scanner.sekidesu.xyz/scan",
|
||||
VendorID: 0xFFFF,
|
||||
ProductID: 0x0035,
|
||||
}
|
||||
file, err := os.ReadFile("config.json")
|
||||
if err == nil {
|
||||
json.Unmarshal(file, &conf)
|
||||
} else {
|
||||
// Create default config if missing
|
||||
data, _ := json.MarshalIndent(conf, "", " ")
|
||||
os.WriteFile("config.json", data, 0644)
|
||||
}
|
||||
return conf
|
||||
}
|
||||
|
||||
func main() {
|
||||
cliMode := flag.Bool("cli", false, "Run in CLI mode without GUI")
|
||||
flag.Parse()
|
||||
|
||||
conf := loadConfig()
|
||||
bridge := &BridgeApp{
|
||||
config: conf,
|
||||
isCLI: *cliMode,
|
||||
}
|
||||
|
||||
if *cliMode {
|
||||
fmt.Println("Running in CLI mode...")
|
||||
bridge.usbListenLoop()
|
||||
return
|
||||
}
|
||||
|
||||
a := app.New()
|
||||
w := a.NewWindow("POS Hardware Bridge (Go)")
|
||||
bridge.window = w
|
||||
bridge.urlEntry = widget.NewEntry()
|
||||
bridge.urlEntry.SetText(conf.TargetURL)
|
||||
bridge.status = canvas.NewText("Status: Booting...", color.Black)
|
||||
bridge.status.TextSize = 14
|
||||
|
||||
bridge.logList = widget.NewList(
|
||||
func() int { return len(bridge.logs) },
|
||||
func() fyne.CanvasObject { return widget.NewLabel("template") },
|
||||
func(i widget.ListItemID, o fyne.CanvasObject) {
|
||||
o.(*widget.Label).SetText(bridge.logs[i])
|
||||
},
|
||||
)
|
||||
|
||||
content := container.NewBorder(
|
||||
container.NewVBox(
|
||||
widget.NewLabel("Target POS Endpoint:"),
|
||||
bridge.urlEntry,
|
||||
bridge.status,
|
||||
widget.NewLabel("Activity Log:"),
|
||||
),
|
||||
nil, nil, nil,
|
||||
bridge.logList,
|
||||
)
|
||||
|
||||
w.SetContent(content)
|
||||
w.Resize(fyne.NewSize(500, 400))
|
||||
|
||||
w.SetOnClosed(func() {
|
||||
if !bridge.isCLI {
|
||||
bridge.config.TargetURL = bridge.urlEntry.Text
|
||||
data, err := json.MarshalIndent(bridge.config, "", " ")
|
||||
if err == nil {
|
||||
_ = os.WriteFile("config.json", data, 0644)
|
||||
fmt.Println("Configuration saved.")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
go bridge.usbListenLoop()
|
||||
w.ShowAndRun()
|
||||
}
|
||||
|
||||
func (b *BridgeApp) addLog(msg string) {
|
||||
ts := time.Now().Format("15:04:05")
|
||||
formatted := fmt.Sprintf("[%s] %s", ts, msg)
|
||||
|
||||
if b.isCLI {
|
||||
fmt.Println(formatted)
|
||||
return
|
||||
}
|
||||
|
||||
fyne.DoAndWait(func() {
|
||||
b.logs = append([]string{formatted}, b.logs...)
|
||||
if len(b.logs) > 15 {
|
||||
b.logs = b.logs[:15]
|
||||
}
|
||||
b.logList.Refresh()
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BridgeApp) updateStatus(msg string, col color.Color) {
|
||||
if b.isCLI {
|
||||
fmt.Printf("STATUS: %s\n", msg)
|
||||
return
|
||||
}
|
||||
fyne.DoAndWait(func() {
|
||||
b.status.Text = msg
|
||||
b.status.Color = col
|
||||
b.status.Refresh()
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BridgeApp) sendToPos(barcode string) {
|
||||
url := b.config.TargetURL
|
||||
if !b.isCLI {
|
||||
url = b.urlEntry.Text
|
||||
}
|
||||
|
||||
b.addLog(fmt.Sprintf("Captured: %s. Sending to %s", barcode, url))
|
||||
client := http.Client{Timeout: 3 * time.Second}
|
||||
resp, err := client.Get(url + "?content=" + barcode)
|
||||
if err != nil {
|
||||
b.addLog("HTTP Error: Backend unreachable")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
b.addLog(fmt.Sprintf("Success: POS returned %d", resp.StatusCode))
|
||||
}
|
||||
|
||||
func (b *BridgeApp) usbListenLoop() {
|
||||
ctx := gousb.NewContext()
|
||||
defer ctx.Close()
|
||||
|
||||
for {
|
||||
dev, err := ctx.OpenDeviceWithVIDPID(gousb.ID(b.config.VendorID), gousb.ID(b.config.ProductID))
|
||||
|
||||
if err != nil || dev == nil {
|
||||
b.updateStatus("Scanner unplugged. Waiting...", color.NRGBA{200, 0, 0, 255})
|
||||
time.Sleep(2 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
b.updateStatus("Scanner Locked & Ready", color.NRGBA{0, 180, 0, 255})
|
||||
|
||||
intf, done, err := dev.DefaultInterface()
|
||||
if err != nil {
|
||||
b.addLog("Error claiming interface")
|
||||
dev.Close()
|
||||
time.Sleep(2 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
var inEp *gousb.InEndpoint
|
||||
for _, epDesc := range intf.Setting.Endpoints {
|
||||
if epDesc.Direction == gousb.EndpointDirectionIn {
|
||||
inEp, _ = intf.InEndpoint(epDesc.Number)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if inEp == nil {
|
||||
b.addLog("No IN endpoint found")
|
||||
done()
|
||||
dev.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
currentBarcode := ""
|
||||
buf := make([]byte, inEp.Desc.MaxPacketSize)
|
||||
|
||||
for {
|
||||
n, err := inEp.Read(buf)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if n < 3 || buf[2] == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
modifier := buf[0]
|
||||
keycode := buf[2]
|
||||
isShift := (modifier == 2 || modifier == 32)
|
||||
|
||||
if keycode == 40 {
|
||||
if currentBarcode != "" {
|
||||
go b.sendToPos(currentBarcode)
|
||||
currentBarcode = ""
|
||||
}
|
||||
} else if val, ok := hidMap[keycode]; ok {
|
||||
if isShift && len(val) == 1 && val[0] >= 'a' && val[0] <= 'z' {
|
||||
val = string(val[0] - 32)
|
||||
}
|
||||
currentBarcode += val
|
||||
}
|
||||
}
|
||||
|
||||
done()
|
||||
dev.Close()
|
||||
b.addLog("Hardware connection lost. Reconnecting...")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user