From d199fba93c2fa95d0256c9fd7e22077b4b9b480d Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Fri, 19 Aug 2022 14:02:52 -0700 Subject: [PATCH 01/19] Update go-bluetooth library for 5.65 support --- go.mod | 2 +- go.sum | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 58eed5a..9e885f7 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/fxamacker/cbor/v2 v2.4.0 github.com/godbus/dbus/v5 v5.0.6 - github.com/muka/go-bluetooth v0.0.0-20220219050759-674a63b8741a + github.com/muka/go-bluetooth v0.0.0-20220819140550-1d8857e3b268 github.com/rs/zerolog v1.26.1 golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect ) diff --git a/go.sum b/go.sum index 992599e..aa0b3aa 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/muka/go-bluetooth v0.0.0-20220219050759-674a63b8741a h1:fnzS9RRQW8B5AgNCxkN0vJ/AoX+Xfqk3sAYon3iVrzA= -github.com/muka/go-bluetooth v0.0.0-20220219050759-674a63b8741a/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= From 5af53d1dc68cfd5470152c18564b0fad8e70e67e Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 29 Aug 2022 14:05:33 -0700 Subject: [PATCH 02/19] Fix bug where the filesystem implementation misreports the amount of bytes written, causing functions such as io.Copy() to return an error --- blefs/file.go | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/blefs/file.go b/blefs/file.go index 4a4ee4e..bbe65da 100644 --- a/blefs/file.go +++ b/blefs/file.go @@ -3,7 +3,6 @@ package blefs import ( "io" "io/fs" - "path/filepath" "time" ) @@ -291,7 +290,7 @@ func (fl *File) Write(b []byte) (n int, err error) { } close(fl.offsetCh) - return int(fl.offset), nil + return int(fl.amtTferd), nil } // WriteString converts the string to []byte and calls Write() @@ -335,23 +334,9 @@ func (fl *File) Close() error { return nil } -// Stat does a RedDir() and finds the current file in the output +// Stat does a ReadDir() and finds the current file in the output func (fl *File) Stat() (fs.FileInfo, error) { - // Get directory in filepath - dir := filepath.Dir(fl.path) - // Read directory - dirEntries, err := fl.fs.ReadDir(dir) - if err != nil { - return nil, err - } - for _, entry := range dirEntries { - // If file name is base name of path - if entry.Name() == filepath.Base(fl.path) { - // Return file info - return entry.Info() - } - } - return nil, ErrFileNotExists + return fl.fs.Stat(fl.path) } // fileReadResponse represents a response for a read request From e4c12d32a1eb0c84d862d59ede1e37780601fd23 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 29 Aug 2022 14:06:56 -0700 Subject: [PATCH 03/19] Add Stat() to filesystem implementation --- blefs/basic.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/blefs/basic.go b/blefs/basic.go index 3097d9e..bfb5861 100644 --- a/blefs/basic.go +++ b/blefs/basic.go @@ -1,5 +1,29 @@ package blefs +import ( + "io/fs" + "path/filepath" +) + +// Stat does a ReadDir() and finds the current file in the output +func (blefs *FS) Stat(path string) (fs.FileInfo, error) { + // Get directory in filepath + dir := filepath.Dir(path) + // Read directory + dirEntries, err := blefs.ReadDir(dir) + if err != nil { + return nil, err + } + for _, entry := range dirEntries { + // If file name is base name of path + if entry.Name() == filepath.Base(path) { + // Return file info + return entry.Info() + } + } + return nil, ErrFileNotExists +} + // Rename moves or renames a file or directory func (blefs *FS) Rename(old, new string) error { // Create move request From 0eead333b733c80d79b6e6424b12c8ae0f105e74 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 29 Aug 2022 14:22:02 -0700 Subject: [PATCH 04/19] Add RemoveAll() and MkdirAll() to the filesystem implementation --- blefs/all.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 blefs/all.go diff --git a/blefs/all.go b/blefs/all.go new file mode 100644 index 0000000..a29719c --- /dev/null +++ b/blefs/all.go @@ -0,0 +1,73 @@ +package blefs + +import ( + "fmt" + "path/filepath" + "strings" +) + +func (blefs *FS) RemoveAll(path string) error { + if path == "" { + return nil + } + + if filepath.Clean(path) == "/" { + return ErrNoRemoveRoot + } + + fi, err := blefs.Stat(path) + if err != nil { + return nil + } + + if fi.IsDir() { + return blefs.removeAllChildren(path) + } else { + err = blefs.Remove(path) + if err != nil && err.(FSError).Code != -2 { + return err + } + } + + return nil +} + +func (blefs *FS) removeAllChildren(path string) error { + list, err := blefs.ReadDir(path) + if err != nil { + return err + } + + for _, entry := range list { + if entry.IsDir() { + err = blefs.removeAllChildren(filepath.Join(path, entry.Name())) + } else { + err = blefs.Remove(path) + } + if err != nil { + return err + } + } + + return nil +} + +func (blefs *FS) MkdirAll(path string) error { + if path == "" || path == "/" { + return nil + } + + splitPath := strings.Split(path, "/") + fmt.Println("p", path, splitPath) + for i := 1; i < len(splitPath); i++ { + curPath := strings.Join(splitPath[0:i], "/") + fmt.Println("cp", curPath) + + err := blefs.Mkdir(curPath) + if err != nil && err.(FSError).Code != -17 { + return err + } + } + + return nil +} From b5d345cdec703b08f4f7a0241b1ed24e14435220 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 29 Aug 2022 14:23:10 -0700 Subject: [PATCH 05/19] Remove debug code --- blefs/all.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/blefs/all.go b/blefs/all.go index a29719c..56d82c4 100644 --- a/blefs/all.go +++ b/blefs/all.go @@ -1,7 +1,6 @@ package blefs import ( - "fmt" "path/filepath" "strings" ) @@ -58,10 +57,8 @@ func (blefs *FS) MkdirAll(path string) error { } splitPath := strings.Split(path, "/") - fmt.Println("p", path, splitPath) for i := 1; i < len(splitPath); i++ { curPath := strings.Join(splitPath[0:i], "/") - fmt.Println("cp", curPath) err := blefs.Mkdir(curPath) if err != nil && err.(FSError).Code != -17 { From 3e9957d419616768438692ae476c72a8be8a1649 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 29 Aug 2022 14:43:16 -0700 Subject: [PATCH 06/19] Implement resource loading feature --- blefs/error.go | 1 + blefs/iofs.go | 2 +- go.sum | 2 + resources.go | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 resources.go diff --git a/blefs/error.go b/blefs/error.go index 8441929..7328e2d 100644 --- a/blefs/error.go +++ b/blefs/error.go @@ -13,6 +13,7 @@ var ( ErrOffsetChanged = errors.New("offset has already been changed") ErrReadOpen = errors.New("only one file can be opened for reading at a time") ErrWriteOpen = errors.New("only one file can be opened for writing at a time") + ErrNoRemoveRoot = errors.New("refusing to remove root directory") ) // FSError represents an error returned by BLE FS diff --git a/blefs/iofs.go b/blefs/iofs.go index 05d1c1c..c602926 100644 --- a/blefs/iofs.go +++ b/blefs/iofs.go @@ -12,4 +12,4 @@ func (iofs goFS) Open(path string) (fs.File, error) { func (blefs *FS) GoFS() fs.FS { return goFS{blefs} -} \ No newline at end of file +} diff --git a/go.sum b/go.sum index aa0b3aa..feac569 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/paypal/gatt v0.0.0-20151011220935-4ae819d591cf/go.mod h1:+AwQL2mK3Pd3S+TUwg0tYQjid0q1txyNUJuuSmz8Kdk= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/resources.go b/resources.go new file mode 100644 index 0000000..92e9ddb --- /dev/null +++ b/resources.go @@ -0,0 +1,180 @@ +package infinitime + +import ( + "archive/zip" + "encoding/json" + "io" + "os" + "path/filepath" + + "go.arsenm.dev/infinitime/blefs" +) + +// ResourceOperation represents an operation performed during +// resource loading +type ResourceOperation uint8 + +const ( + // ResourceOperationUpload represents the upload phase + // of resource loading + ResourceOperationUpload = iota + // ResourceOperationRemoveObsolete represents the obsolete + // file removal phase of resource loading + ResourceOperationRemoveObsolete +) + +// 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 int64 + Sent int64 + Err error +} + +// LoadResources accepts a resources zip file and a BLE FS. +// It loads the resources from the zip onto the FS. +func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, error) { + out := make(chan ResourceLoadProgress, 10) + + fi, err := file.Stat() + if err != nil { + return nil, err + } + + r, err := zip.NewReader(file, fi.Size()) + if err != nil { + return nil, err + } + + m, err := r.Open("resources.json") + if err != nil { + return nil, err + } + + var manifest ResourceManifest + err = json.NewDecoder(m).Decode(&manifest) + if err != nil { + return nil, err + } + + go func() { + defer close(out) + + for _, file := range manifest.Obsolete { + name := filepath.Base(file.Path) + + err := fs.RemoveAll(file.Path) + if err != nil { + out <- ResourceLoadProgress{ + Name: name, + Operation: ResourceOperationRemoveObsolete, + Err: err, + } + return + } + + out <- ResourceLoadProgress{ + Name: name, + Operation: ResourceOperationRemoveObsolete, + } + } + + for _, file := range manifest.Resources { + src, err := r.Open(file.Name) + if err != nil { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Err: err, + } + return + } + + srcFi, err := src.Stat() + if err != nil { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Total: srcFi.Size(), + Err: err, + } + return + } + + err = fs.MkdirAll(filepath.Dir(file.Path)) + if err != nil { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Total: srcFi.Size(), + Err: err, + } + return + } + + dst, err := fs.Create(file.Path, uint32(srcFi.Size())) + if err != nil { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Total: srcFi.Size(), + Err: err, + } + return + } + + progCh := dst.Progress() + go func() { + for sent := range progCh { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Total: srcFi.Size(), + Sent: int64(sent), + } + + if sent == uint32(srcFi.Size()) { + return + } + } + }() + + n, err := io.Copy(dst, src) + if err != nil { + out <- ResourceLoadProgress{ + Name: file.Name, + Operation: ResourceOperationUpload, + Total: srcFi.Size(), + Sent: n, + Err: err, + } + return + } + + src.Close() + dst.Close() + } + }() + + return out, nil +} From b476853dc0e3fc641a9fd104fe3847e4ebc09f92 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 16 Oct 2022 12:39:11 -0700 Subject: [PATCH 07/19] Fix RemoveAll() and MkdirAll() functions --- blefs/all.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/blefs/all.go b/blefs/all.go index 56d82c4..7ba9809 100644 --- a/blefs/all.go +++ b/blefs/all.go @@ -38,12 +38,19 @@ func (blefs *FS) removeAllChildren(path string) error { } for _, entry := range list { - if entry.IsDir() { - err = blefs.removeAllChildren(filepath.Join(path, entry.Name())) - } else { - err = blefs.Remove(path) + name := entry.Name() + + if name == "." || name == ".." { + continue } - if err != nil { + entryPath := filepath.Join(path, name) + + if entry.IsDir() { + err = blefs.removeAllChildren(entryPath) + } else { + err = blefs.Remove(entryPath) + } + if err != nil && err.(FSError).Code != -2 { return err } } @@ -58,7 +65,7 @@ func (blefs *FS) MkdirAll(path string) error { splitPath := strings.Split(path, "/") for i := 1; i < len(splitPath); i++ { - curPath := strings.Join(splitPath[0:i], "/") + curPath := strings.Join(splitPath[0:i+1], "/") err := blefs.Mkdir(curPath) if err != nil && err.(FSError).Code != -17 { From 01970b2bb7701a5e78e35348247eb4292cc12b0d Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 16 Oct 2022 12:39:42 -0700 Subject: [PATCH 08/19] Add debug logging to resource loading --- resources.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/resources.go b/resources.go index 92e9ddb..4eb7307 100644 --- a/resources.go +++ b/resources.go @@ -77,12 +77,16 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er return nil, err } + log.Debug().Msg("Decoded manifest file") + go func() { defer close(out) for _, file := range manifest.Obsolete { name := filepath.Base(file.Path) + log.Debug().Str("file", file.Path).Msg("Removing file") + err := fs.RemoveAll(file.Path) if err != nil { out <- ResourceLoadProgress{ @@ -93,6 +97,8 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er return } + log.Debug().Str("file", file.Path).Msg("Removed file") + out <- ResourceLoadProgress{ Name: name, Operation: ResourceOperationRemoveObsolete, @@ -121,8 +127,11 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er return } + log.Debug().Str("file", file.Path).Msg("Making directories") + err = fs.MkdirAll(filepath.Dir(file.Path)) if err != nil { + log.Debug().Err(err).Msg("Error making directories") out <- ResourceLoadProgress{ Name: file.Name, Operation: ResourceOperationUpload, @@ -132,8 +141,14 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er return } + log.Debug(). + Str("file", file.Path). + Int64("size", srcFi.Size()). + Msg("Creating file") + dst, err := fs.Create(file.Path, uint32(srcFi.Size())) if err != nil { + log.Debug().Err(err).Msg("Error creating file") out <- ResourceLoadProgress{ Name: file.Name, Operation: ResourceOperationUpload, @@ -146,6 +161,11 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er progCh := dst.Progress() go func() { for sent := range progCh { + log.Debug(). + Int64("total", srcFi.Size()). + Uint32("sent", sent). + Msg("Progress event sent") + out <- ResourceLoadProgress{ Name: file.Name, Operation: ResourceOperationUpload, @@ -161,6 +181,7 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er n, err := io.Copy(dst, src) if err != nil { + log.Debug().Err(err).Msg("Error writing to file") out <- ResourceLoadProgress{ Name: file.Name, Operation: ResourceOperationUpload, From bb017b471ebec09d2f020c3cb144c3a028b60f34 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 17 Oct 2022 12:19:23 -0700 Subject: [PATCH 09/19] Stop DBus errors from causing panics by checking error type (Arsen6331/itd#29) --- blefs/all.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/blefs/all.go b/blefs/all.go index 7ba9809..5978de2 100644 --- a/blefs/all.go +++ b/blefs/all.go @@ -23,7 +23,13 @@ func (blefs *FS) RemoveAll(path string) error { return blefs.removeAllChildren(path) } else { err = blefs.Remove(path) - if err != nil && err.(FSError).Code != -2 { + + var code int8 + if err, ok := err.(FSError); ok { + code = err.Code + } + + if err != nil && code != -2 { return err } } @@ -50,7 +56,13 @@ func (blefs *FS) removeAllChildren(path string) error { } else { err = blefs.Remove(entryPath) } - if err != nil && err.(FSError).Code != -2 { + + var code int8 + if err, ok := err.(FSError); ok { + code = err.Code + } + + if err != nil && code != -2 { return err } } @@ -68,7 +80,13 @@ func (blefs *FS) MkdirAll(path string) error { curPath := strings.Join(splitPath[0:i+1], "/") err := blefs.Mkdir(curPath) - if err != nil && err.(FSError).Code != -17 { + + var code int8 + if err, ok := err.(FSError); ok { + code = err.Code + } + + if err != nil && code != -17 { return err } } From a01f1b9d92cb915214e64b911380092ab5d6943a Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Mon, 17 Oct 2022 12:49:49 -0700 Subject: [PATCH 10/19] Close files properly when returning an error (Arsen6331/itd#29) --- resources.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/resources.go b/resources.go index 4eb7307..4f753cf 100644 --- a/resources.go +++ b/resources.go @@ -70,6 +70,7 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er if err != nil { return nil, err } + defer m.Close() var manifest ResourceManifest err = json.NewDecoder(m).Decode(&manifest) @@ -77,6 +78,8 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er return nil, err } + m.Close() + log.Debug().Msg("Decoded manifest file") go func() { @@ -124,6 +127,7 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er Total: srcFi.Size(), Err: err, } + src.Close() return } @@ -138,6 +142,7 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er Total: srcFi.Size(), Err: err, } + src.Close() return } @@ -155,6 +160,7 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er Total: srcFi.Size(), Err: err, } + src.Close() return } @@ -189,6 +195,8 @@ func LoadResources(file *os.File, fs *blefs.FS) (<-chan ResourceLoadProgress, er Sent: n, Err: err, } + src.Close() + dst.Close() return } From 54fdd19bec3c6db666377d623f664cc083e79b47 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Thu, 20 Oct 2022 01:41:15 -0700 Subject: [PATCH 11/19] Use timestamp with timezone offset to (finally) fix weather issue --- weather/weather.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/weather/weather.go b/weather/weather.go index 7a8765d..1265c50 100644 --- a/weather/weather.go +++ b/weather/weather.go @@ -82,8 +82,12 @@ type TimelineHeader struct { // NewHeader creates and populates a new timeline header // and returns it func NewHeader(evtType EventType, expires time.Duration) TimelineHeader { + now := time.Now() + _, offset := now.Zone() + now = now.Add(time.Duration(offset) * time.Second) + return TimelineHeader{ - Timestamp: uint64(time.Now().Unix()), + Timestamp: uint64(now.Unix()), Expires: uint32(expires.Seconds()), EventType: evtType, } From 0ad671d3f5505e2e318b73c5356e159b82a08375 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Tue, 25 Oct 2022 12:36:34 -0700 Subject: [PATCH 12/19] Assume MTU if not available from BlueZ --- blefs/fs.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/blefs/fs.go b/blefs/fs.go index 6d9d06f..6f2ade9 100644 --- a/blefs/fs.go +++ b/blefs/fs.go @@ -199,7 +199,13 @@ func decode(data []byte, vals ...interface{}) error { // to send in a packet. Subtracting 20 ensures that the MTU // is never exceeded. func (blefs *FS) maxData() uint16 { - return blefs.transferChar.Properties.MTU - 20 + mtu := blefs.transferChar.Properties.MTU + // If MTU is zero, the current version of BlueZ likely + // doesn't support the MTU property, so assume 256. + if mtu == 0 { + mtu = 256 + } + return mtu - 20 } // padding returns a slice of len amount of 0x00. From 1f5301f5de9c2e8d67cb4049b6dbaa6c963ce3e1 Mon Sep 17 00:00:00 2001 From: yannickulrich Date: Thu, 3 Nov 2022 19:09:06 +0000 Subject: [PATCH 13/19] Added Navigation service (#5) InfiniTime implements a [Navigation Service](https://github.com/InfiniTimeOrg/InfiniTime/blob/develop/doc/NavigationService.md). This pull request will add it to the go library by defining a function ```go func (i *Device) Navigation(flag string, narrative string, dist string, progress uint8) error { ... } ``` From the InfiniTime manual * `flag`: the graphic instruction as provided by [Pure Maps](https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation). A list of valid instruction icons can be found [here](https://github.com/rinigus/pure-maps/tree/master/qml/icons/navigation) * `narrative`: the instruction in words, eg. "At the roundabout take the first exit". * `dist`: a short string describing the distance to the upcoming instruction such as "50 m". * `progress`: the percent complete in a `uint8` Adding this to the `itd` daemon is straightforward ```patch diff --git a/api/types.go b/api/types.go index 281a85b..14c84de 100644 --- a/api/types.go +++ b/api/types.go @@ -22,6 +22,13 @@ type FwUpgradeData struct { Files []string } +type NavigationData struct { + Flag string + Narrative string + Dist string + Progress uint8 +} + type NotifyData struct { Title string Body string diff --git a/socket.go b/socket.go index 6fcba5c..91b37c0 100644 --- a/socket.go +++ b/socket.go @@ -204,6 +204,10 @@ func (i *ITD) Address(_ *server.Context) string { return i.dev.Address() } +func (i *ITD) Navigation(_ *server.Context, data api.NavigationData) error { + return i.dev.Navigation(data.Flag, data.Narrative, data.Dist, data.Progress) +} + func (i *ITD) Notify(_ *server.Context, data api.NotifyData) error { return i.dev.Notify(data.Title, data.Body) } ``` Co-authored-by: Yannick Ulrich Reviewed-on: https://gitea.arsenm.dev/Arsen6331/infinitime/pulls/5 Co-authored-by: yannickulrich Co-committed-by: yannickulrich --- README.md | 1 + infinitime.go | 16 +++++ navigation.go | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 navigation.go diff --git a/README.md b/README.md index 9a7c7fa..37210a7 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ This library currently supports the following features: - Battery level - Music control - OTA firmware upgrades +- Navigation --- diff --git a/infinitime.go b/infinitime.go index d48e902..e234949 100644 --- a/infinitime.go +++ b/infinitime.go @@ -52,6 +52,10 @@ var charNames = map[string]string{ FSTransferChar: "Filesystem Transfer", FSVersionChar: "Filesystem Version", WeatherDataChar: "Weather Data", + NavFlagsChar: "Navigation Icon", + NavNarrativeChar:"Navigation Instruction", + NavManDistChar: "Navigation Distance to next event", + NavProgressChar: "Navigation Progress", } type Device struct { @@ -67,10 +71,13 @@ type Device struct { fsVersionChar *gatt.GattCharacteristic1 fsTransferChar *gatt.GattCharacteristic1 weatherDataChar *gatt.GattCharacteristic1 + weatherdataChar *gatt.GattCharacteristic1 notifEventCh chan uint8 notifEventDone bool Music MusicCtrl + Navigation NavigationCtrl DFU DFU + navigationEv NavigationEvent } var ( @@ -394,6 +401,14 @@ func (i *Device) resolveChars() error { charResolved := true // Set correct characteristics switch char.Properties.UUID { + case NavFlagsChar: + i.Navigation.flagsChar = char + case NavNarrativeChar: + i.Navigation.narrativeChar = char + case NavManDistChar: + i.Navigation.mandistChar = char + case NavProgressChar: + i.Navigation.progressChar = char case NewAlertChar: i.newAlertChar = char case NotifEventChar: @@ -723,6 +738,7 @@ func (i *Device) Notify(title, body string) error { ) } + // These constants represent the possible call statuses selected by the user const ( CallStatusDeclined uint8 = iota diff --git a/navigation.go b/navigation.go new file mode 100644 index 0000000..16e7da4 --- /dev/null +++ b/navigation.go @@ -0,0 +1,188 @@ +package infinitime + +import ( + "bytes" + "encoding/binary" + "errors" + "github.com/muka/go-bluetooth/bluez/profile/gatt" +) + +const ( + NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0" + NavNarrativeChar= "00010002-78fc-48fe-8e23-433b3a1942d0" + NavManDistChar = "00010003-78fc-48fe-8e23-433b3a1942d0" + NavProgressChar = "00010004-78fc-48fe-8e23-433b3a1942d0" +) + +type NavigationCtrl struct { + flagsChar *gatt.GattCharacteristic1 + narrativeChar*gatt.GattCharacteristic1 + mandistChar *gatt.GattCharacteristic1 + progressChar *gatt.GattCharacteristic1 +} + +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" + NavFlagTurnStright NavFlag = "turn-stright" + NavFlagUpdown NavFlag = "updown" + NavFlagUturn NavFlag = "uturn" +) + +type NavigationEvent struct { + Flag NavFlag + Narrative string + Dist string + Progress uint8 +} + +var ( + ErrNavProgress = errors.New("progress needs to between 0 and 100") + ErrNavInvalidFlag = errors.New("this flag is invalid") +) + +// Navigation sends a NavigationEvent to the watch +func (i *Device) SetNavigation(ev NavigationEvent) error { + if ev.Progress > 100 { + return ErrNavProgress + } + + if ev.Flag != i.navigationEv.Flag { + log.Debug().Str("func", "Navigation"). + Msg("Sending flag") + if err := i.checkStatus(i.Navigation.flagsChar, NavFlagsChar); err != nil { + return err + } + if err := i.Navigation.flagsChar.WriteValue([]byte(ev.Flag), nil); err != nil { + return err + } + i.navigationEv.Flag = ev.Flag + } + + if ev.Narrative != i.navigationEv.Narrative { + log.Debug().Str("func", "Navigation"). + Msg("Sending narrative") + if err := i.checkStatus(i.Navigation.narrativeChar, NavNarrativeChar); err != nil { + return err + } + if err := i.Navigation.narrativeChar.WriteValue([]byte(ev.Narrative), nil); err != nil { + return err + } + i.navigationEv.Narrative = ev.Narrative + } + + if ev.Dist != i.navigationEv.Dist { + log.Debug().Str("func", "Navigation"). + Msg("Sending mandist") + if err := i.checkStatus(i.Navigation.mandistChar, NavManDistChar); err != nil { + return err + } + if err := i.Navigation.mandistChar.WriteValue([]byte(ev.Dist), nil); err != nil { + return err + } + i.navigationEv.Dist = ev.Dist + } + + if ev.Progress != i.navigationEv.Progress { + log.Debug().Str("func", "Navigation"). + Msg("Sending progress") + if err := i.checkStatus(i.Navigation.progressChar, NavProgressChar); err != nil { + return err + } + buf := &bytes.Buffer{} + binary.Write(buf, binary.LittleEndian, ev.Progress) + if err := i.Navigation.progressChar.WriteValue(buf.Bytes(), nil); err != nil { + return err + } + i.navigationEv.Progress = ev.Progress + } + + return nil +} From e6fb402c0c4d1e56359305f64bfa7d42df885bc7 Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sat, 5 Nov 2022 20:33:30 -0700 Subject: [PATCH 14/19] Remove check for unchanged values and refactor code --- infinitime.go | 34 ++++++++--------- navigation.go | 100 ++++++++++++++++++++------------------------------ 2 files changed, 55 insertions(+), 79 deletions(-) diff --git a/infinitime.go b/infinitime.go index e234949..a042483 100644 --- a/infinitime.go +++ b/infinitime.go @@ -41,21 +41,21 @@ const ( ) var charNames = map[string]string{ - NewAlertChar: "New Alert", - NotifEventChar: "Notification Event", - StepCountChar: "Step Count", - MotionValChar: "Motion Values", - FirmwareVerChar: "Firmware Version", - CurrentTimeChar: "Current Time", - BatteryLvlChar: "Battery Level", - HeartRateChar: "Heart Rate", - FSTransferChar: "Filesystem Transfer", - FSVersionChar: "Filesystem Version", - WeatherDataChar: "Weather Data", - NavFlagsChar: "Navigation Icon", - NavNarrativeChar:"Navigation Instruction", - NavManDistChar: "Navigation Distance to next event", - NavProgressChar: "Navigation Progress", + NewAlertChar: "New Alert", + NotifEventChar: "Notification Event", + StepCountChar: "Step Count", + MotionValChar: "Motion Values", + FirmwareVerChar: "Firmware Version", + CurrentTimeChar: "Current Time", + BatteryLvlChar: "Battery Level", + HeartRateChar: "Heart Rate", + FSTransferChar: "Filesystem Transfer", + FSVersionChar: "Filesystem Version", + WeatherDataChar: "Weather Data", + NavFlagsChar: "Navigation Icon", + NavNarrativeChar: "Navigation Instruction", + NavManDistChar: "Navigation Distance to next event", + NavProgressChar: "Navigation Progress", } type Device struct { @@ -75,9 +75,8 @@ type Device struct { notifEventCh chan uint8 notifEventDone bool Music MusicCtrl - Navigation NavigationCtrl + Navigation NavigationService DFU DFU - navigationEv NavigationEvent } var ( @@ -738,7 +737,6 @@ func (i *Device) Notify(title, body string) error { ) } - // These constants represent the possible call statuses selected by the user const ( CallStatusDeclined uint8 = iota diff --git a/navigation.go b/navigation.go index 16e7da4..faecd50 100644 --- a/navigation.go +++ b/navigation.go @@ -1,27 +1,26 @@ package infinitime import ( - "bytes" - "encoding/binary" "errors" "github.com/muka/go-bluetooth/bluez/profile/gatt" ) const ( - NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0" - NavNarrativeChar= "00010002-78fc-48fe-8e23-433b3a1942d0" - NavManDistChar = "00010003-78fc-48fe-8e23-433b3a1942d0" - NavProgressChar = "00010004-78fc-48fe-8e23-433b3a1942d0" + NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0" + NavNarrativeChar = "00010002-78fc-48fe-8e23-433b3a1942d0" + NavManDistChar = "00010003-78fc-48fe-8e23-433b3a1942d0" + NavProgressChar = "00010004-78fc-48fe-8e23-433b3a1942d0" ) -type NavigationCtrl struct { - flagsChar *gatt.GattCharacteristic1 - narrativeChar*gatt.GattCharacteristic1 - mandistChar *gatt.GattCharacteristic1 - progressChar *gatt.GattCharacteristic1 +type NavigationService struct { + flagsChar *gatt.GattCharacteristic1 + narrativeChar *gatt.GattCharacteristic1 + mandistChar *gatt.GattCharacteristic1 + progressChar *gatt.GattCharacteristic1 } type NavFlag string + const ( NavFlagArrive NavFlag = "arrive" NavFlagArriveLeft NavFlag = "arrive-left" @@ -117,16 +116,13 @@ const ( ) type NavigationEvent struct { - Flag NavFlag - Narrative string - Dist string - Progress uint8 + Flag NavFlag + Narrative string + Dist string + Progress uint8 } -var ( - ErrNavProgress = errors.New("progress needs to between 0 and 100") - ErrNavInvalidFlag = errors.New("this flag is invalid") -) +var ErrNavProgress = errors.New("progress needs to between 0 and 100") // Navigation sends a NavigationEvent to the watch func (i *Device) SetNavigation(ev NavigationEvent) error { @@ -134,54 +130,36 @@ func (i *Device) SetNavigation(ev NavigationEvent) error { return ErrNavProgress } - if ev.Flag != i.navigationEv.Flag { - log.Debug().Str("func", "Navigation"). - Msg("Sending flag") - if err := i.checkStatus(i.Navigation.flagsChar, NavFlagsChar); err != nil { - return err - } - if err := i.Navigation.flagsChar.WriteValue([]byte(ev.Flag), nil); err != nil { - return err - } - i.navigationEv.Flag = ev.Flag + log.Debug().Str("func", "SetNavigation").Msg("Sending flag") + if err := i.checkStatus(i.Navigation.flagsChar, NavFlagsChar); err != nil { + return err + } + if err := i.Navigation.flagsChar.WriteValue([]byte(ev.Flag), nil); err != nil { + return err } - if ev.Narrative != i.navigationEv.Narrative { - log.Debug().Str("func", "Navigation"). - Msg("Sending narrative") - if err := i.checkStatus(i.Navigation.narrativeChar, NavNarrativeChar); err != nil { - return err - } - if err := i.Navigation.narrativeChar.WriteValue([]byte(ev.Narrative), nil); err != nil { - return err - } - i.navigationEv.Narrative = ev.Narrative + log.Debug().Str("func", "SetNavigation").Msg("Sending narrative") + if err := i.checkStatus(i.Navigation.narrativeChar, NavNarrativeChar); err != nil { + return err + } + if err := i.Navigation.narrativeChar.WriteValue([]byte(ev.Narrative), nil); err != nil { + return err } - if ev.Dist != i.navigationEv.Dist { - log.Debug().Str("func", "Navigation"). - Msg("Sending mandist") - if err := i.checkStatus(i.Navigation.mandistChar, NavManDistChar); err != nil { - return err - } - if err := i.Navigation.mandistChar.WriteValue([]byte(ev.Dist), nil); err != nil { - return err - } - i.navigationEv.Dist = ev.Dist + log.Debug().Str("func", "SetNavigation").Msg("Sending mandist") + if err := i.checkStatus(i.Navigation.mandistChar, NavManDistChar); err != nil { + return err + } + if err := i.Navigation.mandistChar.WriteValue([]byte(ev.Dist), nil); err != nil { + return err } - if ev.Progress != i.navigationEv.Progress { - log.Debug().Str("func", "Navigation"). - Msg("Sending progress") - if err := i.checkStatus(i.Navigation.progressChar, NavProgressChar); err != nil { - return err - } - buf := &bytes.Buffer{} - binary.Write(buf, binary.LittleEndian, ev.Progress) - if err := i.Navigation.progressChar.WriteValue(buf.Bytes(), nil); err != nil { - return err - } - i.navigationEv.Progress = ev.Progress + log.Debug().Str("func", "SetNavigation").Msg("Sending progress") + if err := i.checkStatus(i.Navigation.progressChar, NavProgressChar); err != nil { + return err + } + if err := i.Navigation.progressChar.WriteValue([]byte{ev.Progress}, nil); err != nil { + return err } return nil From 8e5bbafba82557a2d0bd23a8099813b58bc9b68b Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sat, 5 Nov 2022 20:54:45 -0700 Subject: [PATCH 15/19] Fix typo --- navigation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/navigation.go b/navigation.go index faecd50..bc6dfd9 100644 --- a/navigation.go +++ b/navigation.go @@ -122,7 +122,7 @@ type NavigationEvent struct { Progress uint8 } -var ErrNavProgress = errors.New("progress needs to between 0 and 100") +var ErrNavProgress = errors.New("progress needs to be between 0 and 100") // Navigation sends a NavigationEvent to the watch func (i *Device) SetNavigation(ev NavigationEvent) error { From 31f4c51a6141d9a12c0cf98a7b1a0aaaacc6183e Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 6 Nov 2022 20:08:13 -0800 Subject: [PATCH 16/19] Improve navigation API --- infinitime.go | 1 + navigation.go | 73 ++++++++++++++++++++------------------------------- 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/infinitime.go b/infinitime.go index a042483..10e9f25 100644 --- a/infinitime.go +++ b/infinitime.go @@ -136,6 +136,7 @@ func Connect(ctx context.Context, opts *Options) (*Device, error) { // Create new device out := &Device{device: btDev} + out.Navigation = NavigationService{dev: out} // Resolve characteristics err = out.resolveChars() diff --git a/navigation.go b/navigation.go index bc6dfd9..73d93b0 100644 --- a/navigation.go +++ b/navigation.go @@ -5,6 +5,8 @@ import ( "github.com/muka/go-bluetooth/bluez/profile/gatt" ) +var ErrNavProgress = errors.New("progress needs to be between 0 and 100") + const ( NavFlagsChar = "00010001-78fc-48fe-8e23-433b3a1942d0" NavNarrativeChar = "00010002-78fc-48fe-8e23-433b3a1942d0" @@ -13,6 +15,7 @@ const ( ) type NavigationService struct { + dev *Device flagsChar *gatt.GattCharacteristic1 narrativeChar *gatt.GattCharacteristic1 mandistChar *gatt.GattCharacteristic1 @@ -115,52 +118,34 @@ const ( NavFlagUturn NavFlag = "uturn" ) -type NavigationEvent struct { - Flag NavFlag - Narrative string - Dist string - Progress uint8 +func (n *NavigationService) SetFlag(flag string) error { + log.Debug().Str("func", "SetFlag").Msg("Sending flag") + if err := n.dev.checkStatus(n.flagsChar, NavFlagsChar); err != nil { + return err + } + return n.flagsChar.WriteValue([]byte(flag), nil) } -var ErrNavProgress = errors.New("progress needs to be between 0 and 100") - -// Navigation sends a NavigationEvent to the watch -func (i *Device) SetNavigation(ev NavigationEvent) error { - if ev.Progress > 100 { - return ErrNavProgress - } - - log.Debug().Str("func", "SetNavigation").Msg("Sending flag") - if err := i.checkStatus(i.Navigation.flagsChar, NavFlagsChar); err != nil { +func (n *NavigationService) SetNarrative(narrative string) error { + log.Debug().Str("func", "SetNarrative").Msg("Sending narrative") + if err := n.dev.checkStatus(n.narrativeChar, NavNarrativeChar); err != nil { return err } - if err := i.Navigation.flagsChar.WriteValue([]byte(ev.Flag), nil); err != nil { - return err - } - - log.Debug().Str("func", "SetNavigation").Msg("Sending narrative") - if err := i.checkStatus(i.Navigation.narrativeChar, NavNarrativeChar); err != nil { - return err - } - if err := i.Navigation.narrativeChar.WriteValue([]byte(ev.Narrative), nil); err != nil { - return err - } - - log.Debug().Str("func", "SetNavigation").Msg("Sending mandist") - if err := i.checkStatus(i.Navigation.mandistChar, NavManDistChar); err != nil { - return err - } - if err := i.Navigation.mandistChar.WriteValue([]byte(ev.Dist), nil); err != nil { - return err - } - - log.Debug().Str("func", "SetNavigation").Msg("Sending progress") - if err := i.checkStatus(i.Navigation.progressChar, NavProgressChar); err != nil { - return err - } - if err := i.Navigation.progressChar.WriteValue([]byte{ev.Progress}, nil); err != nil { - return err - } - - return nil + return n.narrativeChar.WriteValue([]byte(narrative), nil) +} + +func (n *NavigationService) SetManDist(manDist string) error { + log.Debug().Str("func", "SetNarrative").Msg("Sending maneuver distance") + if err := n.dev.checkStatus(n.mandistChar, NavManDistChar); err != nil { + return err + } + return n.mandistChar.WriteValue([]byte(manDist), nil) +} + +func (n *NavigationService) SetProgress(progress uint8) error { + log.Debug().Str("func", "SetNarrative").Msg("Sending progress") + if err := n.dev.checkStatus(n.progressChar, NavProgressChar); err != nil { + return err + } + return n.progressChar.WriteValue([]byte{progress}, nil) } From 72b558707ee3096d4a77d262025c3bf695073fcf Mon Sep 17 00:00:00 2001 From: Arsen Musayelyan Date: Sun, 6 Nov 2022 20:20:15 -0800 Subject: [PATCH 17/19] Use NavFlag type in SetFlag() --- navigation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/navigation.go b/navigation.go index 73d93b0..ff44a36 100644 --- a/navigation.go +++ b/navigation.go @@ -118,7 +118,7 @@ const ( NavFlagUturn NavFlag = "uturn" ) -func (n *NavigationService) SetFlag(flag string) error { +func (n *NavigationService) SetFlag(flag NavFlag) error { log.Debug().Str("func", "SetFlag").Msg("Sending flag") if err := n.dev.checkStatus(n.flagsChar, NavFlagsChar); err != nil { return err From 76809726d5b712099ff705bb8bdaeef6583df4db Mon Sep 17 00:00:00 2001 From: razorkitty Date: Sat, 19 Nov 2022 21:30:54 +0000 Subject: [PATCH 18/19] replace pactl based volume control with mpris based volume control methods --- pkg/player/pactl.go | 16 ---------------- pkg/player/player.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 16 deletions(-) delete mode 100644 pkg/player/pactl.go diff --git a/pkg/player/pactl.go b/pkg/player/pactl.go deleted file mode 100644 index 3dc3441..0000000 --- a/pkg/player/pactl.go +++ /dev/null @@ -1,16 +0,0 @@ -package player - -import ( - "fmt" - "os/exec" -) - -// VolUp uses pactl to increase the volume of the default sink -func VolUp(percent uint) error { - return exec.Command("pactl", "set-sink-volume", "@DEFAULT_SINK@", fmt.Sprintf("+%d%%", percent)).Run() -} - -// VolDown uses pactl to decrease the volume of the default sink -func VolDown(percent uint) error { - return exec.Command("pactl", "set-sink-volume", "@DEFAULT_SINK@", fmt.Sprintf("-%d%%", percent)).Run() -} diff --git a/pkg/player/player.go b/pkg/player/player.go index 6f3e202..5358a80 100644 --- a/pkg/player/player.go +++ b/pkg/player/player.go @@ -107,6 +107,46 @@ func Prev() error { return nil } +func VolUp(percent uint) error { + + player, err := getPlayerObj() + if err != nil { + return err + } + if player != nil { + currentVal, err := player.GetProperty("org.mpris.MediaPlayer2.Player.Volume") + if err != nil { + return err + } + newVal := currentVal.Value().(float64) + (float64(percent) / 100) + err = player.SetProperty("org.mpris.MediaPlayer2.Player.Volume", newVal) + if err != nil { + return err + } + } + return nil +} + +func VolDown(percent uint) error { + + player, err := getPlayerObj() + if err != nil { + return err + } + if player != nil { + currentVal, err := player.GetProperty("org.mpris.MediaPlayer2.Player.Volume") + if err != nil { + return err + } + newVal := currentVal.Value().(float64) - (float64(percent) / 100) + err = player.SetProperty("org.mpris.MediaPlayer2.Player.Volume", newVal) + if err != nil { + return err + } + } + return nil +} + type ChangeType int const ( From 5fb5cf4b928bb0962a4c17fd94ea63eb8a98139b Mon Sep 17 00:00:00 2001 From: razorkitty Date: Sat, 19 Nov 2022 22:43:03 +0000 Subject: [PATCH 19/19] removed pulseaudio-utils and libpulse dependencies --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 37210a7..3494639 100644 --- a/README.md +++ b/README.md @@ -15,24 +15,24 @@ This library's import path is `go.arsenm.dev/infinitime`. ### Dependencies -This library requires `dbus`, `bluez`, and `pactl` to function. These allow the library to use bluetooth, control media, control volume, etc. +This library requires `dbus`, and `bluez` to function. These allow the library to use bluetooth, control media, control volume, etc. #### Arch ```shell -sudo pacman -S dbus bluez libpulse --needed +sudo pacman -S dbus bluez --needed ``` #### Debian/Ubuntu ```shell -sudo apt install dbus bluez pulseaudio-utils +sudo apt install dbus bluez ``` #### Fedora ```shell -sudo dnf install dbus bluez pulseaudio-utils +sudo dnf install dbus bluez ``` --- @@ -53,4 +53,4 @@ This library currently supports the following features: ### Mentions -The DFU process used in this library was created with the help of [siglo](https://github.com/alexr4535/siglo)'s source code. Specifically, this file: [ble_dfu.py](https://github.com/alexr4535/siglo/blob/main/src/ble_dfu.py) \ No newline at end of file +The DFU process used in this library was created with the help of [siglo](https://github.com/alexr4535/siglo)'s source code. Specifically, this file: [ble_dfu.py](https://github.com/alexr4535/siglo/blob/main/src/ble_dfu.py)