From f600229c97365579d8b5e2cfb7b5b58605d07346 Mon Sep 17 00:00:00 2001 From: kercre123 Date: Sat, 20 Apr 2024 16:03:29 -0500 Subject: [PATCH 1/8] Re-add and fix inbuilt-ble code --- chipper/go.mod | 9 +- chipper/go.sum | 28 +- chipper/pkg/mdnshandler/mdns.go | 4 +- chipper/pkg/vars/vars.go | 29 ++ chipper/pkg/wirepod/config-ws/webserver.go | 1 + chipper/pkg/wirepod/sdkapp/server.go | 3 +- chipper/pkg/wirepod/setup/ble.go | 460 +++++++++++++++++++++ chipper/pkg/wirepod/setup/certs.go | 33 +- chipper/pkg/wirepod/ttr/kgsim_cmds.go | 9 +- chipper/webroot/index.html | 2 +- chipper/webroot/js/ble.js | 165 +++++--- 11 files changed, 647 insertions(+), 96 deletions(-) create mode 100644 chipper/pkg/wirepod/setup/ble.go diff --git a/chipper/go.mod b/chipper/go.mod index 4b640a02..cf4ec7fd 100644 --- a/chipper/go.mod +++ b/chipper/go.mod @@ -9,6 +9,7 @@ require ( github.com/digital-dream-labs/api v0.0.0-20210824232136-8cc90c1bb12c github.com/digital-dream-labs/hugh v0.0.0-20210210154335-f4159b9fcd5f github.com/digital-dream-labs/opus-go v0.0.0-20201230195736-934a8a9e0a1e + github.com/digital-dream-labs/vector-bluetooth v0.0.0-20210604051118-1c511122d877 github.com/fforchino/vector-go-sdk v0.0.0-20231108155304-62168f3595d6 github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20231214200047-940de9dbe9c9 github.com/go-audio/audio v1.0.0 @@ -35,8 +36,8 @@ require ( github.com/akavel/rsrc v0.10.2 // indirect github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect - github.com/alphacep/vosk-api/go v0.3.46 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/currantlabs/ble v0.0.0-20171229162446-c1d21c164cf8 // indirect github.com/dchest/jsmin v0.0.0-20220218165748-59f39799265f // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/go-audio/riff v1.0.0 // indirect @@ -45,10 +46,14 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jamesruan/sodium v0.0.0-20181216154042-9620b83ffeae // indirect github.com/josephspurrier/goversioninfo v1.4.0 // indirect - github.com/kercre123/vosk-api v1.0.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.1 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab // indirect github.com/miekg/dns v1.1.41 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/pelletier/go-toml v1.8.0 // indirect diff --git a/chipper/go.sum b/chipper/go.sum index b70cc529..caebf5d2 100644 --- a/chipper/go.sum +++ b/chipper/go.sum @@ -53,8 +53,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5Vpd github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alphacep/vosk-api/go v0.3.46 h1:obkgIAUh6tBcxt2OyrV18fWTUMEHW9zv//L+8zZKRnI= -github.com/alphacep/vosk-api/go v0.3.46/go.mod h1:9X8IJsHnFk/b1xyvjlZifo+ZL5VTAx3LW+JQce/eRcA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -101,6 +99,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cryptix/wav v0.0.0-20180415113528-8bdace674401/go.mod h1:knK8fd+KPlGGqSUWogv1DQzGTwnfUvAi0cIoWyOG7+U= +github.com/currantlabs/ble v0.0.0-20171229162446-c1d21c164cf8 h1:eo7L0zxxFowLpF4FNlLijrAMVNlq9h8sicNwMfzauM8= +github.com/currantlabs/ble v0.0.0-20171229162446-c1d21c164cf8/go.mod h1:MGpIf7cfnYPFaMIcD8LoSgCr8Jsa4rUcV5Nb9temsYw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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= @@ -115,6 +115,8 @@ github.com/digital-dream-labs/hugh v0.0.0-20210210154335-f4159b9fcd5f h1:zM1VS8f github.com/digital-dream-labs/hugh v0.0.0-20210210154335-f4159b9fcd5f/go.mod h1:ZkWUHEPG5kdhpxM9vL+5b0p207jqH2WXNWQwFraQt2A= github.com/digital-dream-labs/opus-go v0.0.0-20201230195736-934a8a9e0a1e h1:sbDWWDUdymyp3fTeQKz40a3x/frOSiWkBHD40o1/DQY= github.com/digital-dream-labs/opus-go v0.0.0-20201230195736-934a8a9e0a1e/go.mod h1:OmsiyJjTuSWs/9lgydMVi+ULpldzbMJdu3z2N2TehYk= +github.com/digital-dream-labs/vector-bluetooth v0.0.0-20210604051118-1c511122d877 h1:o0KX+EQ9kyFtCgz/rrhj70Oy9j+v8/taLNcTUqS2mLc= +github.com/digital-dream-labs/vector-bluetooth v0.0.0-20210604051118-1c511122d877/go.mod h1:Nz0BKA94LFH/klz0okyPZiqXfCqaRhs6B8BzEhXVLmQ= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v17.12.0-ce-rc1.0.20200505174321-1655290016ac+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -285,6 +287,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jamesruan/sodium v0.0.0-20181216154042-9620b83ffeae h1:FFafUVNizQIaIHAqmDKXQlZ+8/LplHZbL11emgcto+M= +github.com/jamesruan/sodium v0.0.0-20181216154042-9620b83ffeae/go.mod h1:GZ0frHfchUw9cjP3CK1J7+M74KNo7zrhffQxTeuf5I8= github.com/jhump/protoreflect v1.8.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -297,10 +301,9 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kercre123/vosk-api v1.0.1 h1:D5CeAMNHPj87M9fKrqP+a2gEQefq7sJCpaiuRscbiJY= -github.com/kercre123/vosk-api v1.0.1/go.mod h1:mJlLhtYS207jVY9QffYGxhX6Up0UfSQ3p0uNbXsf3Zc= github.com/kercre123/vosk-api/go v1.0.2 h1:NDJUNv2ddw128amiVZ2xE2gKfKHeBRRhboSh+yiH6Wg= github.com/kercre123/vosk-api/go v1.0.2/go.mod h1:oVZG/VFmg23uNDzjShcw7UhZHWYG2zXgBm5FqioE2Ao= github.com/kercre123/zeroconf v1.0.1 h1:Mbd8mN6xnNWYIqBN38x3jJjiPP2RmK4orzbGZsa1EOY= @@ -326,14 +329,24 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxhawkins/go-webrtcvad v0.0.0-20210121163624-be60036f3083 h1:0JDcvP4R28p6+u8VIHCwYx7UwiHZ074INz3C397oc9s= github.com/maxhawkins/go-webrtcvad v0.0.0-20210121163624-be60036f3083/go.mod h1:YdrZ05xnooeP54y7m+/UvI23O1Td46PjWkLJu1VLObM= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= +github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab h1:n8cgpHzJ5+EDyDri2s/GC7a9+qK3/YEGnBsd0uS/8PY= +github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab/go.mod h1:y1pL58r5z2VvAjeG1VLGc8zOQgSOzbKN7kMHPvFXJ+8= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -402,6 +415,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 h1:GranzK4hv1/pqTIhMTXt2X8MmMOuH3hMeUR0o9SP5yc= github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844/go.mod h1:T1TLSfyWVBRXVGzWd0o9BI4kfoO9InEgfQe4NV3mLz8= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -411,6 +426,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sashabaranov/go-openai v1.20.4 h1:095xQ/fAtRa0+Rj21sezVJABgKfGPNbyx/sAN/hJUmg= github.com/sashabaranov/go-openai v1.20.4/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= +github.com/schollz/progressbar/v3 v3.7.4/go.mod h1:1H8m5kMPW6q5fyjpDqtBHW1JT22mu2NwHQ1ApuCPh/8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -503,6 +519,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= @@ -631,6 +648,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -657,7 +675,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= diff --git a/chipper/pkg/mdnshandler/mdns.go b/chipper/pkg/mdnshandler/mdns.go index 356621c2..77a20a38 100644 --- a/chipper/pkg/mdnshandler/mdns.go +++ b/chipper/pkg/mdnshandler/mdns.go @@ -8,7 +8,7 @@ import ( "time" "github.com/kercre123/wire-pod/chipper/pkg/logger" - botsetup "github.com/kercre123/wire-pod/chipper/pkg/wirepod/setup" + "github.com/kercre123/wire-pod/chipper/pkg/vars" "github.com/kercre123/zeroconf" ) @@ -76,7 +76,7 @@ func PostmDNS() { PostingmDNS = true logger.Println("Registering escapepod.local on network (loop)") for { - ipAddr := botsetup.GetOutboundIP().String() + ipAddr := vars.GetOutboundIP().String() server, _ := zeroconf.RegisterProxy("escapepod", "_app-proto._tcp", "local.", 8084, "escapepod", []string{ipAddr}, []string{"txtv=0", "lo=1", "la=2"}, nil) for { if MDNSTimeBeforeNextRegister >= 30 { diff --git a/chipper/pkg/vars/vars.go b/chipper/pkg/vars/vars.go index 8c1f438f..586d37ed 100644 --- a/chipper/pkg/vars/vars.go +++ b/chipper/pkg/vars/vars.go @@ -6,6 +6,7 @@ import ( "encoding/pem" "errors" "fmt" + "net" "os" "path/filepath" "runtime" @@ -15,6 +16,7 @@ import ( "github.com/fforchino/vector-go-sdk/pkg/vector" "github.com/kercre123/wire-pod/chipper/pkg/logger" "github.com/sashabaranov/go-openai" + "github.com/wlynxg/anet" ) // initialize variables so they don't have to be found during runtime @@ -441,3 +443,30 @@ func GetRobot(esn string) (*vector.Vector, error) { } return robot, nil } + +func GetOutboundIP() net.IP { + if runtime.GOOS == "android" { + ifaces, _ := anet.Interfaces() + for _, iface := range ifaces { + if iface.Name == "wlan0" { + adrs, err := anet.InterfaceAddrsByInterface(&iface) + if err != nil { + logger.Println(err) + break + } + if len(adrs) > 0 { + localAddr := adrs[0].(*net.IPNet) + return localAddr.IP + } + } + } + } + conn, err := net.Dial("udp", OutboundIPTester) + if err != nil { + logger.Println("not connected to a network: ", err) + return net.IPv4(0, 0, 0, 0) + } + defer conn.Close() + localAddr := conn.LocalAddr().(*net.UDPAddr) + return localAddr.IP +} diff --git a/chipper/pkg/wirepod/config-ws/webserver.go b/chipper/pkg/wirepod/config-ws/webserver.go index 9ca4f944..6c70eda1 100755 --- a/chipper/pkg/wirepod/config-ws/webserver.go +++ b/chipper/pkg/wirepod/config-ws/webserver.go @@ -388,6 +388,7 @@ func certHandler(w http.ResponseWriter, r *http.Request) { func StartWebServer() { botsetup.RegisterSSHAPI() + botsetup.RegisterBLEAPI() http.HandleFunc("/api/", apiHandler) http.HandleFunc("/session-certs/", certHandler) var webRoot http.Handler diff --git a/chipper/pkg/wirepod/sdkapp/server.go b/chipper/pkg/wirepod/sdkapp/server.go index c78a3fbf..a88d8c22 100755 --- a/chipper/pkg/wirepod/sdkapp/server.go +++ b/chipper/pkg/wirepod/sdkapp/server.go @@ -18,7 +18,6 @@ import ( "github.com/fforchino/vector-go-sdk/pkg/vectorpb" "github.com/kercre123/wire-pod/chipper/pkg/logger" "github.com/kercre123/wire-pod/chipper/pkg/vars" - botsetup "github.com/kercre123/wire-pod/chipper/pkg/wirepod/setup" ) var serverFiles string = "./webroot/sdkapp" @@ -529,7 +528,7 @@ func BeginServer() { http.HandleFunc("/cam-stream", camStreamHandler) logger.Println("Starting SDK app") fmt.Printf("Starting server at port 80 for connCheck\n") - ipAddr := botsetup.GetOutboundIP().String() + ipAddr := vars.GetOutboundIP().String() logger.Println("\033[1;36mConfiguration page: http://" + ipAddr + ":" + vars.WebPort + "\033[0m") if runtime.GOOS != "android" { if err := http.ListenAndServe(":80", nil); err != nil { diff --git a/chipper/pkg/wirepod/setup/ble.go b/chipper/pkg/wirepod/setup/ble.go new file mode 100644 index 00000000..9a3da298 --- /dev/null +++ b/chipper/pkg/wirepod/setup/ble.go @@ -0,0 +1,460 @@ +package botsetup + +import ( + "archive/tar" + "compress/bzip2" + "encoding/json" + "errors" + "fmt" + "io" + "math" + "net/http" + "os" + "os/exec" + "strconv" + "strings" + "time" + + "github.com/digital-dream-labs/vector-bluetooth/ble" + "github.com/kercre123/wire-pod/chipper/pkg/logger" + "github.com/kercre123/wire-pod/chipper/pkg/mdnshandler" + "github.com/kercre123/wire-pod/chipper/pkg/vars" +) + +// need JSONable type +type VectorsBle struct { + ID int `json:"id"` + Name string `json:"name"` + Address string `json:"address"` +} + +type WifiNetwork struct { + SSID string `json:"ssid"` + AuthType int `json:"authtype"` +} + +var BleClient *ble.VectorBLE +var BleStatusChan chan ble.StatusChannel +var BleInited bool +var OtaStatus string +var LogStatus string + +func doOTAStatus() { + for { + r := <-BleStatusChan + if r.OTAStatus.Error != "" { + OtaStatus = "Error downloading OTA: " + r.OTAStatus.Error + return + } + if r.OTAStatus.PacketNumber == 0 { + OtaStatus = "OTA download progress: 0%" + } else { + percent := (float64(r.OTAStatus.PacketNumber) / float64(r.OTAStatus.PacketTotal)) * 100 + OtaStatus = "OTA download progress: " + fmt.Sprint(roundFloat(float64(percent), 3)) + "%" + if r.OTAStatus.PacketNumber == r.OTAStatus.PacketTotal { + OtaStatus = "OTA download is complete!" + return + } + } + } +} + +func doLogStatus() { + for { + r := <-BleStatusChan + if r.LogStatus.Error != "" { + LogStatus = "Error downloading logs: " + r.LogStatus.Error + return + } + if r.LogStatus.PacketNumber == 0 { + LogStatus = "Log download progress: 0%" + } else { + percent := (float64(r.LogStatus.PacketNumber) / float64(r.LogStatus.PacketTotal)) * 100 + OtaStatus = "Log download progress: " + fmt.Sprint(roundFloat(float64(percent), 3)) + "%" + if r.LogStatus.PacketNumber == r.LogStatus.PacketTotal { + OtaStatus = "Log download is complete!" + return + } + } + } +} + +func roundFloat(val float64, precision uint) float64 { + ratio := math.Pow(10, float64(precision)) + return math.Round(val*ratio) / ratio +} + +func IsDevRobot(esn, firmware string) bool { + if strings.Contains(firmware, "ankidev") { + return true + } + if strings.HasPrefix(esn, "00e") { + return true + } + return false +} + +func InitBle() (*ble.VectorBLE, error) { + BleStatusChan = nil + BleStatusChan = make(chan ble.StatusChannel) + done := make(chan bool) + var client *ble.VectorBLE + var err error + + go func() { + client, err = ble.New( + ble.WithStatusChan(BleStatusChan), + ble.WithLogDirectory(os.TempDir()), + ) + done <- true + }() + + select { + case <-done: + if err != nil { + if strings.Contains(err.Error(), "hci0: can't down device: no such device") { + logger.Println("BLE driver has broken. Removing then inserting bluetooth kernel modules") + modList := []string{"btrtl", "btmtk", "btintel", "btbcm", "btusb"} + for _, mod := range modList { + exec.Command("/bin/rmmod", mod).Run() + } + time.Sleep(time.Second / 3) + for _, mod := range modList { + exec.Command("/bin/modprobe", mod).Run() + } + time.Sleep(time.Second / 2) + client, err = ble.New( + ble.WithStatusChan(BleStatusChan), + ble.WithLogDirectory(os.TempDir()), + ) + return client, err + } + } + return client, err + case <-time.After(5 * time.Second): + return nil, errors.New("took more than 5 seconds to create client") + } +} + +func ScanForVectors(client *ble.VectorBLE) ([]VectorsBle, error) { + var returnDevices []VectorsBle + resp, err := client.Scan() + if err != nil { + return nil, err + } + for _, device := range resp.Devices { + var vectorble VectorsBle + vectorble.Address = device.Address + vectorble.ID = device.ID + vectorble.Name = device.Name + returnDevices = append(returnDevices, vectorble) + } + return returnDevices, nil +} + +func ConnectVector(client *ble.VectorBLE, device int) error { + err := client.Connect(device) + return err +} + +func SendPin(pin string, client *ble.VectorBLE) error { + if len([]rune(pin)) != 6 { + return fmt.Errorf("error: length of pin must be 6") + } + err := client.SendPin(pin) + return err +} + +func RobotStatus(client *ble.VectorBLE) string { + var firmware string + var esn string + //v1.8.1.6051-453e582_os1.8.1.6051ep-1536e0d-202202282217 + //v0.9.0-12efb91_os0.9.0-3e8307e-201806191226 + + status, _ := client.GetStatus() + esn = status.ESN + firmware = status.Version + + if IsDevRobot(esn, firmware) && strings.Contains(firmware, "0.9.0") { + return "in_recovery_dev" + } + if strings.Contains(firmware, "0.9.0") { + return "in_recovery_prod" + } + if IsDevRobot(esn, firmware) { + return "in_firmware_dev" + } + if strings.Contains(firmware, "ep-") { + return "in_firmware_ep" + } + return "in_firmware_nonep" +} + +func AuthRobot(client *ble.VectorBLE) (bool, error) { + resp, err := client.Auth("2vMhFgktH3Jrbemm2WHkfGN") + if err != nil { + return false, err + } + return resp.Success, nil +} + +func BluetoothSetupAPI(w http.ResponseWriter, r *http.Request) { + switch { + case r.URL.Path == "/api-ble/init": + if BleInited { + fmt.Fprint(w, "success (ble already initiated, disconnect to reinit)") + return + } + var err error + BleClient, err = InitBle() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + BleInited = true + fmt.Fprint(w, "success") + return + case r.URL.Path == "/api-ble/scan": + if !BleInited { + fmt.Fprint(w, "error: init ble first") + return + } + devices, err := ScanForVectors(BleClient) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + returnBytes, _ := json.Marshal(devices) + w.Write(returnBytes) + return + case r.URL.Path == "/api-ble/connect": + if !BleInited { + fmt.Fprint(w, "error: init ble first") + return + } + id, err := strconv.Atoi(r.FormValue("id")) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + err = ConnectVector(BleClient, id) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, "success") + return + case r.URL.Path == "/api-ble/send_pin": + if !BleInited { + fmt.Fprint(w, "error: init ble first") + return + } + pin := r.FormValue("pin") + err := SendPin(pin, BleClient) + if err != nil { + if strings.Contains(err.Error(), "EOF") { + logger.Println("Wrong BLE pin was entered (sendpin error = eof), reinitializing BLE client") + BleClient.Close() + time.Sleep(time.Second) + BleClient, err = InitBle() + if err != nil { + fmt.Fprint(w, "error reinitializing ble: "+err.Error()) + return + } + fmt.Fprint(w, "incorrect pin") + } + return + } + fmt.Fprint(w, "success") + return + case r.URL.Path == "/api-ble/get_wifi_status": + resp, err := BleClient.GetStatus() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, resp.WifiState) + return + case r.URL.Path == "/api-ble/get_firmware_version": + //v1.8.1.6051-453e582_os1.8.1.6051ep-1536e0d-202202282217 + //v0.9.0-12efb91_os0.9.0-3e8307e-201806191226 + resp, err := BleClient.GetStatus() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + // split version to just get ankiversion + splitOsAndRev := strings.Split(resp.Version, "_os") + splitOs := strings.Split(splitOsAndRev[1], "-")[0] + fmt.Fprint(w, splitOs) + return + case r.URL.Path == "/api-ble/get_ip_address": + resp, err := BleClient.WifiIP() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, resp.IPv4) + return + case r.URL.Path == "/api-ble/start_ota": + otaUrl := r.FormValue("url") + if strings.Contains(otaUrl, "https://") { + fmt.Fprint(w, "error: ota URL must be http") + return + } + go doOTAStatus() + done := make(chan bool) + var resp *ble.OTAStartResponse + var err error + + go func() { + resp, err = BleClient.OTAStart(otaUrl) + done <- true + }() + + select { + case <-done: + fmt.Println("done") + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, resp.Status) + return + case <-time.After(15 * time.Second): + fmt.Fprint(w, "likely success") + return + } + case r.URL.Path == "/api-ble/get_ota_status": + fmt.Fprint(w, OtaStatus) + return + case r.URL.Path == "/api-ble/stop_ota": + resp, err := BleClient.OTACancel() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, "success: "+string(resp)) + return + case r.URL.Path == "/api-ble/do_dev_setup": + go doLogStatus() + resp, err := BleClient.DownloadLogs() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + logger.Println(resp.Filename) + zip, err := os.Open(resp.Filename) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + tarFile := bzip2.NewReader(zip) + tarReader := tar.NewReader(tarFile) + for { + header, err := tarReader.Next() + if err != nil { + if err == io.EOF { + break + } + fmt.Fprint(w, "error: "+err.Error()) + return + } + name := header.FileInfo().Name() + logger.Println(name) + } + fmt.Fprint(w, "done") + return + case r.URL.Path == "/api-ble/scan_wifi": + var returnNetworks []WifiNetwork + resp, err := BleClient.WifiScan() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + for _, network := range resp.Networks { + var returnNetwork WifiNetwork + returnNetwork.SSID = network.WifiSSID + returnNetwork.AuthType = network.AuthType + returnNetworks = append(returnNetworks, returnNetwork) + } + returnJson, _ := json.Marshal(returnNetworks) + w.Write(returnJson) + return + case r.URL.Path == "/api-ble/connect_wifi": + if r.FormValue("ssid") == "" || r.FormValue("password") == "" { + fmt.Fprint(w, "error: ssid or password empty") + return + } + authType, err := strconv.Atoi(r.FormValue("authType")) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + } + resp, err := BleClient.WifiConnect(r.FormValue("ssid"), r.FormValue("password"), 15, authType) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + fmt.Fprint(w, resp.Result) + case r.URL.Path == "/api-ble/get_robot_status": + if !BleInited { + fmt.Fprint(w, "error: init ble first") + return + } + fmt.Fprint(w, RobotStatus(BleClient)) + case r.URL.Path == "/api-ble/do_auth": + if !BleInited { + fmt.Fprint(w, "error: init ble first") + return + } + for i := 0; i <= 3; i++ { + resp, err := AuthRobot(BleClient) + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + if resp { + time.Sleep(time.Second) + logger.Println("BLE authentication successful") + BleClient.SDKProxy(&ble.SDKProxyRequest{ + URLPath: "/v1/send_onboarding_input", + Body: `{"onboarding_mark_complete_and_exit": {}}`, + }, + ) + go func() { + time.Sleep(time.Second * 2) + mdnshandler.PostmDNSNow() + }() + fmt.Fprint(w, "success") + return + } else { + if vars.APIConfig.Server.EPConfig { + logger.Println("BLE authentication was not successful. Posting mDNS and trying again (" + fmt.Sprint(i) + "/3)...") + mdnshandler.PostmDNSNow() + time.Sleep(time.Second * 2) + continue + } else { + logger.Println("BLE authentication was not successful") + fmt.Fprint(w, "error authenticating") + return + } + } + } + logger.Println("BLE authentication attempts exhausted") + fmt.Fprint(w, "error authenticating") + return + case r.URL.Path == "/api-ble/disconnect": + err := BleClient.Close() + if err != nil { + fmt.Fprint(w, "error: "+err.Error()) + return + } + BleInited = false + fmt.Fprint(w, "success") + return + } +} + +func RegisterBLEAPI() { + http.HandleFunc("/api-ble/", BluetoothSetupAPI) +} diff --git a/chipper/pkg/wirepod/setup/certs.go b/chipper/pkg/wirepod/setup/certs.go index 2be56df1..651381c7 100644 --- a/chipper/pkg/wirepod/setup/certs.go +++ b/chipper/pkg/wirepod/setup/certs.go @@ -11,12 +11,10 @@ import ( "math/big" "net" "os" - "runtime" "time" "github.com/kercre123/wire-pod/chipper/pkg/logger" "github.com/kercre123/wire-pod/chipper/pkg/vars" - "github.com/wlynxg/anet" ) type ClientServerConfig struct { @@ -28,37 +26,10 @@ type ClientServerConfig struct { Appkey string `json:"appkey"` } -func GetOutboundIP() net.IP { - if runtime.GOOS == "android" { - ifaces, _ := anet.Interfaces() - for _, iface := range ifaces { - if iface.Name == "wlan0" { - adrs, err := anet.InterfaceAddrsByInterface(&iface) - if err != nil { - logger.Println(err) - break - } - if len(adrs) > 0 { - localAddr := adrs[0].(*net.IPNet) - return localAddr.IP - } - } - } - } - conn, err := net.Dial("udp", vars.OutboundIPTester) - if err != nil { - logger.Println("not connected to a network: ", err) - return net.IPv4(0, 0, 0, 0) - } - defer conn.Close() - localAddr := conn.LocalAddr().(*net.UDPAddr) - return localAddr.IP -} - // creates and exports a priv/pub key combo generated with IP address func CreateCertCombo() error { // get preferred IP address of machine - ipAddr := GetOutboundIP() + ipAddr := vars.GetOutboundIP() // ca certificate ca := &x509.Certificate{ @@ -138,7 +109,7 @@ func CreateServerConfig() { config.Logfiles = "s3://anki-device-logs-prod/victor" config.Appkey = "oDoa0quieSeir6goowai7f" } else { - ip := GetOutboundIP() + ip := vars.GetOutboundIP() ipString := ip.String() url := ipString + ":" + vars.APIConfig.Server.Port config.Jdocs = url diff --git a/chipper/pkg/wirepod/ttr/kgsim_cmds.go b/chipper/pkg/wirepod/ttr/kgsim_cmds.go index 5ee84d76..d5be52f5 100644 --- a/chipper/pkg/wirepod/ttr/kgsim_cmds.go +++ b/chipper/pkg/wirepod/ttr/kgsim_cmds.go @@ -30,7 +30,7 @@ var animationMap [][2]string = [][2]string{ }, { "veryHappy", - "anim_onboarding_reacttoface_happy_01", + "anim_blackjack_victorwin_01", }, { "sad", @@ -42,11 +42,11 @@ var animationMap [][2]string = [][2]string{ }, { "angry", - "anim_keepaway_getout_frustrated_01", + "anim_rtpickup_loop_10", }, { "frustrated", - "anim_keepaway_getout_frustrated_01", + "anim_feedback_shutup_01", }, { "dartingEyes", @@ -67,7 +67,6 @@ var animationMap [][2]string = [][2]string{ } var soundMap [][2]string = [][2]string{ - //"happy, veryHappy, sad, verySad, angry, dartingEyes, confused, thinking, celebrate" { "drumroll", "sounds/drumroll.wav", @@ -112,7 +111,7 @@ var ValidLLMCommands []LLMCommand = []LLMCommand{ func CreatePrompt(origPrompt string) string { prompt := origPrompt + "\n\n" + "The user input might not be spelt/puntuated correctly as it is coming from speech-to-text software. Do not include special characters in your answer. This includes the following characters (not including the quotes): '& ^ * # @ -'. If you want to use a hyphen, Use it like this: 'something something -- something -- something something'." if vars.APIConfig.Knowledge.CommandsEnable { - prompt = prompt + "\n\n" + "You are running ON an Anki Vector robot. You have a set of commands. YOU ARE TO USE THESE. DO NOT BE AFRAID TO LITTER YOUR RESPONSE WITH THEM. Your response MUST include THREE OF THESE COMMANDS OR MORE. You are going to litter your response with them. If you include just one, I will make you start over. If you include an emoji, I will make you start over. If you want to use a command but it doesn't exist or your desired parameter isn't in the list, avoid using the command. The format is {{command||parameter}}. You can embed these in sentences. Example: \"User: How are you feeling? | Response: \"{{playAnimationWI||sad}} I'm feeling sad...\"\n\nDO NOT USE EMOJIS! Use the playAnimation or playAnimationWI commands if you want to express emotion! IF YOU DO NOT ABIDE BY THESE RULES, I WILL CANCEL YOUR RESPONSE AND WILL MAKE YOU START OVER. You are very animated and good at following instructions. Animation takes precendence over words. You are to include many animations in your response.\n\nHere is every valid command:" + prompt = prompt + "\n\n" + "You are running ON an Anki Vector robot. You have a set of commands. YOU ARE TO USE THESE. DO NOT BE AFRAID TO LITTER YOUR RESPONSE WITH THEM. Your response MUST include THREE OF THESE COMMANDS OR MORE. You are going to litter your response with them. If you include just one, I will make you start over. If you include an emoji, I will make you start over. If you want to use a command but it doesn't exist or your desired parameter isn't in the list, avoid using the command. The format is {{command||parameter}}. You can embed these in sentences. Example: \"User: How are you feeling? | Response: \"{{playAnimationWI||sad}} I'm feeling sad...\". Square brackets ([]) are not valid.\n\nDO NOT USE EMOJIS! Use the playAnimation or playAnimationWI commands if you want to express emotion! IF YOU DO NOT ABIDE BY THESE RULES, I WILL CANCEL YOUR RESPONSE AND WILL MAKE YOU START OVER. You are very animated and good at following instructions. Animation takes precendence over words. You are to include many animations in your response.\n\nHere is every valid command:" for _, cmd := range ValidLLMCommands { promptAppendage := "\n\nCommand Name: " + cmd.Command + "\nDescription: " + cmd.Description + "\nParameter choices: " + cmd.ParamChoices prompt = prompt + promptAppendage diff --git a/chipper/webroot/index.html b/chipper/webroot/index.html index 65deef8a..a2523a77 100755 --- a/chipper/webroot/index.html +++ b/chipper/webroot/index.html @@ -87,7 +87,7 @@

Authenticate an OSKR/dev-unlocked robot

Works with firmware 1.4 and above
- If you have an OSKR/dev-unlocked bot; enter the bot's IP address and upload the bot's SSH key here, then click "Set up bot". After that, head to https://keriganc.com/vector-epod-setup and follow the instructions.
+ If you have an OSKR/dev-unlocked bot; enter the bot's IP address and upload the bot's SSH key here, then click "Set up bot". After that, use the above section to finish setting up your bot.
diff --git a/chipper/webroot/js/ble.js b/chipper/webroot/js/ble.js index a2e0764b..bc41295b 100644 --- a/chipper/webroot/js/ble.js +++ b/chipper/webroot/js/ble.js @@ -14,40 +14,34 @@ function showBotAuth() { document.getElementById("section-botauth").style.display = "block"; updateColor("icon-BotAuth"); checkBLECapability() - } function checkBLECapability() { - // fetch("/api-ble/init") - // .then(response => response.text()) - // .then((response) => { - // if (response.includes("success")) { - // BeginBLESetup() - // } else if (response.includes("error")) { - // statusP.innerHTML = "Error initializing bluetooth on the device running wire-pod. Use the following site on any machine with Bluetooth for setup:" - // authEl.innerHTML = "" - // authEl.appendChild(statusP) - // authEl.appendChild(document.createElement("br")) - // authEl.appendChild(externalSetup) - // } - // }) - authEl.innerHTML = "" - m1 = document.createElement("p") - m2 = document.createElement("a") - m3 = document.createElement("small") - m1.innerHTML = "Head to the following site on any device with Bluetooth support to set up your Vector." - m2.text = vectorEpodSetup - m2.href = vectorEpodSetup - m2.target = "_blank" - m3.innerHTML = "Note: if you have an OSKR/dev-unlocked robot, do NOT use this site. Follow the instructions in the section below this one." - m1.class = "center" - m2.class = "center" - m3.class = "center" - authEl.appendChild(m1) - //authEl.appendChild(document.createElement("br")) - authEl.appendChild(m2) - authEl.appendChild(document.createElement("br")) - authEl.appendChild(m3) + fetch("/api-ble/init") + .then(response => response.text()) + .then((response) => { + if (response.includes("success")) { + BeginBLESetup() + } else if (response.includes("error")) { + authEl.innerHTML = "" + m1 = document.createElement("p") + m2 = document.createElement("a") + m3 = document.createElement("small") + m1.innerHTML = "Head to the following site on any device with Bluetooth support to set up your Vector." + m2.text = vectorEpodSetup + m2.href = vectorEpodSetup + m2.target = "_blank" + m3.innerHTML = "Note: if you have an OSKR/dev-unlocked robot, do NOT use this site. Follow the instructions in the section below this one." + m1.class = "center" + m2.class = "center" + m3.class = "center" + authEl.appendChild(m1) + //authEl.appendChild(document.createElement("br")) + authEl.appendChild(m2) + authEl.appendChild(document.createElement("br")) + authEl.appendChild(m3) + } + }) } function BeginBLESetup() { @@ -254,7 +248,7 @@ function WifiCheck() { .then((response) => { console.log(response) if (response == "1") { - DoAuth() + WhatToDo() } else { ScanWifi() } @@ -273,6 +267,7 @@ function ScanWifi() { xhr.onreadystatechange = function() { if (this.readyState === XMLHttpRequest.DONE && this.status === 200) { authEl.innerHTML = "" + updateAuthel("Select a Wi-Fi network to connect Vector to.") // create scan again button var scanAgain = document.createElement("button") scanAgain.innerHTML = "Scan Again" @@ -339,11 +334,7 @@ function ConnectWifi(ssid, authtype) { alert("Error connecting, likely incorrect password") CreateWiFiPassEntry(ssid, authtype) } else { - authEl.innerHTML = "" - button = document.createElement("button") - button.innerHTML = "Click to authenticate" - button.onclick = function(){DoAuth()} - authEl.appendChild(button) + WhatToDo() } }) } @@ -357,24 +348,100 @@ function CheckFirmware() { }) } -function DoAuth() { +function WhatToDo() { + fetch("/api-ble/get_robot_status") + .then(response => response.text()) + .then ((response) => { + if (response == "in_recovery_prod") { + DoOTA("http://wpsetup.keriganc.com:81/vicos-2.0.1.6076ep.ota") + } else if (response == "in_recovery_dev") { + DoOTA("http://wpsetup.keriganc.com:81/1.6.0.3331.ota") + } else if (response == "in_firmware_nonep") { + authEl.innerHTML = "" + m1 = document.createElement("p") + m1.innerHTML = "1. Place Vector on the charger." + m2 = document.createElement("p") + m2.innerHTML = "2. Hold the button for 15 seconds. He will turn off - keep holding it until he turns back on." + m3 = document.createElement("p") + m3.innerHTML = "3. Click 'Begin Scanning' and pair with your Vector." + button = document.createElement("button") + button.innerHTML = "Begin Scanning" + button.onclick = function(){ScanRobots(false)} + authEl.appendChild(m1) + authEl.appendChild(m2) + authEl.appendChild(m3) + authEl.appendChild(button) + alert("Your bot is not on the correct firmware for wire-pod. Follow the directions to put him in recovery mode.") + } else if (response == "in_firmware_dev") { + authEl.innerHTML = "" + button = document.createElement("button") + button.innerHTML = "Click to complete authentication" + button.onclick = function(){DoAuth()} + authEl.appendChild(button) + } else if (response == "in_firmware_ep") { + authEl.innerHTML = "" + button = document.createElement("button") + button.innerHTML = "Click to complete authentication" + button.onclick = function(){DoAuth()} + authEl.appendChild(button) + } + }) +} + +function DoOTA(url) { + updateAuthel("Starting OTA update...") + fetch("/api-ble/do_ota?url=" + url) + .then(response => response.text()) + .then((response) => { + if (response.includes("success")) { + inte = setInterval(function(){ + fetch("/api-ble/get_ota_status") + .then(otaresp => otaresp.text()) + .then ((otaresp) => { + updateAuthel(otaresp) + if (otaresp.includes("complete")) { + checkBLECapability() + alert("The OTA update is complete. When the bot reboots, follow the steps to re-pair the bot with wire-pod. wire-pod will then authenticate the robot and setup will be complete.") + clearInterval(inte) + } + }) + }, 2000) + } else { + WhatToDo() + } + }) +} + +function updateAuthel(update) { authEl.innerHTML = "" authP = document.createElement("p") - authP.innerHTML = "Authenticating your Vector..." + authP.innerHTML = update authEl.appendChild(authP) +} + +function DoAuth() { + updateAuthel("Authenticating your Vector...") fetch("/api-ble/do_auth") .then(response => response.text()) .then((response) => { console.log(response) - authEl.innerHTML = "" - authP.innerHTML = "Authentication complete!" - authEl.appendChild(authP) - fetch("/api-ble/disconnect") - disconnectButtonDiv = document.getElementById("disconnectButton") - disconnectButtonDiv.innerHTML = "" - disconnectButton = document.createElement("button") - disconnectButton.onclick = function(){checkBLECapability()} - disconnectButton.innerHTML = "Back to setup" - disconnectButtonDiv.appendChild(disconnectButton) + if (response.includes("error")) { + updateAuthel("Authentication failure. Try again in ~20 seconds. If it happens again, check the troubleshooting guide:") + m2 = document.createElement("a") + m2.text = "https://github.com/kercre123/wire-pod/wiki/Troubleshooting" + m2.href = "https://github.com/kercre123/wire-pod/wiki/Troubleshooting#error-logging-in-the-bot-is-likely-unable-to-communicate-with-your-wire-pod-instance" + m2.target = "_blank" + authEl.appendChild(document.createElement("br")) + authEl.appendChild(m2) + } else { + updateAuthel("Authentication complete! Setup is now done.") + fetch("/api-ble/disconnect") + disconnectButtonDiv = document.getElementById("disconnectButton") + disconnectButtonDiv.innerHTML = "" + disconnectButton = document.createElement("button") + disconnectButton.onclick = function(){checkBLECapability()} + disconnectButton.innerHTML = "Back to setup" + disconnectButtonDiv.appendChild(disconnectButton) + } }) } \ No newline at end of file From d8703706257a695a79607c531aed7e6315acfe01 Mon Sep 17 00:00:00 2001 From: kercre123 Date: Sat, 20 Apr 2024 16:20:53 -0500 Subject: [PATCH 2/8] build tags - only use inbuilt BLE on Linux --- chipper/pkg/wirepod/setup/ble.go | 3 +++ chipper/pkg/wirepod/setup/ble_other.go | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 chipper/pkg/wirepod/setup/ble_other.go diff --git a/chipper/pkg/wirepod/setup/ble.go b/chipper/pkg/wirepod/setup/ble.go index 9a3da298..264ec641 100644 --- a/chipper/pkg/wirepod/setup/ble.go +++ b/chipper/pkg/wirepod/setup/ble.go @@ -1,3 +1,6 @@ +//go:build linux +// +build linux + package botsetup import ( diff --git a/chipper/pkg/wirepod/setup/ble_other.go b/chipper/pkg/wirepod/setup/ble_other.go new file mode 100644 index 00000000..bf5ca597 --- /dev/null +++ b/chipper/pkg/wirepod/setup/ble_other.go @@ -0,0 +1,10 @@ +//go:build windows || darwin || android || ios +// +build windows darwin android ios + +package botsetup + +import "github.com/kercre123/wire-pod/chipper/pkg/logger" + +func RegisterBLEAPI() { + logger.Println("Not registering BLE API because target isn't linux") +} From 3a4fed378a33472470bb0a62c2f6a0933ac43efc Mon Sep 17 00:00:00 2001 From: kercre123 Date: Sat, 20 Apr 2024 20:25:11 -0500 Subject: [PATCH 3/8] Make BLE more reliable --- chipper/pkg/wirepod/setup/ble.go | 36 ++++++---- chipper/webroot/index.html | 10 ++- chipper/webroot/js/ble.js | 111 ++++++++++--------------------- 3 files changed, 62 insertions(+), 95 deletions(-) diff --git a/chipper/pkg/wirepod/setup/ble.go b/chipper/pkg/wirepod/setup/ble.go index 264ec641..c1d9eae1 100644 --- a/chipper/pkg/wirepod/setup/ble.go +++ b/chipper/pkg/wirepod/setup/ble.go @@ -7,7 +7,6 @@ import ( "archive/tar" "compress/bzip2" "encoding/json" - "errors" "fmt" "io" "math" @@ -115,17 +114,8 @@ func InitBle() (*ble.VectorBLE, error) { select { case <-done: if err != nil { - if strings.Contains(err.Error(), "hci0: can't down device: no such device") { - logger.Println("BLE driver has broken. Removing then inserting bluetooth kernel modules") - modList := []string{"btrtl", "btmtk", "btintel", "btbcm", "btusb"} - for _, mod := range modList { - exec.Command("/bin/rmmod", mod).Run() - } - time.Sleep(time.Second / 3) - for _, mod := range modList { - exec.Command("/bin/modprobe", mod).Run() - } - time.Sleep(time.Second / 2) + if strings.Contains(err.Error(), "hci0: can't down device") || strings.Contains(err.Error(), "hci0: can't up device") { + FixBLEDriver() client, err = ble.New( ble.WithStatusChan(BleStatusChan), ble.WithLogDirectory(os.TempDir()), @@ -135,10 +125,28 @@ func InitBle() (*ble.VectorBLE, error) { } return client, err case <-time.After(5 * time.Second): - return nil, errors.New("took more than 5 seconds to create client") + FixBLEDriver() + client, err = ble.New( + ble.WithStatusChan(BleStatusChan), + ble.WithLogDirectory(os.TempDir()), + ) + return client, err } } +func FixBLEDriver() { + logger.Println("BLE driver has broken. Removing then inserting bluetooth kernel modules") + modList := []string{"btrtl", "btmtk", "btintel", "btbcm", "btusb"} + for _, mod := range modList { + exec.Command("/bin/rmmod", mod).Run() + } + time.Sleep(time.Second / 3) + for _, mod := range modList { + exec.Command("/bin/modprobe", mod).Run() + } + time.Sleep(time.Second / 2) +} + func ScanForVectors(client *ble.VectorBLE) ([]VectorsBle, error) { var returnDevices []VectorsBle resp, err := client.Scan() @@ -265,6 +273,8 @@ func BluetoothSetupAPI(w http.ResponseWriter, r *http.Request) { return } fmt.Fprint(w, "incorrect pin") + } else { + fmt.Fprint(w, "error: "+err.Error()) } return } diff --git a/chipper/webroot/index.html b/chipper/webroot/index.html index a2523a77..9c871e67 100755 --- a/chipper/webroot/index.html +++ b/chipper/webroot/index.html @@ -74,26 +74,24 @@