diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index b34f65b..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -liberapay: Elara6331 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 8d98099..ea8ba6b 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -14,7 +14,6 @@ builds: - amd64 - arm - arm64 - - riscv64 goarm: - 7 - id: itctl @@ -44,7 +43,8 @@ archives: - README.md - itd.toml - itd.service - allow_different_binary_count: true + - itgui.desktop + - itgui-linux-{{.Arch}}{{if eq .Arch "arm"}}-7{{end}} nfpms: - id: itd file_name_template: >- @@ -55,8 +55,8 @@ nfpms: {{- else }}{{.Arch}} {{- end }} description: "Companion daemon for the InfiniTime firmware on the PineTime smartwatch" - homepage: 'https://gitea.elara.ws/Elara6331/itd' - maintainer: 'Elara Musayelyan ' + homepage: 'https://gitea.arsenm.dev/Arsen6331/itd' + maintainer: 'Arsen Musyaelyan ' license: GPLv3 formats: - apk @@ -72,14 +72,18 @@ nfpms: type: "config|noreplace" - src: itd.service dst: /usr/lib/systemd/user/itd.service + - src: itgui.desktop + dst: /usr/share/applications/itgui.desktop + - src: itgui-linux-{{.Arch}}{{if eq .Arch "arm"}}-7{{end}} + dst: /usr/bin/itgui file_info: mode: 0755 aurs: - name: itd-bin - homepage: 'https://gitea.elara.ws/Elara6331/itd' + homepage: 'https://gitea.arsenm.dev/Arsen6331/itd' description: "Companion daemon for the InfiniTime firmware on the PineTime smartwatch" maintainers: - - 'Elara Musayelyan ' + - 'Arsen Musyaelyan ' license: GPLv3 private_key: '{{ .Env.AUR_KEY }}' git_url: 'ssh://aur@aur.archlinux.org/itd-bin.git' @@ -96,6 +100,10 @@ aurs: # binaries install -Dm755 ./itd "${pkgdir}/usr/bin/itd" install -Dm755 ./itctl "${pkgdir}/usr/bin/itctl" + install -Dm755 ./itgui-linux-* "${pkgdir/usr/bin/itgui}" + + # desktop files + install -Dm644 "./itgui.desktop" "${pkgdir}/usr/share/applications/itgui.desktop" # service install -Dm644 "./itd.service" ${pkgdir}/usr/lib/systemd/user/itd.service @@ -107,11 +115,11 @@ aurs: install -Dm644 "./LICENSE" "${pkgdir}/usr/share/licenses/itd/LICENSE" release: gitea: - owner: Elara6331 + owner: Arsen6331 name: itd gitea_urls: - api: 'https://gitea.elara.ws/api/v1/' - download: 'https://gitea.elara.ws' + api: 'https://gitea.arsenm.dev/api/v1/' + download: 'https://gitea.arsenm.dev' skip_tls_verify: false checksum: name_template: 'checksums.txt' diff --git a/.woodpecker.yml b/.woodpecker.yml index fbb803d..d3e2f7b 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -1,4 +1,16 @@ pipeline: + xgo-itgui: + image: arsen6331/fyne-xgo + environment: + - 'TARGETS=linux/amd64 linux/arm64 linux/386 linux/arm-7' + - 'OUT=itgui' + - 'PACK=./cmd/itgui' + commands: + - export SOURCE_DIR=$${CI_WORKSPACE} OUT_DIR=$${CI_WORKSPACE} + - /build.sh + when: + event: tag + release: image: goreleaser/goreleaser commands: diff --git a/README.md b/README.md index ac3b2a2..5a896f4 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,11 @@ # ITD ## InfiniTime Daemon -`itd` is a daemon that uses my infinitime [library](https://go.elara.ws/infinitime) to interact with the [PineTime](https://www.pine64.org/pinetime/) running [InfiniTime](https://infinitime.io). +`itd` is a daemon that uses my infinitime [library](https://go.arsenm.dev/infinitime) to interact with the [PineTime](https://www.pine64.org/pinetime/) running [InfiniTime](https://infinitime.io). -[![status-badge](https://ci.elara.ws/api/badges/Elara6331/itd/status.svg)](https://ci.elara.ws/Elara6331/itd) +[![status-badge](https://ci.arsenm.dev/api/badges/Arsen6331/itd/status.svg)](https://ci.arsenm.dev/Arsen6331/itd) [![itd-git AUR package](https://img.shields.io/aur/version/itd-git?label=itd-git&logo=archlinux)](https://aur.archlinux.org/packages/itd-git/) [![itd-bin AUR package](https://img.shields.io/aur/version/itd-bin?label=itd-bin&logo=archlinux)](https://aur.archlinux.org/packages/itd-bin/) -[![LURE badge for itd-git](https://lure.sh/pkg/default/itd-git/badge.svg)](https://lure.sh/pkg/default/itd-git) -[![LURE badge for itd-bin](https://lure.sh/pkg/default/itd-bin/badge.svg)](https://lure.sh/pkg/default/itd-bin) - -This repository is part of the Software Heritage Archive: - -[![SWH](https://archive.softwareheritage.org/badge/swh:1:dir:1374aa47b5c0a0d636d6f9c69f77af5e5bae99b2/)](https://archive.softwareheritage.org/swh:1:dir:1374aa47b5c0a0d636d6f9c69f77af5e5bae99b2;origin=https://gitea.elara.ws/Elara6331/itd;visit=swh:1:snp:d2935acbc966dfe1b15c771927bb08b5fc2ec89f;anchor=swh:1:rev:395cded9758dccc020fcd5b666f83a62308c9ab7) --- @@ -28,7 +22,6 @@ This repository is part of the Software Heritage Archive: - Weather - BLE Filesystem - Navigation (PureMaps) -- FUSE Filesystem --- @@ -42,19 +35,19 @@ Use the `itd-bin` or `itd-git` AUR packages. #### Debian/Ubuntu -- Go to the [latest release](https://gitea.elara.ws/Elara6331/itd/releases/latest) and download the `.deb` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. +- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.deb` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. - Run `sudo apt install `, replacing `` with the path to the downloaded file. Note: relative paths must begin with `./`. - Example: `sudo apt install ~/Downloads/itd-0.0.7-linux-aarch64.deb` #### Fedora -- Go to the [latest release](https://gitea.elara.ws/Elara6331/itd/releases/latest) and download the `.rpm` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. +- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.rpm` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. - Run `sudo dnf install `, replacing `` with the path to the downloaded file. - Example: `sudo dnf install ~/Downloads/itd-0.0.7-linux-aarch64.rpm` #### Alpine (and postmarketOS) -- Go to the [latest release](https://gitea.elara.ws/Elara6331/itd/releases/latest) and download the `.apk` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. +- Go to the [latest release](https://gitea.arsenm.dev/Arsen6331/itd/releases/latest) and download the `.apk` package for your CPU architecture. You can find your architecture by running `uname -m` in the terminal. - Run `sudo apk add --allow-untrusted `, replacing `` with the path to the downloaded file. - Example: `sudo apk add --allow-untrusted ~/Downloads/itd-0.0.7-linux-aarch64.apk` @@ -62,6 +55,57 @@ Note: `--allow-untrusted` is required because ITD isn't part of a repository, an --- +### Socket + +This daemon creates a UNIX socket at `/tmp/itd/socket`. It allows you to directly control the daemon and, by extension, the connected watch. + +The socket uses my [lrpc](https://gitea.arsenm.dev/Arsen6331/lrpc) library for requests. This library accepts requests in msgpack, with the following format: + +```json +{"Receiver": "ITD", "Method": "Notify", "Arg": {"title": "title1", "body": "body1"}, "ID": "some-id-here"} +``` + +It will return a msgpack response, the format of which can be found [here](https://gitea.arsenm.dev/Arsen6331/lrpc/src/branch/master/internal/types/types.go#L30). The response will have the same ID as was sent in the request in order to allow the client to keep track of which request the response belongs to. + +--- + +### Transliteration + +Since the PineTime does not have enough space to store all unicode glyphs, it only stores the ASCII space and Cyrillic. Therefore, this daemon can transliterate unsupported characters into supported ones. Since some languages have different transliterations, the transliterators to be used must be specified in the config. Here are the available transliterators: + +- eASCII +- Scandinavian +- German +- Hebrew +- Greek +- Russian +- Ukranian +- Arabic +- Farsi +- Polish +- Lithuanian +- Estonian +- Icelandic +- Czech +- French +- Armenian +- Korean +- Chinese +- Romanian +- Emoji + +Place the desired map names in an array as `notifs.translit.use`. They will be evaluated in order. You can also put custom transliterations in `notifs.translit.custom`. These take priority over any other maps. The `notifs.translit` config section should look like this: + +```toml +[notifs.translit] + use = ["eASCII", "Russian", "Emoji"] + custom = [ + "test", "replaced" + ] +``` + +--- + ### `itctl` This daemon comes with a binary called `itctl` which uses the socket to control the daemon from the command line. As such, it can be scripted using bash. @@ -95,17 +139,6 @@ GLOBAL OPTIONS: In `cmd/itgui`, there is a gui frontend to the socket of `itd`. It uses the [Fyne library](https://fyne.io/) for Go. -#### Easy Installation - -The easiest way to install `itgui` is to use my other project, [LURE](https://gitea.elara.ws/Elara6331/lure). LURE will only work if your package manager is `apt`, `dnf`, `yum`, `zypper`, `pacman`, or `apk`. - -Instructions: - -1. Install LURE. This can be done with the following command: `curl https://www.elara.ws/lure.sh | bash`. -2. Check to make sure LURE is properly installed by running `lure ref`. -3. Run `lure in itgui`. This process may take a while as it will compile `itgui` from source and package it for your distro. -4. Once the process is complete, you should be able to open and use `itgui` like any other app. - #### Compilation Before compiling, certain prerequisites must be installed. These are listed on the following page: https://developer.fyne.io/started/#prerequisites @@ -144,13 +177,14 @@ Due to the use of OpenGL, cross-compilation of `itgui` isn't as simple as that o --- -### Socket +### Installation -This daemon creates a UNIX socket at `/tmp/itd/socket`. It allows you to directly control the daemon and, by extension, the connected watch. +To install, install the go compiler and make. Usually, go is provided by a package either named `go` or `golang`, and make is usually provided by `make`. The go compiler must be version 1.17 or newer for various new `reflect` features. -The socket uses the [DRPC](https://github.com/storj/drpc) library for requests. The code generated by this framework is located in [`internal/rpc`](internal/rpc) - -The API description is located in the [`internal/rpc/itd.proto`](internal/rpc/itd.proto) file. +To install, run +```shell +make && sudo make install +``` --- @@ -193,4 +227,4 @@ Most of the time, the daemon does not need to be restarted for config changes to Location data from OpenStreetMap Nominatim, © [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors -Weather data from the [Norwegian Meteorological Institute](https://www.met.no/en) +Weather data from the [Norwegian Meteorological Institute](https://www.met.no/en) \ No newline at end of file diff --git a/api/api.go b/api/api.go index 996e29b..adb6a06 100644 --- a/api/api.go +++ b/api/api.go @@ -4,59 +4,34 @@ import ( "io" "net" - "go.elara.ws/drpc/muxconn" - "go.elara.ws/itd/internal/rpc" - "storj.io/drpc" + "go.arsenm.dev/lrpc/client" + "go.arsenm.dev/lrpc/codec" ) const DefaultAddr = "/tmp/itd/socket" -// Client is a client for ITD's socket API type Client struct { - conn drpc.Conn - client rpc.DRPCITDClient + client *client.Client } -// New connects to the UNIX socket at the given -// path, and returns a client that communicates -// with that socket. func New(sockPath string) (*Client, error) { conn, err := net.Dial("unix", sockPath) if err != nil { return nil, err } - mconn, err := muxconn.New(conn) - if err != nil { - return nil, err + out := &Client{ + client: client.New(conn, codec.Default), } - - return &Client{ - conn: mconn, - client: rpc.NewDRPCITDClient(mconn), - }, nil + return out, nil } -// NewFromConn returns a client that communicates -// over the given connection. -func NewFromConn(conn io.ReadWriteCloser) (*Client, error) { - mconn, err := muxconn.New(conn) - if err != nil { - return nil, err +func NewFromConn(conn io.ReadWriteCloser) *Client { + return &Client{ + client: client.New(conn, codec.Default), } - - return &Client{ - conn: mconn, - client: rpc.NewDRPCITDClient(mconn), - }, nil } -// FS returns the filesystem API client -func (c *Client) FS() *FSClient { - return &FSClient{rpc.NewDRPCFSClient(c.conn)} -} - -// Close closes the client connection func (c *Client) Close() error { - return c.conn.Close() + return c.client.Close() } diff --git a/api/firmware.go b/api/firmware.go index 0af58e0..406fac7 100644 --- a/api/firmware.go +++ b/api/firmware.go @@ -3,34 +3,24 @@ package api import ( "context" - "go.elara.ws/itd/internal/rpc" + "go.arsenm.dev/infinitime" ) -type DFUProgress struct { - Sent int64 - Received int64 - Total int64 - Err error -} - -func (c *Client) FirmwareUpgrade(ctx context.Context, upgType UpgradeType, files ...string) (chan DFUProgress, error) { - progressCh := make(chan DFUProgress, 5) - fc, err := c.client.FirmwareUpgrade(ctx, &rpc.FirmwareUpgradeRequest{ - Type: rpc.FirmwareUpgradeRequest_Type(upgType), - Files: files, - }) +func (c *Client) FirmwareUpgrade(ctx context.Context, upgType UpgradeType, files ...string) (chan infinitime.DFUProgress, error) { + progressCh := make(chan infinitime.DFUProgress, 5) + err := c.client.Call( + ctx, + "ITD", + "FirmwareUpgrade", + FwUpgradeData{ + Type: upgType, + Files: files, + }, + progressCh, + ) if err != nil { return nil, err } - go fsRecvToChannel[rpc.DFUProgress](fc, progressCh, func(evt *rpc.DFUProgress, err error) DFUProgress { - return DFUProgress{ - Sent: evt.Sent, - Received: evt.Recieved, - Total: evt.Total, - Err: err, - } - }) - return progressCh, nil } diff --git a/api/fs.go b/api/fs.go index 6d5d178..7b05b51 100644 --- a/api/fs.go +++ b/api/fs.go @@ -1,119 +1,96 @@ package api -import ( - "context" - "errors" - "io" +import "context" - "go.elara.ws/itd/internal/rpc" -) - -type FSClient struct { - client rpc.DRPCFSClient +func (c *Client) RemoveAll(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "RemoveAll", + paths, + nil, + ) } -func (c *FSClient) RemoveAll(ctx context.Context, paths ...string) error { - _, err := c.client.RemoveAll(ctx, &rpc.PathsRequest{Paths: paths}) - return err +func (c *Client) Remove(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "Remove", + paths, + nil, + ) } -func (c *FSClient) Remove(ctx context.Context, paths ...string) error { - _, err := c.client.Remove(ctx, &rpc.PathsRequest{Paths: paths}) - return err +func (c *Client) Rename(ctx context.Context, old, new string) error { + return c.client.Call( + ctx, + "FS", + "Rename", + [2]string{old, new}, + nil, + ) } -func (c *FSClient) Rename(ctx context.Context, old, new string) error { - _, err := c.client.Rename(ctx, &rpc.RenameRequest{ - From: old, - To: new, - }) - return err +func (c *Client) MkdirAll(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "MkdirAll", + paths, + nil, + ) } -func (c *FSClient) MkdirAll(ctx context.Context, paths ...string) error { - _, err := c.client.MkdirAll(ctx, &rpc.PathsRequest{Paths: paths}) - return err +func (c *Client) Mkdir(ctx context.Context, paths ...string) error { + return c.client.Call( + ctx, + "FS", + "Mkdir", + paths, + nil, + ) } -func (c *FSClient) Mkdir(ctx context.Context, paths ...string) error { - _, err := c.client.Mkdir(ctx, &rpc.PathsRequest{Paths: paths}) - return err +func (c *Client) ReadDir(ctx context.Context, dir string) (out []FileInfo, err error) { + err = c.client.Call( + ctx, + "FS", + "ReadDir", + dir, + &out, + ) + return } -func (c *FSClient) ReadDir(ctx context.Context, dir string) ([]FileInfo, error) { - res, err := c.client.ReadDir(ctx, &rpc.PathRequest{Path: dir}) - return convertEntries(res.Entries), err -} - -func convertEntries(e []*rpc.FileInfo) []FileInfo { - out := make([]FileInfo, len(e)) - for i, fi := range e { - out[i] = FileInfo{ - Name: fi.Name, - Size: fi.Size, - IsDir: fi.IsDir, - } - } - return out -} - -func (c *FSClient) Upload(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { +func (c *Client) Upload(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { progressCh := make(chan FSTransferProgress, 5) - tc, err := c.client.Upload(ctx, &rpc.TransferRequest{Source: src, Destination: dst}) + err := c.client.Call( + ctx, + "FS", + "Upload", + [2]string{dst, src}, + progressCh, + ) if err != nil { return nil, err } - go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress { - return FSTransferProgress{ - Sent: evt.Sent, - Total: evt.Total, - Err: err, - } - }) - return progressCh, nil } -func (c *FSClient) Download(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { +func (c *Client) Download(ctx context.Context, dst, src string) (chan FSTransferProgress, error) { progressCh := make(chan FSTransferProgress, 5) - tc, err := c.client.Download(ctx, &rpc.TransferRequest{Source: src, Destination: dst}) + err := c.client.Call( + ctx, + "FS", + "Download", + [2]string{dst, src}, + progressCh, + ) if err != nil { return nil, err } - go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress { - return FSTransferProgress{ - Sent: evt.Sent, - Total: evt.Total, - Err: err, - } - }) - return progressCh, nil } - -// fsRecvToChannel converts a DRPC stream client to a Go channel, using cf to convert -// RPC generated types to API response types. -func fsRecvToChannel[R any, A any](s StreamClient[R], ch chan<- A, cf func(evt *R, err error) A) { - defer close(ch) - - var err error - var evt *R - - for { - select { - case <-s.Context().Done(): - return - default: - evt, err = s.Recv() - if errors.Is(err, io.EOF) { - return - } else if err != nil { - ch <- cf(new(R), err) - return - } - ch <- cf(evt, nil) - } - } -} diff --git a/api/get.go b/api/get.go index 3008349..bc61703 100644 --- a/api/get.go +++ b/api/get.go @@ -3,39 +3,71 @@ package api import ( "context" - "go.elara.ws/itd/internal/rpc" + "go.arsenm.dev/infinitime" ) -func (c *Client) HeartRate(ctx context.Context) (uint8, error) { - res, err := c.client.HeartRate(ctx, &rpc.Empty{}) - return uint8(res.Value), err +func (c *Client) HeartRate(ctx context.Context) (out uint8, err error) { + err = c.client.Call( + ctx, + "ITD", + "HeartRate", + nil, + &out, + ) + return } -func (c *Client) BatteryLevel(ctx context.Context) (uint8, error) { - res, err := c.client.BatteryLevel(ctx, &rpc.Empty{}) - return uint8(res.Value), err +func (c *Client) BatteryLevel(ctx context.Context) (out uint8, err error) { + err = c.client.Call( + ctx, + "ITD", + "BatteryLevel", + nil, + &out, + ) + return } -type MotionValues struct { - X, Y, Z int16 -} - -func (c *Client) Motion(ctx context.Context) (MotionValues, error) { - res, err := c.client.Motion(ctx, &rpc.Empty{}) - return MotionValues{int16(res.X), int16(res.Y), int16(res.Z)}, err +func (c *Client) Motion(ctx context.Context) (out infinitime.MotionValues, err error) { + err = c.client.Call( + ctx, + "ITD", + "Motion", + nil, + &out, + ) + return } func (c *Client) StepCount(ctx context.Context) (out uint32, err error) { - res, err := c.client.StepCount(ctx, &rpc.Empty{}) - return res.Value, err + err = c.client.Call( + ctx, + "ITD", + "StepCount", + nil, + &out, + ) + return } func (c *Client) Version(ctx context.Context) (out string, err error) { - res, err := c.client.Version(ctx, &rpc.Empty{}) - return res.Value, err + err = c.client.Call( + ctx, + "ITD", + "Version", + nil, + &out, + ) + return } func (c *Client) Address(ctx context.Context) (out string, err error) { - res, err := c.client.Address(ctx, &rpc.Empty{}) - return res.Value, err + err = c.client.Call( + ctx, + "ITD", + "Address", + nil, + &out, + ) + return } diff --git a/api/notify.go b/api/notify.go index be4e413..a5b0344 100644 --- a/api/notify.go +++ b/api/notify.go @@ -1,15 +1,16 @@ package api -import ( - "context" - - "go.elara.ws/itd/internal/rpc" -) +import "context" func (c *Client) Notify(ctx context.Context, title, body string) error { - _, err := c.client.Notify(ctx, &rpc.NotifyRequest{ - Title: title, - Body: body, - }) - return err + return c.client.Call( + ctx, + "ITD", + "Notify", + NotifyData{ + Title: title, + Body: body, + }, + nil, + ) } diff --git a/api/resources.go b/api/resources.go index 0c48fa3..8690ddc 100644 --- a/api/resources.go +++ b/api/resources.go @@ -3,49 +3,24 @@ package api import ( "context" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/rpc" + "go.arsenm.dev/infinitime" ) -type ResourceOperation infinitime.ResourceOperation - -const ( - ResourceRemove = infinitime.ResourceRemove - ResourceUpload = infinitime.ResourceUpload -) - -type ResourceLoadProgress struct { - Operation ResourceOperation - Name string - Total int64 - Sent int64 - Err error -} - // LoadResources loads resources onto the watch from the given // file path to the resources zip -func (c *FSClient) LoadResources(ctx context.Context, path string) (<-chan ResourceLoadProgress, error) { - progCh := make(chan ResourceLoadProgress, 2) +func (c *Client) LoadResources(ctx context.Context, path string) (<-chan infinitime.ResourceLoadProgress, error) { + progCh := make(chan infinitime.ResourceLoadProgress) - rc, err := c.client.LoadResources(ctx, &rpc.PathRequest{Path: path}) + err := c.client.Call( + ctx, + "FS", + "LoadResources", + path, + progCh, + ) if err != nil { return nil, err } - go fsRecvToChannel[rpc.ResourceLoadProgress](rc, progCh, func(evt *rpc.ResourceLoadProgress, err error) ResourceLoadProgress { - return ResourceLoadProgress{ - Operation: ResourceOperation(evt.Operation), - Name: evt.Name, - Sent: evt.Sent, - Total: evt.Total, - Err: err, - } - }) - return progCh, nil } - -type StreamClient[T any] interface { - Recv() (*T, error) - Context() context.Context -} diff --git a/api/set.go b/api/set.go index 88cbba5..efe283b 100644 --- a/api/set.go +++ b/api/set.go @@ -3,11 +3,14 @@ package api import ( "context" "time" - - "go.elara.ws/itd/internal/rpc" ) func (c *Client) SetTime(ctx context.Context, t time.Time) error { - _, err := c.client.SetTime(ctx, &rpc.SetTimeRequest{UnixNano: t.UnixNano()}) - return err + return c.client.Call( + ctx, + "ITD", + "SetTime", + t, + nil, + ) } diff --git a/api/types.go b/api/types.go index 0bec24c..281a85b 100644 --- a/api/types.go +++ b/api/types.go @@ -30,7 +30,6 @@ type NotifyData struct { type FSTransferProgress struct { Total uint32 Sent uint32 - Err error } type FileInfo struct { diff --git a/api/update.go b/api/update.go index 9f42fef..5b6bbb1 100644 --- a/api/update.go +++ b/api/update.go @@ -1,12 +1,13 @@ package api -import ( - "context" - - "go.elara.ws/itd/internal/rpc" -) +import "context" func (c *Client) WeatherUpdate(ctx context.Context) error { - _, err := c.client.WeatherUpdate(ctx, &rpc.Empty{}) - return err + return c.client.Call( + ctx, + "ITD", + "WeatherUpdate", + nil, + nil, + ) } diff --git a/api/watch.go b/api/watch.go index 6d41388..1b4964b 100644 --- a/api/watch.go +++ b/api/watch.go @@ -3,133 +3,69 @@ package api import ( "context" - "go.elara.ws/itd/internal/rpc" + "go.arsenm.dev/infinitime" ) func (c *Client) WatchHeartRate(ctx context.Context) (<-chan uint8, error) { outCh := make(chan uint8, 2) - wc, err := c.client.WatchHeartRate(ctx, &rpc.Empty{}) + err := c.client.Call( + ctx, + "ITD", + "WatchHeartRate", + nil, + outCh, + ) if err != nil { return nil, err } - go func() { - defer close(outCh) - - var err error - var evt *rpc.IntResponse - - for { - select { - case <-ctx.Done(): - wc.Close() - return - default: - evt, err = wc.Recv() - if err != nil { - return - } - } - - outCh <- uint8(evt.Value) - } - }() - return outCh, nil } func (c *Client) WatchBatteryLevel(ctx context.Context) (<-chan uint8, error) { outCh := make(chan uint8, 2) - wc, err := c.client.WatchBatteryLevel(ctx, &rpc.Empty{}) + err := c.client.Call( + ctx, + "ITD", + "WatchBatteryLevel", + nil, + outCh, + ) if err != nil { return nil, err } - go func() { - defer close(outCh) - - var err error - var evt *rpc.IntResponse - - for { - select { - case <-ctx.Done(): - wc.Close() - return - default: - evt, err = wc.Recv() - if err != nil { - return - } - } - - outCh <- uint8(evt.Value) - } - }() - return outCh, nil } func (c *Client) WatchStepCount(ctx context.Context) (<-chan uint32, error) { outCh := make(chan uint32, 2) - wc, err := c.client.WatchStepCount(ctx, &rpc.Empty{}) + err := c.client.Call( + ctx, + "ITD", + "WatchStepCount", + nil, + outCh, + ) if err != nil { return nil, err } - go func() { - defer close(outCh) - - var err error - var evt *rpc.IntResponse - - for { - select { - case <-ctx.Done(): - wc.Close() - return - default: - evt, err = wc.Recv() - if err != nil { - return - } - } - - outCh <- evt.Value - } - }() - return outCh, nil } -func (c *Client) WatchMotion(ctx context.Context) (<-chan MotionValues, error) { - outCh := make(chan MotionValues, 2) - wc, err := c.client.WatchMotion(ctx, &rpc.Empty{}) +func (c *Client) WatchMotion(ctx context.Context) (<-chan infinitime.MotionValues, error) { + outCh := make(chan infinitime.MotionValues, 2) + err := c.client.Call( + ctx, + "ITD", + "WatchMotion", + nil, + outCh, + ) if err != nil { return nil, err } - go func() { - defer close(outCh) - - var err error - var evt *rpc.MotionResponse - - for { - select { - case <-ctx.Done(): - wc.Close() - return - default: - evt, err = wc.Recv() - if err != nil { - return - } - } - - outCh <- MotionValues{int16(evt.X), int16(evt.Y), int16(evt.Z)} - } - }() - return outCh, nil } diff --git a/calls.go b/calls.go index 6dfd4d3..14886d2 100644 --- a/calls.go +++ b/calls.go @@ -2,14 +2,15 @@ package main import ( "context" + "sync" "github.com/godbus/dbus/v5" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/utils" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/itd/internal/utils" ) -func initCallNotifs(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initCallNotifs(ctx context.Context, dev *infinitime.Device) error { // Connect to system bus. This connection is for method calls. conn, err := utils.NewSystemBusConn(ctx) if err != nil { @@ -49,67 +50,56 @@ func initCallNotifs(ctx context.Context, wg WaitGroup, dev *infinitime.Device) e // Notify channel upon received message monitorConn.Eavesdrop(callCh) + var respHandlerOnce sync.Once var callObj dbus.BusObject - wg.Add(1) go func() { - defer wg.Done("callNotifs") - for { - select { - case event := <-callCh: - // Get path to call object - callPath := event.Body[0].(dbus.ObjectPath) - // Get call object - callObj = conn.Object("org.freedesktop.ModemManager1", callPath) + // For every message received + for event := range callCh { + // Get path to call object + callPath := event.Body[0].(dbus.ObjectPath) + // Get call object + callObj = conn.Object("org.freedesktop.ModemManager1", callPath) - // Get phone number from call object using method call connection - phoneNum, err := getPhoneNum(conn, callObj) - if err != nil { - log.Error("Error getting phone number").Err(err).Send() - continue - } + // Get phone number from call object using method call connection + phoneNum, err := getPhoneNum(conn, callObj) + if err != nil { + log.Error().Err(err).Msg("Error getting phone number") + continue + } - // Get direction of call object using method call connection - direction, err := getDirection(conn, callObj) - if err != nil { - log.Error("Error getting call direction").Err(err).Send() - continue - } + // Send call notification to InfiniTime + resCh, err := dev.NotifyCall(phoneNum) + if err != nil { + continue + } - if direction != MMCallDirectionIncoming { - continue - } - - // Send call notification to InfiniTime - err = dev.NotifyCall(phoneNum, func(cs infinitime.CallStatus) { - switch cs { + go respHandlerOnce.Do(func() { + // Wait for PineTime response + for res := range resCh { + switch res { case infinitime.CallStatusAccepted: // Attempt to accept call err = acceptCall(ctx, conn, callObj) if err != nil { - log.Warn("Error accepting call").Err(err).Send() + log.Warn().Err(err).Msg("Error accepting call") } case infinitime.CallStatusDeclined: // Attempt to decline call err = declineCall(ctx, conn, callObj) if err != nil { - log.Warn("Error declining call").Err(err).Send() + log.Warn().Err(err).Msg("Error declining call") } case infinitime.CallStatusMuted: // Warn about unimplemented muting - log.Warn("Muting calls is not implemented").Send() + log.Warn().Msg("Muting calls is not implemented") } - }) - if err != nil { - continue } - case <-ctx.Done(): - return - } + }) } }() - log.Info("Relaying calls to InfiniTime").Send() + log.Info().Msg("Relaying calls to InfiniTime") return nil } @@ -135,25 +125,6 @@ func getPhoneNum(conn *dbus.Conn, callObj dbus.BusObject) (string, error) { return out, nil } -type MMCallDirection int - -const ( - MMCallDirectionUnknown MMCallDirection = iota - MMCallDirectionIncoming - MMCallDirectionOutgoing -) - -// getDirection gets the direction of a call object using a DBus connection -func getDirection(conn *dbus.Conn, callObj dbus.BusObject) (MMCallDirection, error) { - var out MMCallDirection - // Get number property on DBus object and store return value in out - err := callObj.StoreProperty("org.freedesktop.ModemManager1.Call.Direction", &out) - if err != nil { - return 0, err - } - return out, nil -} - // getPhoneNum accepts a call using a DBus connection func acceptCall(ctx context.Context, conn *dbus.Conn, callObj dbus.BusObject) error { // Call Accept() method on DBus object diff --git a/cmd/itctl/firmware.go b/cmd/itctl/firmware.go index 2790e26..d8d3f39 100644 --- a/cmd/itctl/firmware.go +++ b/cmd/itctl/firmware.go @@ -6,9 +6,9 @@ import ( "time" "github.com/cheggaaa/pb/v3" + "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" - "go.elara.ws/itd/api" - "go.elara.ws/logger/log" + "go.arsenm.dev/itd/api" ) func fwUpgrade(c *cli.Context) error { @@ -21,7 +21,7 @@ func fwUpgrade(c *cli.Context) error { err = resLoad(c.Context, []string{absRes}) if err != nil { - log.Error("Resource loading has returned an error. This can happen if your current version of InfiniTime doesn't support BLE FS. Try updating without resource loading, and then load them after using the `itctl res load` command.").Send() + log.Error().Msg("Resource loading has returned an error. This can happen if your current version of InfiniTime doesn't support BLE FS. Try updating without resource loading, and then load them after using the `itctl res load` command.") return err } } @@ -54,10 +54,6 @@ func fwUpgrade(c *cli.Context) error { bar := pb.ProgressBarTemplate(barTmpl).Start(0) // Create new scanner of connection for event := range progress { - if event.Err != nil { - return event.Err - } - // Set total bytes in progress bar bar.SetTotal(event.Total) // Set amount of bytes received in progress bar diff --git a/cmd/itctl/fs.go b/cmd/itctl/fs.go index 393759e..fc2ec0a 100644 --- a/cmd/itctl/fs.go +++ b/cmd/itctl/fs.go @@ -3,6 +3,7 @@ package main import ( "fmt" "io" + "io/ioutil" "os" "path/filepath" @@ -16,7 +17,7 @@ func fsList(c *cli.Context) error { dirPath = c.Args().Get(0) } - listing, err := client.FS().ReadDir(c.Context, dirPath) + listing, err := client.ReadDir(c.Context, dirPath) if err != nil { return err } @@ -35,9 +36,9 @@ func fsMkdir(c *cli.Context) error { var err error if c.Bool("parents") { - err = client.FS().MkdirAll(c.Context, c.Args().Slice()...) + err = client.MkdirAll(c.Context, c.Args().Slice()...) } else { - err = client.FS().Mkdir(c.Context, c.Args().Slice()...) + err = client.Mkdir(c.Context, c.Args().Slice()...) } if err != nil { return err @@ -51,7 +52,7 @@ func fsMove(c *cli.Context) error { return cli.Exit("Command move requires two arguments", 1) } - err := client.FS().Rename(c.Context, c.Args().Get(0), c.Args().Get(1)) + err := client.Rename(c.Context, c.Args().Get(0), c.Args().Get(1)) if err != nil { return err } @@ -68,7 +69,7 @@ func fsRead(c *cli.Context) error { var path string var err error if c.Args().Get(1) == "-" { - tmpFile, err = os.CreateTemp("/tmp", "itctl.*") + tmpFile, err = ioutil.TempFile("/tmp", "itctl.*") if err != nil { return err } @@ -80,7 +81,7 @@ func fsRead(c *cli.Context) error { } } - progress, err := client.FS().Download(c.Context, path, c.Args().Get(0)) + progress, err := client.Download(c.Context, path, c.Args().Get(0)) if err != nil { return err } @@ -91,10 +92,6 @@ func fsRead(c *cli.Context) error { bar := pb.ProgressBarTemplate(barTmpl).Start(0) // Get progress events for event := range progress { - if event.Err != nil { - return event.Err - } - // Set total bytes in progress bar bar.SetTotal(int64(event.Total)) // Set amount of bytes sent in progress bar @@ -119,9 +116,9 @@ func fsRemove(c *cli.Context) error { var err error if c.Bool("recursive") { - err = client.FS().RemoveAll(c.Context, c.Args().Slice()...) + err = client.RemoveAll(c.Context, c.Args().Slice()...) } else { - err = client.FS().Remove(c.Context, c.Args().Slice()...) + err = client.Remove(c.Context, c.Args().Slice()...) } if err != nil { return err @@ -139,7 +136,7 @@ func fsWrite(c *cli.Context) error { var path string var err error if c.Args().Get(0) == "-" { - tmpFile, err = os.CreateTemp("/tmp", "itctl.*") + tmpFile, err = ioutil.TempFile("/tmp", "itctl.*") if err != nil { return err } @@ -157,7 +154,7 @@ func fsWrite(c *cli.Context) error { defer os.Remove(path) } - progress, err := client.FS().Upload(c.Context, c.Args().Get(1), path) + progress, err := client.Upload(c.Context, c.Args().Get(1), path) if err != nil { return err } @@ -168,10 +165,6 @@ func fsWrite(c *cli.Context) error { bar := pb.ProgressBarTemplate(barTmpl).Start(0) // Get progress events for event := range progress { - if event.Err != nil { - return event.Err - } - // Set total bytes in progress bar bar.SetTotal(int64(event.Total)) // Set amount of bytes sent in progress bar diff --git a/cmd/itctl/main.go b/cmd/itctl/main.go index a0048b8..c4f865d 100644 --- a/cmd/itctl/main.go +++ b/cmd/itctl/main.go @@ -7,16 +7,16 @@ import ( "syscall" "time" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" - "go.elara.ws/itd/api" - "go.elara.ws/logger" - "go.elara.ws/logger/log" + "go.arsenm.dev/itd/api" ) var client *api.Client func main() { - log.Logger = logger.NewPretty(os.Stderr) + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) ctx := context.Background() ctx, _ = signal.NotifyContext( @@ -296,7 +296,7 @@ func main() { err := app.RunContext(ctx, os.Args) if err != nil { - log.Fatal("Error while running app").Err(err).Send() + log.Fatal().Err(err).Msg("Error while running app") } } diff --git a/cmd/itctl/resources.go b/cmd/itctl/resources.go index 2f0364a..2600ef5 100644 --- a/cmd/itctl/resources.go +++ b/cmd/itctl/resources.go @@ -6,7 +6,7 @@ import ( "github.com/cheggaaa/pb/v3" "github.com/urfave/cli/v2" - "go.elara.ws/itd/infinitime" + "go.arsenm.dev/infinitime" ) func resourcesLoad(c *cli.Context) error { @@ -29,7 +29,7 @@ func resLoad(ctx context.Context, args []string) error { return err } - progCh, err := client.FS().LoadResources(ctx, path) + progCh, err := client.LoadResources(ctx, path) if err != nil { return err } @@ -39,7 +39,7 @@ func resLoad(ctx context.Context, args []string) error { return evt.Err } - if evt.Operation == infinitime.ResourceRemove { + if evt.Operation == infinitime.ResourceOperationRemoveObsolete { bar.SetTemplateString(rmTmpl) bar.Set("filename", evt.Name) } else { diff --git a/cmd/itgui/firmware.go b/cmd/itgui/firmware.go index db8a3bf..b3f9ff1 100644 --- a/cmd/itgui/firmware.go +++ b/cmd/itgui/firmware.go @@ -9,7 +9,7 @@ import ( "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/widget" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func firmwareTab(ctx context.Context, client *api.Client, w fyne.Window) fyne.CanvasObject { diff --git a/cmd/itgui/fs.go b/cmd/itgui/fs.go index 1d7f3e5..1011730 100644 --- a/cmd/itgui/fs.go +++ b/cmd/itgui/fs.go @@ -11,8 +11,8 @@ import ( "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" - "go.elara.ws/itd/api" - "go.elara.ws/itd/infinitime" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/itd/api" ) func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan struct{}) fyne.CanvasObject { @@ -36,7 +36,7 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s loading.Show() // Read root directory - ls, err := client.FS().ReadDir(ctx, "/") + ls, err := client.ReadDir(ctx, "/") if err != nil { guiErr(err, "Error reading directory", false, w) return @@ -69,17 +69,22 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s progressDlg := newProgress(w) progressDlg.Show() - progCh, err := client.FS().LoadResources(ctx, resPath) + progCh, err := client.LoadResources(ctx, resPath) if err != nil { guiErr(err, "Error loading resources", false, w) return } for evt := range progCh { + if evt.Err != nil { + guiErr(evt.Err, "Error loading resources", false, w) + return + } + switch evt.Operation { - case infinitime.ResourceRemove: + case infinitime.ResourceOperationRemoveObsolete: progressDlg.SetText("Removing " + evt.Name) - case infinitime.ResourceUpload: + case infinitime.ResourceOperationUpload: progressDlg.SetText("Uploading " + evt.Name) progressDlg.SetTotal(float64(evt.Total)) progressDlg.SetValue(float64(evt.Sent)) @@ -130,7 +135,7 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s progressDlg.Show() // Upload file - progressCh, err := client.FS().Upload(ctx, remotePath, localPath) + progressCh, err := client.Upload(ctx, remotePath, localPath) if err != nil { guiErr(err, "Error uploading file", false, w) return @@ -177,7 +182,7 @@ func fsTab(ctx context.Context, client *api.Client, w fyne.Window, opened chan s remotePath := filepath.Join(cwd, filenameEntry.Text) // Make directory - err := client.FS().Mkdir(ctx, remotePath) + err := client.Mkdir(ctx, remotePath) if err != nil { guiErr(err, "Error creating directory", false, w) return @@ -277,7 +282,7 @@ func makeItems( progressDlg.Show() // Download file - progressCh, err := client.FS().Download(ctx, localPath, remotePath) + progressCh, err := client.Download(ctx, localPath, remotePath) if err != nil { guiErr(err, "Error downloading file", false, w) return @@ -318,7 +323,7 @@ func makeItems( oldPath := filepath.Join(cwd, item.Name) // Rename file - err := client.FS().Rename(ctx, oldPath, moveEntry.Text) + err := client.Rename(ctx, oldPath, moveEntry.Text) if err != nil { guiErr(err, "Error renaming file", false, w) return @@ -337,7 +342,7 @@ func makeItems( path := filepath.Join(cwd, item.Name) // Remove file - err := client.FS().Remove(ctx, path) + err := client.Remove(ctx, path) if err != nil { guiErr(err, "Error removing file", false, w) return @@ -376,7 +381,7 @@ func refresh( // Get current directory cwd, _ := cwdData.Get() // Read directory - ls, err := client.FS().ReadDir(ctx, cwd) + ls, err := client.ReadDir(ctx, cwd) if err != nil { guiErr(err, "Error reading directory", false, w) return diff --git a/cmd/itgui/graph.go b/cmd/itgui/graph.go index 189d5ad..9f2cf85 100644 --- a/cmd/itgui/graph.go +++ b/cmd/itgui/graph.go @@ -11,7 +11,7 @@ import ( "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/theme" "fyne.io/x/fyne/widget/charts" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" _ "modernc.org/sqlite" ) diff --git a/cmd/itgui/info.go b/cmd/itgui/info.go index 8665bb0..ab92528 100644 --- a/cmd/itgui/info.go +++ b/cmd/itgui/info.go @@ -6,7 +6,7 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func infoTab(ctx context.Context, client *api.Client, w fyne.Window) fyne.CanvasObject { diff --git a/cmd/itgui/main.go b/cmd/itgui/main.go index 082ab12..dfbc515 100644 --- a/cmd/itgui/main.go +++ b/cmd/itgui/main.go @@ -6,7 +6,7 @@ import ( "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func main() { diff --git a/cmd/itgui/motion.go b/cmd/itgui/motion.go index 3cdf8d1..ff1cd3d 100644 --- a/cmd/itgui/motion.go +++ b/cmd/itgui/motion.go @@ -7,7 +7,7 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func motionTab(ctx context.Context, client *api.Client, w fyne.Window) fyne.CanvasObject { diff --git a/cmd/itgui/notify.go b/cmd/itgui/notify.go index d3ec7a0..f4b5d4b 100644 --- a/cmd/itgui/notify.go +++ b/cmd/itgui/notify.go @@ -7,7 +7,7 @@ import ( "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func notifyTab(ctx context.Context, client *api.Client, w fyne.Window) fyne.CanvasObject { diff --git a/cmd/itgui/screenshots/firmware.png b/cmd/itgui/screenshots/firmware.png index b59dcad..655922f 100644 Binary files a/cmd/itgui/screenshots/firmware.png and b/cmd/itgui/screenshots/firmware.png differ diff --git a/cmd/itgui/screenshots/fs.png b/cmd/itgui/screenshots/fs.png index b295b14..023d622 100644 Binary files a/cmd/itgui/screenshots/fs.png and b/cmd/itgui/screenshots/fs.png differ diff --git a/cmd/itgui/screenshots/info.png b/cmd/itgui/screenshots/info.png index 81cfef8..f8e6e39 100644 Binary files a/cmd/itgui/screenshots/info.png and b/cmd/itgui/screenshots/info.png differ diff --git a/cmd/itgui/screenshots/metrics.png b/cmd/itgui/screenshots/metrics.png index 4dd616e..529d9e8 100644 Binary files a/cmd/itgui/screenshots/metrics.png and b/cmd/itgui/screenshots/metrics.png differ diff --git a/cmd/itgui/screenshots/mkdir.png b/cmd/itgui/screenshots/mkdir.png index 2e47477..ae274a0 100644 Binary files a/cmd/itgui/screenshots/mkdir.png and b/cmd/itgui/screenshots/mkdir.png differ diff --git a/cmd/itgui/screenshots/motion.png b/cmd/itgui/screenshots/motion.png index 8d8d0d2..0a9b208 100644 Binary files a/cmd/itgui/screenshots/motion.png and b/cmd/itgui/screenshots/motion.png differ diff --git a/cmd/itgui/screenshots/notify.png b/cmd/itgui/screenshots/notify.png index 3f1877f..b2a2a1e 100644 Binary files a/cmd/itgui/screenshots/notify.png and b/cmd/itgui/screenshots/notify.png differ diff --git a/cmd/itgui/screenshots/progress.png b/cmd/itgui/screenshots/progress.png index 1b208f6..15fcb54 100644 Binary files a/cmd/itgui/screenshots/progress.png and b/cmd/itgui/screenshots/progress.png differ diff --git a/cmd/itgui/screenshots/resources.png b/cmd/itgui/screenshots/resources.png index 5d8f86e..f44aba6 100644 Binary files a/cmd/itgui/screenshots/resources.png and b/cmd/itgui/screenshots/resources.png differ diff --git a/cmd/itgui/screenshots/time.png b/cmd/itgui/screenshots/time.png index 1502213..14f0908 100644 Binary files a/cmd/itgui/screenshots/time.png and b/cmd/itgui/screenshots/time.png differ diff --git a/cmd/itgui/time.go b/cmd/itgui/time.go index 9496d5a..30c1836 100644 --- a/cmd/itgui/time.go +++ b/cmd/itgui/time.go @@ -8,7 +8,7 @@ import ( "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" - "go.elara.ws/itd/api" + "go.arsenm.dev/itd/api" ) func timeTab(ctx context.Context, client *api.Client, w fyne.Window) fyne.CanvasObject { diff --git a/config.go b/config.go index ba47c09..8956d4d 100644 --- a/config.go +++ b/config.go @@ -9,17 +9,17 @@ import ( "github.com/knadh/koanf/providers/confmap" "github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/file" - "go.elara.ws/logger" - "go.elara.ws/logger/log" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" ) var cfgDir string func init() { - etcPath := "/etc/itd.toml" + etcPath := "/etc/itd.toml"; // Set up logger - log.Logger = logger.NewPretty(os.Stderr) + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) // Get user's configuration directory userCfgDir, err := os.UserConfigDir() @@ -67,7 +67,7 @@ func loadAndwatchCfgFile(filename string) { provider := file.Provider(filename) if cfgError := k.Load(provider, toml.Parser()); cfgError != nil { - log.Warn("Error while trying to read config file").Str("filename", filename).Err(cfgError).Send() + log.Warn().Str("filename", filename).Err(cfgError).Msg("Error while trying to read config file") } // Watch for changes and reload when detected @@ -77,7 +77,7 @@ func loadAndwatchCfgFile(filename string) { } if cfgError := k.Load(provider, toml.Parser()); cfgError != nil { - log.Warn("Error while trying to read config file").Str("filename", filename).Err(cfgError).Send() + log.Warn().Str("filename", filename).Err(cfgError).Msg("Error while trying to read config file") } }) } @@ -106,8 +106,5 @@ func setCfgDefaults() { "notifs.ignore.body": []string{}, "music.vol.interval": 5, - - "fuse.enabled": false, - "fuse.mountpoint": "/tmp/itd/mnt", }, "."), nil) } diff --git a/fuse.go b/fuse.go deleted file mode 100644 index 205a875..0000000 --- a/fuse.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import ( - "context" - "os" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/fusefs" - "go.elara.ws/logger/log" -) - -func startFUSE(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { - // This is where we'll mount the FS - err := os.MkdirAll(k.String("fuse.mountpoint"), 0o755) - if err != nil && !os.IsExist(err) { - return err - } - - // Ignore the error because nothing might be mounted on the mountpoint - _ = fusefs.Unmount(k.String("fuse.mountpoint")) - - root, err := fusefs.BuildRootNode(dev) - if err != nil { - log.Error("Building root node failed"). - Err(err). - Send() - return err - } - - server, err := fs.Mount(k.String("fuse.mountpoint"), root, &fs.Options{ - MountOptions: fuse.MountOptions{ - // Set to true to see how the file system works. - Debug: false, - SingleThreaded: true, - }, - }) - if err != nil { - log.Error("Mounting failed"). - Str("target", k.String("fuse.mountpoint")). - Err(err). - Send() - return err - } - - log.Info("Mounted on target"). - Str("target", k.String("fuse.mountpoint")). - Send() - - fusefs.BuildProperties(dev) - - if err != nil { - log.Warn("Error getting BLE filesystem").Err(err).Send() - return err - } - - wg.Add(1) - go func() { - defer wg.Done("fuse") - <-ctx.Done() - server.Unmount() - }() - - return nil -} diff --git a/go.mod b/go.mod index e9f8e59..7c3bd5e 100644 --- a/go.mod +++ b/go.mod @@ -1,91 +1,83 @@ -module go.elara.ws/itd +module go.arsenm.dev/itd -go 1.18 +go 1.17 replace fyne.io/x/fyne => github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb -replace tinygo.org/x/bluetooth => github.com/elara6331/bluetooth v0.9.1-0.20240413234149-a0e71474a768 - require ( - fyne.io/fyne/v2 v2.3.0 + fyne.io/fyne/v2 v2.2.3 fyne.io/x/fyne v0.0.0-20220107050838-c4a1de51d4ce - github.com/cheggaaa/pb/v3 v3.1.0 - github.com/gen2brain/dlgs v0.0.0-20220603100644-40c77870fa8d + github.com/cheggaaa/pb/v3 v3.0.8 + github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b github.com/godbus/dbus/v5 v5.1.0 - github.com/hanwen/go-fuse/v2 v2.2.0 - github.com/knadh/koanf v1.4.4 - github.com/mattn/go-isatty v0.0.17 + github.com/knadh/koanf v1.4.0 + github.com/mattn/go-isatty v0.0.14 github.com/mozillazg/go-pinyin v0.19.0 - github.com/urfave/cli/v2 v2.23.7 - go.elara.ws/drpc v0.0.0-20230421021209-fe4c05460a3d - go.elara.ws/logger v0.0.0-20230928062203-85e135cf02ae - golang.org/x/text v0.5.0 - google.golang.org/protobuf v1.28.1 - modernc.org/sqlite v1.20.1 - storj.io/drpc v0.0.32 - tinygo.org/x/bluetooth v0.9.0 + github.com/rs/zerolog v1.26.1 + github.com/urfave/cli/v2 v2.4.0 + go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94 + go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 + golang.org/x/text v0.3.7 + modernc.org/sqlite v1.17.2 ) require ( - fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1 // indirect - github.com/VividCortex/ewma v1.2.0 // indirect - github.com/benoitkugler/textlayout v0.3.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93 // indirect + github.com/VividCortex/ewma v1.1.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/fredbi/uri v1.0.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/fyne-io/gl-js v0.0.0-20220802150000-8e339395f381 // indirect - github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 // indirect - github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345 // indirect + github.com/fatih/color v1.10.0 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fxamacker/cbor/v2 v2.4.0 // indirect + github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect + github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect + github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect - github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-text/typesetting v0.0.0-20221219135543-5d0d724ee181 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec // indirect + github.com/gofrs/uuid v4.2.0+incompatible // indirect github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c // indirect github.com/google/uuid v1.3.0 // indirect - github.com/gookit/color v1.5.1 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect - github.com/hashicorp/yamux v0.1.1 // indirect github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.8 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect + github.com/muka/go-bluetooth v0.0.0-20220819140550-1d8857e3b268 // indirect + github.com/pelletier/go-toml v1.9.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa // indirect - github.com/rivo/uniseg v0.4.3 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/saltosystems/winrt-go v0.0.0-20240320113951-a2e4fc03f5f4 // indirect - github.com/sirupsen/logrus v1.9.3 // 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.8.1 // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44 // indirect + github.com/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41 // indirect + github.com/stretchr/testify v1.7.2 // indirect github.com/tevino/abool v1.2.0 // indirect - github.com/tinygo-org/cbgo v0.0.4 // indirect - github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - github.com/yuin/goldmark v1.5.3 // indirect - github.com/zeebo/errs v1.3.0 // indirect - golang.org/x/image v0.2.0 // indirect - golang.org/x/mobile v0.0.0-20221110043201-43a038452099 // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.4.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/tools v0.4.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/yuin/goldmark v1.4.10 // indirect + golang.org/x/image v0.0.0-20220601225756-64ec528b34cd // indirect + golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect + golang.org/x/mod v0.4.2 // indirect + golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 // indirect - lukechampine.com/uint128 v1.2.0 // indirect - modernc.org/cc/v3 v3.40.0 // indirect - modernc.org/ccgo/v3 v3.16.13 // indirect - modernc.org/libc v1.22.2 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.5.0 // indirect - modernc.org/opt v0.1.3 // indirect - modernc.org/strutil v1.1.3 // indirect - modernc.org/token v1.1.0 // indirect + honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect + lukechampine.com/uint128 v1.1.1 // indirect + modernc.org/cc/v3 v3.36.0 // indirect + modernc.org/ccgo/v3 v3.16.6 // indirect + modernc.org/libc v1.16.7 // indirect + modernc.org/mathutil v1.4.1 // indirect + modernc.org/memory v1.1.1 // indirect + modernc.org/opt v0.1.1 // indirect + modernc.org/strutil v1.1.1 // indirect + modernc.org/token v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 781ed95..8d73d68 100644 --- a/go.sum +++ b/go.sum @@ -38,31 +38,24 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= fyne.io/fyne/v2 v2.1.0/go.mod h1:c1vwI38Ebd0dAdxVa6H1Pj6/+cK1xtDy61+I31g+s14= -fyne.io/fyne/v2 v2.3.0 h1:g9tPI3lyBK50IvyPbXqv2zI3JJ4uhMAffu89f3nX5PU= -fyne.io/fyne/v2 v2.3.0/go.mod h1:odfJmbFnODiKn1MXdL44JR6CK+0v8lrmgdPlrUF6w0M= -fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1 h1:OiHw+bZAGEaSreHsA8dDkBOVJmSFzsNTOc/htpM+fOc= -fyne.io/systray v1.10.1-0.20221115204952-d16a6177e6f1/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= +fyne.io/fyne/v2 v2.2.3 h1:Umi3vVVW8XnWWPJmMkhIWQOMU/jxB1OqpWVUmjhODD0= +fyne.io/fyne/v2 v2.2.3/go.mod h1:MBoGuHzLLSXdQOWFAwWhIhYTEMp33zqtGCReSWhaQTA= +fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93 h1:V2IC9t0Zj9Ur6qDbfhUuzVmIvXKFyxZXRJyigUvovs4= +fyne.io/systray v1.10.1-0.20220621085403-9a2652634e93/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= github.com/Andrew-M-C/go.jsonvalue v1.1.2-0.20211223013816-e873b56b4a84/go.mod h1:oTJGG91FhtsxvUFVwHSvr6zuaTcAuroj/ToxfT7Ox8U= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= +github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= -github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= -github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= @@ -73,20 +66,11 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72H github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/benoitkugler/pstokenizer v1.0.0/go.mod h1:l1G2Voirz0q/jj0TQfabNxVsa8HZXh/VMxFSRALWTiE= -github.com/benoitkugler/textlayout v0.3.0 h1:2ehWXEkgb6RUokTjXh1LzdGwG4dRP6X3dqhYYDYhUVk= -github.com/benoitkugler/textlayout v0.3.0/go.mod h1:o+1hFV+JSHBC9qNLIuwVoLedERU7sBPgEFcuSgfvi/w= -github.com/benoitkugler/textlayout-testdata v0.1.1 h1:AvFxBxpfrQd8v55qH59mZOJOQjtD6K2SFe9/HvnIbJk= -github.com/benoitkugler/textlayout-testdata v0.1.1/go.mod h1:i/qZl09BbUOtd7Bu/W1CAubRwTWrEXWq6JwMkw8wYxo= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheggaaa/pb/v3 v3.1.0 h1:3uouEsl32RL7gTiQsuaXD4Bzbfl5tGztXGUvXbs4O04= -github.com/cheggaaa/pb/v3 v3.1.0/go.mod h1:YjrevcBqadFDaGQKRdmZxTY42pXEqda48Ea3lt0K/BE= +github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA= +github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -98,17 +82,14 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc= -github.com/elara6331/bluetooth v0.9.1-0.20240413234149-a0e71474a768 h1:iWP52WinMhd+pQB+2GedWvUxkd4pMqFvV0S6MjMFQSc= -github.com/elara6331/bluetooth v0.9.1-0.20240413234149-a0e71474a768/go.mod h1:V9XwH/xQ2SmCIW+T0pmpL7VzijY53JRVsJcDM0YN6PI= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -117,60 +98,47 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA= github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8= -github.com/fredbi/uri v0.1.0/go.mod h1:1xC40RnIOGCaQzswaOvrzvG/3M3F0hyDVb3aO/1iGy0= -github.com/fredbi/uri v1.0.0 h1:s4QwUAZ8fz+mbTsukND+4V5f+mJ/wjaTokwstGUAemg= -github.com/fredbi/uri v1.0.0/go.mod h1:1xC40RnIOGCaQzswaOvrzvG/3M3F0hyDVb3aO/1iGy0= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= +github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4= github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg= -github.com/fyne-io/gl-js v0.0.0-20220802150000-8e339395f381 h1:SFtj9yo9C7F4CxyJeSJi9AjT6x9c88gnY1tjlXWh9QU= -github.com/fyne-io/gl-js v0.0.0-20220802150000-8e339395f381/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg= +github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 h1:+31CdF/okdokeFNoy9L/2PccG3JFidQT3ev64/r4pYU= github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E= -github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 h1:0Ayg0/do/sqX2R7NonoLZvWxGrd9utTVf3A0QvCbC88= -github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E= +github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 h1:hnLq+55b7Zh7/2IRzWCpiTcAvjv/P8ERF+N7+xXbZhk= github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0= -github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345 h1:ONkcbJmsWUOHyjUm0wlnkFc/uaacFFtStVbsG6qJfew= -github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0= -github.com/gen2brain/dlgs v0.0.0-20220603100644-40c77870fa8d h1:dHYKX8CBAs1zSGXm3q3M15CLAEwPEkwrK1ed8FCo+Xo= -github.com/gen2brain/dlgs v0.0.0-20220603100644-40c77870fa8d/go.mod h1:/eFcjDXaU2THSOOqLxOPETIbHETnamk8FA/hMjhg/gU= +github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b h1:M0/hjawi9ur15zpqL/h66ga87jlYA7iAuZ4HC6ak08k= +github.com/gen2brain/dlgs v0.0.0-20211108104213-bade24837f0b/go.mod h1:/eFcjDXaU2THSOOqLxOPETIbHETnamk8FA/hMjhg/gU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210410170116-ea3d685f79fb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-text/typesetting v0.0.0-20221212183139-1eb938670a1f/go.mod h1:/cmOXaoTiO+lbCwkTZBgCvevJpbFsZ5reXIpEJVh5MI= -github.com/go-text/typesetting v0.0.0-20221219135543-5d0d724ee181 h1:J6XG/Xx7uCCpskM71R6YAgPHd/E8FzhyPhL6Ll94uMY= -github.com/go-text/typesetting v0.0.0-20221219135543-5d0d724ee181/go.mod h1:/cmOXaoTiO+lbCwkTZBgCvevJpbFsZ5reXIpEJVh5MI= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c h1:JGCm/+tJ9gC6THUxooTldS+CUDsba0qvkvU3DHklqW8= @@ -218,9 +186,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -236,15 +203,13 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ= -github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= @@ -252,29 +217,21 @@ github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfre github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY= github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hanwen/go-fuse/v2 v2.2.0 h1:jo5QZYmBLNcl9ovypWaQ5yXMSSV+Ch68xoC3rtZvvBM= -github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -288,19 +245,12 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= -github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= -github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -312,65 +262,43 @@ github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk= github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw= 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/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/knadh/koanf v1.4.4 h1:d2jY5nCCeoaiqvEKSBW9rEc93EfNy/XWgWsSB3j7JEA= -github.com/knadh/koanf v1.4.4/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/knadh/koanf v1.4.0 h1:/k0Bh49SqLyLNfte9r6cvuZWrApOQhglOmhIU3L/zDw= +github.com/knadh/koanf v1.4.0/go.mod h1:1cfH5223ZeZUOs8FU2UdTmaNfHpqgtjV0+NHjRO43gs= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +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-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= +github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb h1:+fP6ENsbd+BUOmD/kSjNtrOmi2vgJ/JfWDSWjTKmTVY= github.com/metal3d/fyne-x v0.0.0-20220508095732-177117e583fb/go.mod h1:jBspDudEQ+Rdono8vBGHDtMUPE8ZpB/xq7FUYRqT3CI= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -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/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -390,13 +318,12 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mozillazg/go-pinyin v0.19.0 h1:p+J8/kjJ558KPvVGYLvqBhxf8jbZA2exSLCs2uUVN8c= github.com/mozillazg/go-pinyin v0.19.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/muka/go-bluetooth v0.0.0-20220819140550-1d8857e3b268 h1:kOnq7TfaAO2Vc/MHxPqFIXe00y1qBxJAvhctXdko6vo= +github.com/muka/go-bluetooth v0.0.0-20220819140550-1d8857e3b268/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= @@ -406,10 +333,10 @@ github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnu github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -418,52 +345,32 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa h1:tEkEyxYeZ43TR55QU/hsIt9aRGBxbgGuz9CGykjvogY= -github.com/remyoudompheng/bigfft v0.0.0-20220927061507-ef77025ab5aa/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= -github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= +github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= -github.com/saltosystems/winrt-go v0.0.0-20240320113951-a2e4fc03f5f4 h1:zurEWtOr/OYiTb5bcD7eeHLOfj6vCR30uldlwse1cSM= -github.com/saltosystems/winrt-go v0.0.0-20240320113951-a2e4fc03f5f4/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -476,17 +383,13 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= -github.com/srwiley/oksvg v0.0.0-20220731023508-a61f04f16b76/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= -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/oksvg v0.0.0-20220128195007-1f435e4c2b44 h1:XPYXKIuH/n5zpUoEWk2jWV/SjEMNYmqDYmTgbjmhtaI= +github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= -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/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41 h1:YR16ysw3I1bqwtEcYV9dpvhHEe7j55hIClkLoAqY31I= +github.com/srwiley/rasterx v0.0.0-20220128185129-2efea2b9ea41/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -494,24 +397,22 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQEfeEIhcKe4Qy8= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= -github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU= -github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I= github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg= -github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY= -github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wagslane/go-password-validator v0.3.0/go.mod h1:TI1XJ6T5fRdRnHqHt14pvy1tNVnrwe7m3/f1f2fDphQ= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -519,22 +420,15 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.3 h1:3HUJmBFbQW9fhQOzMgseU134xfi6hU+mjWywx5Ty+/M= -github.com/yuin/goldmark v1.5.3/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= -github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= -github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= -go.elara.ws/drpc v0.0.0-20230421021209-fe4c05460a3d h1:ANb8YPtcxPipwKgmnW688e5PGpNaLh+22nO2LBpIPOU= -go.elara.ws/drpc v0.0.0-20230421021209-fe4c05460a3d/go.mod h1:NDprjiVqKXQKVGzX7jp2g/jctsUbvOxz1nN15QOBEGk= -go.elara.ws/logger v0.0.0-20230928062203-85e135cf02ae h1:d+gJUhEWSrOjrrfgeydYWEr8TTnx0DLvcVhghaOsFeE= -go.elara.ws/logger v0.0.0-20230928062203-85e135cf02ae/go.mod h1:qng49owViqsW5Aey93lwBXONw20oGbJIoLVscB16mPM= +github.com/yuin/goldmark v1.4.10 h1:+WgKGo8CQrlMTRJpGCFCyNddOhW801TKC2QijVV9QVg= +github.com/yuin/goldmark v1.4.10/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= +go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94 h1:b3kEsAfUyJN5781f0+K72v30MDrwusyPDh/1kPFCDNQ= +go.arsenm.dev/infinitime v0.0.0-20221119224612-0c369dc5df94/go.mod h1:K3NJ6fyPv5qqHUedB3MccKOE0whJMJZ80l/yTzzTrgc= +go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0 h1:1K96g1eww+77GeGchwMhd0NTrs7Mk/Hc3M3ItW5NbG4= +go.arsenm.dev/lrpc v0.0.0-20220513001344-3bcc01fdb6a0/go.mod h1:goK9z735lfXmqlDxu9qN7FS8t0HJHN3PjyDtCToUY4w= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -545,17 +439,15 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -570,12 +462,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210504121937-7319ad40d33e/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220601225756-64ec528b34cd h1:9NbNcTg//wfC5JskFW4Z3sqwVnjmJKHxLAol1bW2qgw= golang.org/x/image v0.0.0-20220601225756-64ec528b34cd/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY= -golang.org/x/image v0.2.0 h1:/DcQ0w3VHKCC5p0/P2B0JpAZ9Z++V2KOo2fyU89CXBQ= -golang.org/x/image v0.2.0/go.mod h1:la7oBXb9w3YFjBqaAwtynVioc1ZvOnNteUNrifGNmAI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -590,9 +479,8 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee h1:/tShaw8UTf0XzI8DOZwQHzC7d6Vi3EtrBnftiZ4vAvU= golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= -golang.org/x/mobile v0.0.0-20221110043201-43a038452099 h1:aIu0lKmfdgtn2uTj7JI2oN4TUrQvgB+wzTPO23bCKt8= -golang.org/x/mobile v0.0.0-20221110043201-43a038452099/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= @@ -601,14 +489,11 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -617,11 +502,9 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -645,13 +528,10 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -675,16 +555,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -695,19 +570,14 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20200106162015-b016eb3dc98e/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-20200124204421-9fbb57f87de9/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= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -718,8 +588,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -727,9 +596,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -737,19 +604,14 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -761,9 +623,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -781,7 +642,6 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -812,7 +672,9 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200925191224-5d1fdd8fa346/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -820,13 +682,13 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098 h1:YuekqPskqwCCPM79F1X5Dhv4ezTCj+Ki1oNwiafxkA0= golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -933,33 +795,25 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 h1:oomkgU6VaQDsV6qZby2uz1Lap0eXmku8+2em3A/l700= honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4= -honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 h1:2ZZFiPwRLxiNX2E/YO6Jgw1pCjDRDgmx20PGyw/cw+M= -honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -967,33 +821,41 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= -lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw= -modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= -modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw= -modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= +lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6 h1:3l18poV+iUemQ98O3X5OMr97LOqlzis+ytivU4NqGhA= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0= -modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= -modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= -modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.20.1 h1:z6qRLw72B0VfRrJjs3l6hWkzYDx1bo0WGVrBGP4ohhM= -modernc.org/sqlite v1.20.1/go.mod h1:fODt+bFmc/j8LcoCbMSkAuKuGmhxjG45KGc25N2705M= -modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= -modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= -modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.7 h1:qzQtHhsZNpVPpeCu+aMIQldXeV1P0vRhSqCL0nOIJOA= +modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.17.2 h1:TjmF36Wi5QcPYqRoAacV1cAyJ7xB/CD0ExpVUEMebnw= +modernc.org/sqlite v1.17.2/go.mod h1:GOQmuiXd6pTTes1Fi2s9apiCcD/wbKQtBZ0Nw6/etjM= +modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -storj.io/drpc v0.0.32 h1:5p5ZwsK/VOgapaCu+oxaPVwO6UwIs+iwdMiD50+R4PI= -storj.io/drpc v0.0.32/go.mod h1:6rcOyR/QQkSTX/9L5ZGtlZaE2PtXTTZl8d+ulSeeYEg= diff --git a/infinitime/chars.go b/infinitime/chars.go deleted file mode 100644 index efac8f5..0000000 --- a/infinitime/chars.go +++ /dev/null @@ -1,142 +0,0 @@ -package infinitime - -import "tinygo.org/x/bluetooth" - -type btChar struct { - Name string - ID bluetooth.UUID - ServiceID bluetooth.UUID -} - -var ( - musicServiceUUID = mustParse("00000000-78fc-48fe-8e23-433b3a1942d0") - navigationServiceUUID = mustParse("00010000-78fc-48fe-8e23-433b3a1942d0") - motionServiceUUID = mustParse("00030000-78fc-48fe-8e23-433b3a1942d0") - weatherServiceUUID = mustParse("00050000-78fc-48fe-8e23-433b3a1942d0") -) - -var ( - newAlertChar = btChar{ - "New Alert", - bluetooth.CharacteristicUUIDNewAlert, - bluetooth.ServiceUUIDAlertNotification, - } - notifEventChar = btChar{ - "Notification Event", - mustParse("00020001-78fc-48fe-8e23-433b3a1942d0"), - bluetooth.ServiceUUIDAlertNotification, - } - stepCountChar = btChar{ - "Step Count", - mustParse("00030001-78fc-48fe-8e23-433b3a1942d0"), - motionServiceUUID, - } - rawMotionChar = btChar{ - "Raw Motion", - mustParse("00030002-78fc-48fe-8e23-433b3a1942d0"), - motionServiceUUID, - } - firmwareVerChar = btChar{ - "Firmware Version", - bluetooth.CharacteristicUUIDFirmwareRevisionString, - bluetooth.ServiceUUIDDeviceInformation, - } - currentTimeChar = btChar{ - "Current Time", - bluetooth.CharacteristicUUIDCurrentTime, - bluetooth.ServiceUUIDCurrentTime, - } - localTimeChar = btChar{ - "Local Time", - bluetooth.CharacteristicUUIDLocalTimeInformation, - bluetooth.ServiceUUIDCurrentTime, - } - batteryLevelChar = btChar{ - "Battery Level", - bluetooth.CharacteristicUUIDBatteryLevel, - bluetooth.ServiceUUIDBattery, - } - heartRateChar = btChar{ - "Heart Rate", - bluetooth.CharacteristicUUIDHeartRateMeasurement, - bluetooth.ServiceUUIDHeartRate, - } - fsVersionChar = btChar{ - "Filesystem Version", - mustParse("adaf0200-4669-6c65-5472-616e73666572"), - bluetooth.ServiceUUIDFileTransferByAdafruit, - } - fsTransferChar = btChar{ - "Filesystem Transfer", - mustParse("adaf0200-4669-6c65-5472-616e73666572"), - bluetooth.ServiceUUIDFileTransferByAdafruit, - } - dfuCtrlPointChar = btChar{ - "DFU Control Point", - bluetooth.CharacteristicUUIDLegacyDFUControlPoint, - bluetooth.ServiceUUIDLegacyDFU, - } - dfuPacketChar = btChar{ - "DFU Packet", - bluetooth.CharacteristicUUIDLegacyDFUPacket, - bluetooth.ServiceUUIDLegacyDFU, - } - navigationFlagsChar = btChar{ - "Navigation Flags", - mustParse("00010001-78fc-48fe-8e23-433b3a1942d0"), - navigationServiceUUID, - } - navigationNarrativeChar = btChar{ - "Navigation Narrative", - mustParse("00010002-78fc-48fe-8e23-433b3a1942d0"), - navigationServiceUUID, - } - navigationManDist = btChar{ - "Navigation Man Dist", - mustParse("00010003-78fc-48fe-8e23-433b3a1942d0"), - navigationServiceUUID, - } - navigationProgress = btChar{ - "Navigation Progress", - mustParse("00010004-78fc-48fe-8e23-433b3a1942d0"), - navigationServiceUUID, - } - weatherDataChar = btChar{ - "Weather Data", - mustParse("00050001-78fc-48fe-8e23-433b3a1942d0"), - weatherServiceUUID, - } - musicEventChar = btChar{ - "Music Event", - mustParse("00000001-78fc-48fe-8e23-433b3a1942d0"), - musicServiceUUID, - } - musicStatusChar = btChar{ - "Music Status", - mustParse("00000002-78fc-48fe-8e23-433b3a1942d0"), - musicServiceUUID, - } - musicArtistChar = btChar{ - "Music Artist", - mustParse("00000003-78fc-48fe-8e23-433b3a1942d0"), - musicServiceUUID, - } - musicTrackChar = btChar{ - "Music Track", - mustParse("00000004-78fc-48fe-8e23-433b3a1942d0"), - musicServiceUUID, - } - musicAlbumChar = btChar{ - "Music Album", - mustParse("00000005-78fc-48fe-8e23-433b3a1942d0"), - musicServiceUUID, - } -) - -func mustParse(s string) bluetooth.UUID { - uuid, err := bluetooth.ParseUUID(s) - if err != nil { - panic(err) - } - return uuid -} diff --git a/infinitime/dfu.go b/infinitime/dfu.go deleted file mode 100644 index 19836f7..0000000 --- a/infinitime/dfu.go +++ /dev/null @@ -1,222 +0,0 @@ -package infinitime - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "io/fs" - - "tinygo.org/x/bluetooth" -) - -const ( - dfuSegmentSize = 20 // Size of each firmware packet - dfuPktRecvInterval = 10 // Amount of packets to send before checking for receipt -) - -var ( - dfuCmdStart = []byte{0x01, 0x04} - dfuCmdRecvInitPkt = []byte{0x02, 0x00} - dfuCmdInitPktComplete = []byte{0x02, 0x01} - dfuCmdPktReceiptInterval = []byte{0x08} - dfuCmdRecvFirmware = []byte{0x03} - dfuCmdValidate = []byte{0x04} - dfuCmdActivateReset = []byte{0x05} - - dfuResponseStart = []byte{0x10, 0x01, 0x01} - dfuResponseInitParams = []byte{0x10, 0x02, 0x01} - dfuResponseRecvFwImgSuccess = []byte{0x10, 0x03, 0x01} - dfuResponseValidate = []byte{0x10, 0x04, 0x01} -) - -// DFUOptions contains options for [UpgradeFirmware] -type DFUOptions struct { - InitPacket fs.File - FirmwareImage fs.File - ProgressFunc func(sent, received, total uint32) - SegmentSize int - ReceiveInterval uint8 -} - -// UpgradeFirmware upgrades the firmware running on the PineTime. -func (d *Device) UpgradeFirmware(opts DFUOptions) error { - if opts.SegmentSize <= 0 { - opts.SegmentSize = dfuSegmentSize - } - - if opts.ReceiveInterval <= 0 { - opts.ReceiveInterval = dfuPktRecvInterval - } - - ctrlPoint, err := d.getChar(dfuCtrlPointChar) - if err != nil { - return err - } - - packet, err := d.getChar(dfuPacketChar) - if err != nil { - return err - } - - d.deviceMtx.Lock() - defer d.deviceMtx.Unlock() - - d.updating.Store(true) - defer d.updating.Store(false) - - _, err = ctrlPoint.WriteWithoutResponse(dfuCmdStart) - if err != nil { - return err - } - - fi, err := opts.FirmwareImage.Stat() - if err != nil { - return err - } - size := uint32(fi.Size()) - - sizePacket := make([]byte, 8, 12) - sizePacket = binary.LittleEndian.AppendUint32(sizePacket, size) - _, err = packet.WriteWithoutResponse(sizePacket) - if err != nil { - return err - } - - _, err = awaitDFUResponse(ctrlPoint, dfuResponseStart) - if err != nil { - return err - } - - err = writeDFUInitPacket(ctrlPoint, packet, opts.InitPacket) - if err != nil { - return err - } - - err = setRecvInterval(ctrlPoint, opts.ReceiveInterval) - if err != nil { - return err - } - - err = sendFirmware(ctrlPoint, packet, opts, size) - if err != nil { - return err - } - - return finalize(ctrlPoint) -} - -func finalize(ctrlPoint *bluetooth.DeviceCharacteristic) error { - _, err := ctrlPoint.WriteWithoutResponse(dfuCmdValidate) - if err != nil { - return err - } - - _, err = awaitDFUResponse(ctrlPoint, dfuResponseValidate) - if err != nil { - return err - } - - _, _ = ctrlPoint.WriteWithoutResponse(dfuCmdActivateReset) - return nil -} - -func sendFirmware(ctrlPoint, packet *bluetooth.DeviceCharacteristic, opts DFUOptions, totalSize uint32) error { - _, err := ctrlPoint.WriteWithoutResponse(dfuCmdRecvFirmware) - if err != nil { - return err - } - - var ( - chunksSinceReceipt uint8 - bytesSent uint32 - ) - - chunk := make([]byte, opts.SegmentSize) - for { - n, err := opts.FirmwareImage.Read(chunk) - if err != nil && !errors.Is(err, io.EOF) { - return err - } else if n == 0 { - break - } - - bytesSent += uint32(n) - _, err = packet.WriteWithoutResponse(chunk[:n]) - if err != nil { - return err - } - - if errors.Is(err, io.EOF) { - break - } - - chunksSinceReceipt += 1 - if chunksSinceReceipt == opts.ReceiveInterval { - sizeData, err := awaitDFUResponse(ctrlPoint, []byte{0x11}) - if err != nil { - return err - } - size := binary.LittleEndian.Uint32(sizeData) - if size != bytesSent { - return fmt.Errorf("size mismatch: expected %d, got %d", bytesSent, size) - } - if opts.ProgressFunc != nil { - opts.ProgressFunc(bytesSent, size, totalSize) - } - chunksSinceReceipt = 0 - } - } - - return nil -} - -func writeDFUInitPacket(ctrlPoint, packet *bluetooth.DeviceCharacteristic, initPkt fs.File) error { - _, err := ctrlPoint.WriteWithoutResponse(dfuCmdRecvInitPkt) - if err != nil { - return err - } - - initData, err := io.ReadAll(initPkt) - if err != nil { - return err - } - - _, err = packet.WriteWithoutResponse(initData) - if err != nil { - return err - } - - _, err = ctrlPoint.WriteWithoutResponse(dfuCmdInitPktComplete) - if err != nil { - return err - } - - _, err = awaitDFUResponse(ctrlPoint, dfuResponseInitParams) - return err -} - -func setRecvInterval(ctrlPoint *bluetooth.DeviceCharacteristic, interval uint8) error { - _, err := ctrlPoint.WriteWithoutResponse(append(dfuCmdPktReceiptInterval, interval)) - return err -} - -func awaitDFUResponse(ctrlPoint *bluetooth.DeviceCharacteristic, expect []byte) ([]byte, error) { - respCh := make(chan []byte, 1) - err := ctrlPoint.EnableNotifications(func(buf []byte) { - respCh <- buf - }) - if err != nil { - return nil, err - } - - data := <-respCh - ctrlPoint.EnableNotifications(nil) - - if !bytes.HasPrefix(data, expect) { - return nil, fmt.Errorf("unexpected dfu response %x (expected %x)", data, expect) - } - - return bytes.TrimPrefix(data, expect), nil -} diff --git a/infinitime/fs.go b/infinitime/fs.go deleted file mode 100644 index 5470154..0000000 --- a/infinitime/fs.go +++ /dev/null @@ -1,617 +0,0 @@ -package infinitime - -import ( - "errors" - "io" - "io/fs" - "math" - "path" - "strings" - "sync" - "sync/atomic" - - "go.elara.ws/itd/internal/fsproto" - "tinygo.org/x/bluetooth" -) - -// FS represents a remote BLE filesystem -type FS struct { - mtx sync.Mutex - dev *Device -} - -// Stat gets information about a file at the given path. -// -// WARNING: Since there's no stat command in the BLE FS protocol, -// this function does a ReadDir and then finds the requested file -// in the results, which makes it pretty slow. -func (ifs *FS) Stat(p string) (fs.FileInfo, error) { - dir := path.Dir(p) - entries, err := ifs.ReadDir(dir) - if err != nil { - return nil, err - } - - for _, entry := range entries { - if entry.Name() == path.Base(p) { - return entry.Info() - } - } - - return nil, fsproto.ErrFileNotExists -} - -// Remove removes a file or empty directory at the given path. -// -// For a function that removes directories recursively, see [FS.RemoveAll] -func (ifs *FS) Remove(path string) error { - ifs.mtx.Lock() - defer ifs.mtx.Unlock() - - char, err := ifs.dev.getChar(fsTransferChar) - if err != nil { - return err - } - - return ifs.requestThenAwaitResponse( - char, - fsproto.DeleteFileOpcode, - fsproto.DeleteFileRequest{ - PathLen: uint16(len(path)), - Path: path, - }, - func(buf []byte) (bool, error) { - var mdr fsproto.DeleteFileResponse - return true, fsproto.ReadResponse(buf, fsproto.DeleteFileResp, &mdr) - }, - ) -} - -// Rename moves a file or directory from an old path to a new path. -func (ifs *FS) Rename(old, new string) error { - ifs.mtx.Lock() - defer ifs.mtx.Unlock() - - char, err := ifs.dev.getChar(fsTransferChar) - if err != nil { - return err - } - - return ifs.requestThenAwaitResponse( - char, - fsproto.MoveFileOpcode, - fsproto.MoveFileRequest{ - OldPathLen: uint16(len(old)), - OldPath: old, - NewPathLen: uint16(len(new)), - NewPath: new, - }, - func(buf []byte) (bool, error) { - var mfr fsproto.MoveFileResponse - return true, fsproto.ReadResponse(buf, fsproto.MoveFileResp, &mfr) - }, - ) -} - -// Mkdir creates a new directory at the specified path. -// -// For a function that creates necessary parents as well, see [FS.MkdirAll] -func (ifs *FS) Mkdir(path string) error { - ifs.mtx.Lock() - defer ifs.mtx.Unlock() - - char, err := ifs.dev.getChar(fsTransferChar) - if err != nil { - return err - } - - return ifs.requestThenAwaitResponse( - char, - fsproto.MakeDirectoryOpcode, - fsproto.MkdirRequest{ - PathLen: uint16(len(path)), - Path: path, - }, - func(buf []byte) (bool, error) { - var mdr fsproto.MkdirResponse - return true, fsproto.ReadResponse(buf, fsproto.MakeDirectoryResp, &mdr) - }, - ) -} - -// ReadDir reads the directory at the specified path and returns a list of directory entries. -func (ifs *FS) ReadDir(path string) ([]fs.DirEntry, error) { - ifs.mtx.Lock() - defer ifs.mtx.Unlock() - - char, err := ifs.dev.getChar(fsTransferChar) - if err != nil { - return nil, err - } - - var out []fs.DirEntry - return out, ifs.requestThenAwaitResponse( - char, - fsproto.ListDirectoryOpcode, - fsproto.ListDirRequest{ - PathLen: uint16(len(path)), - Path: path, - }, - func(buf []byte) (bool, error) { - var ldr fsproto.ListDirResponse - err := fsproto.ReadResponse(buf, fsproto.ListDirectoryResp, &ldr) - if err != nil { - return true, err - } - - if ldr.EntryNum == ldr.TotalEntries { - return true, nil - } - - out = append(out, DirEntry{ - flags: ldr.Flags, - modtime: ldr.ModTime, - size: ldr.FileSize, - path: string(ldr.Path), - }) - - return false, nil - }, - ) -} - -// RemoveAll removes the file at the specified path and any children it contains, -// similar to the rm -r command. -func (ifs *FS) RemoveAll(p string) error { - if p == "" { - return nil - } - - if path.Clean(p) == "/" { - return fsproto.ErrNoRemoveRoot - } - - fi, err := ifs.Stat(p) - if err != nil { - return nil - } - - if fi.IsDir() { - return ifs.removeWithChildren(p) - } else { - err = ifs.Remove(p) - - var code int8 - if err, ok := err.(fsproto.Error); ok { - code = err.Code - } - - if err != nil && code != -2 { - return err - } - } - - return nil -} - -// removeWithChildren removes the directory at the given path and its children recursively. -func (ifs *FS) removeWithChildren(p string) error { - list, err := ifs.ReadDir(p) - if err != nil { - return err - } - - for _, entry := range list { - name := entry.Name() - - if name == "." || name == ".." { - continue - } - entryPath := path.Join(p, name) - - if entry.IsDir() { - err = ifs.removeWithChildren(entryPath) - } else { - err = ifs.Remove(entryPath) - } - - var code int8 - if err, ok := err.(fsproto.Error); ok { - code = err.Code - } - - if err != nil && code != -2 { - return err - } - } - - return ifs.Remove(p) -} - -// MkdirAll creates a directory and any necessary parents in the file system, -// similar to the mkdir -p command. -func (ifs *FS) MkdirAll(path string) error { - if path == "" || path == "/" { - return nil - } - - splitPath := strings.Split(path, "/") - for i := 1; i < len(splitPath); i++ { - curPath := strings.Join(splitPath[0:i+1], "/") - - err := ifs.Mkdir(curPath) - - var code int8 - if err, ok := err.(fsproto.Error); ok { - code = err.Code - } - - if err != nil && code != -17 { - return err - } - } - - return nil -} - -var _ fs.File = (*File)(nil) - -// File represents a remote file on a BLE filesystem. -// -// If ProgressFunc is set, it will be called whenever a read or write happens -// with the amount of bytes transferred and the total size of the file. -type File struct { - fs *FS - path string - offset uint32 - size uint32 - readOnly bool - closed bool - ProgressFunc func(transferred, total uint32) -} - -// Open opens an existing file at the specified path. -// It returns a handle for the file and an error, if any. -func (ifs *FS) Open(path string) (*File, error) { - return &File{ - fs: ifs, - path: path, - offset: 0, - readOnly: true, - }, nil -} - -// Create creates a new file with the specified path and size. -// It returns a handle for the created file and an error, if any. -func (ifs *FS) Create(path string, size uint32) (*File, error) { - return &File{ - fs: ifs, - path: path, - offset: 0, - size: size, - }, nil -} - -// Write writes data from the byte slice b to the file. -// It returns the number of bytes written and an error, if any. -func (fl *File) Write(b []byte) (int, error) { - if fl.closed { - return 0, fsproto.ErrFileClosed - } - - if fl.readOnly { - return 0, fsproto.ErrFileReadOnly - } - - fl.fs.mtx.Lock() - defer fl.fs.mtx.Unlock() - - char, err := fl.fs.dev.getChar(fsTransferChar) - if err != nil { - return 0, err - } - defer char.EnableNotifications(nil) - - var chunkLen uint32 - - dataLen := uint32(len(b)) - transferred := uint32(0) - mtu := uint32(fl.fs.mtu(char)) - - // continueCh is used to prevent race conditions. When the - // request loop starts, it reads from continueCh, blocking it - // until it's "released" by the notification function after - // the response is processed. - continueCh := make(chan struct{}, 2) - var notifErr error - err = char.EnableNotifications(func(buf []byte) { - var wfr fsproto.WriteFileResponse - err = fsproto.ReadResponse(buf, fsproto.WriteFileResp, &wfr) - if err != nil { - notifErr = err - char.EnableNotifications(nil) - close(continueCh) - return - } - - transferred += chunkLen - fl.offset += chunkLen - - if wfr.FreeSpace == 0 || transferred == dataLen { - char.EnableNotifications(nil) - close(continueCh) - return - } - - if fl.ProgressFunc != nil { - fl.ProgressFunc(transferred, fl.size) - } - - // Release the request loop - continueCh <- struct{}{} - }) - - err = fsproto.WriteRequest(char, fsproto.WriteFileHeaderOpcode, fsproto.WriteFileHeaderRequest{ - PathLen: uint16(len(fl.path)), - Offset: fl.offset, - FileSize: fl.size, - Path: fl.path, - }) - if err != nil { - return int(transferred), err - } - - for range continueCh { - if notifErr != nil { - return int(transferred), notifErr - } - - amountLeft := dataLen - transferred - chunkLen = mtu - if amountLeft < mtu { - chunkLen = amountLeft - } - - err = fsproto.WriteRequest(char, fsproto.WriteFileOpcode, fsproto.WriteFileRequest{ - Status: 0x01, - Offset: fl.offset, - ChunkLen: chunkLen, - Data: b[transferred : transferred+chunkLen], - }) - if err != nil { - return int(transferred), err - } - } - - return int(transferred), notifErr -} - -// Read reads data from the file into the byte slice b. -// It returns the number of bytes read and an error, if any. -func (fl *File) Read(b []byte) (int, error) { - if fl.closed { - return 0, fsproto.ErrFileClosed - } - - fl.fs.mtx.Lock() - defer fl.fs.mtx.Unlock() - - char, err := fl.fs.dev.getChar(fsTransferChar) - if err != nil { - return 0, err - } - defer char.EnableNotifications(nil) - - transferred := uint32(0) - maxLen := uint32(len(b)) - mtu := uint32(fl.fs.mtu(char)) - - var ( - notifErr error - done bool - ) - - // continueCh is used to prevent race conditions. When the - // request loop starts, it reads from continueCh, blocking it - // until it's "released" by the notification function after - // the response is processed. - continueCh := make(chan struct{}, 2) - err = char.EnableNotifications(func(buf []byte) { - var rfr fsproto.ReadFileResponse - err = fsproto.ReadResponse(buf, fsproto.ReadFileResp, &rfr) - if err != nil { - notifErr = err - char.EnableNotifications(nil) - close(continueCh) - return - } - - fl.size = rfr.FileSize - - if rfr.Offset == rfr.FileSize || rfr.ChunkLen == 0 { - notifErr = io.EOF - done = true - char.EnableNotifications(nil) - close(continueCh) - return - } - - n := copy(b[transferred:], rfr.Data[:rfr.ChunkLen]) - fl.offset += uint32(n) - transferred += uint32(n) - - if fl.ProgressFunc != nil { - fl.ProgressFunc(transferred, rfr.FileSize) - } - - // Release the request loop - continueCh <- struct{}{} - }) - if err != nil { - return 0, err - } - defer char.EnableNotifications(nil) - - amountLeft := maxLen - transferred - chunkLen := mtu - if amountLeft < mtu { - chunkLen = amountLeft - } - - err = fsproto.WriteRequest(char, fsproto.ReadFileHeaderOpcode, fsproto.ReadFileHeaderRequest{ - PathLen: uint16(len(fl.path)), - Offset: fl.offset, - ReadLen: chunkLen, - Path: fl.path, - }) - if err != nil { - return 0, err - } - - if notifErr != nil { - return int(transferred), notifErr - } - - for !done { - // Wait for the notification function to release the loop - <-continueCh - - if notifErr != nil { - return int(transferred), notifErr - } - - amountLeft = maxLen - transferred - chunkLen = mtu - if amountLeft < mtu { - chunkLen = amountLeft - } - - err = fsproto.WriteRequest(char, fsproto.ReadFileOpcode, fsproto.ReadFileRequest{ - Status: 0x01, - Offset: fl.offset, - ReadLen: chunkLen, - }) - if err != nil { - return int(transferred), err - } - } - - return int(transferred), notifErr -} - -// Stat returns information about the file, -func (fl *File) Stat() (fs.FileInfo, error) { - return fl.fs.Stat(fl.path) -} - -// Seek sets the offset for the next Read or Write on the file to the specified offset. -// The whence parameter specifies the seek reference point: -// -// io.SeekStart: offset is relative to the start of the file. -// io.SeekCurrent: offset is relative to the current offset. -// io.SeekEnd: offset is relative to the end of the file. -// -// Seek returns the new offset and an error, if any. -func (fl *File) Seek(offset int64, whence int) (int64, error) { - if fl.closed { - return 0, fsproto.ErrFileClosed - } - - if offset > math.MaxUint32 { - return 0, fsproto.ErrInvalidOffset - } - u32Offset := uint32(offset) - - fl.fs.mtx.Lock() - defer fl.fs.mtx.Unlock() - - if fl.size == 0 { - return 0, errors.New("file size unknown") - } - - var newOffset uint32 - switch whence { - case io.SeekStart: - newOffset = u32Offset - case io.SeekCurrent: - newOffset = fl.offset + u32Offset - case io.SeekEnd: - newOffset = fl.size + u32Offset - } - - if newOffset > fl.size || newOffset < 0 { - return 0, fsproto.ErrInvalidOffset - } - fl.offset = newOffset - - return int64(fl.offset), nil -} - -// Close closes the file for future operations -func (fl *File) Close() error { - fl.fs.mtx.Lock() - defer fl.fs.mtx.Unlock() - fl.closed = true - return nil -} - -// requestThenAwaitResponse executes a BLE FS request and then waits for one or more responses, -// until fn returns true or an error is encountered. -func (ifs *FS) requestThenAwaitResponse(char *bluetooth.DeviceCharacteristic, opcode fsproto.FSReqOpcode, req any, fn func(buf []byte) (bool, error)) error { - var stopped atomic.Bool - errCh := make(chan error, 1) - char.EnableNotifications(func(buf []byte) { - stop, err := fn(buf) - if err != nil && !stopped.Load() { - errCh <- err - char.EnableNotifications(nil) - return - } else if !stopped.Load() { - errCh <- nil - } - - if stop && !stopped.Load() { - stopped.Store(true) - close(errCh) - char.EnableNotifications(nil) - } - }) - defer char.EnableNotifications(nil) - - err := fsproto.WriteRequest(char, opcode, req) - if err != nil { - return err - } - - for err := range errCh { - if err != nil { - return err - } - } - - return nil -} - -func (ifs *FS) mtu(char *bluetooth.DeviceCharacteristic) uint16 { - mtuVal, _ := char.GetMTU() - if mtuVal == 0 { - mtuVal = 256 - } - return mtuVal - 20 -} - -var _ fs.FS = (*GoFS)(nil) -var _ fs.StatFS = (*GoFS)(nil) -var _ fs.ReadDirFS = (*GoFS)(nil) - -// GoFS implements [io/fs.FS], [io/fs.StatFS], and [io/fs.ReadDirFS] -// for the InfiniTime filesystem -type GoFS struct { - *FS -} - -// Open opens an existing file at the specified path. -// It returns a handle for the file and an error, if any. -func (gfs GoFS) Open(path string) (fs.File, error) { - return gfs.FS.Open(path) -} diff --git a/infinitime/fstypes.go b/infinitime/fstypes.go deleted file mode 100644 index 1752b69..0000000 --- a/infinitime/fstypes.go +++ /dev/null @@ -1,142 +0,0 @@ -package infinitime - -import ( - "fmt" - "io/fs" - "strconv" - "time" -) - -// DirEntry represents an entry from a directory listing -type DirEntry struct { - flags uint32 - modtime uint64 - size uint32 - path string -} - -// Name returns the name of the file described by the entry -func (de DirEntry) Name() string { - return de.path -} - -// IsDir reports whether the entry describes a directory. -func (de DirEntry) IsDir() bool { - return de.flags&0b1 == 1 -} - -// Type returns the type bits for the entry. -func (de DirEntry) Type() fs.FileMode { - if de.IsDir() { - return fs.ModeDir - } else { - return 0 - } -} - -// Info returns the FileInfo for the file or subdirectory described by the entry. -func (de DirEntry) Info() (fs.FileInfo, error) { - return FileInfo{ - name: de.path, - size: de.size, - modtime: de.modtime, - mode: de.Type(), - isDir: de.IsDir(), - }, nil -} - -func (de DirEntry) String() string { - var isDirChar rune - if de.IsDir() { - isDirChar = 'd' - } else { - isDirChar = '-' - } - - // Get human-readable value for file size - val, unit := bytesHuman(de.size) - prec := 0 - // If value is less than 10, set precision to 1 - if val < 10 { - prec = 1 - } - // Convert float to string - valStr := strconv.FormatFloat(val, 'f', prec, 64) - - // Return string formatted like so: - // - 10 kB file - // or: - // d 0 B . - return fmt.Sprintf( - "%c %3s %-2s %s", - isDirChar, - valStr, - unit, - de.path, - ) -} - -func bytesHuman(b uint32) (float64, string) { - const unit = 1000 - // Set possible unit prefixes (PineTime flash is 4MB) - units := [2]rune{'k', 'M'} - // If amount of bytes is less than smallest unit - if b < unit { - // Return unchanged with unit "B" - return float64(b), "B" - } - - div, exp := uint32(unit), 0 - // Get decimal values and unit prefix index - for n := b / unit; n >= unit; n /= unit { - div *= unit - exp++ - } - - // Create string for full unit - unitStr := string([]rune{units[exp], 'B'}) - - // Return decimal with unit string - return float64(b) / float64(div), unitStr -} - -// FileInfo implements fs.FileInfo -type FileInfo struct { - name string - size uint32 - modtime uint64 - mode fs.FileMode - isDir bool -} - -// Name returns the base name of the file -func (fi FileInfo) Name() string { - return fi.name -} - -// Size returns the total size of the file -func (fi FileInfo) Size() int64 { - return int64(fi.size) -} - -// Mode returns the mode of the file -func (fi FileInfo) Mode() fs.FileMode { - return fi.mode -} - -// ModTime returns the modification time of the file -// As of now, this is unimplemented in InfiniTime, and -// will always return 0. -func (fi FileInfo) ModTime() time.Time { - return time.Unix(0, int64(fi.modtime)) -} - -// IsDir returns whether the file is a directory -func (fi FileInfo) IsDir() bool { - return fi.isDir -} - -// Sys is unimplemented and returns nil -func (fi FileInfo) Sys() any { - return nil -} diff --git a/infinitime/infinitime.go b/infinitime/infinitime.go deleted file mode 100644 index ed3d146..0000000 --- a/infinitime/infinitime.go +++ /dev/null @@ -1,173 +0,0 @@ -package infinitime - -import ( - "fmt" - "sync" - "sync/atomic" - "time" - - "tinygo.org/x/bluetooth" -) - -type Options struct { - Allowlist []string - Blocklist []string - ScanInterval time.Duration - - OnDisconnect func(dev *Device) - OnReconnect func(dev *Device) - OnConnect func(dev *Device) -} - -func reconnect(opts Options, adapter *bluetooth.Adapter, device *Device, mac string) { - if device == nil { - return - } - - done := false - for { - adapter.Scan(func(a *bluetooth.Adapter, sr bluetooth.ScanResult) { - if sr.Address.String() != mac { - return - } - - dev, err := a.Connect(sr.Address, bluetooth.ConnectionParams{}) - if err != nil { - return - } - adapter.StopScan() - - device.deviceMtx.Lock() - device.device = dev - device.deviceMtx.Unlock() - - device.notifierMtx.Lock() - for char, notifier := range device.notifierMap { - c, err := device.getChar(char) - if err != nil { - continue - } - - err = c.EnableNotifications(nil) - if err != nil { - continue - } - - err = c.EnableNotifications(notifier.notify) - if err != nil { - continue - } - } - device.notifierMtx.Unlock() - - done = true - }) - - if done { - return - } - - time.Sleep(opts.ScanInterval) - } -} - -func Connect(opts Options) (device *Device, err error) { - adapter := bluetooth.DefaultAdapter - - if opts.ScanInterval == 0 { - opts.ScanInterval = 2 * time.Minute - } - - var mac string - adapter.SetConnectHandler(func(dev bluetooth.Device, connected bool) { - if mac == "" || dev.Address.String() != mac { - return - } - - if connected { - if opts.OnReconnect != nil { - opts.OnReconnect(device) - } - } else { - if opts.OnDisconnect != nil { - opts.OnDisconnect(device) - } - go reconnect(opts, adapter, device, mac) - } - }) - - err = adapter.Enable() - if err != nil { - return nil, err - } - - var scanErr error - err = adapter.Scan(func(a *bluetooth.Adapter, sr bluetooth.ScanResult) { - if sr.LocalName() != "InfiniTime" { - return - } - - dev, err := a.Connect(sr.Address, bluetooth.ConnectionParams{}) - if err != nil { - scanErr = err - adapter.StopScan() - return - } - mac = dev.Address.String() - - device = &Device{adapter: a, device: dev, notifierMap: map[btChar]notifier{}} - if opts.OnConnect != nil { - opts.OnConnect(device) - } - adapter.StopScan() - }) - if err != nil { - return nil, err - } - - if scanErr != nil { - return nil, scanErr - } - - return device, nil -} - -// Device represents an InfiniTime device -type Device struct { - adapter *bluetooth.Adapter - - deviceMtx sync.Mutex - device bluetooth.Device - updating atomic.Bool - - notifierMtx sync.Mutex - notifierMap map[btChar]notifier -} - -// FS returns a handle for InifniTime's filesystem' -func (d *Device) FS() *FS { - return &FS{ - dev: d, - } -} - -func (d *Device) getChar(c btChar) (*bluetooth.DeviceCharacteristic, error) { - if d.updating.Load() { - return nil, fmt.Errorf("device is currently updating") - } - - d.deviceMtx.Lock() - defer d.deviceMtx.Unlock() - - services, err := d.device.DiscoverServices([]bluetooth.UUID{c.ServiceID}) - if err != nil { - return nil, fmt.Errorf("characteristic %s (%s) not found", c.ID, c.Name) - } - - chars, err := services[0].DiscoverCharacteristics([]bluetooth.UUID{c.ID}) - if err != nil { - return nil, fmt.Errorf("characteristic %s (%s) not found", c.ID, c.Name) - } - - return chars[0], err -} diff --git a/infinitime/info.go b/infinitime/info.go deleted file mode 100644 index 3e898d4..0000000 --- a/infinitime/info.go +++ /dev/null @@ -1,101 +0,0 @@ -package infinitime - -import ( - "context" - "encoding/binary" -) - -// Address returns the MAC address of the connected device. -func (d *Device) Address() string { - return d.device.Address.String() -} - -// Version returns the version of InifniTime that the connected device is running. -func (d *Device) Version() (string, error) { - c, err := d.getChar(firmwareVerChar) - if err != nil { - return "", err - } - - ver := make([]byte, 16) - n, err := c.Read(ver) - return string(ver[:n]), err -} - -// BatteryLevel returns the current battery level of the connected PineTime. -func (d *Device) BatteryLevel() (lvl uint8, err error) { - c, err := d.getChar(batteryLevelChar) - if err != nil { - return 0, err - } - - err = binary.Read(c, binary.LittleEndian, &lvl) - return lvl, err -} - -// WatchBatteryLevel calls fn whenever the battery level changes. -func (d *Device) WatchBatteryLevel(ctx context.Context, fn func(level uint8, err error)) error { - return watchChar(ctx, d, batteryLevelChar, fn) -} - -// StepCount returns the current step count recorded on the watch. -func (d *Device) StepCount() (sc uint32, err error) { - c, err := d.getChar(stepCountChar) - if err != nil { - return 0, err - } - - err = binary.Read(c, binary.LittleEndian, &sc) - return sc, err -} - -// WatchStepCount calls fn whenever the step count changes. -func (d *Device) WatchStepCount(ctx context.Context, fn func(count uint32, err error)) error { - return watchChar(ctx, d, stepCountChar, fn) -} - -// HeartRate returns the current heart rate recorded on the watch. -func (d *Device) HeartRate() (uint8, error) { - c, err := d.getChar(heartRateChar) - if err != nil { - return 0, err - } - - data := make([]byte, 2) - _, err = c.Read(data) - if err != nil { - return 0, err - } - - return data[1], nil -} - -// WatchHeartRate calls fn whenever the heart rate changes. -func (d *Device) WatchHeartRate(ctx context.Context, fn func(rate uint8, err error)) error { - return watchChar(ctx, d, heartRateChar, func(rate [2]uint8, err error) { - fn(rate[1], err) - }) -} - -// MotionValues represents gyroscope coordinates. -type MotionValues struct { - X int16 - Y int16 - Z int16 -} - -// Motion returns the current gyroscope coordinates of the PineTime. -func (d *Device) Motion() (mv MotionValues, err error) { - c, err := d.getChar(rawMotionChar) - if err != nil { - return MotionValues{}, err - } - - err = binary.Read(c, binary.LittleEndian, &mv) - return mv, err -} - -// WatchMotion calls fn whenever the gyroscope coordinates change. -func (d *Device) WatchMotion(ctx context.Context, fn func(level MotionValues, err error)) error { - return watchChar(ctx, d, rawMotionChar, fn) -} diff --git a/infinitime/music.go b/infinitime/music.go deleted file mode 100644 index 982e049..0000000 --- a/infinitime/music.go +++ /dev/null @@ -1,68 +0,0 @@ -package infinitime - -import "context" - -type MusicEvent uint8 - -const ( - MusicEventOpen MusicEvent = 0xe0 - MusicEventPlay MusicEvent = 0x00 - MusicEventPause MusicEvent = 0x01 - MusicEventNext MusicEvent = 0x03 - MusicEventPrev MusicEvent = 0x04 - MusicEventVolUp MusicEvent = 0x05 - MusicEventVolDown MusicEvent = 0x06 -) - -// SetMusicStatus sets whether the music is playing or paused. -func (d *Device) SetMusicStatus(playing bool) error { - char, err := d.getChar(musicStatusChar) - if err != nil { - return err - } - - if playing { - _, err = char.WriteWithoutResponse([]byte{0x1}) - } else { - _, err = char.WriteWithoutResponse([]byte{0x0}) - } - return err -} - -// SetMusicArtist sets the music artist. -func (d *Device) SetMusicArtist(artist string) error { - char, err := d.getChar(musicArtistChar) - if err != nil { - return err - } - - _, err = char.WriteWithoutResponse([]byte(artist)) - return err -} - -// SetMusicTrack sets the music track name. -func (d *Device) SetMusicTrack(track string) error { - char, err := d.getChar(musicTrackChar) - if err != nil { - return err - } - - _, err = char.WriteWithoutResponse([]byte(track)) - return err -} - -// SetMusicAlbum sets the music album name. -func (d *Device) SetMusicAlbum(album string) error { - char, err := d.getChar(musicAlbumChar) - if err != nil { - return err - } - - _, err = char.WriteWithoutResponse([]byte(album)) - return err -} - -// WatchMusicEvents calls fn whenever the InfiniTime music app broadcasts an event. -func (d *Device) WatchMusicEvents(ctx context.Context, fn func(event MusicEvent, err error)) error { - return watchChar(ctx, d, musicEventChar, fn) -} diff --git a/infinitime/navigation.go b/infinitime/navigation.go deleted file mode 100644 index fca70ac..0000000 --- a/infinitime/navigation.go +++ /dev/null @@ -1,137 +0,0 @@ -package infinitime - -type NavFlag string - -const ( - NavFlagArrive NavFlag = "arrive" - NavFlagArriveLeft NavFlag = "arrive-left" - NavFlagArriveRight NavFlag = "arrive-right" - NavFlagArriveStraight NavFlag = "arrive-straight" - NavFlagClose NavFlag = "close" - NavFlagContinue NavFlag = "continue" - NavFlagContinueLeft NavFlag = "continue-left" - NavFlagContinueRight NavFlag = "continue-right" - NavFlagContinueSlightLeft NavFlag = "continue-slight-left" - NavFlagContinueSlightRight NavFlag = "continue-slight-right" - NavFlagContinueStraight NavFlag = "continue-straight" - NavFlagContinueUturn NavFlag = "continue-uturn" - NavFlagDepart NavFlag = "depart" - NavFlagDepartLeft NavFlag = "depart-left" - NavFlagDepartRight NavFlag = "depart-right" - NavFlagDepartStraight NavFlag = "depart-straight" - NavFlagEndOfRoadLeft NavFlag = "end-of-road-left" - NavFlagEndOfRoadRight NavFlag = "end-of-road-right" - NavFlagFerry NavFlag = "ferry" - NavFlagFlag NavFlag = "flag" - NavFlagFork NavFlag = "fork" - NavFlagForkLeft NavFlag = "fork-left" - NavFlagForkRight NavFlag = "fork-right" - NavFlagForkSlightLeft NavFlag = "fork-slight-left" - NavFlagForkSlightRight NavFlag = "fork-slight-right" - NavFlagForkStraight NavFlag = "fork-straight" - NavFlagInvalid NavFlag = "invalid" - NavFlagInvalidLeft NavFlag = "invalid-left" - NavFlagInvalidRight NavFlag = "invalid-right" - NavFlagInvalidSlightLeft NavFlag = "invalid-slight-left" - NavFlagInvalidSlightRight NavFlag = "invalid-slight-right" - NavFlagInvalidStraight NavFlag = "invalid-straight" - NavFlagInvalidUturn NavFlag = "invalid-uturn" - NavFlagMergeLeft NavFlag = "merge-left" - NavFlagMergeRight NavFlag = "merge-right" - NavFlagMergeSlightLeft NavFlag = "merge-slight-left" - NavFlagMergeSlightRight NavFlag = "merge-slight-right" - NavFlagMergeStraight NavFlag = "merge-straight" - NavFlagNewNameLeft NavFlag = "new-name-left" - NavFlagNewNameRight NavFlag = "new-name-right" - NavFlagNewNameSharpLeft NavFlag = "new-name-sharp-left" - NavFlagNewNameSharpRight NavFlag = "new-name-sharp-right" - NavFlagNewNameSlightLeft NavFlag = "new-name-slight-left" - NavFlagNewNameSlightRight NavFlag = "new-name-slight-right" - NavFlagNewNameStraight NavFlag = "new-name-straight" - NavFlagNotificationLeft NavFlag = "notification-left" - NavFlagNotificationRight NavFlag = "notification-right" - NavFlagNotificationSharpLeft NavFlag = "notification-sharp-left" - NavFlagNotificationSharpRight NavFlag = "notification-sharp-right" - NavFlagNotificationSlightLeft NavFlag = "notification-slight-left" - NavFlagNotificationSlightRight NavFlag = "notification-slight-right" - NavFlagNotificationStraight NavFlag = "notification-straight" - NavFlagOffRampLeft NavFlag = "off-ramp-left" - NavFlagOffRampRight NavFlag = "off-ramp-right" - NavFlagOffRampSharpLeft NavFlag = "off-ramp-sharp-left" - NavFlagOffRampSharpRight NavFlag = "off-ramp-sharp-right" - NavFlagOffRampSlightLeft NavFlag = "off-ramp-slight-left" - NavFlagOffRampSlightRight NavFlag = "off-ramp-slight-right" - NavFlagOffRampStraight NavFlag = "off-ramp-straight" - NavFlagOnRampLeft NavFlag = "on-ramp-left" - NavFlagOnRampRight NavFlag = "on-ramp-right" - NavFlagOnRampSharpLeft NavFlag = "on-ramp-sharp-left" - NavFlagOnRampSharpRight NavFlag = "on-ramp-sharp-right" - NavFlagOnRampSlightLeft NavFlag = "on-ramp-slight-left" - NavFlagOnRampSlightRight NavFlag = "on-ramp-slight-right" - NavFlagOnRampStraight NavFlag = "on-ramp-straight" - NavFlagRotary NavFlag = "rotary" - NavFlagRotaryLeft NavFlag = "rotary-left" - NavFlagRotaryRight NavFlag = "rotary-right" - NavFlagRotarySharpLeft NavFlag = "rotary-sharp-left" - NavFlagRotarySharpRight NavFlag = "rotary-sharp-right" - NavFlagRotarySlightLeft NavFlag = "rotary-slight-left" - NavFlagRotarySlightRight NavFlag = "rotary-slight-right" - NavFlagRotaryStraight NavFlag = "rotary-straight" - NavFlagRoundabout NavFlag = "roundabout" - NavFlagRoundaboutLeft NavFlag = "roundabout-left" - NavFlagRoundaboutRight NavFlag = "roundabout-right" - NavFlagRoundaboutSharpLeft NavFlag = "roundabout-sharp-left" - NavFlagRoundaboutSharpRight NavFlag = "roundabout-sharp-right" - NavFlagRoundaboutSlightLeft NavFlag = "roundabout-slight-left" - NavFlagRoundaboutSlightRight NavFlag = "roundabout-slight-right" - NavFlagRoundaboutStraight NavFlag = "roundabout-straight" - NavFlagTurnLeft NavFlag = "turn-left" - NavFlagTurnRight NavFlag = "turn-right" - NavFlagTurnSharpLeft NavFlag = "turn-sharp-left" - NavFlagTurnSharpRight NavFlag = "turn-sharp-right" - NavFlagTurnSlightLeft NavFlag = "turn-slight-left" - NavFlagTurnSlightRight NavFlag = "turn-slight-right" - NavFlagTurnStraight NavFlag = "turn-straight" - NavFlagUpDown NavFlag = "updown" - NavFlagUTurn NavFlag = "uturn" -) - -// SetNavFlag sets the navigation flag icon. -func (d *Device) SetNavFlag(flag NavFlag) error { - char, err := d.getChar(navigationFlagsChar) - if err != nil { - return err - } - _, err = char.WriteWithoutResponse([]byte(flag)) - return err -} - -// SetNavNarrative sets the navigation narrative string. -func (d *Device) SetNavNarrative(narrative string) error { - char, err := d.getChar(navigationNarrativeChar) - if err != nil { - return err - } - _, err = char.WriteWithoutResponse([]byte(narrative)) - return err -} - -// SetNavManeuverDistance sets the navigation maneuver distance. -func (d *Device) SetNavManeuverDistance(manDist string) error { - char, err := d.getChar(navigationManDist) - if err != nil { - return err - } - _, err = char.WriteWithoutResponse([]byte(manDist)) - return err -} - -// SetNavProgress sets the navigation progress. -func (d *Device) SetNavProgress(progress uint8) error { - char, err := d.getChar(navigationProgress) - if err != nil { - return err - } - _, err = char.WriteWithoutResponse([]byte{progress}) - return err -} diff --git a/infinitime/notifs.go b/infinitime/notifs.go deleted file mode 100644 index 3547c0f..0000000 --- a/infinitime/notifs.go +++ /dev/null @@ -1,42 +0,0 @@ -package infinitime - -var ( - regularNotifHeader = []byte{0x00, 0x01, 0x00} - callNotifHeader = []byte{0x03, 0x01, 0x00} -) - -// Notify sends a notification to the PineTime using the Alert Notification Service -func (d *Device) Notify(title, body string) error { - c, err := d.getChar(newAlertChar) - if err != nil { - return err - } - - content := title + "\x00" + body - _, err = c.WriteWithoutResponse(append(regularNotifHeader, content...)) - return err -} - -type CallStatus uint8 - -const ( - CallStatusDeclined CallStatus = iota - CallStatusAccepted - CallStatusMuted -) - -// NotifyCall sends a call to the PineTime using the Alert Notification Service, -// then executes fn once the user presses a button on the watch. -func (d *Device) NotifyCall(from string, fn func(CallStatus)) error { - c, err := d.getChar(newAlertChar) - if err != nil { - return err - } - - _, err = c.WriteWithoutResponse(append(callNotifHeader, from...)) - if err != nil { - return err - } - - return watchCharOnce(d, notifEventChar, fn) -} diff --git a/infinitime/resources.go b/infinitime/resources.go deleted file mode 100644 index 628e4c6..0000000 --- a/infinitime/resources.go +++ /dev/null @@ -1,135 +0,0 @@ -package infinitime - -import ( - "archive/zip" - "encoding/json" - "errors" - "io" - "path/filepath" -) - -type ResourceOperation int - -const ( - // ResourceUpload represents the upload phase - // of resource loading - ResourceUpload = iota - // ResourceRemove represents the obsolete - // file removal phase of resource loading - ResourceRemove -) - -// resourceManifest is the structure of the resource manifest file -type resourceManifest struct { - Resources []resource `json:"resources"` - Obsolete []obsoleteResource `json:"obsolete_files"` -} - -// resource represents a resource entry in the manifest -type resource struct { - Name string `json:"filename"` - Path string `json:"path"` -} - -// obsoleteResource represents an obsolete file entry in the manifest -type obsoleteResource struct { - Path string `json:"path"` - Since string `json:"since"` -} - -// ResourceLoadProgress contains information on the progress of -// a resource load -type ResourceLoadProgress struct { - Operation ResourceOperation - Name string - Total uint32 - Transferred uint32 -} - -// LoadResources accepts the path of an InfiniTime resource archive and loads its contents to the watch's filesystem. -func LoadResources(archivePath string, fs *FS, progress func(ResourceLoadProgress)) error { - r, err := zip.OpenReader(archivePath) - if err != nil { - return err - } - defer r.Close() - - manifestFl, err := r.Open("resources.json") - if err != nil { - return err - } - - var manifest resourceManifest - err = json.NewDecoder(manifestFl).Decode(&manifest) - if err != nil { - return err - } - - err = manifestFl.Close() - if err != nil { - return err - } - - for _, file := range manifest.Obsolete { - err := fs.RemoveAll(file.Path) - if err != nil { - return err - } - - progress(ResourceLoadProgress{ - Operation: ResourceRemove, - Name: filepath.Base(file.Path), - }) - } - - for _, file := range manifest.Resources { - src, err := r.Open(file.Name) - if err != nil { - return err - } - - fi, err := src.Stat() - if err != nil { - return err - } - - err = fs.MkdirAll(filepath.Dir(file.Path)) - if err != nil { - return err - } - - dst, err := fs.Create(file.Path, uint32(fi.Size())) - if err != nil { - return err - } - - dst.ProgressFunc = func(transferred, total uint32) { - progress(ResourceLoadProgress{ - Name: file.Name, - Transferred: transferred, - Total: total, - }) - } - - _, err = io.Copy(dst, src) - if err != nil { - return errors.Join( - err, - src.Close(), - dst.Close(), - ) - } - - err = src.Close() - if err != nil { - return err - } - - err = dst.Close() - if err != nil { - return err - } - } - - return nil -} diff --git a/infinitime/time.go b/infinitime/time.go deleted file mode 100644 index bb081b6..0000000 --- a/infinitime/time.go +++ /dev/null @@ -1,58 +0,0 @@ -package infinitime - -import ( - "bytes" - "encoding/binary" - "time" -) - -// SetTime sets the current time, and then sets the timezone data, -// if the local time characteristic is available. -func (d *Device) SetTime(t time.Time) error { - c, err := d.getChar(currentTimeChar) - if err != nil { - return err - } - - buf := &bytes.Buffer{} - binary.Write(buf, binary.LittleEndian, uint16(t.Year())) - binary.Write(buf, binary.LittleEndian, uint8(t.Month())) - binary.Write(buf, binary.LittleEndian, uint8(t.Day())) - binary.Write(buf, binary.LittleEndian, uint8(t.Hour())) - binary.Write(buf, binary.LittleEndian, uint8(t.Minute())) - binary.Write(buf, binary.LittleEndian, uint8(t.Second())) - binary.Write(buf, binary.LittleEndian, uint8(t.Weekday())) - binary.Write(buf, binary.LittleEndian, uint8((t.Nanosecond()/1000)/1e6*256)) - binary.Write(buf, binary.LittleEndian, uint8(0b0001)) - - _, err = c.WriteWithoutResponse(buf.Bytes()) - if err != nil { - return err - } - - ltc, err := d.getChar(localTimeChar) - if err != nil { - return nil - } - - _, offset := t.Zone() - dst := 0 - - // Local time expects two values: the timezone offset and the dst offset, both - // expressed in quarters of an hour. - // Timezone offset is to be constant over DST, with dst offset holding the offset != 0 - // when DST is in effect. - // As there is no standard way in go to get the actual dst offset, we assume it to be 1h - // when DST is in effect - if t.IsDST() { - dst = 3600 - offset -= 3600 - } - - buf.Reset() - binary.Write(buf, binary.LittleEndian, uint8(offset/3600*4)) - binary.Write(buf, binary.LittleEndian, uint8(dst/3600*4)) - - _, err = ltc.WriteWithoutResponse(buf.Bytes()) - return err -} diff --git a/infinitime/watch.go b/infinitime/watch.go deleted file mode 100644 index fc87c02..0000000 --- a/infinitime/watch.go +++ /dev/null @@ -1,108 +0,0 @@ -package infinitime - -import ( - "bytes" - "context" - "encoding/binary" - "sync" - - "tinygo.org/x/bluetooth" -) - -type notifier interface { - notify([]byte) -} - -type watcher[T any] struct { - mu sync.Mutex - nextFuncID int - callbacks map[int]func(T, error) - char *bluetooth.DeviceCharacteristic -} - -func (w *watcher[T]) addCallback(fn func(T, error)) int { - w.mu.Lock() - defer w.mu.Unlock() - funcID := w.nextFuncID - w.callbacks[funcID] = fn - w.nextFuncID++ - return funcID -} - -func (w *watcher[T]) notify(b []byte) { - var val T - err := binary.Read(bytes.NewReader(b), binary.LittleEndian, &val) - w.mu.Lock() - for _, fn := range w.callbacks { - go fn(val, err) - } - w.mu.Unlock() -} - -func (w *watcher[T]) cancelFn(d *Device, ch btChar, id int) func() { - return func() { - w.mu.Lock() - delete(w.callbacks, id) - w.mu.Unlock() - - if len(w.callbacks) == 0 { - d.notifierMtx.Lock() - delete(d.notifierMap, ch) - d.notifierMtx.Unlock() - w.char.EnableNotifications(nil) - } - } -} - -func watchChar[T any](ctx context.Context, d *Device, ch btChar, fn func(T, error)) error { - d.notifierMtx.Lock() - defer d.notifierMtx.Unlock() - - if n, ok := d.notifierMap[ch]; ok { - w := n.(*watcher[T]) - funcID := w.addCallback(fn) - context.AfterFunc(ctx, w.cancelFn(d, ch, funcID)) - go func() { - <-ctx.Done() - w.cancelFn(d, ch, funcID)() - }() - return nil - } else { - c, err := d.getChar(ch) - if err != nil { - return err - } - - w := &watcher[T]{callbacks: map[int]func(T, error){}} - err = c.EnableNotifications(w.notify) - if err != nil { - return err - } - w.char = c - funcID := w.addCallback(fn) - d.notifierMap[ch] = w - - context.AfterFunc(ctx, w.cancelFn(d, ch, funcID)) - return nil - } -} - -func watchCharOnce[T any](d *Device, ch btChar, fn func(T)) error { - ctx, cancel := context.WithCancel(context.Background()) - - var watchErr error - err := watchChar(ctx, d, ch, func(val T, err error) { - defer cancel() - if err != nil { - watchErr = err - return - } - fn(val) - }) - if err != nil { - return err - } - - <-ctx.Done() - return watchErr -} diff --git a/infinitime/weather.go b/infinitime/weather.go deleted file mode 100644 index c7176b8..0000000 --- a/infinitime/weather.go +++ /dev/null @@ -1,124 +0,0 @@ -package infinitime - -import ( - "bytes" - "encoding/binary" - "errors" - "time" -) - -const ( - weatherVersion = 0 - - currentWeatherType = 0 - forecastWeatherType = 1 -) - -type WeatherIcon uint8 - -const ( - WeatherIconClear WeatherIcon = iota - WeatherIconFewClouds - WeatherIconClouds - WeatherIconHeavyClouds - WeatherIconCloudsWithRain - WeatherIconRain - WeatherIconThunderstorm - WeatherIconSnow - WeatherIconMist -) - -// CurrentWeather represents the current weather -type CurrentWeather struct { - Time time.Time - CurrentTemp float32 - MinTemp float32 - MaxTemp float32 - Location string - Icon WeatherIcon -} - -// Bytes returns the [CurrentWeather] struct encoded using the InfiniTime -// weather wire protocol. -func (cw CurrentWeather) Bytes() []byte { - buf := &bytes.Buffer{} - - buf.WriteByte(currentWeatherType) - buf.WriteByte(weatherVersion) - - _, offset := cw.Time.Zone() - binary.Write(buf, binary.LittleEndian, cw.Time.Unix()+int64(offset)) - - binary.Write(buf, binary.LittleEndian, int16(cw.CurrentTemp*100)) - binary.Write(buf, binary.LittleEndian, int16(cw.MinTemp*100)) - binary.Write(buf, binary.LittleEndian, int16(cw.MaxTemp*100)) - - location := make([]byte, 32) - copy(location, cw.Location) - buf.Write(location) - - buf.WriteByte(byte(cw.Icon)) - - return buf.Bytes() -} - -// Forecast represents a weather forecast -type Forecast struct { - Time time.Time - Days []ForecastDay -} - -// ForecastDay represents a forecast for a single day -type ForecastDay struct { - MinTemp int16 - MaxTemp int16 - Icon WeatherIcon -} - -// Bytes returns the [Forecast] struct encoded using the InfiniTime -// weather wire protocol. -func (f Forecast) Bytes() []byte { - buf := &bytes.Buffer{} - - buf.WriteByte(forecastWeatherType) - buf.WriteByte(weatherVersion) - - _, offset := f.Time.Zone() - binary.Write(buf, binary.LittleEndian, f.Time.Unix()+int64(offset)) - - buf.WriteByte(uint8(len(f.Days))) - - for _, day := range f.Days { - binary.Write(buf, binary.LittleEndian, day.MinTemp*100) - binary.Write(buf, binary.LittleEndian, day.MaxTemp*100) - buf.WriteByte(byte(day.Icon)) - } - - return buf.Bytes() -} - -// SetCurrentWeather updates the current weather data on the PineTime -func (d *Device) SetCurrentWeather(cw CurrentWeather) error { - c, err := d.getChar(weatherDataChar) - if err != nil { - return err - } - - _, err = c.WriteWithoutResponse(cw.Bytes()) - return err -} - -// SetForecast sets future forecast data on the PineTime -func (d *Device) SetForecast(f Forecast) error { - c, err := d.getChar(weatherDataChar) - if err != nil { - return err - } - - if len(f.Days) > 5 { - return errors.New("amount of forecast days exceeds maximum of 5") - } - - _, err = c.WriteWithoutResponse(f.Bytes()) - return err -} diff --git a/internal/fsproto/errors.go b/internal/fsproto/errors.go deleted file mode 100644 index 6a8de3a..0000000 --- a/internal/fsproto/errors.go +++ /dev/null @@ -1,62 +0,0 @@ -package fsproto - -import ( - "errors" - "fmt" -) - -var ( - ErrFileNotExists = errors.New("file does not exist") - ErrFileReadOnly = errors.New("file is read only") - ErrFileWriteOnly = errors.New("file is write only") - ErrInvalidOffset = errors.New("offset out of range") - ErrNoRemoveRoot = errors.New("refusing to remove root directory") - ErrFileClosed = errors.New("cannot perform operation on a closed file") -) - -// Error represents an error returned by BLE FS -type Error struct { - Code int8 -} - -// Error returns the string associated with the error code -func (err Error) Error() string { - switch err.Code { - case 0x02: - return "filesystem error" - case 0x05: - return "read-only filesystem" - case 0x03: - return "no such file" - case 0x04: - return "protocol error" - case -5: - return "input/output error" - case -84: - return "filesystem is corrupted" - case -2: - return "no such directory entry" - case -17: - return "entry already exists" - case -20: - return "entry is not a directory" - case -39: - return "directory is not empty" - case -9: - return "bad file number" - case -27: - return "file is too large" - case -22: - return "invalid parameter" - case -28: - return "no space left on device" - case -12: - return "no more memory available" - case -61: - return "no attr available" - case -36: - return "file name is too long" - default: - return fmt.Sprintf("unknown error (code %d)", err.Code) - } -} diff --git a/internal/fsproto/fsproto.go b/internal/fsproto/fsproto.go deleted file mode 100644 index 4310fb3..0000000 --- a/internal/fsproto/fsproto.go +++ /dev/null @@ -1,212 +0,0 @@ -package fsproto - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "reflect" - - "tinygo.org/x/bluetooth" -) - -type FSReqOpcode uint8 - -const ( - ReadFileHeaderOpcode FSReqOpcode = 0x10 - ReadFileOpcode FSReqOpcode = 0x12 - WriteFileHeaderOpcode FSReqOpcode = 0x20 - WriteFileOpcode FSReqOpcode = 0x22 - DeleteFileOpcode FSReqOpcode = 0x30 - MakeDirectoryOpcode FSReqOpcode = 0x40 - ListDirectoryOpcode FSReqOpcode = 0x50 - MoveFileOpcode FSReqOpcode = 0x60 -) - -type FSRespOpcode uint8 - -const ( - ReadFileResp FSRespOpcode = 0x11 - WriteFileResp FSRespOpcode = 0x21 - DeleteFileResp FSRespOpcode = 0x31 - MakeDirectoryResp FSRespOpcode = 0x41 - ListDirectoryResp FSRespOpcode = 0x51 - MoveFileResp FSRespOpcode = 0x61 -) - -type ReadFileHeaderRequest struct { - Padding byte - PathLen uint16 - Offset uint32 - ReadLen uint32 - Path string -} - -type ReadFileRequest struct { - Status uint8 - Padding [2]byte - Offset uint32 - ReadLen uint32 -} - -type ReadFileResponse struct { - Status int8 - Padding [2]byte - Offset uint32 - FileSize uint32 - ChunkLen uint32 - Data []byte -} - -type WriteFileHeaderRequest struct { - Padding byte - PathLen uint16 - Offset uint32 - ModTime uint64 - FileSize uint32 - Path string -} - -type WriteFileRequest struct { - Status uint8 - Padding [2]byte - Offset uint32 - ChunkLen uint32 - Data []byte -} - -type WriteFileResponse struct { - Status int8 - Padding [2]byte - Offset uint32 - ModTime uint64 - FreeSpace uint32 -} - -type DeleteFileRequest struct { - Padding byte - PathLen uint16 - Path string -} - -type DeleteFileResponse struct { - Status int8 -} - -type MkdirRequest struct { - Padding byte - PathLen uint16 - Padding2 [4]byte - Timestamp uint64 - Path string -} - -type MkdirResponse struct { - Status int8 - Padding [6]byte - ModTime uint64 -} - -type ListDirRequest struct { - Padding byte - PathLen uint16 - Path string -} - -type ListDirResponse struct { - Status int8 - PathLen uint16 - EntryNum uint32 - TotalEntries uint32 - Flags uint32 - ModTime uint64 - FileSize uint32 - Path []byte -} - -type MoveFileRequest struct { - Padding byte - OldPathLen uint16 - NewPathLen uint16 - OldPath string - Padding2 byte - NewPath string -} - -type MoveFileResponse struct { - Status int8 -} - -func WriteRequest(char *bluetooth.DeviceCharacteristic, opcode FSReqOpcode, req any) error { - buf := &bytes.Buffer{} - buf.WriteByte(byte(opcode)) - - rv := reflect.ValueOf(req) - for rv.Kind() == reflect.Pointer { - rv = rv.Elem() - } - - for i := 0; i < rv.NumField(); i++ { - switch field := rv.Field(i); field.Kind() { - case reflect.String: - io.WriteString(buf, field.String()) - case reflect.Slice: - if field.Type().Elem().Kind() == reflect.Uint8 { - buf.Write(field.Bytes()) - } - default: - binary.Write(buf, binary.LittleEndian, field.Interface()) - } - } - - _, err := char.WriteWithoutResponse(buf.Bytes()) - return err -} - -func ReadResponse(b []byte, expect FSRespOpcode, out interface{}) error { - if len(b) == 0 { - return errors.New("empty response packet") - } - if opcode := FSRespOpcode(b[0]); opcode != expect { - return fmt.Errorf("unexpected response opcode: expected %x, got %x", expect, opcode) - } - - r := bytes.NewReader(b[1:]) - - ot := reflect.TypeOf(out) - if ot.Kind() != reflect.Ptr || ot.Elem().Kind() != reflect.Struct { - return errors.New("out parameter must be a pointer to a struct") - } - - ov := reflect.ValueOf(out).Elem() - for i := 0; i < ot.Elem().NumField(); i++ { - field := ot.Elem().Field(i) - fieldValue := ov.Field(i) - - // If the last field is a byte slice, just read the remaining data into it and return. - if i == ot.Elem().NumField()-1 { - if field.Type.Kind() == reflect.Slice && field.Type.Elem().Kind() == reflect.Uint8 { - data, err := io.ReadAll(r) - if err != nil { - return err - } - fieldValue.SetBytes(data) - return nil - } - } - - if err := binary.Read(r, binary.LittleEndian, fieldValue.Addr().Interface()); err != nil { - return err - } - } - - if statusField := ov.FieldByName("Status"); !statusField.IsZero() { - code := statusField.Interface().(int8) - if code != 0x01 { - return Error{code} - } - } - - return nil -} diff --git a/internal/fusefs/fuse.go b/internal/fusefs/fuse.go deleted file mode 100644 index c36abdc..0000000 --- a/internal/fusefs/fuse.go +++ /dev/null @@ -1,600 +0,0 @@ -package fusefs - -import ( - "bytes" - "context" - "io" - "strconv" - "syscall" - - "github.com/hanwen/go-fuse/v2/fs" - "github.com/hanwen/go-fuse/v2/fuse" - "go.elara.ws/itd/infinitime" - "go.elara.ws/logger/log" -) - -type ITProperty struct { - name string - Ino uint64 - gen func() ([]byte, error) -} - -type DirEntry struct { - isDir bool - modtime uint64 - size uint32 - path string -} - -type ITNode struct { - fs.Inode - kind nodeKind - Ino uint64 - - lst []DirEntry - self DirEntry - path string -} - -type nodeKind uint8 - -const ( - nodeKindRoot = iota - nodeKindInfo - nodeKindFS - nodeKindReadOnly -) - -var ( - myfs *infinitime.FS = nil - inodemap map[string]uint64 = nil -) - -func BuildRootNode(dev *infinitime.Device) (*ITNode, error) { - var err error - inodemap = make(map[string]uint64) - myfs = dev.FS() - if err != nil { - log.Error("FUSE Failed to get filesystem").Err(err).Send() - return nil, err - } - - return &ITNode{kind: nodeKindRoot}, nil -} - -var properties = make([]ITProperty, 6) - -func BuildProperties(dev *infinitime.Device) { - properties[0] = ITProperty{ - "heartrate", 2, - func() ([]byte, error) { - ans, err := dev.HeartRate() - return []byte(strconv.Itoa(int(ans)) + "\n"), err - }, - } - properties[1] = ITProperty{ - "battery", 3, - func() ([]byte, error) { - ans, err := dev.BatteryLevel() - return []byte(strconv.Itoa(int(ans)) + "\n"), err - }, - } - properties[2] = ITProperty{ - "motion", 4, - func() ([]byte, error) { - ans, err := dev.Motion() - return []byte(strconv.Itoa(int(ans.X)) + " " + strconv.Itoa(int(ans.Y)) + " " + strconv.Itoa(int(ans.Z)) + "\n"), err - }, - } - properties[3] = ITProperty{ - "stepcount", 6, - func() ([]byte, error) { - ans, err := dev.StepCount() - return []byte(strconv.Itoa(int(ans)) + "\n"), err - }, - } - properties[4] = ITProperty{ - "version", 7, - func() ([]byte, error) { - ans, err := dev.Version() - return []byte(ans + "\n"), err - }, - } - properties[5] = ITProperty{ - "address", 8, - func() ([]byte, error) { - ans := dev.Address() - return []byte(ans + "\n"), nil - }, - } -} - -var _ fs.NodeReaddirer = (*ITNode)(nil) - -// Readdir is part of the NodeReaddirer interface -func (n *ITNode) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) { - switch n.kind { - case 0: - // root folder - r := make([]fuse.DirEntry, 2) - r[0] = fuse.DirEntry{ - Name: "info", - Ino: 0, - Mode: fuse.S_IFDIR, - } - r[1] = fuse.DirEntry{ - Name: "fs", - Ino: 1, - Mode: fuse.S_IFDIR, - } - return fs.NewListDirStream(r), 0 - - case 1: - // info folder - r := make([]fuse.DirEntry, 6) - for ind, value := range properties { - r[ind] = fuse.DirEntry{ - Name: value.name, - Ino: value.Ino, - Mode: fuse.S_IFREG, - } - } - - return fs.NewListDirStream(r), 0 - - case 2: - // on info - files, err := myfs.ReadDir(n.path) - if err != nil { - log.Error("FUSE ReadDir failed").Str("path", n.path).Err(err).Send() - return nil, syscallErr(err) - } - - log.Debug("FUSE ReadDir succeeded").Str("path", n.path).Int("objects", len(files)).Send() - r := make([]fuse.DirEntry, len(files)) - n.lst = make([]DirEntry, len(files)) - for ind, entry := range files { - info, err := entry.Info() - if err != nil { - log.Error("FUSE Info failed").Str("path", n.path).Err(err).Send() - return nil, syscallErr(err) - } - name := info.Name() - - file := DirEntry{ - path: n.path + "/" + name, - size: uint32(info.Size()), - modtime: uint64(info.ModTime().Unix()), - isDir: info.IsDir(), - } - n.lst[ind] = file - - ino := inodemap[file.path] - if ino == 0 { - ino = uint64(len(inodemap)) + 1 - inodemap[file.path] = ino - } - - if file.isDir { - r[ind] = fuse.DirEntry{ - Name: name, - Mode: fuse.S_IFDIR, - Ino: ino + 10, - } - } else { - r[ind] = fuse.DirEntry{ - Name: name, - Mode: fuse.S_IFREG, - Ino: ino + 10, - } - } - } - return fs.NewListDirStream(r), 0 - } - r := make([]fuse.DirEntry, 0) - return fs.NewListDirStream(r), 0 -} - -var _ fs.NodeLookuper = (*ITNode)(nil) - -func (n *ITNode) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - switch n.kind { - case 0: - // root folder - if name == "info" { - stable := fs.StableAttr{ - Mode: fuse.S_IFDIR, - Ino: uint64(0), - } - operations := &ITNode{kind: nodeKindInfo, Ino: 0} - child := n.NewInode(ctx, operations, stable) - return child, 0 - } else if name == "fs" { - stable := fs.StableAttr{ - Mode: fuse.S_IFDIR, - Ino: uint64(1), - } - operations := &ITNode{kind: nodeKindFS, Ino: 1, path: ""} - child := n.NewInode(ctx, operations, stable) - return child, 0 - } - case 1: - // info folder - for _, value := range properties { - if value.name == name { - stable := fs.StableAttr{ - Mode: fuse.S_IFREG, - Ino: uint64(value.Ino), - } - operations := &ITNode{kind: nodeKindReadOnly, Ino: value.Ino} - child := n.NewInode(ctx, operations, stable) - return child, 0 - } - } - - case 2: - // FS object - if len(n.lst) == 0 { - n.Readdir(ctx) - } - - for _, file := range n.lst { - if file.path != n.path+"/"+name { - continue - } - log.Debug("FUSE Lookup successful").Str("path", file.path).Send() - - if file.isDir { - stable := fs.StableAttr{ - Mode: fuse.S_IFDIR, - Ino: inodemap[file.path], - } - operations := &ITNode{kind: nodeKindFS, path: file.path} - child := n.NewInode(ctx, operations, stable) - return child, 0 - } else { - stable := fs.StableAttr{ - Mode: fuse.S_IFREG, - Ino: inodemap[file.path], - } - operations := &ITNode{ - kind: nodeKindFS, path: file.path, - self: file, - } - child := n.NewInode(ctx, operations, stable) - return child, 0 - } - } - log.Warn("FUSE Lookup failed").Str("path", n.path+"/"+name).Send() - } - return nil, syscall.ENOENT -} - -type bytesFileReadHandle struct { - content []byte -} - -var _ fs.FileReader = (*bytesFileReadHandle)(nil) - -func (fh *bytesFileReadHandle) Read(ctx context.Context, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { - log.Debug("FUSE Executing Read").Int("size", len(fh.content)).Send() - end := off + int64(len(dest)) - if end > int64(len(fh.content)) { - end = int64(len(fh.content)) - } - return fuse.ReadResultData(fh.content[off:end]), 0 -} - -type sensorFileReadHandle struct { - content []byte -} - -var _ fs.FileReader = (*sensorFileReadHandle)(nil) - -func (fh *sensorFileReadHandle) Read(ctx context.Context, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) { - log.Debug("FUSE Executing Read").Int("size", len(fh.content)).Send() - end := off + int64(len(dest)) - if end > int64(len(fh.content)) { - end = int64(len(fh.content)) - } - return fuse.ReadResultData(fh.content[off:end]), 0 -} - -var _ fs.FileFlusher = (*sensorFileReadHandle)(nil) - -func (fh *sensorFileReadHandle) Flush(ctx context.Context) (errno syscall.Errno) { - return 0 -} - -type bytesFileWriteHandle struct { - content []byte - path string -} - -var _ fs.FileWriter = (*bytesFileWriteHandle)(nil) - -func (fh *bytesFileWriteHandle) Write(ctx context.Context, data []byte, off int64) (written uint32, errno syscall.Errno) { - log.Debug("FUSE Executing Write").Str("path", fh.path).Int("prev_size", len(fh.content)).Int("next_size", len(data)).Send() - if off != int64(len(fh.content)) { - log.Error("FUSE Write file size changed unexpectedly").Int("expect", int(off)).Int("received", len(fh.content)).Send() - return 0, syscall.ENXIO - } - fh.content = append(fh.content[:], data[:]...) - return uint32(len(data)), 0 -} - -var _ fs.FileFlusher = (*bytesFileWriteHandle)(nil) - -func (fh *bytesFileWriteHandle) Flush(ctx context.Context) (errno syscall.Errno) { - log.Debug("FUSE Attempting flush").Str("path", fh.path).Send() - fp, err := myfs.Create(fh.path, uint32(len(fh.content))) - if err != nil { - log.Error("FUSE Flush failed: create").Str("path", fh.path).Err(err).Send() - return syscallErr(err) - } - - if len(fh.content) == 0 { - log.Debug("FUSE Flush no data to write").Str("path", fh.path).Send() - err = fp.Close() - if err != nil { - log.Error("FUSE Flush failed during close").Str("path", fh.path).Err(err).Send() - return syscallErr(err) - } - return 0 - } - - fp.ProgressFunc = func(transferred, total uint32) { - log.Debug("FUSE Read progress").Uint32("bytes", transferred).Uint32("total", total).Send() - } - - r := bytes.NewReader(fh.content) - nread, err := io.Copy(fp, r) - if err != nil { - log.Error("FUSE Flush failed during write").Str("path", fh.path).Err(err).Send() - fp.Close() - return syscallErr(err) - } - if int(nread) != len(fh.content) { - log.Error("FUSE Flush failed during write").Str("path", fh.path).Int("expect", len(fh.content)).Int("got", int(nread)).Send() - fp.Close() - return syscall.EIO - } - err = fp.Close() - if err != nil { - log.Error("FUSE Flush failed during close").Str("path", fh.path).Err(err).Send() - return syscallErr(err) - } - log.Debug("FUSE Flush done").Str("path", fh.path).Int("size", len(fh.content)).Send() - - return 0 -} - -var _ fs.FileFsyncer = (*bytesFileWriteHandle)(nil) - -func (fh *bytesFileWriteHandle) Fsync(ctx context.Context, flags uint32) (errno syscall.Errno) { - return fh.Flush(ctx) -} - -var _ fs.NodeGetattrer = (*ITNode)(nil) - -func (bn *ITNode) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) syscall.Errno { - log.Debug("FUSE getattr").Str("path", bn.path).Send() - out.Ino = bn.Ino - out.Mtime = bn.self.modtime - out.Ctime = bn.self.modtime - out.Atime = bn.self.modtime - out.Size = uint64(bn.self.size) - return 0 -} - -var _ fs.NodeSetattrer = (*ITNode)(nil) - -func (bn *ITNode) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno { - log.Debug("FUSE setattr").Str("path", bn.path).Send() - out.Size = 0 - out.Mtime = 0 - return 0 -} - -var _ fs.NodeOpener = (*ITNode)(nil) - -func (f *ITNode) Open(ctx context.Context, openFlags uint32) (fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - switch f.kind { - case 2: - // FS file - if openFlags&syscall.O_RDWR != 0 { - log.Error("FUSE Open failed: RDWR").Str("path", f.path).Send() - return nil, 0, syscall.EROFS - } - - if openFlags&syscall.O_WRONLY != 0 { - log.Debug("FUSE Opening for write").Str("path", f.path).Send() - fh = &bytesFileWriteHandle{ - path: f.path, - content: make([]byte, 0), - } - return fh, fuse.FOPEN_DIRECT_IO, 0 - } else { - log.Debug("FUSE Opening for read").Str("path", f.path).Send() - fp, err := myfs.Open(f.path) - if err != nil { - log.Error("FUSE: Opening failed").Str("path", f.path).Err(err).Send() - return nil, 0, syscallErr(err) - } - - defer fp.Close() - - b := &bytes.Buffer{} - - fp.ProgressFunc = func(transferred, total uint32) { - log.Debug("FUSE Read progress").Uint32("bytes", transferred).Uint32("total", total).Send() - } - - _, err = io.Copy(b, fp) - if err != nil { - log.Error("FUSE Read failed").Str("path", f.path).Err(err).Send() - fp.Close() - return nil, 0, syscallErr(err) - } - - fh = &bytesFileReadHandle{ - content: b.Bytes(), - } - return fh, fuse.FOPEN_DIRECT_IO, 0 - } - - case 3: - // Device file - - // disallow writes - if openFlags&(syscall.O_RDWR|syscall.O_WRONLY) != 0 { - return nil, 0, syscall.EROFS - } - - for _, value := range properties { - if value.Ino == f.Ino { - ans, err := value.gen() - if err != nil { - return nil, 0, syscallErr(err) - } - - fh = &sensorFileReadHandle{ - content: ans, - } - return fh, fuse.FOPEN_DIRECT_IO, 0 - } - } - } - return nil, 0, syscall.EINVAL -} - -var _ fs.NodeCreater = (*ITNode)(nil) - -func (f *ITNode) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (node *fs.Inode, fh fs.FileHandle, fuseFlags uint32, errno syscall.Errno) { - if f.kind != 2 { - return nil, nil, 0, syscall.EROFS - } - - path := f.path + "/" + name - ino := uint64(len(inodemap)) + 11 - inodemap[path] = ino - - stable := fs.StableAttr{ - Mode: fuse.S_IFREG, - Ino: ino, - } - operations := &ITNode{ - kind: nodeKindFS, Ino: ino, - path: path, - } - node = f.NewInode(ctx, operations, stable) - - fh = &bytesFileWriteHandle{ - path: path, - content: make([]byte, 0), - } - - log.Debug("FUSE Creating file").Str("path", path).Send() - - errno = 0 - return node, fh, fuseFlags, 0 -} - -var _ fs.NodeMkdirer = (*ITNode)(nil) - -func (f *ITNode) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) { - if f.kind != 2 { - return nil, syscall.EROFS - } - - path := f.path + "/" + name - err := myfs.Mkdir(path) - if err != nil { - log.Error("FUSE Mkdir failed"). - Str("path", path). - Err(err). - Send() - return nil, syscallErr(err) - } - - ino := uint64(len(inodemap)) + 11 - inodemap[path] = ino - - stable := fs.StableAttr{ - Mode: fuse.S_IFDIR, - Ino: ino, - } - operations := &ITNode{ - kind: nodeKindFS, Ino: ino, - path: path, - } - node := f.NewInode(ctx, operations, stable) - - log.Debug("FUSE Mkdir success"). - Str("path", path). - Int("ino", int(ino)). - Send() - return node, 0 -} - -var _ fs.NodeRenamer = (*ITNode)(nil) - -func (f *ITNode) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) syscall.Errno { - if f.kind != 2 { - return syscall.EROFS - } - - p1 := f.path + "/" + name - p2 := newParent.EmbeddedInode().Path(nil)[2:] + "/" + newName - - err := myfs.Rename(p1, p2) - if err != nil { - log.Error("FUSE Rename failed"). - Str("src", p1). - Str("dest", p2). - Err(err). - Send() - - return syscallErr(err) - } - log.Debug("FUSE Rename sucess"). - Str("src", p1). - Str("dest", p2). - Send() - - ino := inodemap[p1] - delete(inodemap, p1) - inodemap[p2] = ino - - return 0 -} - -var _ fs.NodeUnlinker = (*ITNode)(nil) - -func (f *ITNode) Unlink(ctx context.Context, name string) syscall.Errno { - if f.kind != 2 { - return syscall.EROFS - } - - delete(inodemap, f.path+"/"+name) - err := myfs.Remove(f.path + "/" + name) - if err != nil { - log.Error("FUSE Unlink failed"). - Str("file", f.path+"/"+name). - Err(err). - Send() - - return syscallErr(err) - } - - log.Debug("FUSE Unlink success"). - Str("file", f.path+"/"+name). - Send() - return 0 -} - -var _ fs.NodeRmdirer = (*ITNode)(nil) - -func (f *ITNode) Rmdir(ctx context.Context, name string) syscall.Errno { - return f.Unlink(ctx, name) -} diff --git a/internal/fusefs/syscallerr.go b/internal/fusefs/syscallerr.go deleted file mode 100644 index ae91624..0000000 --- a/internal/fusefs/syscallerr.go +++ /dev/null @@ -1,72 +0,0 @@ -package fusefs - -import ( - "syscall" - - "go.elara.ws/itd/internal/fsproto" -) - -func syscallErr(err error) syscall.Errno { - if err == nil { - return 0 - } - - switch err := err.(type) { - case fsproto.Error: - switch err.Code { - case 0x02: // filesystem error - return syscall.EIO - case 0x05: // read-only filesystem - return syscall.EROFS - case 0x03: // no such file - return syscall.ENOENT - case 0x04: // protocol error - return syscall.EPROTO - case -5: // input/output error - return syscall.EIO - case -84: // filesystem is corrupted - return syscall.ENOTRECOVERABLE - case -2: // no such directory entry - return syscall.ENOENT - case -17: // entry already exists - return syscall.EEXIST - case -20: // entry is not a directory - return syscall.ENOTDIR - case -39: // directory is not empty - return syscall.ENOTEMPTY - case -9: // bad file number - return syscall.EBADF - case -27: // file is too large - return syscall.EFBIG - case -22: // invalid parameter - return syscall.EINVAL - case -28: // no space left on device - return syscall.ENOSPC - case -12: // no more memory available - return syscall.ENOMEM - case -61: // no attr available - return syscall.ENODATA - case -36: // file name is too long - return syscall.ENAMETOOLONG - } - default: - switch err { - case fsproto.ErrFileNotExists: // file does not exist - return syscall.ENOENT - case fsproto.ErrFileReadOnly: // file is read only - return syscall.EACCES - case fsproto.ErrFileWriteOnly: // file is write only - return syscall.EACCES - case fsproto.ErrInvalidOffset: // invalid file offset - return syscall.EINVAL - case fsproto.ErrNoRemoveRoot: // refusing to remove root directory - return syscall.EPERM - case fsproto.ErrFileClosed: // cannot perform operation on closed file - return syscall.EBADF - default: - return syscall.EINVAL - } - } - - return syscall.EIO -} diff --git a/internal/fusefs/unmount.go b/internal/fusefs/unmount.go deleted file mode 100644 index b1fce17..0000000 --- a/internal/fusefs/unmount.go +++ /dev/null @@ -1,17 +0,0 @@ -package fusefs - -import ( - _ "unsafe" - - "github.com/hanwen/go-fuse/v2/fuse" -) - -func Unmount(mountPoint string) error { - return unmount(mountPoint, &fuse.MountOptions{DirectMount: false}) -} - -// Unfortunately, the FUSE library does not export its unmount function, -// so this is required until that changes -// -//go:linkname unmount github.com/hanwen/go-fuse/v2/fuse.unmount -func unmount(mountPoint string, opts *fuse.MountOptions) error diff --git a/internal/rpc/gen.go b/internal/rpc/gen.go deleted file mode 100644 index c13c0ab..0000000 --- a/internal/rpc/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package rpc - -//go:generate protoc --go_out=. --go_opt=paths=source_relative --go-drpc_out=. --go-drpc_opt=paths=source_relative itd.proto diff --git a/internal/rpc/itd.pb.go b/internal/rpc/itd.pb.go deleted file mode 100644 index 9f62a7a..0000000 --- a/internal/rpc/itd.pb.go +++ /dev/null @@ -1,1424 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 -// source: itd.proto - -package rpc - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type FirmwareUpgradeRequest_Type int32 - -const ( - FirmwareUpgradeRequest_Archive FirmwareUpgradeRequest_Type = 0 - FirmwareUpgradeRequest_Files FirmwareUpgradeRequest_Type = 1 -) - -// Enum value maps for FirmwareUpgradeRequest_Type. -var ( - FirmwareUpgradeRequest_Type_name = map[int32]string{ - 0: "Archive", - 1: "Files", - } - FirmwareUpgradeRequest_Type_value = map[string]int32{ - "Archive": 0, - "Files": 1, - } -) - -func (x FirmwareUpgradeRequest_Type) Enum() *FirmwareUpgradeRequest_Type { - p := new(FirmwareUpgradeRequest_Type) - *p = x - return p -} - -func (x FirmwareUpgradeRequest_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (FirmwareUpgradeRequest_Type) Descriptor() protoreflect.EnumDescriptor { - return file_itd_proto_enumTypes[0].Descriptor() -} - -func (FirmwareUpgradeRequest_Type) Type() protoreflect.EnumType { - return &file_itd_proto_enumTypes[0] -} - -func (x FirmwareUpgradeRequest_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use FirmwareUpgradeRequest_Type.Descriptor instead. -func (FirmwareUpgradeRequest_Type) EnumDescriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{6, 0} -} - -type ResourceLoadProgress_Operation int32 - -const ( - ResourceLoadProgress_Upload ResourceLoadProgress_Operation = 0 - ResourceLoadProgress_RemoveObsolete ResourceLoadProgress_Operation = 1 -) - -// Enum value maps for ResourceLoadProgress_Operation. -var ( - ResourceLoadProgress_Operation_name = map[int32]string{ - 0: "Upload", - 1: "RemoveObsolete", - } - ResourceLoadProgress_Operation_value = map[string]int32{ - "Upload": 0, - "RemoveObsolete": 1, - } -) - -func (x ResourceLoadProgress_Operation) Enum() *ResourceLoadProgress_Operation { - p := new(ResourceLoadProgress_Operation) - *p = x - return p -} - -func (x ResourceLoadProgress_Operation) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ResourceLoadProgress_Operation) Descriptor() protoreflect.EnumDescriptor { - return file_itd_proto_enumTypes[1].Descriptor() -} - -func (ResourceLoadProgress_Operation) Type() protoreflect.EnumType { - return &file_itd_proto_enumTypes[1] -} - -func (x ResourceLoadProgress_Operation) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ResourceLoadProgress_Operation.Descriptor instead. -func (ResourceLoadProgress_Operation) EnumDescriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{15, 0} -} - -type Empty struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *Empty) Reset() { - *x = Empty{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{0} -} - -type IntResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *IntResponse) Reset() { - *x = IntResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IntResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IntResponse) ProtoMessage() {} - -func (x *IntResponse) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IntResponse.ProtoReflect.Descriptor instead. -func (*IntResponse) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{1} -} - -func (x *IntResponse) GetValue() uint32 { - if x != nil { - return x.Value - } - return 0 -} - -type StringResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *StringResponse) Reset() { - *x = StringResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StringResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StringResponse) ProtoMessage() {} - -func (x *StringResponse) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StringResponse.ProtoReflect.Descriptor instead. -func (*StringResponse) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{2} -} - -func (x *StringResponse) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -type MotionResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"` - Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"` - Z int32 `protobuf:"varint,3,opt,name=z,proto3" json:"z,omitempty"` -} - -func (x *MotionResponse) Reset() { - *x = MotionResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MotionResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MotionResponse) ProtoMessage() {} - -func (x *MotionResponse) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MotionResponse.ProtoReflect.Descriptor instead. -func (*MotionResponse) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{3} -} - -func (x *MotionResponse) GetX() int32 { - if x != nil { - return x.X - } - return 0 -} - -func (x *MotionResponse) GetY() int32 { - if x != nil { - return x.Y - } - return 0 -} - -func (x *MotionResponse) GetZ() int32 { - if x != nil { - return x.Z - } - return 0 -} - -type NotifyRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` - Body string `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` -} - -func (x *NotifyRequest) Reset() { - *x = NotifyRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NotifyRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NotifyRequest) ProtoMessage() {} - -func (x *NotifyRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NotifyRequest.ProtoReflect.Descriptor instead. -func (*NotifyRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{4} -} - -func (x *NotifyRequest) GetTitle() string { - if x != nil { - return x.Title - } - return "" -} - -func (x *NotifyRequest) GetBody() string { - if x != nil { - return x.Body - } - return "" -} - -type SetTimeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UnixNano int64 `protobuf:"varint,1,opt,name=unix_nano,json=unixNano,proto3" json:"unix_nano,omitempty"` -} - -func (x *SetTimeRequest) Reset() { - *x = SetTimeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SetTimeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetTimeRequest) ProtoMessage() {} - -func (x *SetTimeRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SetTimeRequest.ProtoReflect.Descriptor instead. -func (*SetTimeRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{5} -} - -func (x *SetTimeRequest) GetUnixNano() int64 { - if x != nil { - return x.UnixNano - } - return 0 -} - -type FirmwareUpgradeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type FirmwareUpgradeRequest_Type `protobuf:"varint,1,opt,name=type,proto3,enum=rpc.FirmwareUpgradeRequest_Type" json:"type,omitempty"` - Files []string `protobuf:"bytes,2,rep,name=files,proto3" json:"files,omitempty"` -} - -func (x *FirmwareUpgradeRequest) Reset() { - *x = FirmwareUpgradeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FirmwareUpgradeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FirmwareUpgradeRequest) ProtoMessage() {} - -func (x *FirmwareUpgradeRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FirmwareUpgradeRequest.ProtoReflect.Descriptor instead. -func (*FirmwareUpgradeRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{6} -} - -func (x *FirmwareUpgradeRequest) GetType() FirmwareUpgradeRequest_Type { - if x != nil { - return x.Type - } - return FirmwareUpgradeRequest_Archive -} - -func (x *FirmwareUpgradeRequest) GetFiles() []string { - if x != nil { - return x.Files - } - return nil -} - -type DFUProgress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Sent int64 `protobuf:"varint,1,opt,name=sent,proto3" json:"sent,omitempty"` - Recieved int64 `protobuf:"varint,2,opt,name=recieved,proto3" json:"recieved,omitempty"` - Total int64 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"` -} - -func (x *DFUProgress) Reset() { - *x = DFUProgress{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DFUProgress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DFUProgress) ProtoMessage() {} - -func (x *DFUProgress) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DFUProgress.ProtoReflect.Descriptor instead. -func (*DFUProgress) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{7} -} - -func (x *DFUProgress) GetSent() int64 { - if x != nil { - return x.Sent - } - return 0 -} - -func (x *DFUProgress) GetRecieved() int64 { - if x != nil { - return x.Recieved - } - return 0 -} - -func (x *DFUProgress) GetTotal() int64 { - if x != nil { - return x.Total - } - return 0 -} - -type PathRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` -} - -func (x *PathRequest) Reset() { - *x = PathRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PathRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PathRequest) ProtoMessage() {} - -func (x *PathRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PathRequest.ProtoReflect.Descriptor instead. -func (*PathRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{8} -} - -func (x *PathRequest) GetPath() string { - if x != nil { - return x.Path - } - return "" -} - -type PathsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` -} - -func (x *PathsRequest) Reset() { - *x = PathsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PathsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PathsRequest) ProtoMessage() {} - -func (x *PathsRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PathsRequest.ProtoReflect.Descriptor instead. -func (*PathsRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{9} -} - -func (x *PathsRequest) GetPaths() []string { - if x != nil { - return x.Paths - } - return nil -} - -type RenameRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - From string `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` - To string `protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"` -} - -func (x *RenameRequest) Reset() { - *x = RenameRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RenameRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RenameRequest) ProtoMessage() {} - -func (x *RenameRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RenameRequest.ProtoReflect.Descriptor instead. -func (*RenameRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{10} -} - -func (x *RenameRequest) GetFrom() string { - if x != nil { - return x.From - } - return "" -} - -func (x *RenameRequest) GetTo() string { - if x != nil { - return x.To - } - return "" -} - -type TransferRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` - Destination string `protobuf:"bytes,2,opt,name=destination,proto3" json:"destination,omitempty"` -} - -func (x *TransferRequest) Reset() { - *x = TransferRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TransferRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TransferRequest) ProtoMessage() {} - -func (x *TransferRequest) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TransferRequest.ProtoReflect.Descriptor instead. -func (*TransferRequest) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{11} -} - -func (x *TransferRequest) GetSource() string { - if x != nil { - return x.Source - } - return "" -} - -func (x *TransferRequest) GetDestination() string { - if x != nil { - return x.Destination - } - return "" -} - -type FileInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` - IsDir bool `protobuf:"varint,3,opt,name=is_dir,json=isDir,proto3" json:"is_dir,omitempty"` -} - -func (x *FileInfo) Reset() { - *x = FileInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FileInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FileInfo) ProtoMessage() {} - -func (x *FileInfo) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FileInfo.ProtoReflect.Descriptor instead. -func (*FileInfo) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{12} -} - -func (x *FileInfo) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *FileInfo) GetSize() int64 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *FileInfo) GetIsDir() bool { - if x != nil { - return x.IsDir - } - return false -} - -type DirResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Entries []*FileInfo `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` -} - -func (x *DirResponse) Reset() { - *x = DirResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DirResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DirResponse) ProtoMessage() {} - -func (x *DirResponse) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DirResponse.ProtoReflect.Descriptor instead. -func (*DirResponse) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{13} -} - -func (x *DirResponse) GetEntries() []*FileInfo { - if x != nil { - return x.Entries - } - return nil -} - -type TransferProgress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Sent uint32 `protobuf:"varint,1,opt,name=sent,proto3" json:"sent,omitempty"` - Total uint32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` -} - -func (x *TransferProgress) Reset() { - *x = TransferProgress{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TransferProgress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TransferProgress) ProtoMessage() {} - -func (x *TransferProgress) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TransferProgress.ProtoReflect.Descriptor instead. -func (*TransferProgress) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{14} -} - -func (x *TransferProgress) GetSent() uint32 { - if x != nil { - return x.Sent - } - return 0 -} - -func (x *TransferProgress) GetTotal() uint32 { - if x != nil { - return x.Total - } - return 0 -} - -type ResourceLoadProgress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Total int64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` - Sent int64 `protobuf:"varint,3,opt,name=sent,proto3" json:"sent,omitempty"` - Operation ResourceLoadProgress_Operation `protobuf:"varint,4,opt,name=operation,proto3,enum=rpc.ResourceLoadProgress_Operation" json:"operation,omitempty"` -} - -func (x *ResourceLoadProgress) Reset() { - *x = ResourceLoadProgress{} - if protoimpl.UnsafeEnabled { - mi := &file_itd_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResourceLoadProgress) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResourceLoadProgress) ProtoMessage() {} - -func (x *ResourceLoadProgress) ProtoReflect() protoreflect.Message { - mi := &file_itd_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResourceLoadProgress.ProtoReflect.Descriptor instead. -func (*ResourceLoadProgress) Descriptor() ([]byte, []int) { - return file_itd_proto_rawDescGZIP(), []int{15} -} - -func (x *ResourceLoadProgress) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ResourceLoadProgress) GetTotal() int64 { - if x != nil { - return x.Total - } - return 0 -} - -func (x *ResourceLoadProgress) GetSent() int64 { - if x != nil { - return x.Sent - } - return 0 -} - -func (x *ResourceLoadProgress) GetOperation() ResourceLoadProgress_Operation { - if x != nil { - return x.Operation - } - return ResourceLoadProgress_Upload -} - -var File_itd_proto protoreflect.FileDescriptor - -var file_itd_proto_rawDesc = []byte{ - 0x0a, 0x09, 0x69, 0x74, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x72, 0x70, 0x63, - 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x23, 0x0a, 0x0b, 0x49, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, - 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x0a, 0x0e, 0x4d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x01, 0x79, 0x12, 0x0c, 0x0a, 0x01, 0x7a, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x01, 0x7a, 0x22, 0x39, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x2d, 0x0a, - 0x0e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x75, 0x6e, 0x69, 0x78, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x78, 0x4e, 0x61, 0x6e, 0x6f, 0x22, 0x84, 0x01, 0x0a, - 0x16, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x72, 0x6d, - 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x41, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x10, 0x01, 0x22, 0x53, 0x0a, 0x0b, 0x44, 0x46, 0x55, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x69, 0x65, 0x76, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x72, 0x65, 0x63, 0x69, 0x65, 0x76, - 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x21, 0x0a, 0x0b, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x24, 0x0a, 0x0c, 0x50, - 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, - 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, - 0x73, 0x22, 0x33, 0x0a, 0x0d, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x49, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x73, 0x5f, 0x64, 0x69, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x69, 0x73, 0x44, 0x69, 0x72, 0x22, 0x36, - 0x0a, 0x0b, 0x44, 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, - 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x65, - 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x3c, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, - 0x65, 0x72, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, - 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xc4, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x09, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, - 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x6f, 0x61, - 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2b, - 0x0a, 0x09, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x4f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x01, 0x32, 0x9a, 0x05, 0x0a, 0x03, - 0x49, 0x54, 0x44, 0x12, 0x29, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x52, 0x61, 0x74, 0x65, - 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, - 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x48, 0x65, 0x61, 0x72, 0x74, 0x52, 0x61, 0x74, 0x65, - 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x2c, 0x0a, 0x0c, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, - 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, - 0x0a, 0x11, 0x57, 0x61, 0x74, 0x63, 0x68, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x30, 0x01, 0x12, 0x29, 0x0a, 0x06, 0x4d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x4d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, - 0x0a, 0x0b, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x4d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x29, 0x0a, 0x09, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x0e, 0x57, - 0x61, 0x74, 0x63, 0x68, 0x53, 0x74, 0x65, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x0a, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, - 0x49, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x2a, 0x0a, - 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, - 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x2a, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x0d, 0x57, - 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x0a, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0f, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, - 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x1b, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x46, 0x69, - 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x46, 0x55, 0x50, 0x72, - 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x30, 0x01, 0x32, 0xb9, 0x03, 0x0a, 0x02, 0x46, 0x53, 0x12, - 0x2a, 0x0a, 0x09, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x12, 0x11, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x06, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x28, 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, - 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x29, - 0x0a, 0x08, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x41, 0x6c, 0x6c, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, - 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, - 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x4d, 0x6b, 0x64, - 0x69, 0x72, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0a, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x2d, 0x0a, 0x07, 0x52, 0x65, 0x61, 0x64, 0x44, 0x69, 0x72, 0x12, 0x10, 0x2e, 0x72, - 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, - 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x37, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, - 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x50, - 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x08, 0x44, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, - 0x63, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x30, 0x01, 0x12, 0x3e, 0x0a, 0x0d, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x30, 0x01, 0x42, 0x20, 0x5a, 0x1e, 0x67, 0x6f, 0x2e, 0x61, 0x72, 0x73, 0x65, 0x6e, - 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x69, 0x74, 0x64, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_itd_proto_rawDescOnce sync.Once - file_itd_proto_rawDescData = file_itd_proto_rawDesc -) - -func file_itd_proto_rawDescGZIP() []byte { - file_itd_proto_rawDescOnce.Do(func() { - file_itd_proto_rawDescData = protoimpl.X.CompressGZIP(file_itd_proto_rawDescData) - }) - return file_itd_proto_rawDescData -} - -var file_itd_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_itd_proto_msgTypes = make([]protoimpl.MessageInfo, 16) -var file_itd_proto_goTypes = []interface{}{ - (FirmwareUpgradeRequest_Type)(0), // 0: rpc.FirmwareUpgradeRequest.Type - (ResourceLoadProgress_Operation)(0), // 1: rpc.ResourceLoadProgress.Operation - (*Empty)(nil), // 2: rpc.Empty - (*IntResponse)(nil), // 3: rpc.IntResponse - (*StringResponse)(nil), // 4: rpc.StringResponse - (*MotionResponse)(nil), // 5: rpc.MotionResponse - (*NotifyRequest)(nil), // 6: rpc.NotifyRequest - (*SetTimeRequest)(nil), // 7: rpc.SetTimeRequest - (*FirmwareUpgradeRequest)(nil), // 8: rpc.FirmwareUpgradeRequest - (*DFUProgress)(nil), // 9: rpc.DFUProgress - (*PathRequest)(nil), // 10: rpc.PathRequest - (*PathsRequest)(nil), // 11: rpc.PathsRequest - (*RenameRequest)(nil), // 12: rpc.RenameRequest - (*TransferRequest)(nil), // 13: rpc.TransferRequest - (*FileInfo)(nil), // 14: rpc.FileInfo - (*DirResponse)(nil), // 15: rpc.DirResponse - (*TransferProgress)(nil), // 16: rpc.TransferProgress - (*ResourceLoadProgress)(nil), // 17: rpc.ResourceLoadProgress -} -var file_itd_proto_depIdxs = []int32{ - 0, // 0: rpc.FirmwareUpgradeRequest.type:type_name -> rpc.FirmwareUpgradeRequest.Type - 14, // 1: rpc.DirResponse.entries:type_name -> rpc.FileInfo - 1, // 2: rpc.ResourceLoadProgress.operation:type_name -> rpc.ResourceLoadProgress.Operation - 2, // 3: rpc.ITD.HeartRate:input_type -> rpc.Empty - 2, // 4: rpc.ITD.WatchHeartRate:input_type -> rpc.Empty - 2, // 5: rpc.ITD.BatteryLevel:input_type -> rpc.Empty - 2, // 6: rpc.ITD.WatchBatteryLevel:input_type -> rpc.Empty - 2, // 7: rpc.ITD.Motion:input_type -> rpc.Empty - 2, // 8: rpc.ITD.WatchMotion:input_type -> rpc.Empty - 2, // 9: rpc.ITD.StepCount:input_type -> rpc.Empty - 2, // 10: rpc.ITD.WatchStepCount:input_type -> rpc.Empty - 2, // 11: rpc.ITD.Version:input_type -> rpc.Empty - 2, // 12: rpc.ITD.Address:input_type -> rpc.Empty - 6, // 13: rpc.ITD.Notify:input_type -> rpc.NotifyRequest - 7, // 14: rpc.ITD.SetTime:input_type -> rpc.SetTimeRequest - 2, // 15: rpc.ITD.WeatherUpdate:input_type -> rpc.Empty - 8, // 16: rpc.ITD.FirmwareUpgrade:input_type -> rpc.FirmwareUpgradeRequest - 11, // 17: rpc.FS.RemoveAll:input_type -> rpc.PathsRequest - 11, // 18: rpc.FS.Remove:input_type -> rpc.PathsRequest - 12, // 19: rpc.FS.Rename:input_type -> rpc.RenameRequest - 11, // 20: rpc.FS.MkdirAll:input_type -> rpc.PathsRequest - 11, // 21: rpc.FS.Mkdir:input_type -> rpc.PathsRequest - 10, // 22: rpc.FS.ReadDir:input_type -> rpc.PathRequest - 13, // 23: rpc.FS.Upload:input_type -> rpc.TransferRequest - 13, // 24: rpc.FS.Download:input_type -> rpc.TransferRequest - 10, // 25: rpc.FS.LoadResources:input_type -> rpc.PathRequest - 3, // 26: rpc.ITD.HeartRate:output_type -> rpc.IntResponse - 3, // 27: rpc.ITD.WatchHeartRate:output_type -> rpc.IntResponse - 3, // 28: rpc.ITD.BatteryLevel:output_type -> rpc.IntResponse - 3, // 29: rpc.ITD.WatchBatteryLevel:output_type -> rpc.IntResponse - 5, // 30: rpc.ITD.Motion:output_type -> rpc.MotionResponse - 5, // 31: rpc.ITD.WatchMotion:output_type -> rpc.MotionResponse - 3, // 32: rpc.ITD.StepCount:output_type -> rpc.IntResponse - 3, // 33: rpc.ITD.WatchStepCount:output_type -> rpc.IntResponse - 4, // 34: rpc.ITD.Version:output_type -> rpc.StringResponse - 4, // 35: rpc.ITD.Address:output_type -> rpc.StringResponse - 2, // 36: rpc.ITD.Notify:output_type -> rpc.Empty - 2, // 37: rpc.ITD.SetTime:output_type -> rpc.Empty - 2, // 38: rpc.ITD.WeatherUpdate:output_type -> rpc.Empty - 9, // 39: rpc.ITD.FirmwareUpgrade:output_type -> rpc.DFUProgress - 2, // 40: rpc.FS.RemoveAll:output_type -> rpc.Empty - 2, // 41: rpc.FS.Remove:output_type -> rpc.Empty - 2, // 42: rpc.FS.Rename:output_type -> rpc.Empty - 2, // 43: rpc.FS.MkdirAll:output_type -> rpc.Empty - 2, // 44: rpc.FS.Mkdir:output_type -> rpc.Empty - 15, // 45: rpc.FS.ReadDir:output_type -> rpc.DirResponse - 16, // 46: rpc.FS.Upload:output_type -> rpc.TransferProgress - 16, // 47: rpc.FS.Download:output_type -> rpc.TransferProgress - 17, // 48: rpc.FS.LoadResources:output_type -> rpc.ResourceLoadProgress - 26, // [26:49] is the sub-list for method output_type - 3, // [3:26] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_itd_proto_init() } -func file_itd_proto_init() { - if File_itd_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_itd_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Empty); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MotionResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NotifyRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SetTimeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FirmwareUpgradeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DFUProgress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PathsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RenameRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransferRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FileInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DirResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransferProgress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_itd_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceLoadProgress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_itd_proto_rawDesc, - NumEnums: 2, - NumMessages: 16, - NumExtensions: 0, - NumServices: 2, - }, - GoTypes: file_itd_proto_goTypes, - DependencyIndexes: file_itd_proto_depIdxs, - EnumInfos: file_itd_proto_enumTypes, - MessageInfos: file_itd_proto_msgTypes, - }.Build() - File_itd_proto = out.File - file_itd_proto_rawDesc = nil - file_itd_proto_goTypes = nil - file_itd_proto_depIdxs = nil -} diff --git a/internal/rpc/itd.proto b/internal/rpc/itd.proto deleted file mode 100644 index 15fdaaa..0000000 --- a/internal/rpc/itd.proto +++ /dev/null @@ -1,124 +0,0 @@ -syntax = "proto3"; -package rpc; -option go_package = "go.arsenm.dev/itd/internal/rpc"; - -message Empty {}; - -message IntResponse { - uint32 value = 1; -} - -message StringResponse { - string value = 1; -} - -message MotionResponse { - int32 x = 1; - int32 y = 2; - int32 z = 3; -} - -message NotifyRequest { - string title = 1; - string body = 2; -} - -message SetTimeRequest { - int64 unix_nano = 1; -} - - -message FirmwareUpgradeRequest { - enum Type { - Archive = 0; - Files = 1; - } - - Type type = 1; - repeated string files = 2; -} - -message DFUProgress { - int64 sent = 1; - int64 recieved = 2; - int64 total = 3; -} - -service ITD { - rpc HeartRate(Empty) returns (IntResponse); - rpc WatchHeartRate(Empty) returns (stream IntResponse); - - rpc BatteryLevel(Empty) returns (IntResponse); - rpc WatchBatteryLevel(Empty) returns (stream IntResponse); - - rpc Motion(Empty) returns (MotionResponse); - rpc WatchMotion(Empty) returns (stream MotionResponse); - - rpc StepCount(Empty) returns (IntResponse); - rpc WatchStepCount(Empty) returns (stream IntResponse); - - rpc Version(Empty) returns (StringResponse); - rpc Address(Empty) returns (StringResponse); - - rpc Notify(NotifyRequest) returns (Empty); - rpc SetTime(SetTimeRequest) returns (Empty); - rpc WeatherUpdate(Empty) returns (Empty); - rpc FirmwareUpgrade(FirmwareUpgradeRequest) returns (stream DFUProgress); -} - -message PathRequest { - string path = 1; -} - -message PathsRequest { - repeated string paths = 1; -} - -message RenameRequest { - string from = 1; - string to = 2; -} - -message TransferRequest { - string source = 1; - string destination = 2; -} - -message FileInfo { - string name = 1; - int64 size = 2; - bool is_dir = 3; -} - -message DirResponse { - repeated FileInfo entries = 1; -} - -message TransferProgress { - uint32 sent = 1; - uint32 total = 2; -} - -message ResourceLoadProgress { - enum Operation { - Upload = 0; - RemoveObsolete = 1; - } - - string name = 1; - int64 total = 2; - int64 sent = 3; - Operation operation = 4; -} - -service FS { - rpc RemoveAll(PathsRequest) returns (Empty); - rpc Remove(PathsRequest) returns (Empty); - rpc Rename(RenameRequest) returns (Empty); - rpc MkdirAll(PathsRequest) returns (Empty); - rpc Mkdir(PathsRequest) returns (Empty); - rpc ReadDir(PathRequest) returns (DirResponse); - rpc Upload(TransferRequest) returns (stream TransferProgress); - rpc Download(TransferRequest) returns (stream TransferProgress); - rpc LoadResources(PathRequest) returns (stream ResourceLoadProgress); -} \ No newline at end of file diff --git a/internal/rpc/itd_drpc.pb.go b/internal/rpc/itd_drpc.pb.go deleted file mode 100644 index e043a90..0000000 --- a/internal/rpc/itd_drpc.pb.go +++ /dev/null @@ -1,1218 +0,0 @@ -// Code generated by protoc-gen-go-drpc. DO NOT EDIT. -// protoc-gen-go-drpc version: v0.0.32 -// source: itd.proto - -package rpc - -import ( - context "context" - errors "errors" - protojson "google.golang.org/protobuf/encoding/protojson" - proto "google.golang.org/protobuf/proto" - drpc "storj.io/drpc" - drpcerr "storj.io/drpc/drpcerr" -) - -type drpcEncoding_File_itd_proto struct{} - -func (drpcEncoding_File_itd_proto) Marshal(msg drpc.Message) ([]byte, error) { - return proto.Marshal(msg.(proto.Message)) -} - -func (drpcEncoding_File_itd_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) { - return proto.MarshalOptions{}.MarshalAppend(buf, msg.(proto.Message)) -} - -func (drpcEncoding_File_itd_proto) Unmarshal(buf []byte, msg drpc.Message) error { - return proto.Unmarshal(buf, msg.(proto.Message)) -} - -func (drpcEncoding_File_itd_proto) JSONMarshal(msg drpc.Message) ([]byte, error) { - return protojson.Marshal(msg.(proto.Message)) -} - -func (drpcEncoding_File_itd_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error { - return protojson.Unmarshal(buf, msg.(proto.Message)) -} - -type DRPCITDClient interface { - DRPCConn() drpc.Conn - - HeartRate(ctx context.Context, in *Empty) (*IntResponse, error) - WatchHeartRate(ctx context.Context, in *Empty) (DRPCITD_WatchHeartRateClient, error) - BatteryLevel(ctx context.Context, in *Empty) (*IntResponse, error) - WatchBatteryLevel(ctx context.Context, in *Empty) (DRPCITD_WatchBatteryLevelClient, error) - Motion(ctx context.Context, in *Empty) (*MotionResponse, error) - WatchMotion(ctx context.Context, in *Empty) (DRPCITD_WatchMotionClient, error) - StepCount(ctx context.Context, in *Empty) (*IntResponse, error) - WatchStepCount(ctx context.Context, in *Empty) (DRPCITD_WatchStepCountClient, error) - Version(ctx context.Context, in *Empty) (*StringResponse, error) - Address(ctx context.Context, in *Empty) (*StringResponse, error) - Notify(ctx context.Context, in *NotifyRequest) (*Empty, error) - SetTime(ctx context.Context, in *SetTimeRequest) (*Empty, error) - WeatherUpdate(ctx context.Context, in *Empty) (*Empty, error) - FirmwareUpgrade(ctx context.Context, in *FirmwareUpgradeRequest) (DRPCITD_FirmwareUpgradeClient, error) -} - -type drpcITDClient struct { - cc drpc.Conn -} - -func NewDRPCITDClient(cc drpc.Conn) DRPCITDClient { - return &drpcITDClient{cc} -} - -func (c *drpcITDClient) DRPCConn() drpc.Conn { return c.cc } - -func (c *drpcITDClient) HeartRate(ctx context.Context, in *Empty) (*IntResponse, error) { - out := new(IntResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/HeartRate", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) WatchHeartRate(ctx context.Context, in *Empty) (DRPCITD_WatchHeartRateClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.ITD/WatchHeartRate", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcITD_WatchHeartRateClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCITD_WatchHeartRateClient interface { - drpc.Stream - Recv() (*IntResponse, error) -} - -type drpcITD_WatchHeartRateClient struct { - drpc.Stream -} - -func (x *drpcITD_WatchHeartRateClient) Recv() (*IntResponse, error) { - m := new(IntResponse) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcITD_WatchHeartRateClient) RecvMsg(m *IntResponse) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcITDClient) BatteryLevel(ctx context.Context, in *Empty) (*IntResponse, error) { - out := new(IntResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/BatteryLevel", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) WatchBatteryLevel(ctx context.Context, in *Empty) (DRPCITD_WatchBatteryLevelClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.ITD/WatchBatteryLevel", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcITD_WatchBatteryLevelClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCITD_WatchBatteryLevelClient interface { - drpc.Stream - Recv() (*IntResponse, error) -} - -type drpcITD_WatchBatteryLevelClient struct { - drpc.Stream -} - -func (x *drpcITD_WatchBatteryLevelClient) Recv() (*IntResponse, error) { - m := new(IntResponse) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcITD_WatchBatteryLevelClient) RecvMsg(m *IntResponse) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcITDClient) Motion(ctx context.Context, in *Empty) (*MotionResponse, error) { - out := new(MotionResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/Motion", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) WatchMotion(ctx context.Context, in *Empty) (DRPCITD_WatchMotionClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.ITD/WatchMotion", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcITD_WatchMotionClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCITD_WatchMotionClient interface { - drpc.Stream - Recv() (*MotionResponse, error) -} - -type drpcITD_WatchMotionClient struct { - drpc.Stream -} - -func (x *drpcITD_WatchMotionClient) Recv() (*MotionResponse, error) { - m := new(MotionResponse) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcITD_WatchMotionClient) RecvMsg(m *MotionResponse) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcITDClient) StepCount(ctx context.Context, in *Empty) (*IntResponse, error) { - out := new(IntResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/StepCount", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) WatchStepCount(ctx context.Context, in *Empty) (DRPCITD_WatchStepCountClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.ITD/WatchStepCount", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcITD_WatchStepCountClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCITD_WatchStepCountClient interface { - drpc.Stream - Recv() (*IntResponse, error) -} - -type drpcITD_WatchStepCountClient struct { - drpc.Stream -} - -func (x *drpcITD_WatchStepCountClient) Recv() (*IntResponse, error) { - m := new(IntResponse) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcITD_WatchStepCountClient) RecvMsg(m *IntResponse) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcITDClient) Version(ctx context.Context, in *Empty) (*StringResponse, error) { - out := new(StringResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/Version", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) Address(ctx context.Context, in *Empty) (*StringResponse, error) { - out := new(StringResponse) - err := c.cc.Invoke(ctx, "/rpc.ITD/Address", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) Notify(ctx context.Context, in *NotifyRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.ITD/Notify", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) SetTime(ctx context.Context, in *SetTimeRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.ITD/SetTime", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) WeatherUpdate(ctx context.Context, in *Empty) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.ITD/WeatherUpdate", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcITDClient) FirmwareUpgrade(ctx context.Context, in *FirmwareUpgradeRequest) (DRPCITD_FirmwareUpgradeClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.ITD/FirmwareUpgrade", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcITD_FirmwareUpgradeClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCITD_FirmwareUpgradeClient interface { - drpc.Stream - Recv() (*DFUProgress, error) -} - -type drpcITD_FirmwareUpgradeClient struct { - drpc.Stream -} - -func (x *drpcITD_FirmwareUpgradeClient) Recv() (*DFUProgress, error) { - m := new(DFUProgress) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcITD_FirmwareUpgradeClient) RecvMsg(m *DFUProgress) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCITDServer interface { - HeartRate(context.Context, *Empty) (*IntResponse, error) - WatchHeartRate(*Empty, DRPCITD_WatchHeartRateStream) error - BatteryLevel(context.Context, *Empty) (*IntResponse, error) - WatchBatteryLevel(*Empty, DRPCITD_WatchBatteryLevelStream) error - Motion(context.Context, *Empty) (*MotionResponse, error) - WatchMotion(*Empty, DRPCITD_WatchMotionStream) error - StepCount(context.Context, *Empty) (*IntResponse, error) - WatchStepCount(*Empty, DRPCITD_WatchStepCountStream) error - Version(context.Context, *Empty) (*StringResponse, error) - Address(context.Context, *Empty) (*StringResponse, error) - Notify(context.Context, *NotifyRequest) (*Empty, error) - SetTime(context.Context, *SetTimeRequest) (*Empty, error) - WeatherUpdate(context.Context, *Empty) (*Empty, error) - FirmwareUpgrade(*FirmwareUpgradeRequest, DRPCITD_FirmwareUpgradeStream) error -} - -type DRPCITDUnimplementedServer struct{} - -func (s *DRPCITDUnimplementedServer) HeartRate(context.Context, *Empty) (*IntResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) WatchHeartRate(*Empty, DRPCITD_WatchHeartRateStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) BatteryLevel(context.Context, *Empty) (*IntResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) WatchBatteryLevel(*Empty, DRPCITD_WatchBatteryLevelStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) Motion(context.Context, *Empty) (*MotionResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) WatchMotion(*Empty, DRPCITD_WatchMotionStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) StepCount(context.Context, *Empty) (*IntResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) WatchStepCount(*Empty, DRPCITD_WatchStepCountStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) Version(context.Context, *Empty) (*StringResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) Address(context.Context, *Empty) (*StringResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) Notify(context.Context, *NotifyRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) SetTime(context.Context, *SetTimeRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) WeatherUpdate(context.Context, *Empty) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCITDUnimplementedServer) FirmwareUpgrade(*FirmwareUpgradeRequest, DRPCITD_FirmwareUpgradeStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -type DRPCITDDescription struct{} - -func (DRPCITDDescription) NumMethods() int { return 14 } - -func (DRPCITDDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { - switch n { - case 0: - return "/rpc.ITD/HeartRate", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - HeartRate( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.HeartRate, true - case 1: - return "/rpc.ITD/WatchHeartRate", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCITDServer). - WatchHeartRate( - in1.(*Empty), - &drpcITD_WatchHeartRateStream{in2.(drpc.Stream)}, - ) - }, DRPCITDServer.WatchHeartRate, true - case 2: - return "/rpc.ITD/BatteryLevel", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - BatteryLevel( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.BatteryLevel, true - case 3: - return "/rpc.ITD/WatchBatteryLevel", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCITDServer). - WatchBatteryLevel( - in1.(*Empty), - &drpcITD_WatchBatteryLevelStream{in2.(drpc.Stream)}, - ) - }, DRPCITDServer.WatchBatteryLevel, true - case 4: - return "/rpc.ITD/Motion", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - Motion( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.Motion, true - case 5: - return "/rpc.ITD/WatchMotion", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCITDServer). - WatchMotion( - in1.(*Empty), - &drpcITD_WatchMotionStream{in2.(drpc.Stream)}, - ) - }, DRPCITDServer.WatchMotion, true - case 6: - return "/rpc.ITD/StepCount", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - StepCount( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.StepCount, true - case 7: - return "/rpc.ITD/WatchStepCount", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCITDServer). - WatchStepCount( - in1.(*Empty), - &drpcITD_WatchStepCountStream{in2.(drpc.Stream)}, - ) - }, DRPCITDServer.WatchStepCount, true - case 8: - return "/rpc.ITD/Version", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - Version( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.Version, true - case 9: - return "/rpc.ITD/Address", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - Address( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.Address, true - case 10: - return "/rpc.ITD/Notify", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - Notify( - ctx, - in1.(*NotifyRequest), - ) - }, DRPCITDServer.Notify, true - case 11: - return "/rpc.ITD/SetTime", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - SetTime( - ctx, - in1.(*SetTimeRequest), - ) - }, DRPCITDServer.SetTime, true - case 12: - return "/rpc.ITD/WeatherUpdate", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCITDServer). - WeatherUpdate( - ctx, - in1.(*Empty), - ) - }, DRPCITDServer.WeatherUpdate, true - case 13: - return "/rpc.ITD/FirmwareUpgrade", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCITDServer). - FirmwareUpgrade( - in1.(*FirmwareUpgradeRequest), - &drpcITD_FirmwareUpgradeStream{in2.(drpc.Stream)}, - ) - }, DRPCITDServer.FirmwareUpgrade, true - default: - return "", nil, nil, nil, false - } -} - -func DRPCRegisterITD(mux drpc.Mux, impl DRPCITDServer) error { - return mux.Register(impl, DRPCITDDescription{}) -} - -type DRPCITD_HeartRateStream interface { - drpc.Stream - SendAndClose(*IntResponse) error -} - -type drpcITD_HeartRateStream struct { - drpc.Stream -} - -func (x *drpcITD_HeartRateStream) SendAndClose(m *IntResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_WatchHeartRateStream interface { - drpc.Stream - Send(*IntResponse) error -} - -type drpcITD_WatchHeartRateStream struct { - drpc.Stream -} - -func (x *drpcITD_WatchHeartRateStream) Send(m *IntResponse) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCITD_BatteryLevelStream interface { - drpc.Stream - SendAndClose(*IntResponse) error -} - -type drpcITD_BatteryLevelStream struct { - drpc.Stream -} - -func (x *drpcITD_BatteryLevelStream) SendAndClose(m *IntResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_WatchBatteryLevelStream interface { - drpc.Stream - Send(*IntResponse) error -} - -type drpcITD_WatchBatteryLevelStream struct { - drpc.Stream -} - -func (x *drpcITD_WatchBatteryLevelStream) Send(m *IntResponse) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCITD_MotionStream interface { - drpc.Stream - SendAndClose(*MotionResponse) error -} - -type drpcITD_MotionStream struct { - drpc.Stream -} - -func (x *drpcITD_MotionStream) SendAndClose(m *MotionResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_WatchMotionStream interface { - drpc.Stream - Send(*MotionResponse) error -} - -type drpcITD_WatchMotionStream struct { - drpc.Stream -} - -func (x *drpcITD_WatchMotionStream) Send(m *MotionResponse) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCITD_StepCountStream interface { - drpc.Stream - SendAndClose(*IntResponse) error -} - -type drpcITD_StepCountStream struct { - drpc.Stream -} - -func (x *drpcITD_StepCountStream) SendAndClose(m *IntResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_WatchStepCountStream interface { - drpc.Stream - Send(*IntResponse) error -} - -type drpcITD_WatchStepCountStream struct { - drpc.Stream -} - -func (x *drpcITD_WatchStepCountStream) Send(m *IntResponse) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCITD_VersionStream interface { - drpc.Stream - SendAndClose(*StringResponse) error -} - -type drpcITD_VersionStream struct { - drpc.Stream -} - -func (x *drpcITD_VersionStream) SendAndClose(m *StringResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_AddressStream interface { - drpc.Stream - SendAndClose(*StringResponse) error -} - -type drpcITD_AddressStream struct { - drpc.Stream -} - -func (x *drpcITD_AddressStream) SendAndClose(m *StringResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_NotifyStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcITD_NotifyStream struct { - drpc.Stream -} - -func (x *drpcITD_NotifyStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_SetTimeStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcITD_SetTimeStream struct { - drpc.Stream -} - -func (x *drpcITD_SetTimeStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_WeatherUpdateStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcITD_WeatherUpdateStream struct { - drpc.Stream -} - -func (x *drpcITD_WeatherUpdateStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCITD_FirmwareUpgradeStream interface { - drpc.Stream - Send(*DFUProgress) error -} - -type drpcITD_FirmwareUpgradeStream struct { - drpc.Stream -} - -func (x *drpcITD_FirmwareUpgradeStream) Send(m *DFUProgress) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCFSClient interface { - DRPCConn() drpc.Conn - - RemoveAll(ctx context.Context, in *PathsRequest) (*Empty, error) - Remove(ctx context.Context, in *PathsRequest) (*Empty, error) - Rename(ctx context.Context, in *RenameRequest) (*Empty, error) - MkdirAll(ctx context.Context, in *PathsRequest) (*Empty, error) - Mkdir(ctx context.Context, in *PathsRequest) (*Empty, error) - ReadDir(ctx context.Context, in *PathRequest) (*DirResponse, error) - Upload(ctx context.Context, in *TransferRequest) (DRPCFS_UploadClient, error) - Download(ctx context.Context, in *TransferRequest) (DRPCFS_DownloadClient, error) - LoadResources(ctx context.Context, in *PathRequest) (DRPCFS_LoadResourcesClient, error) -} - -type drpcFSClient struct { - cc drpc.Conn -} - -func NewDRPCFSClient(cc drpc.Conn) DRPCFSClient { - return &drpcFSClient{cc} -} - -func (c *drpcFSClient) DRPCConn() drpc.Conn { return c.cc } - -func (c *drpcFSClient) RemoveAll(ctx context.Context, in *PathsRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.FS/RemoveAll", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) Remove(ctx context.Context, in *PathsRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.FS/Remove", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) Rename(ctx context.Context, in *RenameRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.FS/Rename", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) MkdirAll(ctx context.Context, in *PathsRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.FS/MkdirAll", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) Mkdir(ctx context.Context, in *PathsRequest) (*Empty, error) { - out := new(Empty) - err := c.cc.Invoke(ctx, "/rpc.FS/Mkdir", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) ReadDir(ctx context.Context, in *PathRequest) (*DirResponse, error) { - out := new(DirResponse) - err := c.cc.Invoke(ctx, "/rpc.FS/ReadDir", drpcEncoding_File_itd_proto{}, in, out) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *drpcFSClient) Upload(ctx context.Context, in *TransferRequest) (DRPCFS_UploadClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.FS/Upload", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcFS_UploadClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCFS_UploadClient interface { - drpc.Stream - Recv() (*TransferProgress, error) -} - -type drpcFS_UploadClient struct { - drpc.Stream -} - -func (x *drpcFS_UploadClient) Recv() (*TransferProgress, error) { - m := new(TransferProgress) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcFS_UploadClient) RecvMsg(m *TransferProgress) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcFSClient) Download(ctx context.Context, in *TransferRequest) (DRPCFS_DownloadClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.FS/Download", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcFS_DownloadClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCFS_DownloadClient interface { - drpc.Stream - Recv() (*TransferProgress, error) -} - -type drpcFS_DownloadClient struct { - drpc.Stream -} - -func (x *drpcFS_DownloadClient) Recv() (*TransferProgress, error) { - m := new(TransferProgress) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcFS_DownloadClient) RecvMsg(m *TransferProgress) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -func (c *drpcFSClient) LoadResources(ctx context.Context, in *PathRequest) (DRPCFS_LoadResourcesClient, error) { - stream, err := c.cc.NewStream(ctx, "/rpc.FS/LoadResources", drpcEncoding_File_itd_proto{}) - if err != nil { - return nil, err - } - x := &drpcFS_LoadResourcesClient{stream} - if err := x.MsgSend(in, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - if err := x.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type DRPCFS_LoadResourcesClient interface { - drpc.Stream - Recv() (*ResourceLoadProgress, error) -} - -type drpcFS_LoadResourcesClient struct { - drpc.Stream -} - -func (x *drpcFS_LoadResourcesClient) Recv() (*ResourceLoadProgress, error) { - m := new(ResourceLoadProgress) - if err := x.MsgRecv(m, drpcEncoding_File_itd_proto{}); err != nil { - return nil, err - } - return m, nil -} - -func (x *drpcFS_LoadResourcesClient) RecvMsg(m *ResourceLoadProgress) error { - return x.MsgRecv(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCFSServer interface { - RemoveAll(context.Context, *PathsRequest) (*Empty, error) - Remove(context.Context, *PathsRequest) (*Empty, error) - Rename(context.Context, *RenameRequest) (*Empty, error) - MkdirAll(context.Context, *PathsRequest) (*Empty, error) - Mkdir(context.Context, *PathsRequest) (*Empty, error) - ReadDir(context.Context, *PathRequest) (*DirResponse, error) - Upload(*TransferRequest, DRPCFS_UploadStream) error - Download(*TransferRequest, DRPCFS_DownloadStream) error - LoadResources(*PathRequest, DRPCFS_LoadResourcesStream) error -} - -type DRPCFSUnimplementedServer struct{} - -func (s *DRPCFSUnimplementedServer) RemoveAll(context.Context, *PathsRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) Remove(context.Context, *PathsRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) Rename(context.Context, *RenameRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) MkdirAll(context.Context, *PathsRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) Mkdir(context.Context, *PathsRequest) (*Empty, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) ReadDir(context.Context, *PathRequest) (*DirResponse, error) { - return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) Upload(*TransferRequest, DRPCFS_UploadStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) Download(*TransferRequest, DRPCFS_DownloadStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -func (s *DRPCFSUnimplementedServer) LoadResources(*PathRequest, DRPCFS_LoadResourcesStream) error { - return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) -} - -type DRPCFSDescription struct{} - -func (DRPCFSDescription) NumMethods() int { return 9 } - -func (DRPCFSDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { - switch n { - case 0: - return "/rpc.FS/RemoveAll", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - RemoveAll( - ctx, - in1.(*PathsRequest), - ) - }, DRPCFSServer.RemoveAll, true - case 1: - return "/rpc.FS/Remove", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - Remove( - ctx, - in1.(*PathsRequest), - ) - }, DRPCFSServer.Remove, true - case 2: - return "/rpc.FS/Rename", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - Rename( - ctx, - in1.(*RenameRequest), - ) - }, DRPCFSServer.Rename, true - case 3: - return "/rpc.FS/MkdirAll", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - MkdirAll( - ctx, - in1.(*PathsRequest), - ) - }, DRPCFSServer.MkdirAll, true - case 4: - return "/rpc.FS/Mkdir", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - Mkdir( - ctx, - in1.(*PathsRequest), - ) - }, DRPCFSServer.Mkdir, true - case 5: - return "/rpc.FS/ReadDir", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return srv.(DRPCFSServer). - ReadDir( - ctx, - in1.(*PathRequest), - ) - }, DRPCFSServer.ReadDir, true - case 6: - return "/rpc.FS/Upload", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCFSServer). - Upload( - in1.(*TransferRequest), - &drpcFS_UploadStream{in2.(drpc.Stream)}, - ) - }, DRPCFSServer.Upload, true - case 7: - return "/rpc.FS/Download", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCFSServer). - Download( - in1.(*TransferRequest), - &drpcFS_DownloadStream{in2.(drpc.Stream)}, - ) - }, DRPCFSServer.Download, true - case 8: - return "/rpc.FS/LoadResources", drpcEncoding_File_itd_proto{}, - func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { - return nil, srv.(DRPCFSServer). - LoadResources( - in1.(*PathRequest), - &drpcFS_LoadResourcesStream{in2.(drpc.Stream)}, - ) - }, DRPCFSServer.LoadResources, true - default: - return "", nil, nil, nil, false - } -} - -func DRPCRegisterFS(mux drpc.Mux, impl DRPCFSServer) error { - return mux.Register(impl, DRPCFSDescription{}) -} - -type DRPCFS_RemoveAllStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcFS_RemoveAllStream struct { - drpc.Stream -} - -func (x *drpcFS_RemoveAllStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_RemoveStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcFS_RemoveStream struct { - drpc.Stream -} - -func (x *drpcFS_RemoveStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_RenameStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcFS_RenameStream struct { - drpc.Stream -} - -func (x *drpcFS_RenameStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_MkdirAllStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcFS_MkdirAllStream struct { - drpc.Stream -} - -func (x *drpcFS_MkdirAllStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_MkdirStream interface { - drpc.Stream - SendAndClose(*Empty) error -} - -type drpcFS_MkdirStream struct { - drpc.Stream -} - -func (x *drpcFS_MkdirStream) SendAndClose(m *Empty) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_ReadDirStream interface { - drpc.Stream - SendAndClose(*DirResponse) error -} - -type drpcFS_ReadDirStream struct { - drpc.Stream -} - -func (x *drpcFS_ReadDirStream) SendAndClose(m *DirResponse) error { - if err := x.MsgSend(m, drpcEncoding_File_itd_proto{}); err != nil { - return err - } - return x.CloseSend() -} - -type DRPCFS_UploadStream interface { - drpc.Stream - Send(*TransferProgress) error -} - -type drpcFS_UploadStream struct { - drpc.Stream -} - -func (x *drpcFS_UploadStream) Send(m *TransferProgress) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCFS_DownloadStream interface { - drpc.Stream - Send(*TransferProgress) error -} - -type drpcFS_DownloadStream struct { - drpc.Stream -} - -func (x *drpcFS_DownloadStream) Send(m *TransferProgress) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} - -type DRPCFS_LoadResourcesStream interface { - drpc.Stream - Send(*ResourceLoadProgress) error -} - -type drpcFS_LoadResourcesStream struct { - drpc.Stream -} - -func (x *drpcFS_LoadResourcesStream) Send(m *ResourceLoadProgress) error { - return x.MsgSend(m, drpcEncoding_File_itd_proto{}) -} diff --git a/itd b/itd new file mode 100644 index 0000000..8bf094a --- /dev/null +++ b/itd @@ -0,0 +1,20 @@ +#!/sbin/openrc-run + +name="itd" +description="Infinitime Daemon (itd)" +command="@bindir@/itd" +pidfile="@piddir@/${RC_SVCNAME}.pid" +command_user="user:group" +command_background="yes" +respawn_period=30 + +depend() { + after bluetooth +} + +reload() { + checkconfig || return $? + ebegin "Reloading ${RC_SVCNAME}" + start-stop-daemon --signal HUP --pidfile "${pidfile}" + eend $? +} diff --git a/main.go b/main.go index 56016cc..c34ebcf 100644 --- a/main.go +++ b/main.go @@ -26,16 +26,15 @@ import ( "os" "os/signal" "strconv" - "sync" "syscall" "time" "github.com/gen2brain/dlgs" "github.com/knadh/koanf" "github.com/mattn/go-isatty" - "go.elara.ws/itd/infinitime" - "go.elara.ws/logger" - "go.elara.ws/logger/log" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" ) var k = koanf.New(".") @@ -55,153 +54,140 @@ func main() { return } - level, err := logger.ParseLogLevel(k.String("logging.level")) - if err != nil { - level = logger.LogLevelInfo + level, err := zerolog.ParseLevel(k.String("logging.level")) + if err != nil || level == zerolog.NoLevel { + level = zerolog.InfoLevel } - log.Logger.SetLevel(level) + + // Initialize infinitime library + infinitime.Init(k.String("bluetooth.adapter")) + // Cleanly exit after function + defer infinitime.Exit() // Create infinitime options struct - opts := infinitime.Options{ - OnReconnect: func(dev *infinitime.Device) { - if k.Bool("on.reconnect.setTime") { - // Set time to current time - err = dev.SetTime(time.Now()) - if err != nil { - return - } - } - - // If config specifies to notify on reconnect - if k.Bool("on.reconnect.notify") { - // Send notification to InfiniTime - err = dev.Notify("itd", "Successfully reconnected") - if err != nil { - return - } - } - - // FS must be updated on reconnect - updateFS = true - // Resend weather on reconnect - sendWeatherCh <- struct{}{} - }, + opts := &infinitime.Options{ + AttemptReconnect: k.Bool("conn.reconnect"), + WhitelistEnabled: k.Bool("conn.whitelist.enabled"), + Whitelist: k.Strings("conn.whitelist.devices"), + OnReqPasskey: onReqPasskey, + Logger: log.Logger, + LogLevel: level, } - ctx := context.Background() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + sigCh := make(chan os.Signal, 1) + go func() { + <-sigCh + cancel() + time.Sleep(200 * time.Millisecond) + os.Exit(0) + }() + signal.Notify( + sigCh, + syscall.SIGINT, + syscall.SIGTERM, + ) // Connect to InfiniTime with default options - dev, err := infinitime.Connect(opts) + dev, err := infinitime.Connect(ctx, opts) if err != nil { - log.Fatal("Error connecting to InfiniTime").Err(err).Send() + log.Fatal().Err(err).Msg("Error connecting to InfiniTime") + } + + // When InfiniTime reconnects + opts.OnReconnect = func() { + if k.Bool("on.reconnect.setTime") { + // Set time to current time + err = dev.SetTime(time.Now()) + if err != nil { + return + } + } + + // If config specifies to notify on reconnect + if k.Bool("on.reconnect.notify") { + // Send notification to InfiniTime + err = dev.Notify("itd", "Successfully reconnected") + if err != nil { + return + } + } + + // FS must be updated on reconnect + updateFS = true + // Resend weather on reconnect + sendWeatherCh <- struct{}{} } // Get firmware version ver, err := dev.Version() if err != nil { - log.Error("Error getting firmware version").Err(err).Send() + log.Error().Err(err).Msg("Error getting firmware version") } // Log connection - log.Info("Connected to InfiniTime").Str("version", ver).Send() + log.Info().Str("version", ver).Msg("Connected to InfiniTime") // If config specifies to notify on connect if k.Bool("on.connect.notify") { // Send notification to InfiniTime err = dev.Notify("itd", "Successfully connected") if err != nil { - log.Error("Error sending notification to InfiniTime").Err(err).Send() + log.Error().Err(err).Msg("Error sending notification to InfiniTime") } } // Set time to current time err = dev.SetTime(time.Now()) if err != nil { - log.Error("Error setting current time on connected InfiniTime").Err(err).Send() + log.Error().Err(err).Msg("Error setting current time on connected InfiniTime") } - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) - - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - go func() { - sig := <-sigCh - log.Warn("Signal received, shutting down").Stringer("signal", sig).Send() - cancel() - }() - - wg := WaitGroup{&sync.WaitGroup{}} - // Initialize music controls - err = initMusicCtrl(ctx, wg, dev) + err = initMusicCtrl(ctx, dev) if err != nil { - log.Error("Error initializing music control").Err(err).Send() + log.Error().Err(err).Msg("Error initializing music control") } // Start control socket - err = initCallNotifs(ctx, wg, dev) + err = initCallNotifs(ctx, dev) if err != nil { - log.Error("Error initializing call notifications").Err(err).Send() + log.Error().Err(err).Msg("Error initializing call notifications") } // Initialize notification relay - err = initNotifRelay(ctx, wg, dev) + err = initNotifRelay(ctx, dev) if err != nil { - log.Error("Error initializing notification relay").Err(err).Send() + log.Error().Err(err).Msg("Error initializing notification relay") } // Initializa weather - err = initWeather(ctx, wg, dev) + err = initWeather(ctx, dev) if err != nil { - log.Error("Error initializing weather").Err(err).Send() + log.Error().Err(err).Msg("Error initializing weather") } // Initialize metrics collection - err = initMetrics(ctx, wg, dev) + err = initMetrics(ctx, dev) if err != nil { - log.Error("Error intializing metrics collection").Err(err).Send() + log.Error().Err(err).Msg("Error intializing metrics collection") } - // Initialize puremaps integration - err = initPureMaps(ctx, wg, dev) + // Initialize metrics collection + err = initPureMaps(ctx, dev) if err != nil { - log.Error("Error intializing puremaps integration").Err(err).Send() - } - - // Start fuse socket - if k.Bool("fuse.enabled") { - err = startFUSE(ctx, wg, dev) - if err != nil { - log.Error("Error starting fuse socket").Err(err).Send() - } + log.Error().Err(err).Msg("Error intializing puremaps integration") } // Start control socket - err = startSocket(ctx, wg, dev) + err = startSocket(ctx, dev) if err != nil { - log.Error("Error starting socket").Err(err).Send() + log.Error().Err(err).Msg("Error starting socket") } - - wg.Wait() -} - -type x struct { - n int - *sync.WaitGroup -} - -func (xy *x) Add(i int) { - xy.n += i - xy.WaitGroup.Add(i) - fmt.Println("add: counter:", xy.n) -} - -func (xy *x) Done() { - xy.n -= 1 - xy.WaitGroup.Done() - fmt.Println("done: counter:", xy.n) + // Block forever + select {} } func onReqPasskey() (uint32, error) { diff --git a/maps.go b/maps.go index f195ab7..60a4c14 100644 --- a/maps.go +++ b/maps.go @@ -5,9 +5,9 @@ import ( "strings" "github.com/godbus/dbus/v5" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/utils" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/itd/internal/utils" ) const ( @@ -18,7 +18,7 @@ const ( progressProperty = interfaceName + ".progress" ) -func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initPureMaps(ctx context.Context, dev *infinitime.Device) error { // Connect to session bus. This connection is for method calls. conn, err := utils.NewSessionBusConn(ctx) if err != nil { @@ -55,14 +55,11 @@ func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) err navigator = conn.Object("io.github.rinigus.PureMaps", "/io/github/rinigus/PureMaps/navigator") err = setAll(navigator, dev) if err != nil { - log.Error("Error setting all navigation fields").Err(err).Send() + log.Error().Err(err).Msg("Error setting all navigation fields") } } - wg.Add(1) go func() { - defer wg.Done("pureMaps") - signalCh := make(chan *dbus.Message, 10) monitorConn.Eavesdrop(signalCh) @@ -76,7 +73,7 @@ func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) err var member string err = sig.Headers[dbus.FieldMember].Store(&member) if err != nil { - log.Error("Error getting dbus member field").Err(err).Send() + log.Error().Err(err).Msg("Error getting dbus member field") continue } @@ -84,7 +81,7 @@ func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) err continue } - log.Debug("Signal received from PureMaps navigator").Str("member", member).Send() + log.Debug().Str("member", member).Msg("Signal received from PureMaps navigator") // The object must be retrieved in this loop in case PureMaps was not // open at the time ITD was started. @@ -96,52 +93,52 @@ func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) err var icon string err = navigator.StoreProperty(iconProperty, &icon) if err != nil { - log.Error("Error getting property").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error getting property") continue } - err = dev.SetNavFlag(infinitime.NavFlag(icon)) + err = dev.Navigation.SetFlag(infinitime.NavFlag(icon)) if err != nil { - log.Error("Error setting flag").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error setting flag") continue } case "narrative": var narrative string err = navigator.StoreProperty(narrativeProperty, &narrative) if err != nil { - log.Error("Error getting property").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error getting property") continue } - err = dev.SetNavNarrative(narrative) + err = dev.Navigation.SetNarrative(narrative) if err != nil { - log.Error("Error setting flag").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error setting flag") continue } case "manDist": var manDist string err = navigator.StoreProperty(manDistProperty, &manDist) if err != nil { - log.Error("Error getting property").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error getting property") continue } - err = dev.SetNavManeuverDistance(manDist) + err = dev.Navigation.SetManDist(manDist) if err != nil { - log.Error("Error setting flag").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error setting flag") continue } case "progress": var progress int32 err = navigator.StoreProperty(progressProperty, &progress) if err != nil { - log.Error("Error getting property").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error getting property") continue } - err = dev.SetNavProgress(uint8(progress)) + err = dev.Navigation.SetProgress(uint8(progress)) if err != nil { - log.Error("Error setting flag").Err(err).Str("property", member).Send() + log.Error().Err(err).Str("property", member).Msg("Error setting flag") continue } } @@ -152,7 +149,7 @@ func initPureMaps(ctx context.Context, wg WaitGroup, dev *infinitime.Device) err }() if exists { - log.Info("Sending PureMaps data to InfiniTime").Send() + log.Info().Msg("Sending PureMaps data to InfiniTime") } return nil @@ -165,7 +162,7 @@ func setAll(navigator dbus.BusObject, dev *infinitime.Device) error { return err } - err = dev.SetNavFlag(infinitime.NavFlag(icon)) + err = dev.Navigation.SetFlag(infinitime.NavFlag(icon)) if err != nil { return err } @@ -176,7 +173,7 @@ func setAll(navigator dbus.BusObject, dev *infinitime.Device) error { return err } - err = dev.SetNavNarrative(narrative) + err = dev.Navigation.SetNarrative(narrative) if err != nil { return err } @@ -187,7 +184,7 @@ func setAll(navigator dbus.BusObject, dev *infinitime.Device) error { return err } - err = dev.SetNavManeuverDistance(manDist) + err = dev.Navigation.SetManDist(manDist) if err != nil { return err } @@ -198,7 +195,7 @@ func setAll(navigator dbus.BusObject, dev *infinitime.Device) error { return err } - return dev.SetNavProgress(uint8(progress)) + return dev.Navigation.SetProgress(uint8(progress)) } // pureMapsExists checks to make sure the PureMaps service exists on the bus diff --git a/metrics.go b/metrics.go index 1f4670a..57d45f0 100644 --- a/metrics.go +++ b/metrics.go @@ -6,12 +6,12 @@ import ( "path/filepath" "time" - "go.elara.ws/itd/infinitime" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" _ "modernc.org/sqlite" ) -func initMetrics(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initMetrics(ctx context.Context, dev *infinitime.Device) error { // If metrics disabled, return nil if !k.Bool("metrics.enabled") { return nil @@ -47,105 +47,85 @@ func initMetrics(ctx context.Context, wg WaitGroup, dev *infinitime.Device) erro return err } - // Watch heart rate + // If heart rate metrics enabled in config if k.Bool("metrics.heartRate.enabled") { - err := dev.WatchHeartRate(ctx, func(heartRate uint8, err error) { - if err != nil { - // Handle error - return - } - // Get current time - unixTime := time.Now().UnixNano() - // Insert sample and time into database - db.Exec("INSERT INTO heartRate VALUES (?, ?);", unixTime, heartRate) - }) + // Watch heart rate + heartRateCh, err := dev.WatchHeartRate(ctx) if err != nil { return err } + go func() { + // For every heart rate sample + for heartRate := range heartRateCh { + // Get current time + unixTime := time.Now().UnixNano() + // Insert sample and time into database + db.Exec("INSERT INTO heartRate VALUES (?, ?);", unixTime, heartRate) + } + }() } // If step count metrics enabled in config if k.Bool("metrics.stepCount.enabled") { // Watch step count - err := dev.WatchStepCount(ctx, func(count uint32, err error) { - if err != nil { - return - } - // Get current time - unixTime := time.Now().UnixNano() - // Insert sample and time into database - db.Exec("INSERT INTO stepCount VALUES (?, ?);", unixTime, count) - }) + stepCountCh, err := dev.WatchStepCount(ctx) if err != nil { return err } - } - - // Watch step count - if k.Bool("metrics.stepCount.enabled") { - err := dev.WatchStepCount(ctx, func(count uint32, err error) { - if err != nil { - // Handle error - return + go func() { + // For every step count sample + for stepCount := range stepCountCh { + // Get current time + unixTime := time.Now().UnixNano() + // Insert sample and time into database + db.Exec("INSERT INTO stepCount VALUES (?, ?);", unixTime, stepCount) } - // Get current time - unixTime := time.Now().UnixNano() - // Insert sample and time into database - db.Exec("INSERT INTO stepCount VALUES (?, ?);", unixTime, count) - }) - if err != nil { - return err - } + }() } - // Watch battery level + // If battery level metrics enabled in config if k.Bool("metrics.battLevel.enabled") { - err := dev.WatchBatteryLevel(ctx, func(battLevel uint8, err error) { - if err != nil { - // Handle error - return - } - // Get current time - unixTime := time.Now().UnixNano() - // Insert sample and time into database - db.Exec("INSERT INTO battLevel VALUES (?, ?);", unixTime, battLevel) - }) + // Watch battery level + battLevelCh, err := dev.WatchBatteryLevel(ctx) if err != nil { return err } + go func() { + // For every battery level sample + for battLevel := range battLevelCh { + // Get current time + unixTime := time.Now().UnixNano() + // Insert sample and time into database + db.Exec("INSERT INTO battLevel VALUES (?, ?);", unixTime, battLevel) + } + }() } - // Watch motion values + // If motion metrics enabled in config if k.Bool("metrics.motion.enabled") { - err := dev.WatchMotion(ctx, func(motionVals infinitime.MotionValues, err error) { - if err != nil { - // Handle error - return - } - // Get current time - unixTime := time.Now().UnixNano() - // Insert sample values and time into database - db.Exec( - "INSERT INTO motion VALUES (?, ?, ?, ?);", - unixTime, - motionVals.X, - motionVals.Y, - motionVals.Z, - ) - }) + // Watch motion values + motionCh, err := dev.WatchMotion(ctx) if err != nil { return err } + go func() { + // For every motion sample + for motionVals := range motionCh { + // Get current time + unixTime := time.Now().UnixNano() + // Insert sample values and time into database + db.Exec( + "INSERT INTO motion VALUES (?, ?, ?, ?);", + unixTime, + motionVals.X, + motionVals.Y, + motionVals.Z, + ) + } + }() } - wg.Add(1) - go func() { - defer wg.Done("metrics") - <-ctx.Done() - db.Close() - }() - - log.Info("Initialized metrics collection").Send() + log.Info().Msg("Initialized metrics collection") return nil } diff --git a/mpris/mpris.go b/mpris/mpris.go index 679b915..740d61a 100644 --- a/mpris/mpris.go +++ b/mpris/mpris.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/godbus/dbus/v5" - "go.elara.ws/itd/internal/utils" + "go.arsenm.dev/itd/internal/utils" ) var ( diff --git a/music.go b/music.go index f8e1acb..ee76461 100644 --- a/music.go +++ b/music.go @@ -21,13 +21,13 @@ package main import ( "context" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/mpris" - "go.elara.ws/itd/translit" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/itd/mpris" + "go.arsenm.dev/itd/translit" ) -func initMusicCtrl(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initMusicCtrl(ctx context.Context, dev *infinitime.Device) error { mpris.Init(ctx) maps := k.Strings("notifs.translit.use") @@ -38,45 +38,45 @@ func initMusicCtrl(ctx context.Context, wg WaitGroup, dev *infinitime.Device) er if !firmwareUpdating { switch ct { case mpris.ChangeTypeStatus: - dev.SetMusicStatus(val == "Playing") + dev.Music.SetStatus(val == "Playing") case mpris.ChangeTypeTitle: - dev.SetMusicTrack(newVal) + dev.Music.SetTrack(newVal) case mpris.ChangeTypeAlbum: - dev.SetMusicAlbum(newVal) + dev.Music.SetAlbum(newVal) case mpris.ChangeTypeArtist: - dev.SetMusicArtist(newVal) + dev.Music.SetArtist(newVal) } } }) // Watch for music events - err := dev.WatchMusicEvents(ctx, func(event infinitime.MusicEvent, err error) { - if err != nil { - log.Error("Music event error").Err(err).Send() - } - - // Perform appropriate action based on event - switch event { - case infinitime.MusicEventPlay: - mpris.Play() - case infinitime.MusicEventPause: - mpris.Pause() - case infinitime.MusicEventNext: - mpris.Next() - case infinitime.MusicEventPrev: - mpris.Prev() - case infinitime.MusicEventVolUp: - mpris.VolUp(uint(k.Int("music.vol.interval"))) - case infinitime.MusicEventVolDown: - mpris.VolDown(uint(k.Int("music.vol.interval"))) - } - }) + musicEvtCh, err := dev.Music.WatchEvents() if err != nil { return err } + go func() { + // For every music event received + for musicEvt := range musicEvtCh { + // Perform appropriate action based on event + switch musicEvt { + case infinitime.MusicEventPlay: + mpris.Play() + case infinitime.MusicEventPause: + mpris.Pause() + case infinitime.MusicEventNext: + mpris.Next() + case infinitime.MusicEventPrev: + mpris.Prev() + case infinitime.MusicEventVolUp: + mpris.VolUp(uint(k.Int("music.vol.interval"))) + case infinitime.MusicEventVolDown: + mpris.VolDown(uint(k.Int("music.vol.interval"))) + } + } + }() // Log completed initialization - log.Info("Initialized InfiniTime music controls").Send() + log.Info().Msg("Initialized InfiniTime music controls") return nil } diff --git a/notifs.go b/notifs.go index 422bb8f..7945954 100644 --- a/notifs.go +++ b/notifs.go @@ -23,13 +23,13 @@ import ( "fmt" "github.com/godbus/dbus/v5" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/utils" - "go.elara.ws/itd/translit" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/itd/internal/utils" + "go.arsenm.dev/itd/translit" ) -func initNotifRelay(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initNotifRelay(ctx context.Context, dev *infinitime.Device) error { // Connect to dbus session bus bus, err := utils.NewSessionBusConn(ctx) if err != nil { @@ -54,55 +54,47 @@ func initNotifRelay(ctx context.Context, wg WaitGroup, dev *infinitime.Device) e // Send events to channel bus.Eavesdrop(notifCh) - wg.Add(1) go func() { - defer wg.Done("notifRelay") // For every event sent to channel - for { - select { - case v := <-notifCh: - // If firmware is updating, skip - if firmwareUpdating { - continue - } - - // If body does not contain 5 elements, skip - if len(v.Body) < 5 { - continue - } - - // Get requred fields - sender, summary, body := v.Body[0].(string), v.Body[3].(string), v.Body[4].(string) - - // If fields are ignored in config, skip - if ignored(sender, summary, body) { - continue - } - - maps := k.Strings("notifs.translit.use") - translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom")) - sender = translit.Transliterate(sender, maps...) - summary = translit.Transliterate(summary, maps...) - body = translit.Transliterate(body, maps...) - - var msg string - // If summary does not exist, set message to body. - // If it does, set message to summary, two newlines, and then body - if summary == "" { - msg = body - } else { - msg = fmt.Sprintf("%s\n\n%s", summary, body) - } - - dev.Notify(sender, msg) - case <-ctx.Done(): - bus.Close() - return + for v := range notifCh { + // If firmware is updating, skip + if firmwareUpdating { + continue } + + // If body does not contain 5 elements, skip + if len(v.Body) < 5 { + continue + } + + // Get requred fields + sender, summary, body := v.Body[0].(string), v.Body[3].(string), v.Body[4].(string) + + // If fields are ignored in config, skip + if ignored(sender, summary, body) { + continue + } + + maps := k.Strings("notifs.translit.use") + translit.Transliterators["custom"] = translit.Map(k.Strings("notifs.translit.custom")) + sender = translit.Transliterate(sender, maps...) + summary = translit.Transliterate(summary, maps...) + body = translit.Transliterate(body, maps...) + + var msg string + // If summary does not exist, set message to body. + // If it does, set message to summary, two newlines, and then body + if summary == "" { + msg = body + } else { + msg = fmt.Sprintf("%s\n\n%s", summary, body) + } + + dev.Notify(sender, msg) } }() - log.Info("Relaying notifications to InfiniTime").Send() + log.Info().Msg("Relaying notifications to InfiniTime") return nil } diff --git a/socket.go b/socket.go index f34da10..017712e 100644 --- a/socket.go +++ b/socket.go @@ -19,7 +19,6 @@ package main import ( - "archive/zip" "context" "errors" "io" @@ -28,11 +27,12 @@ import ( "path/filepath" "time" - "go.elara.ws/drpc/muxserver" - "go.elara.ws/itd/infinitime" - "go.elara.ws/itd/internal/rpc" - "go.elara.ws/logger/log" - "storj.io/drpc/drpcmux" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/infinitime/blefs" + "go.arsenm.dev/itd/api" + "go.arsenm.dev/lrpc/codec" + "go.arsenm.dev/lrpc/server" ) var ( @@ -41,7 +41,7 @@ var ( ErrDFUInvalidUpgType = errors.New("invalid upgrade type") ) -func startSocket(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func startSocket(ctx context.Context, dev *infinitime.Device) error { // Make socket directory if non-existant err := os.MkdirAll(filepath.Dir(k.String("socket.path")), 0o755) if err != nil { @@ -60,26 +60,34 @@ func startSocket(ctx context.Context, wg WaitGroup, dev *infinitime.Device) erro return err } - fs := dev.FS() - mux := drpcmux.New() + fs, err := dev.FS() + if err != nil { + log.Warn().Err(err).Msg("Error getting BLE filesystem") + } - err = rpc.DRPCRegisterITD(mux, &ITD{dev}) + srv := server.New() + + itdAPI := &ITD{ + dev: dev, + } + err = srv.Register(itdAPI) if err != nil { return err } - err = rpc.DRPCRegisterFS(mux, &FS{dev, fs}) + fsAPI := &FS{ + dev: dev, + fs: fs, + } + err = srv.Register(fsAPI) if err != nil { return err } - log.Info("Starting control socket").Str("path", k.String("socket.path")).Send() + go srv.Serve(ctx, ln, codec.Default) - wg.Add(1) - go func() { - defer wg.Done("socket") - muxserver.New(mux).Serve(ctx, ln) - }() + // Log socket start + log.Info().Str("path", k.String("socket.path")).Msg("Started control socket") return nil } @@ -88,188 +96,159 @@ type ITD struct { dev *infinitime.Device } -func (i *ITD) HeartRate(_ context.Context, _ *rpc.Empty) (*rpc.IntResponse, error) { - hr, err := i.dev.HeartRate() - return &rpc.IntResponse{Value: uint32(hr)}, err +func (i *ITD) HeartRate(_ *server.Context) (uint8, error) { + return i.dev.HeartRate() } -func (i *ITD) WatchHeartRate(_ *rpc.Empty, s rpc.DRPCITD_WatchHeartRateStream) error { - errCh := make(chan error) - - err := i.dev.WatchHeartRate(s.Context(), func(rate uint8, err error) { - if err != nil { - errCh <- err - return - } - - err = s.Send(&rpc.IntResponse{Value: uint32(rate)}) - if err != nil { - errCh <- err - } - }) +func (i *ITD) WatchHeartRate(ctx *server.Context) error { + ch, err := ctx.MakeChannel() if err != nil { return err } - select { - case <-errCh: - return err - case <-s.Context().Done(): - return nil - } -} - -func (i *ITD) BatteryLevel(_ context.Context, _ *rpc.Empty) (*rpc.IntResponse, error) { - bl, err := i.dev.BatteryLevel() - return &rpc.IntResponse{Value: uint32(bl)}, err -} - -func (i *ITD) WatchBatteryLevel(_ *rpc.Empty, s rpc.DRPCITD_WatchBatteryLevelStream) error { - errCh := make(chan error) - - err := i.dev.WatchBatteryLevel(s.Context(), func(level uint8, err error) { - if err != nil { - errCh <- err - return - } - - err = s.Send(&rpc.IntResponse{Value: uint32(level)}) - if err != nil { - errCh <- err - } - }) + heartRateCh, err := i.dev.WatchHeartRate(ctx) if err != nil { return err } - select { - case <-errCh: - return err - case <-s.Context().Done(): - return nil - } + go func() { + // For every heart rate value + for heartRate := range heartRateCh { + ch <- heartRate + } + }() + + return nil } -func (i *ITD) Motion(_ context.Context, _ *rpc.Empty) (*rpc.MotionResponse, error) { - motionVals, err := i.dev.Motion() - return &rpc.MotionResponse{ - X: int32(motionVals.X), - Y: int32(motionVals.Y), - Z: int32(motionVals.Z), - }, err +func (i *ITD) BatteryLevel(_ *server.Context) (uint8, error) { + return i.dev.BatteryLevel() } -func (i *ITD) WatchMotion(_ *rpc.Empty, s rpc.DRPCITD_WatchMotionStream) error { - errCh := make(chan error) - - err := i.dev.WatchMotion(s.Context(), func(motion infinitime.MotionValues, err error) { - if err != nil { - errCh <- err - return - } - - err = s.Send(&rpc.MotionResponse{ - X: int32(motion.X), - Y: int32(motion.Y), - Z: int32(motion.Z), - }) - if err != nil { - errCh <- err - } - }) +func (i *ITD) WatchBatteryLevel(ctx *server.Context) error { + ch, err := ctx.MakeChannel() if err != nil { return err } - select { - case <-errCh: - return err - case <-s.Context().Done(): - return nil - } -} - -func (i *ITD) StepCount(_ context.Context, _ *rpc.Empty) (*rpc.IntResponse, error) { - sc, err := i.dev.StepCount() - return &rpc.IntResponse{Value: sc}, err -} - -func (i *ITD) WatchStepCount(_ *rpc.Empty, s rpc.DRPCITD_WatchStepCountStream) error { - errCh := make(chan error) - - err := i.dev.WatchStepCount(s.Context(), func(count uint32, err error) { - if err != nil { - errCh <- err - return - } - - err = s.Send(&rpc.IntResponse{Value: count}) - if err != nil { - errCh <- err - } - }) + battLevelCh, err := i.dev.WatchBatteryLevel(ctx) if err != nil { return err } - select { - case <-errCh: + go func() { + // For every heart rate value + for battLevel := range battLevelCh { + ch <- battLevel + } + }() + + return nil +} + +func (i *ITD) Motion(_ *server.Context) (infinitime.MotionValues, error) { + return i.dev.Motion() +} + +func (i *ITD) WatchMotion(ctx *server.Context) error { + ch, err := ctx.MakeChannel() + if err != nil { return err - case <-s.Context().Done(): - return nil } + + motionValsCh, err := i.dev.WatchMotion(ctx) + if err != nil { + return err + } + + go func() { + // For every heart rate value + for motionVals := range motionValsCh { + ch <- motionVals + } + }() + + return nil } -func (i *ITD) Version(_ context.Context, _ *rpc.Empty) (*rpc.StringResponse, error) { - v, err := i.dev.Version() - return &rpc.StringResponse{Value: v}, err +func (i *ITD) StepCount(_ *server.Context) (uint32, error) { + return i.dev.StepCount() } -func (i *ITD) Address(_ context.Context, _ *rpc.Empty) (*rpc.StringResponse, error) { - return &rpc.StringResponse{Value: i.dev.Address()}, nil +func (i *ITD) WatchStepCount(ctx *server.Context) error { + ch, err := ctx.MakeChannel() + if err != nil { + return err + } + + stepCountCh, err := i.dev.WatchStepCount(ctx) + if err != nil { + return err + } + + go func() { + // For every heart rate value + for stepCount := range stepCountCh { + ch <- stepCount + } + }() + + return nil } -func (i *ITD) Notify(_ context.Context, data *rpc.NotifyRequest) (*rpc.Empty, error) { - return &rpc.Empty{}, i.dev.Notify(data.Title, data.Body) +func (i *ITD) Version(_ *server.Context) (string, error) { + return i.dev.Version() } -func (i *ITD) SetTime(_ context.Context, data *rpc.SetTimeRequest) (*rpc.Empty, error) { - return &rpc.Empty{}, i.dev.SetTime(time.Unix(0, data.UnixNano)) +func (i *ITD) Address(_ *server.Context) string { + return i.dev.Address() } -func (i *ITD) WeatherUpdate(context.Context, *rpc.Empty) (*rpc.Empty, error) { +func (i *ITD) Notify(_ *server.Context, data api.NotifyData) error { + return i.dev.Notify(data.Title, data.Body) +} + +func (i *ITD) SetTime(_ *server.Context, t *time.Time) error { + return i.dev.SetTime(*t) +} + +func (i *ITD) WeatherUpdate(_ *server.Context) { sendWeatherCh <- struct{}{} - return &rpc.Empty{}, nil } -func (i *ITD) FirmwareUpgrade(data *rpc.FirmwareUpgradeRequest, s rpc.DRPCITD_FirmwareUpgradeStream) (err error) { - var fwimg, initpkt *os.File +func (i *ITD) FirmwareUpgrade(ctx *server.Context, reqData api.FwUpgradeData) error { + i.dev.DFU.Reset() - switch data.Type { - case rpc.FirmwareUpgradeRequest_Archive: - fwimg, initpkt, err = extractDFU(data.Files[0]) - if err != nil { - return err - } - case rpc.FirmwareUpgradeRequest_Files: - if len(data.Files) < 2 { + switch reqData.Type { + case api.UpgradeTypeArchive: + // If less than one file, return error + if len(reqData.Files) < 1 { return ErrDFUNotEnoughFiles } - - if filepath.Ext(data.Files[0]) != ".dat" { + // If file is not zip archive, return error + if filepath.Ext(reqData.Files[0]) != ".zip" { return ErrDFUInvalidFile } - - if filepath.Ext(data.Files[1]) != ".bin" { - return ErrDFUInvalidFile - } - - initpkt, err = os.Open(data.Files[0]) + // Load DFU archive + err := i.dev.DFU.LoadArchive(reqData.Files[0]) if err != nil { return err } - - fwimg, err = os.Open(data.Files[1]) + case api.UpgradeTypeFiles: + // If less than two files, return error + if len(reqData.Files) < 2 { + return ErrDFUNotEnoughFiles + } + // If first file is not init packet, return error + if filepath.Ext(reqData.Files[0]) != ".dat" { + return ErrDFUInvalidFile + } + // If second file is not firmware image, return error + if filepath.Ext(reqData.Files[1]) != ".bin" { + return ErrDFUInvalidFile + } + // Load individual DFU files + err := i.dev.DFU.LoadFiles(reqData.Files[0], reqData.Files[1]) if err != nil { return err } @@ -277,99 +256,119 @@ func (i *ITD) FirmwareUpgrade(data *rpc.FirmwareUpgradeRequest, s rpc.DRPCITD_Fi return ErrDFUInvalidUpgType } - defer os.Remove(fwimg.Name()) - defer os.Remove(initpkt.Name()) - defer fwimg.Close() - defer initpkt.Close() + ch, err := ctx.MakeChannel() + if err != nil { + return err + } + go func() { + // For every progress event + for event := range i.dev.DFU.Progress() { + ch <- event + } + + firmwareUpdating = false + // Send zero object to signal completion + close(ch) + }() + + // Set firmwareUpdating firmwareUpdating = true - defer func() { firmwareUpdating = false }() - return i.dev.UpgradeFirmware(infinitime.DFUOptions{ - InitPacket: initpkt, - FirmwareImage: fwimg, - ProgressFunc: func(sent, received, total uint32) { - _ = s.Send(&rpc.DFUProgress{ - Sent: int64(sent), - Recieved: int64(received), - Total: int64(total), - }) - }, - }) + go func() { + // Start DFU + err := i.dev.DFU.Start() + if err != nil { + log.Error().Err(err).Msg("Error while upgrading firmware") + firmwareUpdating = false + return + } + }() + + return nil } type FS struct { dev *infinitime.Device - fs *infinitime.FS + fs *blefs.FS } -func (fs *FS) RemoveAll(_ context.Context, req *rpc.PathsRequest) (*rpc.Empty, error) { - for _, path := range req.Paths { +func (fs *FS) RemoveAll(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { err := fs.fs.RemoveAll(path) if err != nil { - return &rpc.Empty{}, err + return err } } - return &rpc.Empty{}, nil + return nil } -func (fs *FS) Remove(_ context.Context, req *rpc.PathsRequest) (*rpc.Empty, error) { - for _, path := range req.Paths { +func (fs *FS) Remove(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { err := fs.fs.Remove(path) if err != nil { - return &rpc.Empty{}, err + return err } } - return &rpc.Empty{}, nil + return nil } -func (fs *FS) Rename(_ context.Context, req *rpc.RenameRequest) (*rpc.Empty, error) { - return &rpc.Empty{}, fs.fs.Rename(req.From, req.To) +func (fs *FS) Rename(_ *server.Context, paths [2]string) error { + fs.updateFS() + return fs.fs.Rename(paths[0], paths[1]) } -func (fs *FS) MkdirAll(_ context.Context, req *rpc.PathsRequest) (*rpc.Empty, error) { - for _, path := range req.Paths { +func (fs *FS) MkdirAll(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { err := fs.fs.MkdirAll(path) if err != nil { - return &rpc.Empty{}, err + return err } } - return &rpc.Empty{}, nil + return nil } -func (fs *FS) Mkdir(_ context.Context, req *rpc.PathsRequest) (*rpc.Empty, error) { - for _, path := range req.Paths { +func (fs *FS) Mkdir(_ *server.Context, paths []string) error { + fs.updateFS() + for _, path := range paths { err := fs.fs.Mkdir(path) if err != nil { - return &rpc.Empty{}, err + return err } } - return &rpc.Empty{}, nil + return nil } -func (fs *FS) ReadDir(_ context.Context, req *rpc.PathRequest) (*rpc.DirResponse, error) { - entries, err := fs.fs.ReadDir(req.Path) +func (fs *FS) ReadDir(_ *server.Context, dir string) ([]api.FileInfo, error) { + fs.updateFS() + + entries, err := fs.fs.ReadDir(dir) if err != nil { return nil, err } - var fileInfo []*rpc.FileInfo + var fileInfo []api.FileInfo for _, entry := range entries { info, err := entry.Info() if err != nil { return nil, err } - fileInfo = append(fileInfo, &rpc.FileInfo{ + fileInfo = append(fileInfo, api.FileInfo{ Name: info.Name(), Size: info.Size(), IsDir: info.IsDir(), }) } - return &rpc.DirResponse{Entries: fileInfo}, nil + return fileInfo, nil } -func (fs *FS) Upload(req *rpc.TransferRequest, s rpc.DRPCFS_UploadStream) error { - localFile, err := os.Open(req.Source) +func (fs *FS) Upload(ctx *server.Context, paths [2]string) error { + fs.updateFS() + + localFile, err := os.Open(paths[1]) if err != nil { return err } @@ -379,135 +378,111 @@ func (fs *FS) Upload(req *rpc.TransferRequest, s rpc.DRPCFS_UploadStream) error return err } - remoteFile, err := fs.fs.Create(req.Destination, uint32(localInfo.Size())) + remoteFile, err := fs.fs.Create(paths[0], uint32(localInfo.Size())) if err != nil { return err } - remoteFile.ProgressFunc = func(transferred, total uint32) { - _ = s.Send(&rpc.TransferProgress{ - Total: total, - Sent: transferred, - }) + ch, err := ctx.MakeChannel() + if err != nil { + return err } + go func() { + // For every progress event + for sent := range remoteFile.Progress() { + ch <- api.FSTransferProgress{ + Total: remoteFile.Size(), + Sent: sent, + } + } - io.Copy(remoteFile, localFile) - localFile.Close() - remoteFile.Close() + // Send zero object to signal completion + close(ch) + }() + + go func() { + io.Copy(remoteFile, localFile) + localFile.Close() + remoteFile.Close() + }() return nil } -func (fs *FS) Download(req *rpc.TransferRequest, s rpc.DRPCFS_DownloadStream) error { - localFile, err := os.Create(req.Destination) +func (fs *FS) Download(ctx *server.Context, paths [2]string) error { + fs.updateFS() + + localFile, err := os.Create(paths[0]) if err != nil { return err } - remoteFile, err := fs.fs.Open(req.Source) + remoteFile, err := fs.fs.Open(paths[1]) if err != nil { return err } - defer localFile.Close() - defer remoteFile.Close() - - remoteFile.ProgressFunc = func(transferred, total uint32) { - _ = s.Send(&rpc.TransferProgress{ - Total: total, - Sent: transferred, - }) - } - - _, err = io.Copy(localFile, remoteFile) + ch, err := ctx.MakeChannel() if err != nil { return err } + go func() { + // For every progress event + for sent := range remoteFile.Progress() { + ch <- api.FSTransferProgress{ + Total: remoteFile.Size(), + Sent: sent, + } + } + + // Send zero object to signal completion + close(ch) + localFile.Close() + remoteFile.Close() + }() + + go io.Copy(localFile, remoteFile) return nil } -func (fs *FS) LoadResources(req *rpc.PathRequest, s rpc.DRPCFS_LoadResourcesStream) error { - return infinitime.LoadResources(req.Path, fs.fs, func(evt infinitime.ResourceLoadProgress) { - _ = s.Send(&rpc.ResourceLoadProgress{ - Name: evt.Name, - Total: int64(evt.Total), - Sent: int64(evt.Transferred), - Operation: rpc.ResourceLoadProgress_Operation(evt.Operation), - }) - }) -} - -func extractDFU(path string) (fwimg, initpkt *os.File, err error) { - zipReader, err := zip.OpenReader(path) +func (fs *FS) LoadResources(ctx *server.Context, path string) error { + resFl, err := os.Open(path) if err != nil { - return nil, nil, err + return err } - defer zipReader.Close() - for _, file := range zipReader.File { - if fwimg != nil && initpkt != nil { - break + progCh, err := infinitime.LoadResources(resFl, fs.fs) + if err != nil { + return err + } + + ch, err := ctx.MakeChannel() + if err != nil { + return err + } + + go func() { + for evt := range progCh { + ch <- evt } + close(ch) + }() - switch filepath.Ext(file.Name) { - case ".bin": - fwimg, err = os.CreateTemp(os.TempDir(), "itd_dfu_fwimg_*.bin") - if err != nil { - return nil, nil, err - } - - zipFile, err := file.Open() - if err != nil { - return nil, nil, err - } - defer zipFile.Close() - - _, err = io.Copy(fwimg, zipFile) - if err != nil { - return nil, nil, err - } - - err = zipFile.Close() - if err != nil { - return nil, nil, err - } - - _, err = fwimg.Seek(0, io.SeekStart) - if err != nil { - return nil, nil, err - } - case ".dat": - initpkt, err = os.CreateTemp(os.TempDir(), "itd_dfu_initpkt_*.dat") - if err != nil { - return nil, nil, err - } - - zipFile, err := file.Open() - if err != nil { - return nil, nil, err - } - - _, err = io.Copy(initpkt, zipFile) - if err != nil { - return nil, nil, err - } - - err = zipFile.Close() - if err != nil { - return nil, nil, err - } - - _, err = initpkt.Seek(0, io.SeekStart) - if err != nil { - return nil, nil, err - } - } - } - - if fwimg == nil || initpkt == nil { - return nil, nil, errors.New("invalid dfu archive") - } - - return fwimg, initpkt, nil + return nil +} + +func (fs *FS) updateFS() { + if fs.fs == nil || updateFS { + // Get new FS + newFS, err := fs.dev.FS() + if err != nil { + log.Warn().Err(err).Msg("Error updating BLE filesystem") + } else { + // Set FS pointer to new FS + fs.fs = newFS + // Reset updateFS + updateFS = false + } + } } diff --git a/translit/translit_test.go b/translit/translit_test.go index a3cff17..07cc678 100644 --- a/translit/translit_test.go +++ b/translit/translit_test.go @@ -9,7 +9,7 @@ func TestTransliterate(t *testing.T) { expected string } - cases := []testCase{ + var cases = []testCase{ {"eASCII", "œª°«»", `oeao""`}, {"Scandinavian", "ÆæØøÅå", "AeaeOeoeAaaa"}, {"German", "äöüÄÖÜßẞ", "aeoeueAeOeUessSS"}, diff --git a/waitgroup.go b/waitgroup.go deleted file mode 100644 index 777a692..0000000 --- a/waitgroup.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "sync" - - "go.elara.ws/logger/log" -) - -type WaitGroup struct { - *sync.WaitGroup -} - -func (wg WaitGroup) Done(c string) { - log.Info("Component stopped").Str("name", c).Send() - wg.WaitGroup.Done() -} diff --git a/weather.go b/weather.go index 19d66f5..040c63e 100644 --- a/weather.go +++ b/weather.go @@ -4,14 +4,16 @@ import ( "context" "encoding/json" "fmt" + "math" "net/http" "net/url" "strconv" "strings" "time" - "go.elara.ws/itd/infinitime" - "go.elara.ws/logger/log" + "github.com/rs/zerolog/log" + "go.arsenm.dev/infinitime" + "go.arsenm.dev/infinitime/weather" ) // METResponse represents a response from @@ -30,7 +32,7 @@ type METData struct { Instant struct { Details struct { AirPressure float32 `json:"air_pressure_at_sea_level"` - Temperature float32 `json:"air_temperature"` + AirTemperature float32 `json:"air_temperature"` DewPoint float32 `json:"dew_point_temperature"` CloudAreaFraction float32 `json:"cloud_area_fraction"` FogAreaFraction float32 `json:"fog_area_fraction"` @@ -48,12 +50,6 @@ type METData struct { PrecipitationAmount float32 `json:"precipitation_amount"` } } `json:"next_1_hours"` - Next6Hours struct { - Details struct { - MaxTemp float32 `json:"air_temperature_max"` - MinTemp float32 `json:"air_temperature_min"` - } - } `json:"next_6_hours"` } // OSMData represents lat/long data from @@ -65,14 +61,7 @@ type OSMData []struct { var sendWeatherCh = make(chan struct{}, 1) -func sleepCtx(ctx context.Context, d time.Duration) { - select { - case <-time.After(d): - case <-ctx.Done(): - } -} - -func initWeather(ctx context.Context, wg WaitGroup, dev *infinitime.Device) error { +func initWeather(ctx context.Context, dev *infinitime.Device) error { if !k.Bool("weather.enabled") { return nil } @@ -85,24 +74,14 @@ func initWeather(ctx context.Context, wg WaitGroup, dev *infinitime.Device) erro timer := time.NewTimer(time.Hour) - wg.Add(1) go func() { - defer wg.Done("weather") for { - select { - case _, ok := <-ctx.Done(): - if !ok { - return - } - default: - } - // Attempt to get weather data, err := getWeather(ctx, lat, lon) if err != nil { - log.Warn("Error getting weather data").Err(err).Send() + log.Warn().Err(err).Msg("Error getting weather data") // Wait 15 minutes before retrying - sleepCtx(ctx, 15*time.Minute) + time.Sleep(15 * time.Minute) continue } @@ -110,28 +89,81 @@ func initWeather(ctx context.Context, wg WaitGroup, dev *infinitime.Device) erro current := data.Properties.Timeseries[0] currentData := current.Data.Instant.Details - icon := parseSymbol(current.Data.NextHour.Summary.SymbolCode) - if icon == infinitime.WeatherIconClear { - switch { - case currentData.CloudAreaFraction > 50: - icon = infinitime.WeatherIconHeavyClouds - case currentData.CloudAreaFraction == 50: - icon = infinitime.WeatherIconClouds - case currentData.CloudAreaFraction > 0: - icon = infinitime.WeatherIconFewClouds - } - } - - err = dev.SetCurrentWeather(infinitime.CurrentWeather{ - Time: time.Now(), - CurrentTemp: currentData.Temperature, - MaxTemp: current.Data.Next6Hours.Details.MaxTemp, - MinTemp: current.Data.Next6Hours.Details.MinTemp, - Location: k.String("weather.location"), - Icon: icon, + // Add temperature event + err = dev.AddWeatherEvent(weather.TemperatureEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypeTemperature, + time.Hour, + ), + Temperature: int16(round(currentData.AirTemperature * 100)), + DewPoint: int16(round(currentData.DewPoint)), }) if err != nil { - log.Error("Error setting weather").Err(err).Send() + log.Error().Err(err).Msg("Error adding temperature event") + } + + // Add precipitation event + err = dev.AddWeatherEvent(weather.PrecipitationEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypePrecipitation, + time.Hour, + ), + Type: parseSymbol(current.Data.NextHour.Summary.SymbolCode), + Amount: uint8(round(current.Data.NextHour.Details.PrecipitationAmount)), + }) + if err != nil { + log.Error().Err(err).Msg("Error adding precipitation event") + } + + // Add wind event + err = dev.AddWeatherEvent(weather.WindEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypeWind, + time.Hour, + ), + SpeedMin: uint8(round(currentData.WindSpeed)), + SpeedMax: uint8(round(currentData.WindSpeed)), + DirectionMin: uint8(round(currentData.WindDirection)), + DirectionMax: uint8(round(currentData.WindDirection)), + }) + if err != nil { + log.Error().Err(err).Msg("Error adding wind event") + } + + // Add cloud event + err = dev.AddWeatherEvent(weather.CloudsEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypeClouds, + time.Hour, + ), + Amount: uint8(round(currentData.CloudAreaFraction)), + }) + if err != nil { + log.Error().Err(err).Msg("Error adding clouds event") + } + + // Add humidity event + err = dev.AddWeatherEvent(weather.HumidityEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypeHumidity, + time.Hour, + ), + Humidity: uint8(round(currentData.RelativeHumidity)), + }) + if err != nil { + log.Error().Err(err).Msg("Error adding humidity event") + } + + // Add pressure event + err = dev.AddWeatherEvent(weather.PressureEvent{ + TimelineHeader: weather.NewHeader( + weather.EventTypePressure, + time.Hour, + ), + Pressure: int16(round(currentData.AirPressure)), + }) + if err != nil { + log.Error().Err(err).Msg("Error adding pressure event") } // Reset timer to 1 hour @@ -142,8 +174,6 @@ func initWeather(ctx context.Context, wg WaitGroup, dev *infinitime.Device) erro select { case <-timer.C: case <-sendWeatherCh: - case <-ctx.Done(): - return } } }() @@ -159,7 +189,6 @@ func getLocation(ctx context.Context, loc string) (lat, lon float64, err error) if err != nil { return } - req.Header.Set("User-Agent", fmt.Sprintf("ITD/%s gitea.elara.ws/Elara6331/itd", strings.TrimSpace(version))) res, err := http.DefaultClient.Do(req) if err != nil { return @@ -211,7 +240,7 @@ func getWeather(ctx context.Context, lat, lon float64) (*METResponse, error) { } // Set identifying user agent as per NMI requirements - req.Header.Set("User-Agent", fmt.Sprintf("ITD/%s gitea.elara.ws/Elara6331/itd", strings.TrimSpace(version))) + req.Header.Set("User-Agent", fmt.Sprintf("ITD/%s gitea.arsenm.dev/Arsen6331/itd", version)) // Perform request res, err := http.DefaultClient.Do(req) @@ -229,19 +258,26 @@ func getWeather(ctx context.Context, lat, lon float64) (*METResponse, error) { return out, nil } -// parseSymbol determines what weather icon a symbol code codes for. -func parseSymbol(symCode string) infinitime.WeatherIcon { +// parseSymbol determines what type of precipitation a symbol code +// codes for. +func parseSymbol(symCode string) weather.PrecipitationType { switch { case strings.Contains(symCode, "lightrain"): - return infinitime.WeatherIconRain + return weather.PrecipitationTypeRain case strings.Contains(symCode, "rain"): - return infinitime.WeatherIconCloudsWithRain - case strings.Contains(symCode, "snow"), - strings.Contains(symCode, "sleet"): - return infinitime.WeatherIconSnow - case strings.Contains(symCode, "thunder"): - return infinitime.WeatherIconThunderstorm + return weather.PrecipitationTypeRain + case strings.Contains(symCode, "snow"): + return weather.PrecipitationTypeSnow + case strings.Contains(symCode, "sleet"): + return weather.PrecipitationTypeSleet + case strings.Contains(symCode, "snow"): + return weather.PrecipitationTypeSnow default: - return infinitime.WeatherIconClear + return weather.PrecipitationTypeNone } } + +// round rounds 32-bit floats to 32-bit integers +func round(f float32) int32 { + return int32(math.Round(float64(f))) +}