Merge pull request 'Major refactor in attempt to resolve many issues across the application.' (#44) from issues-6-26-2026 into dev
Reviewed-on: https://codeberg.org/RhemaWave-Technologies/RhemaWave/pulls/44
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
# binaries instead of building everything from source, resulting in faster
|
||||
# updates, once updates work again that is...
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added proclamation sync when entering "proclamations" settings page
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed audio devices page to be strictly an audio on/off toggle
|
||||
- Changed settings menu items to be left-aligned with eachother
|
||||
- Changed settings entry organization
|
||||
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed list of audio devices from audio device page
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed audio device not being initialized on first entry to F2 screen
|
||||
|
||||
### Security
|
||||
|
||||
---
|
||||
|
||||
@@ -8,11 +8,11 @@ require github.com/veandco/go-sdl2 v0.4.40
|
||||
|
||||
require github.com/go-gl/mathgl v1.2.0
|
||||
|
||||
require (
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71
|
||||
github.com/godbus/dbus/v5 v5.1.0
|
||||
github.com/google/uuid v1.6.0
|
||||
)
|
||||
require github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71
|
||||
|
||||
require github.com/Wifx/gonetworkmanager/v2 v2.2.0
|
||||
|
||||
require github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
|
||||
require (
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
github.com/Wifx/gonetworkmanager/v2 v2.2.0 h1:kPstgsQtY8CmDOOFZd81ytM9Gi3f6ImzPCKF7nNhQ2U=
|
||||
github.com/Wifx/gonetworkmanager/v2 v2.2.0/go.mod h1:fMDb//SHsKWxyDUAwXvCqurV3npbIyyaQWenGpZ/uXg=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||
github.com/go-gl/mathgl v1.2.0 h1:v2eOj/y1B2afDxF6URV1qCYmo1KW08lAMtTbOn3KXCY=
|
||||
github.com/go-gl/mathgl v1.2.0/go.mod h1:pf9+b5J3LFP7iZ4XXaVzZrCle0Q/vNpB/vDe5+3ulRE=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
@@ -51,7 +50,6 @@ type Application struct {
|
||||
pendingAction func()
|
||||
running bool
|
||||
DB *gorm.DB
|
||||
Config atomic.Pointer[db.AppConfig]
|
||||
PageRouter *page.Router
|
||||
state State
|
||||
}
|
||||
@@ -68,8 +66,6 @@ func Run() {
|
||||
var homeDir string
|
||||
var dataDir string
|
||||
var DB *gorm.DB
|
||||
var initialConfig db.AppConfig
|
||||
var result *gorm.DB
|
||||
|
||||
networkIsUp = false
|
||||
|
||||
@@ -110,14 +106,15 @@ func Run() {
|
||||
return
|
||||
}
|
||||
|
||||
// Populate the initial Config cache OR create defaults
|
||||
firstRun := false
|
||||
result = DB.First(&initialConfig)
|
||||
if result.Error != nil {
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
logger.Info("First run detected: Creating default configuration...")
|
||||
|
||||
// Populate the initial Config cache OR create defaults
|
||||
cfg, err := db.GetConfig(DB)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
firstRun = true
|
||||
initialConfig = db.AppConfig{
|
||||
cfg = &db.AppConfig{
|
||||
Model: gorm.Model{ID: 1},
|
||||
DataDir: dataDir,
|
||||
AssetsDir: dataDir,
|
||||
SystemLevel: "BASIC",
|
||||
@@ -128,13 +125,11 @@ func Run() {
|
||||
AudioEnabled: true,
|
||||
SavedVolume: 1.0,
|
||||
}
|
||||
if err := DB.Create(&initialConfig).Error; err != nil {
|
||||
logger.Error("failed to insert default config into database: %v", err)
|
||||
|
||||
if err := DB.Create(cfg).Error; err != nil {
|
||||
logger.Error("failed to create config: %v", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.Error("error querying database for initial config: %v", result.Error)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +143,6 @@ func Run() {
|
||||
app.state = FIRST_RUN
|
||||
}
|
||||
|
||||
app.refreshCache()
|
||||
|
||||
w, h := app.initializeSDLAndOpenGL()
|
||||
defer app.cleanup()
|
||||
|
||||
@@ -159,12 +152,10 @@ func Run() {
|
||||
downloadProgressChan := make(chan download.DownloadStatus, 1000)
|
||||
|
||||
app.PageRouter = page.NewRouter(page.PageCtx{
|
||||
CfgPtr: app.Config.Load(),
|
||||
DbPtr: app.DB,
|
||||
W: w,
|
||||
H: h,
|
||||
MessageChannel: downloadProgressChan,
|
||||
RefreshConfig: app.refreshCache,
|
||||
})
|
||||
|
||||
// Sync the proclamations from the API to the Database
|
||||
@@ -188,7 +179,12 @@ func Run() {
|
||||
"PinealGland.wav",
|
||||
}
|
||||
|
||||
go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(app.PageRouter.Context.CfgPtr.AssetsDir, "audio"))
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go download.DownloadAudioFiles(app.PageRouter.Context.MessageChannel, audioFileNames, filepath.Join(config.AssetsDir, "audio"))
|
||||
|
||||
app.runEventLoop()
|
||||
}
|
||||
@@ -204,25 +200,16 @@ func (app *Application) checkState() {
|
||||
// Check if there is an internet connection, and if not, force the WiFi page
|
||||
if !networkIsUp {
|
||||
if lastNetworkCheckTime.IsZero() || time.Since(lastNetworkCheckTime) >= time.Second {
|
||||
networkManager, err := network.New()
|
||||
if err != nil {
|
||||
logger.Error("error obtaining a network manager %v", err)
|
||||
return
|
||||
}
|
||||
lastNetworkCheckTime = time.Now()
|
||||
status, err := networkManager.CheckInternetConnection()
|
||||
if err != nil {
|
||||
logger.Error("error checking for internet connection %v", err)
|
||||
return
|
||||
}
|
||||
if status.StatusCode != network.StatusWifiConnectedInternetUp &&
|
||||
status.StatusCode != network.StatusEthernetConnectedInternetUp {
|
||||
|
||||
if !network.HasInternet() {
|
||||
if app.state != NEEDS_INTERNET {
|
||||
app.PageRouter.NavigateTo(page.WIFI)
|
||||
app.state = NEEDS_INTERNET
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
networkIsUp = true // internet confirmed, don't check again
|
||||
} else {
|
||||
return // throttled, and we don't yet know if network is up — can't proceed
|
||||
@@ -230,7 +217,12 @@ func (app *Application) checkState() {
|
||||
}
|
||||
|
||||
// Then check for an email address
|
||||
if app.Config.Load().EmailAddress == "" {
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if config.EmailAddress == "" {
|
||||
if app.state != NEEDS_EMAIL_ADDRESS {
|
||||
app.PageRouter.NavigateTo(page.EMAIL_ADDRESS)
|
||||
app.state = NEEDS_EMAIL_ADDRESS
|
||||
@@ -239,7 +231,11 @@ func (app *Application) checkState() {
|
||||
}
|
||||
|
||||
// Then check for a license key
|
||||
if app.Config.Load().LicenseKey == "" {
|
||||
config, err = db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if config.LicenseKey == "" {
|
||||
if app.state != NEEDS_LICENSE_KEY {
|
||||
app.PageRouter.NavigateTo(page.LICENSE_KEY)
|
||||
app.state = NEEDS_LICENSE_KEY
|
||||
@@ -251,14 +247,6 @@ func (app *Application) checkState() {
|
||||
app.PageRouter.NavigateTo(page.HOME)
|
||||
}
|
||||
|
||||
func (app *Application) refreshCache() {
|
||||
var freshConfig db.AppConfig
|
||||
if result := app.DB.First(&freshConfig); result.Error != nil {
|
||||
logger.Error("failed to fetch configuration from the database: %v", result.Error)
|
||||
}
|
||||
app.Config.Store(&freshConfig)
|
||||
}
|
||||
|
||||
func (app *Application) initializeSDLAndOpenGL() (W, H int32) {
|
||||
logger.Info("Initializing SDL")
|
||||
if err := sdl.Init(sdl.INIT_VIDEO | sdl.INIT_AUDIO); err != nil {
|
||||
@@ -333,29 +321,38 @@ func (app *Application) initializeSDLAndOpenGL() (W, H int32) {
|
||||
|
||||
func (app *Application) initializeManagers() {
|
||||
logger.Info("Initializing ShaderManager")
|
||||
shaderDir := filepath.Join(app.Config.Load().AssetsDir, "shaders")
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
shaderDir := filepath.Join(config.AssetsDir, "shaders")
|
||||
logger.Info("Loading shaders from %s", shaderDir)
|
||||
if err := shaderManager.InitShaderManager(shaderDir); err != nil {
|
||||
logger.Fatal("ShaderManager initialization failed: %v", err)
|
||||
}
|
||||
|
||||
logger.Info("Initializing FontManager")
|
||||
if err := fontManager.InitFontManager(app.Config.Load()); err != nil {
|
||||
if err := fontManager.InitFontManager(config); err != nil {
|
||||
logger.Fatal("FontManager initialization failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *Application) initializeAudio() {
|
||||
logger.Info("Initializing audio")
|
||||
|
||||
if err := mixer.Init(app.Config.Load(), app.refreshCache); err != nil {
|
||||
logger.Error("Unable to initialize audio device '%s': %v", app.Config.Load().SelectedAudioDevice, err)
|
||||
config, err := db.GetConfig(app.DB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := mixer.Init(config, app.refreshCache); err != nil {
|
||||
logger.Error("Unable to initialize audio device '%s': %v", config.SelectedAudioDevice, err)
|
||||
logger.Error("Audio will be unavailable until a device is configured")
|
||||
} else {
|
||||
logger.Info("Audio initialized with device: '%s'", app.Config.Load().SelectedAudioDevice)
|
||||
logger.Info("Audio initialized with device: '%s'", config.SelectedAudioDevice)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *Application) refreshCache() {}
|
||||
|
||||
func (app *Application) cleanup() {
|
||||
logger.Info("Cleaning up")
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ func Connect(dbpath string) (*gorm.DB, error) {
|
||||
return nil, fmt.Errorf("could not get underlying sql.DB: %w", err)
|
||||
}
|
||||
sqlDB.SetMaxOpenConns(1)
|
||||
sqlDB.SetMaxIdleConns(1)
|
||||
|
||||
// ── Pragmas ───────────────────────────────────────────────────────────
|
||||
pragmas := []string{
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package db
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
// GetConfig fetches the application config from the database
|
||||
func GetConfig(db *gorm.DB) (*AppConfig, error) {
|
||||
var cfg AppConfig
|
||||
err := db.First(&cfg, 1).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
@@ -192,8 +192,6 @@ func DownloadAudioFiles(progressChan chan<- DownloadStatus, filenames []string,
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("Finished downloading %s", filename)
|
||||
|
||||
// Update progress
|
||||
totalDownloaded += int64(n)
|
||||
progressChan <- DownloadStatus{
|
||||
|
||||
@@ -57,7 +57,7 @@ func InitFontManager(cfg *db.AppConfig) error {
|
||||
// --- NEW: Create the scrambled font after loading normal fonts ---
|
||||
// We will use "DejaVuSans" as the base. If you use a different default font,
|
||||
// change this string.
|
||||
baseFontForScramble := "Roboto-Regular"
|
||||
baseFontForScramble := "SpaceMonoNerdFont-Regular"
|
||||
if _, ok := fm.Fonts[baseFontForScramble]; ok {
|
||||
if err := fm.CreateScrambledFont(baseFontForScramble, "Scrambled"); err != nil {
|
||||
// This is not a fatal error for the whole application, so we just log it.
|
||||
@@ -526,6 +526,7 @@ func (fm *FontManager) createFontMap(font *FontEntry, scramble bool, baseFont *F
|
||||
8482, // ™
|
||||
232, // è
|
||||
233, // é
|
||||
10003, // checkmark
|
||||
}
|
||||
tempGlyphs := make([]TempGlyph, 0, len(chars))
|
||||
var totalWidth, maxHeight int32
|
||||
|
||||
+182
-56
@@ -10,6 +10,8 @@ import (
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
)
|
||||
|
||||
// ─── Level ───────────────────────────────────────────────────────────────────
|
||||
|
||||
type Level int
|
||||
|
||||
const (
|
||||
@@ -24,82 +26,206 @@ func (l Level) String() string {
|
||||
return [...]string{"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"}[l]
|
||||
}
|
||||
|
||||
// ─── Internal entry type ──────────────────────────────────────────────────────
|
||||
|
||||
type entry struct {
|
||||
level Level
|
||||
message string
|
||||
timestamp time.Time
|
||||
fatal bool
|
||||
}
|
||||
|
||||
// ─── Package state ────────────────────────────────────────────────────────────
|
||||
|
||||
var (
|
||||
DB *gorm.DB
|
||||
file *os.File
|
||||
console = log.New(os.Stderr, "", 0)
|
||||
SetLevel Level = LevelInfo
|
||||
console = log.New(os.Stderr, "", 0)
|
||||
|
||||
ch chan entry // unbuffered send is a bug; always buffered
|
||||
done chan struct{}
|
||||
db_ *gorm.DB
|
||||
file *os.File
|
||||
)
|
||||
|
||||
// AddFile attaches or replaces the file backend
|
||||
func init() {
|
||||
ch = make(chan entry, 4096)
|
||||
done = make(chan struct{})
|
||||
go drain()
|
||||
}
|
||||
|
||||
// ─── Configuration ────────────────────────────────────────────────────────────
|
||||
|
||||
// AddFile attaches or replaces the file backend. Safe to call at any time.
|
||||
func AddFile(path string) error {
|
||||
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("logger: open file: %w", err)
|
||||
}
|
||||
// Send a sentinel that carries the new file handle.
|
||||
// We do this through the channel so the drain goroutine owns
|
||||
// all file state — no mutex needed.
|
||||
fileSwapCh <- f
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddDatabase attaches or replaces the database backend. Safe to call at any time.
|
||||
func AddDatabase(d *gorm.DB) {
|
||||
dbSwapCh <- d
|
||||
}
|
||||
|
||||
// Close drains remaining entries and shuts down the logger.
|
||||
// Call this with defer in main().
|
||||
func Close() {
|
||||
close(done)
|
||||
<-drainDone // wait for drain goroutine to finish flushing
|
||||
if file != nil {
|
||||
file.Close()
|
||||
file = nil
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Swap channels (owned exclusively by drain goroutine) ────────────────────
|
||||
|
||||
var (
|
||||
fileSwapCh = make(chan *os.File, 1)
|
||||
dbSwapCh = make(chan *gorm.DB, 1)
|
||||
drainDone = make(chan struct{})
|
||||
)
|
||||
|
||||
// ─── Drain goroutine ──────────────────────────────────────────────────────────
|
||||
//
|
||||
// This is the ONLY goroutine that touches file, db_, or does DB writes.
|
||||
// Everything else just sends to ch.
|
||||
|
||||
func drain() {
|
||||
defer close(drainDone)
|
||||
|
||||
batch := make([]entry, 0, 64)
|
||||
ticker := time.NewTicker(250 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
flush := func() {
|
||||
if len(batch) == 0 {
|
||||
return
|
||||
}
|
||||
writeBatchToDB(batch)
|
||||
batch = batch[:0]
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
|
||||
// New log entry
|
||||
case e := <-ch:
|
||||
writeToFile(e)
|
||||
if db_ != nil {
|
||||
batch = append(batch, e)
|
||||
if len(batch) >= 64 {
|
||||
flush()
|
||||
}
|
||||
}
|
||||
|
||||
// Periodic DB flush so low-volume logs don't sit in the batch forever
|
||||
case <-ticker.C:
|
||||
flush()
|
||||
|
||||
// Hot-swap the file backend
|
||||
case f := <-fileSwapCh:
|
||||
if file != nil {
|
||||
file.Close()
|
||||
}
|
||||
file = f
|
||||
|
||||
_, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Hot-swap the DB backend
|
||||
case d := <-dbSwapCh:
|
||||
flush() // flush any pending entries to the old db first
|
||||
db_ = d
|
||||
console.Println("logger: database backend attached")
|
||||
|
||||
return nil
|
||||
// Shutdown: drain what's left, then exit
|
||||
case <-done:
|
||||
// Pull any entries still sitting in the channel
|
||||
for len(ch) > 0 {
|
||||
e := <-ch
|
||||
writeToFile(e)
|
||||
batch = append(batch, e)
|
||||
}
|
||||
|
||||
// AddDatabase attaches or replaces the database backend
|
||||
func AddDatabase(d *gorm.DB) {
|
||||
console.Println("Adding database to logger")
|
||||
DB = d
|
||||
}
|
||||
|
||||
// Close shuts down the file backend.
|
||||
func Close() error {
|
||||
if file != nil {
|
||||
err := file.Close()
|
||||
file = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func logMsg(level Level, format string, args ...any) {
|
||||
if level == LevelDebug && SetLevel != LevelDebug {
|
||||
flush()
|
||||
return
|
||||
}
|
||||
message := fmt.Sprintf(format, args...)
|
||||
now := time.Now()
|
||||
timestamp := now.Format("2006-01-02 15:04:05.000")
|
||||
line := fmt.Sprintf("%s [%s] %s", timestamp, level, message)
|
||||
}
|
||||
}
|
||||
|
||||
// 1. The standard log package is internally thread-safe
|
||||
console.Println(line)
|
||||
// ─── Writers (called only from drain goroutine) ───────────────────────────────
|
||||
|
||||
// 2. Write to file
|
||||
func writeToFile(e entry) {
|
||||
line := formatLine(e)
|
||||
if file != nil {
|
||||
fmt.Fprintln(file, line)
|
||||
}
|
||||
|
||||
// 3. Write to DB using GORM. It handles its own connection pooling and locking.
|
||||
if DB != nil {
|
||||
var entry db.Log
|
||||
entry.Timestamp = now.UnixMilli()
|
||||
entry.Level = level.String()
|
||||
entry.Message = message
|
||||
|
||||
// Use Save() to insert the new record.
|
||||
result := DB.Save(&entry)
|
||||
if result.Error != nil {
|
||||
console.Printf("Failed to write log to database: %v\n", result.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Debug(format string, args ...any) { logMsg(LevelDebug, format, args...) }
|
||||
func Info(format string, args ...any) { logMsg(LevelInfo, format, args...) }
|
||||
func Warning(format string, args ...any) { logMsg(LevelWarning, format, args...) }
|
||||
func Error(format string, args ...any) { logMsg(LevelError, format, args...) }
|
||||
func writeBatchToDB(batch []entry) {
|
||||
if db_ == nil || len(batch) == 0 {
|
||||
return
|
||||
}
|
||||
records := make([]db.Log, len(batch))
|
||||
for i, e := range batch {
|
||||
records[i] = db.Log{
|
||||
Timestamp: e.timestamp.UnixMilli(),
|
||||
Level: e.level.String(),
|
||||
Message: e.message,
|
||||
}
|
||||
}
|
||||
// Single INSERT ... VALUES (...), (...), (...) instead of N individual saves.
|
||||
if result := db_.CreateInBatches(records, 64); result.Error != nil {
|
||||
console.Printf("logger: db batch write failed: %v\n", result.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func Fatal(format string, args ...any) {
|
||||
logMsg(LevelFatal, format, args...)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
func formatLine(e entry) string {
|
||||
return fmt.Sprintf("%s [%s] %s",
|
||||
e.timestamp.Format("2006-01-02 15:04:05.000"),
|
||||
e.level,
|
||||
e.message,
|
||||
)
|
||||
}
|
||||
|
||||
// ─── Public API ───────────────────────────────────────────────────────────────
|
||||
|
||||
func logMsg(level Level, fatal bool, format string, args ...any) {
|
||||
if level == LevelDebug && SetLevel != LevelDebug {
|
||||
return
|
||||
}
|
||||
e := entry{
|
||||
level: level,
|
||||
message: fmt.Sprintf(format, args...),
|
||||
timestamp: time.Now(), // captured here, in the caller's goroutine
|
||||
fatal: fatal,
|
||||
}
|
||||
|
||||
// Console is synchronous — log.Logger is internally mutex-protected,
|
||||
// so this is safe from any goroutine and gives you immediate output.
|
||||
console.Println(formatLine(e))
|
||||
|
||||
// Non-blocking send: if the buffer is full, we drop rather than deadlock.
|
||||
// 4096 entries of headroom means this should never happen in practice.
|
||||
select {
|
||||
case ch <- e:
|
||||
default:
|
||||
console.Println("logger: channel full, entry dropped")
|
||||
}
|
||||
|
||||
if fatal {
|
||||
// Give the drain goroutine a moment to flush before we exit.
|
||||
// Close() is cleaner but Fatal has to exit immediately.
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func Debug(format string, args ...any) { logMsg(LevelDebug, false, format, args...) }
|
||||
func Info(format string, args ...any) { logMsg(LevelInfo, false, format, args...) }
|
||||
func Warning(format string, args ...any) { logMsg(LevelWarning, false, format, args...) }
|
||||
func Error(format string, args ...any) { logMsg(LevelError, false, format, args...) }
|
||||
func Fatal(format string, args ...any) { logMsg(LevelFatal, true, format, args...) }
|
||||
|
||||
@@ -70,7 +70,7 @@ func Init(cfg *db.AppConfig, onUpdate func()) error {
|
||||
return err
|
||||
}
|
||||
|
||||
SetAllSinkVolumes(1.0)
|
||||
SetAllSinkVolumes(0.20)
|
||||
|
||||
inited = true
|
||||
return nil
|
||||
|
||||
+417
-520
File diff suppressed because it is too large
Load Diff
@@ -100,7 +100,7 @@ func (p *AudioOptions) Init(ctx *PageCtx) error {
|
||||
|
||||
// Font
|
||||
fm := fontManager.Get()
|
||||
font, ok := fm.GetFont("Roboto-Regular")
|
||||
font, ok := fm.GetFont("SpaceMonoNerdFont-Regular")
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get font: %w", sdl.GetError())
|
||||
}
|
||||
@@ -121,7 +121,12 @@ func (p *AudioOptions) Init(ctx *PageCtx) error {
|
||||
return fmt.Errorf("base init failed: %w", err)
|
||||
}
|
||||
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
baseFontSize := config.StandardFontSize
|
||||
titleScale := float32(64) / float32(baseFontSize)
|
||||
p.ItemScale = float32(32) / float32(baseFontSize)
|
||||
|
||||
@@ -211,7 +216,11 @@ func (p *AudioOptions) seedAudioFiles() error {
|
||||
// ── Audio status toggle ───────────────────────────────────────────────────────
|
||||
|
||||
func (p *AudioOptions) CreateAudioStatusItem() error {
|
||||
on := p.Context.CfgPtr.AudioEnabled
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
on := config.AudioEnabled
|
||||
statusString := "Turn Audio On"
|
||||
color := colors.Green
|
||||
if on {
|
||||
@@ -277,7 +286,11 @@ func (p *AudioOptions) CreateVolumePercentItem() error {
|
||||
if p.volumePercent.ID != 0 {
|
||||
gl.DeleteTextures(1, &p.volumePercent.ID)
|
||||
}
|
||||
pct := int(p.Context.CfgPtr.SavedVolume * 100)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pct := int(config.SavedVolume * 100)
|
||||
item, err := NewStringItem(fmt.Sprintf("%d%%", pct), p.font, colors.White)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create volume percent item: %v", err)
|
||||
@@ -288,15 +301,19 @@ func (p *AudioOptions) CreateVolumePercentItem() error {
|
||||
}
|
||||
|
||||
func (p *AudioOptions) UpdateVolume(level int) {
|
||||
newVol := mixer.ConvertVolume(level) + p.Context.CfgPtr.SavedVolume
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newVol := mixer.ConvertVolume(level) + config.SavedVolume
|
||||
if newVol < 0.0 || newVol > 1.0 {
|
||||
return
|
||||
}
|
||||
if newVol > .99 {
|
||||
newVol = 1.0
|
||||
}
|
||||
p.Context.CfgPtr.SavedVolume = newVol
|
||||
p.Context.DbPtr.Save(&p.Context.CfgPtr)
|
||||
config.SavedVolume = newVol
|
||||
p.Context.DbPtr.Save(&config)
|
||||
if err := mixer.SetAllSinkVolumes(newVol); err != nil {
|
||||
logger.Error("Error setting allSinkVolumes: %v", err)
|
||||
}
|
||||
@@ -311,6 +328,11 @@ func (p *AudioOptions) UpdateVolume(level int) {
|
||||
// ── Layout ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func (p *AudioOptions) layout() {
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Title
|
||||
p.title.X = p.ScreenCenterX - p.title.W/2
|
||||
p.title.Y = p.ScreenHeight - p.title.H - p.verticalMargin*2
|
||||
@@ -320,7 +342,7 @@ func (p *AudioOptions) layout() {
|
||||
p.prompt.Y = p.title.Y - p.verticalMargin - p.prompt.H
|
||||
|
||||
// Volume row
|
||||
barH := int32(float32(p.Context.CfgPtr.StandardFontSize) * p.ItemScale)
|
||||
barH := int32(float32(config.StandardFontSize) * p.ItemScale)
|
||||
barW := int32(float32(p.ScreenWidth) * 0.30)
|
||||
barX := p.ScreenCenterX - barW/2
|
||||
barY := p.prompt.Y - p.verticalMargin*2 - barH
|
||||
@@ -376,8 +398,12 @@ func (p *AudioOptions) updateCursorPosition() {
|
||||
// ── Toggle ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func (p *AudioOptions) ToggleAudio() {
|
||||
p.Context.CfgPtr.AudioEnabled = !p.Context.CfgPtr.AudioEnabled
|
||||
p.Context.DbPtr.Save(p.Context.CfgPtr)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config.AudioEnabled = !config.AudioEnabled
|
||||
p.Context.DbPtr.Save(config)
|
||||
p.Context.RefreshConfig()
|
||||
p.CreateAudioStatusItem()
|
||||
p.layout()
|
||||
@@ -447,7 +473,11 @@ func (p *AudioOptions) Update(dt float32) error {
|
||||
// ── Render helpers ────────────────────────────────────────────────────────────
|
||||
|
||||
func (p *AudioOptions) renderVolumeBar() error {
|
||||
vol := p.Context.CfgPtr.SavedVolume
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
vol := config.SavedVolume
|
||||
|
||||
fillW := float32(p.volumeBarW) * float32(vol)
|
||||
if fillW > 0 {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/colors"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/fontManager"
|
||||
"rhemawavetech.com/rhemawave/internal/shaderManager"
|
||||
)
|
||||
@@ -59,7 +60,7 @@ func (p *EmailAddressPage) Init(ctx *PageCtx) error {
|
||||
|
||||
p.title = "Your Email Address"
|
||||
|
||||
applicationFont := "Roboto-Regular"
|
||||
applicationFont := "SpaceMonoNerdFont-Regular"
|
||||
|
||||
fm := fontManager.Get()
|
||||
textShader, ok := shaderManager.Get().Get("text")
|
||||
@@ -81,7 +82,11 @@ func (p *EmailAddressPage) Init(ctx *PageCtx) error {
|
||||
p.titleTextureHeight = titleHeight
|
||||
|
||||
// Load existing email address from database
|
||||
emailAddress := ctx.CfgPtr.EmailAddress
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
emailAddress := config.EmailAddress
|
||||
|
||||
if emailAddress != "" {
|
||||
p.inputText = emailAddress
|
||||
@@ -154,9 +159,12 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
|
||||
sdl.StopTextInput()
|
||||
|
||||
// Save email address to database
|
||||
p.Context.CfgPtr.EmailAddress = p.inputText
|
||||
p.Context.DbPtr.Save(p.Context.CfgPtr)
|
||||
p.Context.RefreshConfig()
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config.EmailAddress = p.inputText
|
||||
p.Context.DbPtr.Save(config)
|
||||
|
||||
if p.isFirstTimeSetup {
|
||||
// First-time setup: navigate to License Key page
|
||||
@@ -189,7 +197,7 @@ func (p *EmailAddressPage) HandleEvent(event *sdl.Event) error {
|
||||
// Update updates animations and changing textures and other changes using `dt` which represents a time delta in float32.
|
||||
func (p *EmailAddressPage) Update(dt float32) error {
|
||||
// Get application font from database
|
||||
applicationFont := "Roboto-Regular"
|
||||
applicationFont := "SpaceMonoNerdFont-Regular"
|
||||
|
||||
fm := fontManager.Get()
|
||||
sm := shaderManager.Get()
|
||||
@@ -252,8 +260,12 @@ func (p *EmailAddressPage) Update(dt float32) error {
|
||||
|
||||
// Render performs page drawing logic.
|
||||
func (p *EmailAddressPage) Render() error {
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Get base font size from database
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
baseFontSize := config.StandardFontSize
|
||||
|
||||
sm := shaderManager.Get()
|
||||
|
||||
|
||||
+14
-8
@@ -7,12 +7,13 @@ import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/colors"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/download"
|
||||
"rhemawavetech.com/rhemawave/internal/fontManager"
|
||||
"rhemawavetech.com/rhemawave/internal/shaderManager"
|
||||
)
|
||||
|
||||
var GitVersion = "cd79a6f"
|
||||
var GitVersion = "9beeeb1"
|
||||
|
||||
type Home struct {
|
||||
Base
|
||||
@@ -45,7 +46,7 @@ func (p *Home) Init(ctx *PageCtx) error {
|
||||
|
||||
// Get font
|
||||
p.fm = fontManager.Get()
|
||||
font, ok := p.fm.GetFont("Roboto-Regular")
|
||||
font, ok := p.fm.GetFont("SpaceMonoNerdFont-Regular")
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to fetch font")
|
||||
}
|
||||
@@ -86,8 +87,13 @@ func (p *Home) Init(ctx *PageCtx) error {
|
||||
return fmt.Errorf("unable to create initial message texture: %w", err)
|
||||
}
|
||||
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create license info textures if data exists
|
||||
if p.Context.CfgPtr.EmailAddress != "" || p.Context.CfgPtr.LicenseKey != "" {
|
||||
if config.EmailAddress != "" || config.LicenseKey != "" {
|
||||
p.hasLicenseInfo = true
|
||||
|
||||
// Create heading
|
||||
@@ -97,8 +103,8 @@ func (p *Home) Init(ctx *PageCtx) error {
|
||||
}
|
||||
|
||||
// Create email display if exists
|
||||
if p.Context.CfgPtr.EmailAddress != "" {
|
||||
emailText := fmt.Sprintf("Email: %s", p.Context.CfgPtr.EmailAddress)
|
||||
if config.EmailAddress != "" {
|
||||
emailText := fmt.Sprintf("Email: %s", config.EmailAddress)
|
||||
p.emailDisplay, err = NewStringItem(emailText, font, colors.White)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create email display texture: %w", err)
|
||||
@@ -106,8 +112,8 @@ func (p *Home) Init(ctx *PageCtx) error {
|
||||
}
|
||||
|
||||
// Create license key display if exists
|
||||
if p.Context.CfgPtr.LicenseKey != "" {
|
||||
licenseKeyText := fmt.Sprintf("License Key: %s", p.Context.CfgPtr.LicenseKey)
|
||||
if config.LicenseKey != "" {
|
||||
licenseKeyText := fmt.Sprintf("License Key: %s", config.LicenseKey)
|
||||
p.licenseKeyDisplay, err = NewStringItem(licenseKeyText, font, colors.White)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create license key display texture: %w", err)
|
||||
@@ -116,7 +122,7 @@ func (p *Home) Init(ctx *PageCtx) error {
|
||||
}
|
||||
|
||||
// Get base font size from database
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
baseFontSize := config.StandardFontSize
|
||||
p.baseFontSize = baseFontSize
|
||||
|
||||
// Scale the note text
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/colors"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/fontManager"
|
||||
"rhemawavetech.com/rhemawave/internal/logger"
|
||||
"rhemawavetech.com/rhemawave/internal/shaderManager"
|
||||
@@ -55,7 +56,7 @@ func (p *LicenseKeyPage) Init(ctx *PageCtx) error {
|
||||
p.title = "License Key"
|
||||
|
||||
// Get application font from database
|
||||
applicationFont := "Roboto-Regular"
|
||||
applicationFont := "SpaceMonoNerdFont-Regular"
|
||||
|
||||
fm := fontManager.Get()
|
||||
textShader, ok := shaderManager.Get().Get("text")
|
||||
@@ -77,7 +78,11 @@ func (p *LicenseKeyPage) Init(ctx *PageCtx) error {
|
||||
p.titleTextureHeight = titleHeight
|
||||
|
||||
// Load existing license key from database
|
||||
licenseKey := p.Context.CfgPtr.LicenseKey
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
licenseKey := config.LicenseKey
|
||||
|
||||
if licenseKey != "" {
|
||||
p.inputText = licenseKey
|
||||
@@ -188,9 +193,12 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error {
|
||||
sdl.StopTextInput()
|
||||
|
||||
// Save license key to database
|
||||
p.Context.CfgPtr.LicenseKey = p.inputText
|
||||
p.Context.DbPtr.Save(p.Context.CfgPtr)
|
||||
p.Context.RefreshConfig()
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config.LicenseKey = p.inputText
|
||||
p.Context.DbPtr.Save(config)
|
||||
|
||||
// Write license key to plain text file for the updater
|
||||
if homeDir, err := os.UserHomeDir(); err == nil {
|
||||
@@ -239,7 +247,7 @@ func (p *LicenseKeyPage) HandleEvent(event *sdl.Event) error {
|
||||
// Update updates animations and changing textures and other changes using `dt` which represents a time delta in float32.
|
||||
func (p *LicenseKeyPage) Update(dt float32) error {
|
||||
// Get application font from database
|
||||
applicationFont := "Roboto-Regular"
|
||||
applicationFont := "SpaceMonoNerdFont-Regular"
|
||||
|
||||
fm := fontManager.Get()
|
||||
sm := shaderManager.Get()
|
||||
@@ -302,8 +310,12 @@ func (p *LicenseKeyPage) Update(dt float32) error {
|
||||
|
||||
// Render performs page drawing logic.
|
||||
func (p *LicenseKeyPage) Render() error {
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Get base font size from database
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
baseFontSize := config.StandardFontSize
|
||||
|
||||
sm := shaderManager.Get()
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"slices"
|
||||
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/colors"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/fontManager"
|
||||
"rhemawavetech.com/rhemawave/internal/logger"
|
||||
@@ -25,6 +26,7 @@ type LogViewerPage struct {
|
||||
lineTextureIDs []uint32
|
||||
lineTextureWidths []int32
|
||||
lineTextureHeights []int32
|
||||
lineColors []sdl.Color
|
||||
|
||||
hintTextureID uint32
|
||||
hintTextureWidth int32
|
||||
@@ -47,24 +49,37 @@ func (p *LogViewerPage) Init(ctx *PageCtx) error {
|
||||
return fmt.Errorf("%s", result.Error)
|
||||
}
|
||||
|
||||
// Format and word-wrap each log entry
|
||||
// // Format and word-wrap each log entry
|
||||
// for _, entry := range logs {
|
||||
// formatted := fmt.Sprintf("[%s] [%s] %s", entry.Timestamp, entry.Level, entry.Message)
|
||||
// wrapped := wrapText(formatted, 100)
|
||||
// p.lines = append(p.lines, strings.Split(wrapped, "\n")...)
|
||||
// }
|
||||
displayLevels := []string{"WARNING", "ERROR", "FATAL"}
|
||||
|
||||
levelColors := map[string]sdl.Color{
|
||||
"DEBUG": colors.SkyBlue,
|
||||
"INFO": colors.White,
|
||||
"WARNING": colors.Yellow,
|
||||
"ERROR": colors.RedOrange,
|
||||
}
|
||||
|
||||
fallbackColor := colors.White
|
||||
|
||||
p.lineColors = make([]sdl.Color, len(p.lines))
|
||||
|
||||
for _, entry := range logs {
|
||||
if slices.Contains(displayLevels, entry.Level) {
|
||||
color, ok := levelColors[entry.Level]
|
||||
if !ok {
|
||||
color = fallbackColor
|
||||
}
|
||||
logTime := time.UnixMilli(entry.Timestamp)
|
||||
timeStr := logTime.Format("2006-01-02 15:04")
|
||||
line := fmt.Sprintf("[%s] [%s] %s", timeStr, entry.Level, entry.Message)
|
||||
p.lines = append(p.lines, line)
|
||||
}
|
||||
p.lineColors = append(p.lineColors, color)
|
||||
}
|
||||
|
||||
applicationFont := "Roboto-Regular"
|
||||
applicationFont := "SpaceMonoNerdFont-Regular"
|
||||
|
||||
fm := fontManager.Get()
|
||||
textShader, ok := shaderManager.Get().Get("text")
|
||||
@@ -162,14 +177,15 @@ func (p *LogViewerPage) Update(dt float32) error {
|
||||
}
|
||||
|
||||
func (p *LogViewerPage) Render() error {
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
baseFontSize := config.StandardFontSize
|
||||
|
||||
sm := shaderManager.Get()
|
||||
textShader, _ := sm.Get("text")
|
||||
|
||||
white := sdl.Color{R: 255, G: 255, B: 255, A: 255}
|
||||
grey := sdl.Color{R: 180, G: 180, B: 180, A: 255}
|
||||
|
||||
titleFontSize := int32(48)
|
||||
titleScale := float32(titleFontSize) / float32(baseFontSize)
|
||||
contentFontSize := int32(24)
|
||||
@@ -189,14 +205,14 @@ func (p *LogViewerPage) Render() error {
|
||||
titleW := float32(p.titleTextureWidth) * titleScale
|
||||
titleX := p.Base.ScreenCenterX - int32(titleW/2)
|
||||
titleY := p.Base.ScreenHeight - margin - int32(titleH)
|
||||
p.Base.RenderTexture(textShader, p.titleTextureID, mgl32.Vec2{float32(titleX), float32(titleY)}, mgl32.Vec2{titleW, titleH}, white)
|
||||
p.Base.RenderTexture(textShader, p.titleTextureID, mgl32.Vec2{float32(titleX), float32(titleY)}, mgl32.Vec2{titleW, titleH}, colors.White)
|
||||
|
||||
// Hint at bottom
|
||||
hintH := float32(p.hintTextureHeight) * hintScale
|
||||
hintW := float32(p.hintTextureWidth) * hintScale
|
||||
hintX := p.Base.ScreenCenterX - int32(hintW/2)
|
||||
hintY := margin
|
||||
p.Base.RenderTexture(textShader, p.hintTextureID, mgl32.Vec2{float32(hintX), float32(hintY)}, mgl32.Vec2{hintW, hintH}, grey)
|
||||
p.Base.RenderTexture(textShader, p.hintTextureID, mgl32.Vec2{float32(hintX), float32(hintY)}, mgl32.Vec2{hintW, hintH}, colors.Gray)
|
||||
|
||||
// Content area bounds
|
||||
contentTop := titleY - margin
|
||||
@@ -232,7 +248,12 @@ func (p *LogViewerPage) Render() error {
|
||||
lineW := float32(p.lineTextureWidths[i]) * contentScale
|
||||
lineH := float32(p.lineTextureHeights[i]) * contentScale
|
||||
|
||||
p.Base.RenderTexture(textShader, p.lineTextureIDs[i], mgl32.Vec2{float32(contentLeftX), float32(currentY)}, mgl32.Vec2{lineW, lineH}, white)
|
||||
color := colors.White
|
||||
if i < len(p.lineColors) {
|
||||
color = p.lineColors[i]
|
||||
}
|
||||
|
||||
p.Base.RenderTexture(textShader, p.lineTextureIDs[i], mgl32.Vec2{float32(contentLeftX), float32(currentY)}, mgl32.Vec2{lineW, lineH}, color)
|
||||
currentY -= p.lineHeight
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/go-gl/mathgl/mgl32"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/logger"
|
||||
"rhemawavetech.com/rhemawave/internal/shaderManager"
|
||||
)
|
||||
|
||||
@@ -184,3 +185,54 @@ func (p *Base) RenderSolidColorQuad(shader *shaderManager.Shader, position, size
|
||||
func (p *Base) HandleEvent(event sdl.Event) error { return nil }
|
||||
func (p *Base) Update(dt float32) error { return nil }
|
||||
func (p *Base) Render() error { return nil }
|
||||
|
||||
// --- Helper Functions ---
|
||||
// keycodeToChar converts an SDL keycode to a rune, respecting SHIFT state.
|
||||
// Returns 0 for non-printable keys.
|
||||
func keycodeToChar(sym sdl.Keycode, mod uint16) rune {
|
||||
shifted := mod&sdl.KMOD_SHIFT != 0
|
||||
|
||||
// Letters
|
||||
if sym >= sdl.K_a && sym <= sdl.K_z {
|
||||
ch := rune(sym)
|
||||
if shifted {
|
||||
ch -= 'a' - 'A'
|
||||
}
|
||||
logger.Info("Wifi Password entered: %v", ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
// Digits and their shifted symbols
|
||||
if sym >= sdl.K_0 && sym <= sdl.K_9 {
|
||||
if shifted {
|
||||
shiftDigits := []rune{')', '!', '@', '#', '$', '%', '^', '&', '*', '('}
|
||||
return shiftDigits[sym-sdl.K_0]
|
||||
}
|
||||
return rune(sym)
|
||||
}
|
||||
|
||||
// Common punctuation / symbols
|
||||
type charPair struct{ normal, shifted rune }
|
||||
punctuation := map[sdl.Keycode]charPair{
|
||||
sdl.K_SPACE: {' ', ' '},
|
||||
sdl.K_MINUS: {'-', '_'},
|
||||
sdl.K_EQUALS: {'=', '+'},
|
||||
sdl.K_LEFTBRACKET: {'[', '{'},
|
||||
sdl.K_RIGHTBRACKET: {']', '}'},
|
||||
sdl.K_BACKSLASH: {'\\', '|'},
|
||||
sdl.K_SEMICOLON: {';', ':'},
|
||||
sdl.K_QUOTE: {'\'', '"'},
|
||||
sdl.K_BACKQUOTE: {'`', '~'},
|
||||
sdl.K_COMMA: {',', '<'},
|
||||
sdl.K_PERIOD: {'.', '>'},
|
||||
sdl.K_SLASH: {'/', '?'},
|
||||
}
|
||||
if pair, ok := punctuation[sym]; ok {
|
||||
if shifted {
|
||||
return pair.shifted
|
||||
}
|
||||
return pair.normal
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ func (p *ProclamationOptions) Init(ctx *PageCtx) error {
|
||||
sync.SyncFrequencies(ctx.DbPtr)
|
||||
|
||||
fm := fontManager.Get()
|
||||
font, _ := fm.GetFont("Roboto-Regular")
|
||||
font, _ := fm.GetFont("SpaceMonoNerdFont-Regular")
|
||||
p.font = font
|
||||
|
||||
sm := shaderManager.Get()
|
||||
@@ -114,9 +114,14 @@ func (p *ProclamationOptions) Init(ctx *PageCtx) error {
|
||||
|
||||
p.Base.Init(ctx)
|
||||
|
||||
itemScale := float32(32) / float32(ctx.CfgPtr.StandardFontSize)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
itemScale := float32(32) / float32(config.StandardFontSize)
|
||||
p.title, _ = NewStringItem("Proclamation Browser", p.font, colors.White)
|
||||
p.title.Scale(float32(64) / float32(ctx.CfgPtr.StandardFontSize))
|
||||
p.title.Scale(float32(64) / float32(config.StandardFontSize))
|
||||
|
||||
p.prompt, _ = NewStringItem("Type to Search Space to Select Enter to Save Escape to Exit", p.font, colors.White)
|
||||
p.prompt.Scale(itemScale * 0.8)
|
||||
@@ -183,7 +188,11 @@ func (p *ProclamationOptions) createFlatItem(name, id string, isCat bool, depth
|
||||
if isCat && depth == 0 {
|
||||
text = "[+] " + name
|
||||
}
|
||||
itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
itemScale := float32(32) / float32(config.StandardFontSize)
|
||||
lbl, _ := NewStringItem(text, p.font, colors.White)
|
||||
lbl.Scale(itemScale)
|
||||
return &FlatItem{
|
||||
@@ -277,7 +286,12 @@ func (p *ProclamationOptions) toggleExpansion(index int) {
|
||||
pureName := item.Label.content[4:]
|
||||
gl.DeleteTextures(1, &item.Label.ID)
|
||||
|
||||
itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
itemScale := float32(32) / float32(config.StandardFontSize)
|
||||
if item.Expanded {
|
||||
p.collapse(index)
|
||||
item.Label, _ = NewStringItem("[+] "+pureName, p.font, colors.White)
|
||||
@@ -401,7 +415,11 @@ func (p *ProclamationOptions) rebuildSearchLabel() {
|
||||
if p.searchQuery == "" {
|
||||
return
|
||||
}
|
||||
itemScale := float32(32) / float32(p.Context.CfgPtr.StandardFontSize)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
itemScale := float32(32) / float32(config.StandardFontSize)
|
||||
p.searchInput, _ = NewStringItem("Search: "+p.searchQuery, p.font, colors.Yellow)
|
||||
p.searchInput.Scale(itemScale * 1.1)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package page
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/download"
|
||||
)
|
||||
|
||||
@@ -23,7 +22,6 @@ const (
|
||||
)
|
||||
|
||||
type PageCtx struct {
|
||||
CfgPtr *db.AppConfig
|
||||
DbPtr *gorm.DB
|
||||
W, H int32
|
||||
MessageChannel chan download.DownloadStatus
|
||||
|
||||
@@ -220,8 +220,11 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
|
||||
}
|
||||
|
||||
// Get line pattern from database
|
||||
var err error
|
||||
linePatternName := p.Context.CfgPtr.LinePattern
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
linePatternName := config.LinePattern
|
||||
|
||||
p.activePattern, err = linePattern.Get(linePatternName)
|
||||
if err != nil {
|
||||
@@ -241,7 +244,7 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
|
||||
p.colorPattern = colorPattern.NewColorPattern(baseColors)
|
||||
|
||||
// Font setup
|
||||
p.fontScale = float32(32) / float32(p.Context.CfgPtr.StandardFontSize)
|
||||
p.fontScale = float32(32) / float32(config.StandardFontSize)
|
||||
nLines := int(float32(p.ScreenHeight) / 32.0)
|
||||
p.lines = NewLineDeque(nLines * 2)
|
||||
|
||||
@@ -286,17 +289,16 @@ func (p *ScrollerPage) Init(ctx *PageCtx) error {
|
||||
if !started {
|
||||
var selectedAudio db.AudioFile
|
||||
if err := p.Context.DbPtr.Where("Selected = ?", true).First(&selectedAudio).Error; err != nil {
|
||||
logger.Error("error querying database for selected audio: %v", err)
|
||||
selectedAudio = db.AudioFile{
|
||||
Name: "OriginalAudio",
|
||||
Path: filepath.Join(p.Context.CfgPtr.AssetsDir, "audio", "OriginalAudio.wav"),
|
||||
Path: filepath.Join(config.AssetsDir, "audio", "OriginalAudio.wav"),
|
||||
Selected: true,
|
||||
Order: 0,
|
||||
}
|
||||
}
|
||||
|
||||
logger.Info("Playing %s", selectedAudio.Path)
|
||||
if err := mixer.Play(selectedAudio.Path, true, p.Context.CfgPtr); err != nil {
|
||||
if err := mixer.Play(selectedAudio.Path, true, config); err != nil {
|
||||
logger.Error("Mixer returned an error: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -421,7 +423,11 @@ func (p *ScrollerPage) loadProclamations() error {
|
||||
// audioPathForFrequency builds the on-disk path for a solfeggio frequency's
|
||||
// audio file, e.g. 396 -> "<AssetsDir>/audio/396Hz.wav".
|
||||
func (p *ScrollerPage) audioPathForFrequency(freq int) string {
|
||||
return filepath.Join(p.Context.CfgPtr.AssetsDir, "audio", fmt.Sprintf("%dHz.wav", freq))
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return filepath.Join(config.AssetsDir, "audio", fmt.Sprintf("%dHz.wav", freq))
|
||||
}
|
||||
|
||||
// switchAudioForFrequency swaps the currently playing track to match freq.
|
||||
@@ -450,9 +456,12 @@ func (p *ScrollerPage) switchAudioForFrequency(freq int) bool {
|
||||
logger.Warning("No audio file for %dHz (%s), keeping current track", freq, path)
|
||||
return false
|
||||
}
|
||||
|
||||
mixer.Stop(3000, p.Context.CfgPtr)
|
||||
if err := mixer.Play(path, true, p.Context.CfgPtr); err != nil {
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mixer.Stop(3000, config)
|
||||
if err := mixer.Play(path, true, config); err != nil {
|
||||
logger.Error("Mixer returned an error: %v", err)
|
||||
return false
|
||||
}
|
||||
@@ -723,7 +732,12 @@ func (p *ScrollerPage) Destroy() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
mixer.Stop(3000, p.Context.CfgPtr)
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
mixer.Stop(3000, config)
|
||||
|
||||
// Delete each cached word texture exactly once.
|
||||
for k, item := range p.wordTextureCache {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/go-gl/gl/v3.3-core/gl"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"rhemawavetech.com/rhemawave/internal/colors"
|
||||
"rhemawavetech.com/rhemawave/internal/db"
|
||||
"rhemawavetech.com/rhemawave/internal/fontManager"
|
||||
"rhemawavetech.com/rhemawave/internal/shaderManager"
|
||||
)
|
||||
@@ -34,7 +35,7 @@ func (p *Settings) Init(ctx *PageCtx) error {
|
||||
|
||||
// Get font
|
||||
fm := fontManager.Get()
|
||||
font, ok := fm.GetFont("Roboto-Regular")
|
||||
font, ok := fm.GetFont("SpaceMonoNerdFont-Regular")
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get font: %w", sdl.GetError())
|
||||
}
|
||||
@@ -127,7 +128,11 @@ func (p *Settings) Init(ctx *PageCtx) error {
|
||||
// TODO: Add entry for "About"
|
||||
|
||||
// Get base font size from database
|
||||
baseFontSize := p.Context.CfgPtr.StandardFontSize
|
||||
config, err := db.GetConfig(p.Context.DbPtr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
baseFontSize := config.StandardFontSize
|
||||
|
||||
// Calculate scales
|
||||
titleScale := float32(64) / float32(baseFontSize)
|
||||
|
||||
+426
-579
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,23 @@
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
.idea/
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
AccessPointInterface = NetworkManagerInterface + ".AccessPoint"
|
||||
|
||||
/* Properties */
|
||||
AccessPointPropertyFlags = AccessPointInterface + ".Flags" // readable u
|
||||
AccessPointPropertyWpaFlags = AccessPointInterface + ".WpaFlags" // readable u
|
||||
AccessPointPropertyRsnFlags = AccessPointInterface + ".RsnFlags" // readable u
|
||||
AccessPointPropertySsid = AccessPointInterface + ".Ssid" // readable ay
|
||||
AccessPointPropertyFrequency = AccessPointInterface + ".Frequency" // readable u
|
||||
AccessPointPropertyHwAddress = AccessPointInterface + ".HwAddress" // readable s
|
||||
AccessPointPropertyMode = AccessPointInterface + ".Mode" // readable u
|
||||
AccessPointPropertyMaxBitrate = AccessPointInterface + ".MaxBitrate" // readable u
|
||||
AccessPointPropertyStrength = AccessPointInterface + ".Strength" // readable y
|
||||
AccessPointPropertyLastSeen = AccessPointInterface + ".LastSeen" // readable i
|
||||
)
|
||||
|
||||
type AccessPoint interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// GetPropertyFlags gets flags describing the capabilities of the access point.
|
||||
GetPropertyFlags() (uint32, error)
|
||||
|
||||
// GetPropertyWPAFlags gets flags describing the access point's capabilities
|
||||
// according to WPA (Wi-Fi Protected Access).
|
||||
GetPropertyWPAFlags() (uint32, error)
|
||||
|
||||
// GetPropertyRSNFlags gets flags describing the access point's capabilities
|
||||
// according to the RSN (Robust Secure Network) protocol.
|
||||
GetPropertyRSNFlags() (uint32, error)
|
||||
|
||||
// GetPropertySSID returns the Service Set Identifier identifying the access point.
|
||||
GetPropertySSID() (string, error)
|
||||
|
||||
// GetPropertyFrequency gets the radio channel frequency in use by the access point, in MHz.
|
||||
GetPropertyFrequency() (uint32, error)
|
||||
|
||||
// GetPropertyHWAddress gets the hardware address (BSSID) of the access point.
|
||||
GetPropertyHWAddress() (string, error)
|
||||
|
||||
// GetPropertyMode describes the operating mode of the access point.
|
||||
GetPropertyMode() (Nm80211Mode, error)
|
||||
|
||||
// GetPropertyMaxBitrate gets the maximum bitrate this access point is capable of, in kilobits/second (Kb/s).
|
||||
GetPropertyMaxBitrate() (uint32, error)
|
||||
|
||||
// GetPropertyStrength gets the current signal quality of the access point, in percent.
|
||||
GetPropertyStrength() (uint8, error)
|
||||
|
||||
// GetPropertyLastSeen The timestamp (in CLOCK_BOOTTIME seconds) for the last time the access point was found in scan results.
|
||||
// A value of -1 means the access point has never been found in scan results.
|
||||
GetPropertyLastSeen() (int32, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewAccessPoint(objectPath dbus.ObjectPath) (AccessPoint, error) {
|
||||
var a accessPoint
|
||||
return &a, a.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type accessPoint struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPath() dbus.ObjectPath {
|
||||
return a.obj.Path()
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyFlags() (uint32, error) {
|
||||
return a.getUint32Property(AccessPointPropertyFlags)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyWPAFlags() (uint32, error) {
|
||||
return a.getUint32Property(AccessPointPropertyWpaFlags)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyRSNFlags() (uint32, error) {
|
||||
return a.getUint32Property(AccessPointPropertyRsnFlags)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertySSID() (string, error) {
|
||||
r, err := a.getSliceByteProperty(AccessPointPropertySsid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(r), nil
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyFrequency() (uint32, error) {
|
||||
return a.getUint32Property(AccessPointPropertyFrequency)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyHWAddress() (string, error) {
|
||||
return a.getStringProperty(AccessPointPropertyHwAddress)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyMode() (Nm80211Mode, error) {
|
||||
r, err := a.getUint32Property(AccessPointPropertyMode)
|
||||
if err != nil {
|
||||
return Nm80211ModeUnknown, err
|
||||
}
|
||||
return Nm80211Mode(r), nil
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyMaxBitrate() (uint32, error) {
|
||||
return a.getUint32Property(AccessPointPropertyMaxBitrate)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyStrength() (uint8, error) {
|
||||
return a.getUint8Property(AccessPointPropertyStrength)
|
||||
}
|
||||
|
||||
func (a *accessPoint) GetPropertyLastSeen() (int32, error) {
|
||||
return a.getInt32Property(AccessPointPropertyLastSeen)
|
||||
}
|
||||
|
||||
func (a *accessPoint) MarshalJSON() ([]byte, error) {
|
||||
Flags, err := a.GetPropertyFlags()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
WPAFlags, err := a.GetPropertyWPAFlags()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
RSNFlags, err := a.GetPropertyRSNFlags()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
SSID, err := a.GetPropertySSID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Frequency, err := a.GetPropertyFrequency()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
HWAddress, err := a.GetPropertyHWAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Mode, err := a.GetPropertyMode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
MaxBitrate, err := a.GetPropertyMaxBitrate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Strength, err := a.GetPropertyStrength()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
LastSeen, err := a.GetPropertyLastSeen()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"Flags": Flags,
|
||||
"WPAFlags": WPAFlags,
|
||||
"RSNFlags": RSNFlags,
|
||||
"SSID": SSID,
|
||||
"Frequency": Frequency,
|
||||
"HWAddress": HWAddress,
|
||||
"Mode": Mode.String(),
|
||||
"MaxBitrate": MaxBitrate,
|
||||
"Strength": Strength,
|
||||
"LastSeen": LastSeen,
|
||||
})
|
||||
}
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
ActiveConnectionInterface = NetworkManagerInterface + ".Connection.Active"
|
||||
|
||||
/* Properties */
|
||||
ActiveConnectionPropertyConnection = ActiveConnectionInterface + ".Connection" // readable o
|
||||
ActiveConnectionPropertySpecificObject = ActiveConnectionInterface + ".SpecificObject" // readable o
|
||||
ActiveConnectionPropertyId = ActiveConnectionInterface + ".Id" // readable s
|
||||
ActiveConnectionPropertyUuid = ActiveConnectionInterface + ".Uuid" // readable s
|
||||
ActiveConnectionPropertyType = ActiveConnectionInterface + ".Type" // readable s
|
||||
ActiveConnectionPropertyDevices = ActiveConnectionInterface + ".Devices" // readable ao
|
||||
ActiveConnectionPropertyState = ActiveConnectionInterface + ".State" // readable u
|
||||
ActiveConnectionPropertyStateFlags = ActiveConnectionInterface + ".StateFlags" // readable u
|
||||
ActiveConnectionPropertyDefault = ActiveConnectionInterface + ".Default" // readable b
|
||||
ActiveConnectionPropertyIp4Config = ActiveConnectionInterface + ".Ip4Config" // readable o
|
||||
ActiveConnectionPropertyDhcp4Config = ActiveConnectionInterface + ".Dhcp4Config" // readable o
|
||||
ActiveConnectionPropertyDefault6 = ActiveConnectionInterface + ".Default6" // readable b
|
||||
ActiveConnectionPropertyIp6Config = ActiveConnectionInterface + ".Ip6Config" // readable o
|
||||
ActiveConnectionPropertyDhcp6Config = ActiveConnectionInterface + ".Dhcp6Config" // readable o
|
||||
ActiveConnectionPropertyVpn = ActiveConnectionInterface + ".Vpn" // readable b
|
||||
ActiveConnectionPropertyMaster = ActiveConnectionInterface + ".Master" // readable o
|
||||
|
||||
/* Signals */
|
||||
ActiveConnectionSignalStateChanged = "StateChanged" // u state, u reason
|
||||
|
||||
)
|
||||
|
||||
type ActiveConnection interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// GetPropertyConnection gets connection object of the connection.
|
||||
GetPropertyConnection() (Connection, error)
|
||||
|
||||
// GetPropertySpecificObject gets a specific object associated with the active connection.
|
||||
GetPropertySpecificObject() (AccessPoint, error)
|
||||
|
||||
// GetPropertyID gets the ID of the connection.
|
||||
GetPropertyID() (string, error)
|
||||
|
||||
// GetPropertyUUID gets the UUID of the connection.
|
||||
GetPropertyUUID() (string, error)
|
||||
|
||||
// GetPropertyType gets the type of the connection.
|
||||
GetPropertyType() (string, error)
|
||||
|
||||
// GetPropertyDevices gets array of device objects which are part of this active connection.
|
||||
GetPropertyDevices() ([]Device, error)
|
||||
|
||||
// GetPropertyState gets the state of the connection.
|
||||
GetPropertyState() (NmActiveConnectionState, error)
|
||||
|
||||
// GetPropertyStateFlags gets the state flags of the connection.
|
||||
GetPropertyStateFlags() (uint32, error)
|
||||
|
||||
// GetPropertyDefault gets the default IPv4 flag of the connection.
|
||||
GetPropertyDefault() (bool, error)
|
||||
|
||||
// GetPropertyIP4Config gets the IP4Config of the connection.
|
||||
GetPropertyIP4Config() (IP4Config, error)
|
||||
|
||||
// GetPropertyDHCP4Config gets the DHCP6Config of the connection.
|
||||
GetPropertyDHCP4Config() (DHCP4Config, error)
|
||||
|
||||
// GetPropertyDefault6 gets the default IPv6 flag of the connection.
|
||||
GetPropertyDefault6() (bool, error)
|
||||
|
||||
// GetPropertyIP6Config gets the IP6Config of the connection.
|
||||
GetPropertyIP6Config() (IP6Config, error)
|
||||
|
||||
// GetPropertyDHCP6Config gets the DHCP4Config of the connection.
|
||||
GetPropertyDHCP6Config() (DHCP6Config, error)
|
||||
|
||||
// GetPropertyVPN gets the VPN flag of the connection.
|
||||
GetPropertyVPN() (bool, error)
|
||||
|
||||
// GetPropertyMaster gets the master device of the connection.
|
||||
GetPropertyMaster() (Device, error)
|
||||
|
||||
SubscribeState(receiver chan StateChange, exit chan struct{}) (err error)
|
||||
}
|
||||
|
||||
func NewActiveConnection(objectPath dbus.ObjectPath) (ActiveConnection, error) {
|
||||
var a activeConnection
|
||||
return &a, a.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type activeConnection struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPath() dbus.ObjectPath {
|
||||
return a.obj.Path()
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyConnection() (Connection, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyConnection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
con, err := NewConnection(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return con, nil
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertySpecificObject() (AccessPoint, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertySpecificObject)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ap, err := NewAccessPoint(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ap, nil
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyID() (string, error) {
|
||||
return a.getStringProperty(ActiveConnectionPropertyId)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyUUID() (string, error) {
|
||||
return a.getStringProperty(ActiveConnectionPropertyUuid)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyType() (string, error) {
|
||||
return a.getStringProperty(ActiveConnectionPropertyType)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyDevices() ([]Device, error) {
|
||||
paths, err := a.getSliceObjectProperty(ActiveConnectionPropertyDevices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices := make([]Device, len(paths))
|
||||
for i, path := range paths {
|
||||
devices[i], err = DeviceFactory(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
func (a *activeConnection) GetPropertyState() (NmActiveConnectionState, error) {
|
||||
v, err := a.getUint32Property(ActiveConnectionPropertyState)
|
||||
return NmActiveConnectionState(v), err
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyStateFlags() (uint32, error) {
|
||||
return a.getUint32Property(ActiveConnectionPropertyStateFlags)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyDefault() (bool, error) {
|
||||
b, err := a.getProperty(ActiveConnectionPropertyDefault)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return b.(bool), nil
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyIP4Config() (IP4Config, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyIp4Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
return NewIP4Config(path)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyDHCP4Config() (DHCP4Config, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyDhcp4Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
return NewDHCP4Config(path)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyDefault6() (bool, error) {
|
||||
return a.getBoolProperty(ActiveConnectionPropertyDefault6)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyIP6Config() (IP6Config, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyIp6Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewIP6Config(path)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyDHCP6Config() (DHCP6Config, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyDhcp6Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDHCP6Config(path)
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyVPN() (bool, error) {
|
||||
ret, err := a.getProperty(ActiveConnectionPropertyVpn)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return ret.(bool), nil
|
||||
}
|
||||
|
||||
func (a *activeConnection) GetPropertyMaster() (Device, error) {
|
||||
path, err := a.getObjectProperty(ActiveConnectionPropertyMaster)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
return DeviceFactory(path)
|
||||
}
|
||||
|
||||
type StateChange struct {
|
||||
Path dbus.ObjectPath
|
||||
State NmActiveConnectionState
|
||||
Reason NmActiveConnectionStateReason
|
||||
}
|
||||
|
||||
func (a *activeConnection) SubscribeState(receiver chan StateChange, exit chan struct{}) (err error) {
|
||||
|
||||
channel := make(chan *dbus.Signal, 1)
|
||||
|
||||
a.conn.Signal(channel)
|
||||
|
||||
err = a.conn.AddMatchSignal(
|
||||
dbus.WithMatchInterface(ActiveConnectionInterface),
|
||||
dbus.WithMatchMember(ActiveConnectionSignalStateChanged),
|
||||
dbus.WithMatchObjectPath(a.GetPath()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case signal, ok := <-channel:
|
||||
if !ok {
|
||||
err = fmt.Errorf("connection closed for %s", ActiveConnectionSignalStateChanged)
|
||||
return
|
||||
}
|
||||
|
||||
if signal.Name != ActiveConnectionInterface+"."+ActiveConnectionSignalStateChanged {
|
||||
continue
|
||||
}
|
||||
|
||||
stateChange := StateChange{
|
||||
Path: signal.Path,
|
||||
State: NmActiveConnectionState(signal.Body[0].(uint32)),
|
||||
Reason: NmActiveConnectionStateReason(signal.Body[1].(uint32)),
|
||||
}
|
||||
|
||||
receiver <- stateChange
|
||||
|
||||
case <-exit:
|
||||
a.conn.RemoveSignal(channel)
|
||||
close(channel)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project since will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [2.1.0] - 2023-01-19
|
||||
|
||||
### Added
|
||||
|
||||
- Add device auto-connect setter
|
||||
|
||||
### Fixed
|
||||
|
||||
- Connection settings route and address data types
|
||||
|
||||
## [2.0.0] - 2022-11-22
|
||||
|
||||
### Changes
|
||||
|
||||
- Update go-dbus to v5.1.0
|
||||
- **BREAKING CHANGE** : Generic recursive settings map dbus variants decoding
|
||||
|
||||
## [0.5.0] - 2022-11-22
|
||||
|
||||
### Added
|
||||
|
||||
- Godoc standard comment prefix
|
||||
- DnsManager
|
||||
- Device: GetIp4Connectivity
|
||||
- Constants for Nm80211APSec
|
||||
- Add gitignore
|
||||
|
||||
### Fixed
|
||||
|
||||
- CheckpointCreate: fix devicePaths variable scope
|
||||
|
||||
## [0.4.0] - 2022-01-17
|
||||
|
||||
### Added
|
||||
|
||||
- AccessPoint: add LastSeen property
|
||||
|
||||
### Changed
|
||||
|
||||
- Examples: move examples to their own subfolders
|
||||
|
||||
### Fixed
|
||||
|
||||
- DeviceWireless: remove duplicated fields
|
||||
- PrimaryConnection: use ActiveConnection type
|
||||
- SubscribeState: add the path to the recieved chan type, catch connect event for ActiveConnection
|
||||
|
||||
## [0.3.0] - 2020-03-26
|
||||
|
||||
### Added
|
||||
|
||||
- SetPropertyManaged (@joseffilzmaier)
|
||||
- GetConnectionByUUID (@paulburlumi)
|
||||
- VpnConnection
|
||||
- ActiveConnectionSignalStateChanged
|
||||
- CheckpointRollback
|
||||
- SetPropertyWirelessEnabled (@Raqbit)
|
||||
- Settings.ReloadConnections (@appnostic-io)
|
||||
|
||||
Static connection example (@everactivemilligan)
|
||||
|
||||
### Fixed
|
||||
|
||||
- GetPropertyRouteData panic (@zhengdelun)
|
||||
|
||||
## [0.2.0] - 2020-03-06
|
||||
|
||||
### Fixed
|
||||
|
||||
- added missing flag for Reload
|
||||
- added parameter specific_object for AddAndActivateConnection
|
||||
- Fix CheckpointCreateand GetPropertyCheckpoints
|
||||
|
||||
### Added
|
||||
|
||||
- Add property setter helper
|
||||
- Add Device.SetPropertyRefreshRateMs
|
||||
- Add Device.Reapply
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
CheckpointInterface = NetworkManagerInterface + ".Checkpoint"
|
||||
|
||||
/* Properties */
|
||||
CheckpointPropertyDevices = CheckpointInterface + ".Devices" // readable ao
|
||||
CheckpointPropertyCreated = CheckpointInterface + ".Created" // readable x
|
||||
CheckpointPropertyRollbackTimeout = CheckpointInterface + ".RollbackTimeout" // readable u
|
||||
)
|
||||
|
||||
type Checkpoint interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// GetPropertyDevices Array of object paths for devices which are part of this checkpoint.
|
||||
GetPropertyDevices() ([]Device, error)
|
||||
|
||||
// GetPropertyCreated The timestamp (in CLOCK_BOOTTIME milliseconds) of checkpoint creation.
|
||||
GetPropertyCreated() (int64, error)
|
||||
|
||||
// GetPropertyRollbackTimeout Timeout in seconds for automatic rollback, or zero.
|
||||
GetPropertyRollbackTimeout() (uint32, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewCheckpoint(objectPath dbus.ObjectPath) (Checkpoint, error) {
|
||||
var c checkpoint
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type checkpoint struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (c *checkpoint) GetPropertyDevices() ([]Device, error) {
|
||||
devicesPaths, err := c.getSliceObjectProperty(CheckpointPropertyDevices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
devices := make([]Device, len(devicesPaths))
|
||||
for i, path := range devicesPaths {
|
||||
devices[i], err = NewDevice(path)
|
||||
if err != nil {
|
||||
return devices, err
|
||||
}
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (c *checkpoint) GetPropertyCreated() (int64, error) {
|
||||
return c.getInt64Property(CheckpointPropertyCreated)
|
||||
}
|
||||
|
||||
func (c *checkpoint) GetPropertyRollbackTimeout() (uint32, error) {
|
||||
return c.getUint32Property(CheckpointPropertyRollbackTimeout)
|
||||
}
|
||||
|
||||
func (c *checkpoint) GetPath() dbus.ObjectPath {
|
||||
return c.obj.Path()
|
||||
}
|
||||
|
||||
func (c *checkpoint) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
m["Devices"], _ = c.GetPropertyDevices()
|
||||
m["Created"], _ = c.GetPropertyCreated()
|
||||
m["RollbackTimeout"], _ = c.GetPropertyRollbackTimeout()
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
ConnectionInterface = SettingsInterface + ".Connection"
|
||||
|
||||
/* Methods */
|
||||
ConnectionUpdate = ConnectionInterface + ".Update"
|
||||
ConnectionUpdateUnsaved = ConnectionInterface + ".UpdateUnsaved"
|
||||
ConnectionDelete = ConnectionInterface + ".Delete"
|
||||
ConnectionGetSettings = ConnectionInterface + ".GetSettings"
|
||||
ConnectionGetSecrets = ConnectionInterface + ".GetSecrets"
|
||||
ConnectionClearSecrets = ConnectionInterface + ".ClearSecrets"
|
||||
ConnectionSave = ConnectionInterface + ".Save"
|
||||
ConnectionUpdate2 = ConnectionInterface + ".Update2"
|
||||
|
||||
/* Properties */
|
||||
ConnectionPropertyUnsaved = ConnectionInterface + ".Unsaved" // readable b
|
||||
ConnectionPropertyFlags = ConnectionInterface + ".Flags" // readable u
|
||||
ConnectionPropertyFilename = ConnectionInterface + ".Filename" // readable s
|
||||
)
|
||||
|
||||
//type ConnectionSettings map[string]map[string]interface{}
|
||||
type ConnectionSettings map[string]map[string]interface{}
|
||||
|
||||
type Connection interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// Update the connection with new settings and properties (replacing all previous settings and properties) and save the connection to disk. Secrets may be part of the update request, and will be either stored in persistent storage or sent to a Secret Agent for storage, depending on the flags associated with each secret.
|
||||
Update(settings ConnectionSettings) error
|
||||
|
||||
// UpdateUnsaved Update the connection with new settings and properties (replacing all previous settings and properties) but do not immediately save the connection to disk. Secrets may be part of the update request and may sent to a Secret Agent for storage, depending on the flags associated with each secret. Use the 'Save' method to save these changes to disk. Note that unsaved changes will be lost if the connection is reloaded from disk (either automatically on file change or due to an explicit ReloadConnections call).
|
||||
UpdateUnsaved(settings ConnectionSettings) error
|
||||
|
||||
// Delete the connection.
|
||||
Delete() error
|
||||
|
||||
// GetSettings gets the settings maps describing this network configuration.
|
||||
// This will never include any secrets required for connection to the
|
||||
// network, as those are often protected. Secrets must be requested
|
||||
// separately using the GetSecrets() method.
|
||||
GetSettings() (ConnectionSettings, error)
|
||||
|
||||
// GetSecrets Get the secrets belonging to this network configuration. Only secrets from
|
||||
// persistent storage or a Secret Agent running in the requestor's session
|
||||
// will be returned. The user will never be prompted for secrets as a result
|
||||
// of this request.
|
||||
GetSecrets(settingName string) (ConnectionSettings, error)
|
||||
|
||||
// ClearSecrets Clear the secrets belonging to this network connection profile.
|
||||
ClearSecrets() error
|
||||
|
||||
// Save a "dirty" connection (that had previously been updated with UpdateUnsaved) to persistent storage.
|
||||
Save() error
|
||||
|
||||
// GetPropertyUnsaved If set, indicates that the in-memory state of the connection does not match the on-disk state. This flag will be set when UpdateUnsaved() is called or when any connection details change, and cleared when the connection is saved to disk via Save() or from internal operations.
|
||||
GetPropertyUnsaved() (bool, error)
|
||||
|
||||
// GetPropertyFlags Additional flags of the connection profile.
|
||||
GetPropertyFlags() (uint32, error)
|
||||
|
||||
// GetPropertyFilename File that stores the connection in case the connection is file-backed.
|
||||
GetPropertyFilename() (string, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewConnection(objectPath dbus.ObjectPath) (Connection, error) {
|
||||
var c connection
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type connection struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (c *connection) GetPath() dbus.ObjectPath {
|
||||
return c.obj.Path()
|
||||
}
|
||||
|
||||
func (c *connection) Update(settings ConnectionSettings) error {
|
||||
return c.call(ConnectionUpdate, settings)
|
||||
}
|
||||
|
||||
func (c *connection) UpdateUnsaved(settings ConnectionSettings) error {
|
||||
return c.call(ConnectionUpdateUnsaved, settings)
|
||||
}
|
||||
|
||||
func (c *connection) Delete() error {
|
||||
return c.call(ConnectionDelete)
|
||||
}
|
||||
|
||||
func (c *connection) GetSettings() (ConnectionSettings, error) {
|
||||
var settings map[string]map[string]dbus.Variant
|
||||
|
||||
if err := c.callWithReturn(&settings, ConnectionGetSettings); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decodeSettings(settings), nil
|
||||
}
|
||||
|
||||
func (c *connection) GetSecrets(settingName string) (ConnectionSettings, error) {
|
||||
var settings map[string]map[string]dbus.Variant
|
||||
|
||||
if err := c.callWithReturn(&settings, ConnectionGetSecrets, settingName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decodeSettings(settings), nil
|
||||
}
|
||||
|
||||
func decodeSettings(input map[string]map[string]dbus.Variant) (settings ConnectionSettings) {
|
||||
valueMap := ConnectionSettings{}
|
||||
for key, data := range input {
|
||||
valueMap[key] = decode(data).(map[string]interface{})
|
||||
}
|
||||
return valueMap
|
||||
}
|
||||
|
||||
func decode(input interface{}) (value interface{}) {
|
||||
if variant, isVariant := input.(dbus.Variant); isVariant {
|
||||
return decode(variant.Value())
|
||||
} else if inputMap, isMap := input.(map[string]dbus.Variant); isMap {
|
||||
return decodeMap(inputMap)
|
||||
} else if inputArray, isArray := input.([]dbus.Variant); isArray {
|
||||
return decodeArray(inputArray)
|
||||
} else if inputArray, isArray := input.([]map[string]dbus.Variant); isArray {
|
||||
return decodeMapArray(inputArray)
|
||||
} else {
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
func decodeArray(input []dbus.Variant) (value []interface{}) {
|
||||
for _, data := range input {
|
||||
value = append(value, decode(data))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func decodeMapArray(input []map[string]dbus.Variant) (value []map[string]interface{}) {
|
||||
for _, data := range input {
|
||||
value = append(value, decodeMap(data))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func decodeMap(input map[string]dbus.Variant) (value map[string]interface{}) {
|
||||
value = map[string]interface{}{}
|
||||
for key, data := range input {
|
||||
value[key] = decode(data)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *connection) ClearSecrets() error {
|
||||
return c.call(ConnectionClearSecrets)
|
||||
}
|
||||
|
||||
func (c *connection) Save() error {
|
||||
return c.call(ConnectionSave)
|
||||
}
|
||||
|
||||
func (c *connection) GetPropertyUnsaved() (bool, error) {
|
||||
return c.getBoolProperty(ConnectionPropertyUnsaved)
|
||||
}
|
||||
|
||||
func (c *connection) GetPropertyFlags() (uint32, error) {
|
||||
return c.getUint32Property(ConnectionPropertyFlags)
|
||||
}
|
||||
|
||||
func (c *connection) GetPropertyFilename() (string, error) {
|
||||
return c.getStringProperty(ConnectionPropertyFilename)
|
||||
}
|
||||
|
||||
func (c *connection) MarshalJSON() ([]byte, error) {
|
||||
s, _ := c.GetSettings()
|
||||
return json.Marshal(s)
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DHCP4ConfigInterface = NetworkManagerInterface + ".DHCP4Config"
|
||||
|
||||
// Properties
|
||||
DHCP4ConfigPropertyOptions = DHCP4ConfigInterface + ".Options"
|
||||
)
|
||||
|
||||
type DHCP4Options map[string]interface{}
|
||||
|
||||
type DHCP4Config interface {
|
||||
// GetPropertyOptions GetOptions gets options map of configuration returned by the IPv4 DHCP server.
|
||||
GetPropertyOptions() (DHCP4Options, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewDHCP4Config(objectPath dbus.ObjectPath) (DHCP4Config, error) {
|
||||
var c dhcp4Config
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type dhcp4Config struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (c *dhcp4Config) GetPropertyOptions() (DHCP4Options, error) {
|
||||
options, err := c.getMapStringVariantProperty(DHCP4ConfigPropertyOptions)
|
||||
rv := make(DHCP4Options)
|
||||
if err != nil {
|
||||
return rv, err
|
||||
}
|
||||
|
||||
for k, v := range options {
|
||||
rv[k] = v.Value()
|
||||
}
|
||||
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
func (c *dhcp4Config) MarshalJSON() ([]byte, error) {
|
||||
Options, err := c.GetPropertyOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"Options": Options,
|
||||
})
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DHCP6ConfigInterface = NetworkManagerInterface + ".DHCP6Config"
|
||||
|
||||
// Properties
|
||||
DHCP6ConfigPropertyOptions = DHCP6ConfigInterface + ".Options"
|
||||
)
|
||||
|
||||
type DHCP6Options map[string]interface{}
|
||||
|
||||
type DHCP6Config interface {
|
||||
// GetPropertyOptions GetOptions gets options map of configuration returned by the IPv4 DHCP server.
|
||||
GetPropertyOptions() (DHCP6Options, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewDHCP6Config(objectPath dbus.ObjectPath) (DHCP6Config, error) {
|
||||
var c dhcp6Config
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type dhcp6Config struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (c *dhcp6Config) GetPropertyOptions() (DHCP6Options, error) {
|
||||
options, err := c.getMapStringVariantProperty(DHCP6ConfigPropertyOptions)
|
||||
rv := make(DHCP6Options)
|
||||
|
||||
if err != nil {
|
||||
return rv, err
|
||||
}
|
||||
|
||||
for k, v := range options {
|
||||
rv[k] = v.Value()
|
||||
}
|
||||
|
||||
return rv, nil
|
||||
}
|
||||
|
||||
func (c *dhcp6Config) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]interface{})
|
||||
m["Options"], _ = c.GetPropertyOptions()
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+434
@@ -0,0 +1,434 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceInterface = NetworkManagerInterface + ".Device"
|
||||
|
||||
/* Methods */
|
||||
DeviceReapply = DeviceInterface + ".Reapply"
|
||||
DeviceGetAppliedConnection = DeviceInterface + ".GetAppliedConnection"
|
||||
DeviceDisconnect = DeviceInterface + ".Disconnect"
|
||||
DeviceDelete = DeviceInterface + ".Delete"
|
||||
|
||||
/* Properties */
|
||||
DevicePropertyUdi = DeviceInterface + ".Udi" // readable s
|
||||
DevicePropertyInterface = DeviceInterface + ".Interface" // readable s
|
||||
DevicePropertyIpInterface = DeviceInterface + ".IpInterface" // readable s
|
||||
DevicePropertyDriver = DeviceInterface + ".Driver" // readable s
|
||||
DevicePropertyDriverVersion = DeviceInterface + ".DriverVersion" // readable s
|
||||
DevicePropertyFirmwareVersion = DeviceInterface + ".FirmwareVersion" // readable s
|
||||
DevicePropertyCapabilities = DeviceInterface + ".Capabilities" // readable u
|
||||
DevicePropertyState = DeviceInterface + ".State" // readable u
|
||||
DevicePropertyStateReason = DeviceInterface + ".StateReason" // readable (uu)
|
||||
DevicePropertyActiveConnection = DeviceInterface + ".ActiveConnection" // readable o
|
||||
DevicePropertyIp4Config = DeviceInterface + ".Ip4Config" // readable o
|
||||
DevicePropertyDhcp4Config = DeviceInterface + ".Dhcp4Config" // readable o
|
||||
DevicePropertyIp6Config = DeviceInterface + ".Ip6Config" // readable o
|
||||
DevicePropertyDhcp6Config = DeviceInterface + ".Dhcp6Config" // readable o
|
||||
DevicePropertyManaged = DeviceInterface + ".Managed" // readwrite b
|
||||
DevicePropertyAutoconnect = DeviceInterface + ".Autoconnect" // readwrite b
|
||||
DevicePropertyFirmwareMissing = DeviceInterface + ".FirmwareMissing" // readable b
|
||||
DevicePropertyNmPluginMissing = DeviceInterface + ".NmPluginMissing" // readable b
|
||||
DevicePropertyDeviceType = DeviceInterface + ".DeviceType" // readable u
|
||||
DevicePropertyAvailableConnections = DeviceInterface + ".AvailableConnections" // readable ao
|
||||
DevicePropertyPhysicalPortId = DeviceInterface + ".PhysicalPortId" // readable s
|
||||
DevicePropertyMtu = DeviceInterface + ".Mtu" // readable u
|
||||
DevicePropertyMetered = DeviceInterface + ".Metered" // readable u
|
||||
DevicePropertyLldpNeighbors = DeviceInterface + ".LldpNeighbors" // readable aa{sv}
|
||||
DevicePropertyReal = DeviceInterface + ".Real" // readable b
|
||||
DevicePropertyIp4Connectivity = DeviceInterface + ".Ip4Connectivity" // readable u
|
||||
|
||||
/* Signals */
|
||||
DeviceSignalStateChanged = "StateChanged" // u state, u reason
|
||||
|
||||
)
|
||||
|
||||
func DeviceFactory(objectPath dbus.ObjectPath) (Device, error) {
|
||||
d, err := NewDevice(objectPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deviceType, err := d.GetPropertyDeviceType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch deviceType {
|
||||
case NmDeviceTypeDummy:
|
||||
return NewDeviceDummy(objectPath)
|
||||
case NmDeviceTypeGeneric:
|
||||
return NewDeviceGeneric(objectPath)
|
||||
case NmDeviceTypeIpTunnel:
|
||||
return NewDeviceIpTunnel(objectPath)
|
||||
case NmDeviceTypeBridge:
|
||||
return NewDeviceBridge(objectPath)
|
||||
case NmDeviceTypeEthernet:
|
||||
return NewDeviceWired(objectPath)
|
||||
case NmDeviceTypeWifi:
|
||||
return NewDeviceWireless(objectPath)
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
type Device interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// Reapply Attempts to update the configuration of a device without deactivating it. NetworkManager has the concept of connections, which are profiles that contain the configuration for a networking device. Those connections are exposed via D-Bus as individual objects that can be created, modified and deleted. When activating such a settings-connection on a device, the settings-connection is cloned to become an applied-connection and used to configure the device (see GetAppliedConnection). Subsequent modification of the settings-connection don't propagate automatically to the device's applied-connection (with exception of the firewall-zone and the metered property). For the changes to take effect, you can either re-activate the settings-connection, or call Reapply. The Reapply call allows you to directly update the applied-connection and reconfigure the device. Reapply can also be useful if the currently applied-connection is equal to the connection that is about to be reapplied. This allows to reconfigure the device and revert external changes like removing or adding an IP address (which NetworkManager doesn't revert automatically because it is assumed that the user made these changes intentionally outside of NetworkManager). Reapply can make the applied-connection different from the settings-connection, just like updating the settings-connection can make them different.
|
||||
// connection: The optional connection settings that will be reapplied on the device. If empty, the currently active settings-connection will be used. The connection cannot arbitrarly differ from the current applied-connection otherwise the call will fail. Only certain changes are supported, like adding or removing IP addresses.
|
||||
// versionId: If non-zero, the current version id of the applied-connection must match. The current version id can be retrieved via GetAppliedConnection. This optional argument allows to catch concurrent modifications between the GetAppliedConnection call and Reapply.
|
||||
// flags: Flags which would modify the behavior of the Reapply call. There are no flags defined currently and the users should use the value of 0.
|
||||
Reapply(connection Connection, versionId uint64, flags uint32) error
|
||||
|
||||
// Disconnect a device and prevents the device from automatically activating further connections without user intervention.
|
||||
Disconnect() error
|
||||
|
||||
// Delete a software device from NetworkManager and removes the interface from the system. The method returns an error when called for a hardware device.
|
||||
Delete() error
|
||||
|
||||
// GetPropertyUdi Operating-system specific transient device hardware identifier. This is an opaque string representing the underlying hardware for the device, and shouldn't be used to keep track of individual devices. For some device types (Bluetooth, Modems) it is an identifier used by the hardware service (ie bluez or ModemManager) to refer to that device, and client programs use it get additional information from those services which NM does not provide. The Udi is not guaranteed to be consistent across reboots or hotplugs of the hardware. If you're looking for a way to uniquely track each device in your application, use the object path. If you're looking for a way to track a specific piece of hardware across reboot or hotplug, use a MAC address or USB serial number.
|
||||
GetPropertyUdi() (string, error)
|
||||
|
||||
// GetPropertyInterface The name of the device's control (and often data) interface. Note that non UTF-8 characters are backslash escaped, so the resulting name may be longer then 15 characters. Use g_strcompress() to revert the escaping.
|
||||
GetPropertyInterface() (string, error)
|
||||
|
||||
// GetPropertyIpInterface The name of the device's data interface when available. This property may not refer to the actual data interface until the device has successfully established a data connection, indicated by the device's State becoming ACTIVATED. Note that non UTF-8 characters are backslash escaped, so the resulting name may be longer then 15 characters. Use g_strcompress() to revert the escaping.
|
||||
GetPropertyIpInterface() (string, error)
|
||||
|
||||
// GetPropertyDriver The driver handling the device. Non-UTF-8 sequences are backslash escaped. Use g_strcompress() to revert.
|
||||
GetPropertyDriver() (string, error)
|
||||
|
||||
// GetPropertyDriverVersion The version of the driver handling the device. Non-UTF-8 sequences are backslash escaped. Use g_strcompress() to revert.
|
||||
GetPropertyDriverVersion() (string, error)
|
||||
|
||||
// GetPropertyFirmwareVersion The firmware version for the device. Non-UTF-8 sequences are backslash escaped. Use g_strcompress() to revert.
|
||||
GetPropertyFirmwareVersion() (string, error)
|
||||
|
||||
// GetPropertyState The current state of the device.
|
||||
GetPropertyState() (NmDeviceState, error)
|
||||
|
||||
// GetPropertyActiveConnection Object path of an ActiveConnection object that "owns" this device during activation. The ActiveConnection object tracks the life-cycle of a connection to a specific network and implements the org.freedesktop.NetworkManager.Connection.Active D-Bus interface.
|
||||
GetPropertyActiveConnection() (ActiveConnection, error)
|
||||
|
||||
// GetPropertyIP4Config Object path of the Ip4Config object describing the configuration of the device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state.
|
||||
GetPropertyIP4Config() (IP4Config, error)
|
||||
|
||||
// GetPropertyDHCP4Config Object path of the Dhcp4Config object describing the DHCP options returned by the DHCP server. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state.
|
||||
GetPropertyDHCP4Config() (DHCP4Config, error)
|
||||
|
||||
// GetPropertyIP6Config Object path of the Ip6Config object describing the configuration of the device. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state.
|
||||
GetPropertyIP6Config() (IP6Config, error)
|
||||
|
||||
// GetPropertyDHCP6Config Object path of the Dhcp6Config object describing the DHCP options returned by the DHCP server. Only valid when the device is in the NM_DEVICE_STATE_ACTIVATED state.
|
||||
GetPropertyDHCP6Config() (DHCP6Config, error)
|
||||
|
||||
// GetPropertyManaged Whether this device is managed by NetworkManager. Setting this property has a similar effect to configuring the device as unmanaged via the keyfile.unmanaged-devices setting in NetworkManager.conf. Changes to this value are not persistent and lost after NetworkManager restart.
|
||||
GetPropertyManaged() (bool, error)
|
||||
SetPropertyManaged(bool) error
|
||||
|
||||
// GetPropertyAutoConnect If TRUE, indicates the device is allowed to autoconnect. If FALSE, manual intervention is required before the device will automatically connect to a known network, such as activating a connection using the device, or setting this property to TRUE. This property cannot be set to TRUE for default-unmanaged devices, since they never autoconnect.
|
||||
GetPropertyAutoConnect() (bool, error)
|
||||
SetPropertyAutoConnect(bool) error
|
||||
|
||||
// GetPropertyFirmwareMissing If TRUE, indicates the device is likely missing firmware necessary for its operation.
|
||||
GetPropertyFirmwareMissing() (bool, error)
|
||||
|
||||
// GetPropertyNmPluginMissing If TRUE, indicates the NetworkManager plugin for the device is likely missing or misconfigured.
|
||||
GetPropertyNmPluginMissing() (bool, error)
|
||||
|
||||
// GetPropertyDeviceType The general type of the network device; ie Ethernet, Wi-Fi, etc.
|
||||
GetPropertyDeviceType() (NmDeviceType, error)
|
||||
|
||||
// GetPropertyAvailableConnections An array of object paths of every configured connection that is currently 'available' through this device.
|
||||
GetPropertyAvailableConnections() ([]Connection, error)
|
||||
|
||||
// GetPropertyPhysicalPortId If non-empty, an (opaque) indicator of the physical network port associated with the device. This can be used to recognize when two seemingly-separate hardware devices are actually just different virtual interfaces to the same physical port.
|
||||
GetPropertyPhysicalPortId() (string, error)
|
||||
|
||||
// GetPropertyMtu The device MTU (maximum transmission unit).
|
||||
GetPropertyMtu() (uint32, error)
|
||||
|
||||
// GetPropertyReal True if the device exists, or False for placeholder devices that do not yet exist but could be automatically created by NetworkManager if one of their AvailableConnections was activated.
|
||||
GetPropertyReal() (bool, error)
|
||||
|
||||
// The result of the last IPv4 connectivity check.
|
||||
GetPropertyIp4Connectivity() (NmConnectivity, error)
|
||||
|
||||
SubscribeState(receiver chan DeviceStateChange, exit chan struct{}) (err error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewDevice(objectPath dbus.ObjectPath) (Device, error) {
|
||||
var d device
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type device struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (d *device) GetPath() dbus.ObjectPath {
|
||||
return d.obj.Path()
|
||||
}
|
||||
|
||||
func (d *device) Reapply(connection Connection, versionId uint64, flags uint32) error {
|
||||
return d.call(DeviceReapply, connection, versionId, flags)
|
||||
}
|
||||
|
||||
func (d *device) Disconnect() error {
|
||||
return d.call(DeviceDisconnect)
|
||||
}
|
||||
|
||||
func (d *device) Delete() error {
|
||||
return d.call(DeviceDelete)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyUdi() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyUdi)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyInterface() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyInterface)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyIpInterface() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyIpInterface)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyDriver() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyDriver)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyDriverVersion() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyDriverVersion)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyFirmwareVersion() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyFirmwareVersion)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyState() (NmDeviceState, error) {
|
||||
r, err := d.getUint32Property(DevicePropertyState)
|
||||
if err != nil {
|
||||
return NmDeviceStateFailed, err
|
||||
}
|
||||
return NmDeviceState(r), nil
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyActiveConnection() (ActiveConnection, error) {
|
||||
path, err := d.getObjectProperty(DevicePropertyActiveConnection)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewActiveConnection(path)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyIP4Config() (IP4Config, error) {
|
||||
path, err := d.getObjectProperty(DevicePropertyIp4Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewIP4Config(path)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyDHCP4Config() (DHCP4Config, error) {
|
||||
path, err := d.getObjectProperty(DevicePropertyDhcp4Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDHCP4Config(path)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyIP6Config() (IP6Config, error) {
|
||||
path, err := d.getObjectProperty(DevicePropertyIp6Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewIP6Config(path)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyDHCP6Config() (DHCP6Config, error) {
|
||||
path, err := d.getObjectProperty(DevicePropertyDhcp6Config)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDHCP6Config(path)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyManaged() (bool, error) {
|
||||
return d.getBoolProperty(DevicePropertyManaged)
|
||||
}
|
||||
|
||||
func (d *device) SetPropertyManaged(managed bool) error {
|
||||
return d.setProperty(DevicePropertyManaged, managed)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyAutoConnect() (bool, error) {
|
||||
return d.getBoolProperty(DevicePropertyAutoconnect)
|
||||
}
|
||||
|
||||
func (d *device) SetPropertyAutoConnect(managed bool) error {
|
||||
return d.setProperty(DevicePropertyAutoconnect, managed)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyFirmwareMissing() (bool, error) {
|
||||
return d.getBoolProperty(DevicePropertyFirmwareMissing)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyNmPluginMissing() (bool, error) {
|
||||
return d.getBoolProperty(DevicePropertyNmPluginMissing)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyDeviceType() (NmDeviceType, error) {
|
||||
v, err := d.getUint32Property(DevicePropertyDeviceType)
|
||||
return NmDeviceType(v), err
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyAvailableConnections() ([]Connection, error) {
|
||||
connPaths, err := d.getSliceObjectProperty(DevicePropertyAvailableConnections)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conns := make([]Connection, len(connPaths))
|
||||
for i, path := range connPaths {
|
||||
conns[i], err = NewConnection(path)
|
||||
if err != nil {
|
||||
return conns, err
|
||||
}
|
||||
}
|
||||
|
||||
return conns, nil
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyPhysicalPortId() (string, error) {
|
||||
return d.getStringProperty(DevicePropertyPhysicalPortId)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyMtu() (uint32, error) {
|
||||
return d.getUint32Property(DevicePropertyMtu)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyReal() (bool, error) {
|
||||
return d.getBoolProperty(DevicePropertyReal)
|
||||
}
|
||||
|
||||
func (d *device) GetPropertyIp4Connectivity() (NmConnectivity, error) {
|
||||
u, err := d.getUint32Property(DevicePropertyIp4Connectivity)
|
||||
return NmConnectivity(u), err
|
||||
}
|
||||
|
||||
func (d *device) marshalMap() (map[string]interface{}, error) {
|
||||
Interface, err := d.GetPropertyInterface()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
IpInterface, err := d.GetPropertyIpInterface()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
State, err := d.GetPropertyState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
IP4Config, err := d.GetPropertyIP4Config()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
DHCP4Config, err := d.GetPropertyDHCP4Config()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
DeviceType, err := d.GetPropertyDeviceType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
AvailableConnections, err := d.GetPropertyAvailableConnections()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
"Interface": Interface,
|
||||
"IP interface": IpInterface,
|
||||
"State": State.String(),
|
||||
"IP4Config": IP4Config,
|
||||
"DHCP4Config": DHCP4Config,
|
||||
"DeviceType": DeviceType.String(),
|
||||
"AvailableConnections": AvailableConnections,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type DeviceStateChange struct {
|
||||
Path dbus.ObjectPath
|
||||
State NmDeviceState
|
||||
Reason NmDeviceStateReason
|
||||
}
|
||||
|
||||
func (d *device) SubscribeState(receiver chan DeviceStateChange, exit chan struct{}) (err error) {
|
||||
|
||||
channel := make(chan *dbus.Signal, 1)
|
||||
|
||||
d.conn.Signal(channel)
|
||||
|
||||
err = d.conn.AddMatchSignal(
|
||||
dbus.WithMatchInterface(DeviceInterface),
|
||||
dbus.WithMatchMember(DeviceSignalStateChanged),
|
||||
dbus.WithMatchObjectPath(d.GetPath()),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case signal, ok := <-channel:
|
||||
if !ok {
|
||||
err = fmt.Errorf("connection closed for %s", DeviceSignalStateChanged)
|
||||
return
|
||||
}
|
||||
|
||||
if signal.Name != DeviceInterface+"."+DeviceSignalStateChanged {
|
||||
continue
|
||||
}
|
||||
|
||||
stateChange := DeviceStateChange{
|
||||
Path: signal.Path,
|
||||
State: NmDeviceState(signal.Body[0].(uint32)),
|
||||
Reason: NmDeviceStateReason(signal.Body[1].(uint32)),
|
||||
}
|
||||
|
||||
receiver <- stateChange
|
||||
|
||||
case <-exit:
|
||||
d.conn.RemoveSignal(channel)
|
||||
close(channel)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *device) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceBridgeInterface = DeviceInterface + ".Bridge"
|
||||
|
||||
// Properties
|
||||
DeviceBridgePropertyHwAddress = DeviceBridgeInterface + ".HwAddress" // readable s
|
||||
DeviceBridgePropertySlaves = DeviceBridgeInterface + ".Slaves" // readable as
|
||||
DeviceBridgePropertyCarrier = DeviceBridgeInterface + ".Carrier" // readable b
|
||||
)
|
||||
|
||||
type DeviceBridge interface {
|
||||
Device
|
||||
|
||||
// GetPropertyHwAddress Active hardware address of the device.
|
||||
GetPropertyHwAddress() (string, error)
|
||||
|
||||
// GetPropertySlaves Array of paths of enslaved and active devices.
|
||||
// DEPRECATED. Use the "Ports" property in "org.freedesktop.NetworkManager.Device" instead which exists since version NetworkManager 1.34.0.
|
||||
GetPropertySlaves() ([]Device, error)
|
||||
|
||||
// GetPropertyCarrier Indicates whether the physical carrier is found (e.g. whether a cable is plugged in or not).
|
||||
// DEPRECATED: check for the "carrier" flag in the "InterfaceFlags" property on the "org.freedesktop.NetworkManager.Device" interface.
|
||||
GetPropertyCarrier() (bool, error)
|
||||
}
|
||||
|
||||
func NewDeviceBridge(objectPath dbus.ObjectPath) (DeviceBridge, error) {
|
||||
var d deviceBridge
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceBridge struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceBridge) GetPropertyHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceBridgePropertyHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceBridge) GetPropertySlaves() ([]Device, error) {
|
||||
paths, err := d.getSliceObjectProperty(DeviceBridgePropertySlaves)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices := make([]Device, len(paths))
|
||||
for i, path := range paths {
|
||||
devices[i], err = DeviceFactory(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (d *deviceBridge) GetPropertyCarrier() (bool, error) {
|
||||
return d.getBoolProperty(DeviceBridgePropertyCarrier)
|
||||
}
|
||||
|
||||
func (d *deviceBridge) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["HwAddress"], _ = d.GetPropertyHwAddress()
|
||||
m["Slaves"], _ = d.GetPropertySlaves()
|
||||
m["Carrier"], _ = d.GetPropertyCarrier()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceDummyInterface = DeviceInterface + ".Dummy"
|
||||
|
||||
/* Properties */
|
||||
DeviceDummyPropertyHwAddress = DeviceDummyInterface + ".HwAddress" // readable s
|
||||
)
|
||||
|
||||
type DeviceDummy interface {
|
||||
Device
|
||||
|
||||
// Hardware address of the device.
|
||||
GetPropertyHwAddress() (string, error)
|
||||
}
|
||||
|
||||
func NewDeviceDummy(objectPath dbus.ObjectPath) (DeviceDummy, error) {
|
||||
var d deviceDummy
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceDummy struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceDummy) GetPropertyHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceDummyPropertyHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceDummy) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["HwAddress"], _ = d.GetPropertyHwAddress()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceGenericInterface = DeviceInterface + ".Generic"
|
||||
|
||||
// Properties
|
||||
DeviceGenericPropertyHwAddress = DeviceGenericInterface + ".HwAddress" // readable s
|
||||
DeviceGenericPropertyTypeDescription = DeviceGenericInterface + ".TypeDescription" // readable s
|
||||
)
|
||||
|
||||
type DeviceGeneric interface {
|
||||
Device
|
||||
|
||||
// GetPropertyHwAddress Active hardware address of the device.
|
||||
GetPropertyHwAddress() (string, error)
|
||||
|
||||
// GetPropertyTypeDescription A (non-localized) description of the interface type, if known.
|
||||
GetPropertyTypeDescription() (string, error)
|
||||
}
|
||||
|
||||
func NewDeviceGeneric(objectPath dbus.ObjectPath) (DeviceGeneric, error) {
|
||||
var d deviceGeneric
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceGeneric struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceGeneric) GetPropertyHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceGenericPropertyHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceGeneric) GetPropertyTypeDescription() (string, error) {
|
||||
return d.getStringProperty(DeviceGenericPropertyTypeDescription)
|
||||
}
|
||||
|
||||
func (d *deviceGeneric) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["HwAddress"], _ = d.GetPropertyHwAddress()
|
||||
m["TypeDescription"], _ = d.GetPropertyTypeDescription()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceIpTunnelInterface = DeviceInterface + ".IPTunnel"
|
||||
|
||||
// Properties
|
||||
DeviceIpTunnelPropertyHwAddress = DeviceIpTunnelInterface + "HwAddress" // readable s
|
||||
DeviceIpTunnelPropertyMode = DeviceIpTunnelInterface + ".Mode" // readable u
|
||||
DeviceIpTunnelPropertyParent = DeviceIpTunnelInterface + ".Parent" // readable o
|
||||
DeviceIpTunnelPropertyLocal = DeviceIpTunnelInterface + ".Local" // readable s
|
||||
DeviceIpTunnelPropertyRemote = DeviceIpTunnelInterface + ".Remote" // readable s
|
||||
DeviceIpTunnelPropertyTtl = DeviceIpTunnelInterface + ".Ttl" // readable y
|
||||
DeviceIpTunnelPropertyTos = DeviceIpTunnelInterface + ".Tos" // readable y
|
||||
DeviceIpTunnelPropertyPathMtuDiscovery = DeviceIpTunnelInterface + ".PathMtuDiscovery" // readable b
|
||||
DeviceIpTunnelPropertyInputKey = DeviceIpTunnelInterface + ".InputKey" // readable s
|
||||
DeviceIpTunnelPropertyOutputKey = DeviceIpTunnelInterface + ".OutputKey" // readable s
|
||||
DeviceIpTunnelPropertyEncapsulationLimit = DeviceIpTunnelInterface + ".EncapsulationLimit" // readable y
|
||||
DeviceIpTunnelPropertyFlowLabel = DeviceIpTunnelInterface + ".FlowLabel" // readable u
|
||||
DeviceIpTunnelPropertyFlags = DeviceIpTunnelInterface + ".Flags" // readable u
|
||||
|
||||
)
|
||||
|
||||
type DeviceIpTunnel interface {
|
||||
Device
|
||||
|
||||
// GetPropertyMode The tunneling mode
|
||||
GetPropertyMode() (uint32, error)
|
||||
|
||||
// GetPropertyParent The object path of the parent device.
|
||||
GetPropertyParent() (Device, error)
|
||||
|
||||
// GetPropertyLocal The local endpoint of the tunnel.
|
||||
GetPropertyLocal() (string, error)
|
||||
|
||||
// GetPropertyRemote The remote endpoint of the tunnel.
|
||||
GetPropertyRemote() (string, error)
|
||||
|
||||
// GetPropertyTtl The TTL assigned to tunneled packets. 0 is a special value meaning that packets inherit the TTL value
|
||||
GetPropertyTtl() (uint8, error)
|
||||
|
||||
// GetPropertyTos The type of service (IPv4) or traffic class (IPv6) assigned to tunneled packets.
|
||||
GetPropertyTos() (uint8, error)
|
||||
|
||||
// GetPropertyPathMtuDiscovery Whether path MTU discovery is enabled on this tunnel.
|
||||
GetPropertyPathMtuDiscovery() (bool, error)
|
||||
|
||||
// GetPropertyInputKey The key used for incoming packets.
|
||||
GetPropertyInputKey() (string, error)
|
||||
|
||||
// GetPropertyOutputKey The key used for outgoing packets.
|
||||
GetPropertyOutputKey() (string, error)
|
||||
|
||||
// GetPropertyEncapsulationLimit How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels.
|
||||
GetPropertyEncapsulationLimit() (uint8, error)
|
||||
|
||||
// GetPropertyFlowLabel The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels.
|
||||
GetPropertyFlowLabel() (uint32, error)
|
||||
|
||||
// GetPropertyFlags Tunnel flags.
|
||||
GetPropertyFlags() (uint32, error)
|
||||
}
|
||||
|
||||
func NewDeviceIpTunnel(objectPath dbus.ObjectPath) (DeviceIpTunnel, error) {
|
||||
var d deviceIpTunnel
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceIpTunnel struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyMode() (uint32, error) {
|
||||
return d.getUint32Property(DeviceIpTunnelPropertyMode)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyParent() (Device, error) {
|
||||
path, err := d.getObjectProperty(DeviceIpTunnelPropertyParent)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DeviceFactory(path)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyLocal() (string, error) {
|
||||
return d.getStringProperty(DeviceIpTunnelPropertyLocal)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyRemote() (string, error) {
|
||||
return d.getStringProperty(DeviceIpTunnelPropertyRemote)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyTtl() (uint8, error) {
|
||||
return d.getUint8Property(DeviceIpTunnelPropertyTtl)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyTos() (uint8, error) {
|
||||
return d.getUint8Property(DeviceIpTunnelPropertyTos)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyPathMtuDiscovery() (bool, error) {
|
||||
return d.getBoolProperty(DeviceIpTunnelPropertyPathMtuDiscovery)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyInputKey() (string, error) {
|
||||
return d.getStringProperty(DeviceIpTunnelPropertyInputKey)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyOutputKey() (string, error) {
|
||||
return d.getStringProperty(DeviceIpTunnelPropertyOutputKey)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyEncapsulationLimit() (uint8, error) {
|
||||
return d.getUint8Property(DeviceIpTunnelPropertyEncapsulationLimit)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyFlowLabel() (uint32, error) {
|
||||
return d.getUint32Property(DeviceIpTunnelPropertyFlowLabel)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) GetPropertyFlags() (uint32, error) {
|
||||
return d.getUint32Property(DeviceIpTunnelPropertyFlags)
|
||||
}
|
||||
|
||||
func (d *deviceIpTunnel) MarshalJSON() ([]uint8, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["Mode"], _ = d.GetPropertyMode()
|
||||
m["Parent"], _ = d.GetPropertyParent()
|
||||
m["Local"], _ = d.GetPropertyLocal()
|
||||
m["Remote"], _ = d.GetPropertyRemote()
|
||||
m["Ttl"], _ = d.GetPropertyTtl()
|
||||
m["Tos"], _ = d.GetPropertyTos()
|
||||
m["PathMtuDiscovery"], _ = d.GetPropertyPathMtuDiscovery()
|
||||
m["InputKey"], _ = d.GetPropertyInputKey()
|
||||
m["OutputKey"], _ = d.GetPropertyOutputKey()
|
||||
m["EncapsulationLimit"], _ = d.GetPropertyEncapsulationLimit()
|
||||
m["FlowLabel"], _ = d.GetPropertyFlowLabel()
|
||||
m["Flags"], _ = d.GetPropertyFlags()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceStatisticsInterface = DeviceInterface + ".Statistics"
|
||||
|
||||
// Properties
|
||||
DeviceStatisticsPropertyRefreshRateMs = DeviceStatisticsInterface + ".RefreshRateMs" // readwrite u
|
||||
DeviceStatisticsPropertyTxBytes = DeviceStatisticsInterface + ".TxBytes" // readable t
|
||||
DeviceStatisticsPropertyRxBytes = DeviceStatisticsInterface + ".RxBytes" // readable t
|
||||
)
|
||||
|
||||
type DeviceStatistics interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// GetPropertyRefreshRateMs Refresh rate of the rest of properties of this interface. The properties are guaranteed to be refreshed each RefreshRateMs milliseconds in case the underlying counter has changed too. If zero, there is no guaranteed refresh rate of the properties.
|
||||
GetPropertyRefreshRateMs() (uint32, error)
|
||||
|
||||
SetPropertyRefreshRateMs(uint32) error
|
||||
|
||||
// GetPropertyTxBytes Number of transmitted bytes
|
||||
GetPropertyTxBytes() (uint64, error)
|
||||
|
||||
// GetPropertyRxBytes Number of received bytes
|
||||
GetPropertyRxBytes() (uint64, error)
|
||||
}
|
||||
|
||||
func NewDeviceStatistics(objectPath dbus.ObjectPath) (DeviceStatistics, error) {
|
||||
var d deviceStatistics
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceStatistics struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) GetPath() dbus.ObjectPath {
|
||||
return d.obj.Path()
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) GetPropertyRefreshRateMs() (uint32, error) {
|
||||
return d.getUint32Property(DeviceStatisticsPropertyRefreshRateMs)
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) SetPropertyRefreshRateMs(rate uint32) error {
|
||||
return d.setProperty(DeviceStatisticsPropertyRefreshRateMs, rate)
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) GetPropertyTxBytes() (uint64, error) {
|
||||
return d.getUint64Property(DeviceStatisticsPropertyTxBytes)
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) GetPropertyRxBytes() (uint64, error) {
|
||||
return d.getUint64Property(DeviceStatisticsPropertyRxBytes)
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) marshalMap() map[string]interface{} {
|
||||
return map[string]interface{}{}
|
||||
}
|
||||
|
||||
func (d *deviceStatistics) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
m["RefreshRateMs"], _ = d.GetPropertyRefreshRateMs()
|
||||
m["TxBytes"], _ = d.GetPropertyTxBytes()
|
||||
m["RxBytes"], _ = d.GetPropertyRxBytes()
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceWiredInterface = DeviceInterface + ".Wired"
|
||||
|
||||
// Properties
|
||||
DeviceWiredPropertyHwAddress = DeviceWiredInterface + ".HwAddress" // readable s
|
||||
DeviceWiredPropertyPermHwAddress = DeviceWiredInterface + ".PermHwAddress" // readable s
|
||||
DeviceWiredPropertySpeed = DeviceWiredInterface + ".Speed" // readable u
|
||||
DeviceWiredPropertyS390Subchannels = DeviceWiredInterface + ".S390Subchannels" // readable as
|
||||
DeviceWiredPropertyCarrier = DeviceWiredInterface + ".Carrier" // readable b
|
||||
)
|
||||
|
||||
type DeviceWired interface {
|
||||
Device
|
||||
|
||||
// GetPropertyHwAddress Active hardware address of the device.
|
||||
GetPropertyHwAddress() (string, error)
|
||||
|
||||
// GetPropertyPermHwAddress Permanent hardware address of the device.
|
||||
GetPropertyPermHwAddress() (string, error)
|
||||
|
||||
// GetPropertySpeed Design speed of the device, in megabits/second (Mb/s).
|
||||
GetPropertySpeed() (uint32, error)
|
||||
|
||||
// GetPropertyS390Subchannels Array of S/390 subchannels for S/390 or z/Architecture devices.
|
||||
GetPropertyS390Subchannels() ([]string, error)
|
||||
|
||||
// GetPropertyCarrier Indicates whether the physical carrier is found (e.g. whether a cable is plugged in or not).
|
||||
GetPropertyCarrier() (bool, error)
|
||||
}
|
||||
|
||||
func NewDeviceWired(objectPath dbus.ObjectPath) (DeviceWired, error) {
|
||||
var d deviceWired
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceWired struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceWired) GetPropertyHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceWiredPropertyHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceWired) GetPropertyPermHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceWiredPropertyPermHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceWired) GetPropertySpeed() (uint32, error) {
|
||||
return d.getUint32Property(DeviceWiredPropertySpeed)
|
||||
}
|
||||
|
||||
func (d *deviceWired) GetPropertyS390Subchannels() ([]string, error) {
|
||||
return d.getSliceStringProperty(DeviceWiredPropertyS390Subchannels)
|
||||
}
|
||||
|
||||
func (d *deviceWired) GetPropertyCarrier() (bool, error) {
|
||||
return d.getBoolProperty(DeviceWiredPropertyCarrier)
|
||||
}
|
||||
|
||||
func (d *deviceWired) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["HwAddress"], _ = d.GetPropertyHwAddress()
|
||||
m["PermHwAddress"], _ = d.GetPropertyPermHwAddress()
|
||||
m["Speed"], _ = d.GetPropertySpeed()
|
||||
m["S390Subchannels"], _ = d.GetPropertyS390Subchannels()
|
||||
m["Carrier"], _ = d.GetPropertyCarrier()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DeviceWirelessInterface = DeviceInterface + ".Wireless"
|
||||
|
||||
// Methods
|
||||
DeviceWirelessGetAccessPoints = DeviceWirelessInterface + ".GetAccessPoints"
|
||||
DeviceWirelessGetAllAccessPoints = DeviceWirelessInterface + ".GetAllAccessPoints"
|
||||
DeviceWirelessRequestScan = DeviceWirelessInterface + ".RequestScan"
|
||||
|
||||
// Properties
|
||||
DeviceWirelessPropertyHwAddress = DeviceWirelessInterface + ".HwAddress" // readable s
|
||||
DeviceWirelessPropertyPermHwAddress = DeviceWirelessInterface + ".PermHwAddress" // readable s
|
||||
DeviceWirelessPropertyMode = DeviceWirelessInterface + ".Mode" // readable u
|
||||
DeviceWirelessPropertyBitrate = DeviceWirelessInterface + ".Bitrate" // readable u
|
||||
DeviceWirelessPropertyAccessPoints = DeviceWirelessInterface + ".AccessPoints" // readable ao
|
||||
DeviceWirelessPropertyActiveAccessPoint = DeviceWirelessInterface + ".ActiveAccessPoint" // readable o
|
||||
DeviceWirelessPropertyWirelessCapabilities = DeviceWirelessInterface + ".WirelessCapabilities" // readable u
|
||||
DeviceWirelessPropertyLastScan = DeviceWirelessInterface + ".LastScan" // readable x
|
||||
)
|
||||
|
||||
type DeviceWireless interface {
|
||||
Device
|
||||
|
||||
// GetAccessPoints gets the list of access points visible to this device.
|
||||
// Note that this list does not include access points which hide their SSID.
|
||||
// To retrieve a list of all access points (including hidden ones) use the
|
||||
// GetAllAccessPoints() method.
|
||||
GetAccessPoints() ([]AccessPoint, error)
|
||||
|
||||
// GetAllAccessPoints gets the list of all access points visible to this
|
||||
// device, including hidden ones for which the SSID is not yet known.
|
||||
GetAllAccessPoints() ([]AccessPoint, error)
|
||||
|
||||
// RequestScan Request the device to scan. To know when the scan is finished, use the
|
||||
// "PropertiesChanged" signal from "org.freedesktop.DBus.Properties" to listen
|
||||
// to changes to the "LastScan" property.
|
||||
RequestScan() error
|
||||
|
||||
// GetPropertyHwAddress The active hardware address of the device.
|
||||
GetPropertyHwAddress() (string, error)
|
||||
|
||||
// GetPropertyPermHwAddress The permanent hardware address of the device.
|
||||
GetPropertyPermHwAddress() (string, error)
|
||||
|
||||
// GetPropertyMode The operating mode of the wireless device.
|
||||
GetPropertyMode() (Nm80211Mode, error)
|
||||
|
||||
// GetPropertyBitrate The bit rate currently used by the wireless device, in kilobits/second (Kb/s).
|
||||
GetPropertyBitrate() (uint32, error)
|
||||
|
||||
// GetPropertyAccessPoints List of object paths of access point visible to this wireless device.
|
||||
GetPropertyAccessPoints() ([]AccessPoint, error)
|
||||
|
||||
// GetPropertyActiveAccessPoint Object path of the access point currently used by the wireless device.
|
||||
GetPropertyActiveAccessPoint() (AccessPoint, error)
|
||||
|
||||
// GetPropertyWirelessCapabilities The capabilities of the wireless device.
|
||||
GetPropertyWirelessCapabilities() (uint32, error)
|
||||
|
||||
// GetPropertyLastScan The timestamp (in CLOCK_BOOTTIME milliseconds) for the last finished
|
||||
// network scan. A value of -1 means the device never scanned for access
|
||||
// points.
|
||||
GetPropertyLastScan() (int64, error)
|
||||
}
|
||||
|
||||
func NewDeviceWireless(objectPath dbus.ObjectPath) (DeviceWireless, error) {
|
||||
var d deviceWireless
|
||||
return &d, d.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type deviceWireless struct {
|
||||
device
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetAccessPoints() ([]AccessPoint, error) {
|
||||
var apPaths []dbus.ObjectPath
|
||||
err := d.callWithReturn(&apPaths, DeviceWirelessGetAccessPoints)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aps := make([]AccessPoint, len(apPaths))
|
||||
|
||||
for i, path := range apPaths {
|
||||
aps[i], err = NewAccessPoint(path)
|
||||
if err != nil {
|
||||
return aps, err
|
||||
}
|
||||
}
|
||||
|
||||
return aps, nil
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetAllAccessPoints() ([]AccessPoint, error) {
|
||||
var apPaths []dbus.ObjectPath
|
||||
err := d.callWithReturn(&apPaths, DeviceWirelessGetAllAccessPoints)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
aps := make([]AccessPoint, len(apPaths))
|
||||
|
||||
for i, path := range apPaths {
|
||||
aps[i], err = NewAccessPoint(path)
|
||||
if err != nil {
|
||||
return aps, err
|
||||
}
|
||||
}
|
||||
|
||||
return aps, nil
|
||||
}
|
||||
|
||||
func (d *deviceWireless) RequestScan() error {
|
||||
var options map[string]interface{}
|
||||
return d.obj.Call(DeviceWirelessRequestScan, 0, options).Store()
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceWirelessPropertyHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyPermHwAddress() (string, error) {
|
||||
return d.getStringProperty(DeviceWirelessPropertyPermHwAddress)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyMode() (Nm80211Mode, error) {
|
||||
v, err := d.getUint32Property(DeviceWirelessPropertyMode)
|
||||
return Nm80211Mode(v), err
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyBitrate() (uint32, error) {
|
||||
return d.getUint32Property(DeviceWirelessPropertyBitrate)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyAccessPoints() ([]AccessPoint, error) {
|
||||
apPaths, err := d.getSliceObjectProperty(DeviceWirelessPropertyAccessPoints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ap := make([]AccessPoint, len(apPaths))
|
||||
for i, path := range apPaths {
|
||||
ap[i], err = NewAccessPoint(path)
|
||||
if err != nil {
|
||||
return ap, err
|
||||
}
|
||||
}
|
||||
|
||||
return ap, nil
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyActiveAccessPoint() (AccessPoint, error) {
|
||||
path, err := d.getObjectProperty(DeviceWirelessPropertyActiveAccessPoint)
|
||||
if err != nil || path == "/" {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewAccessPoint(path)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyWirelessCapabilities() (uint32, error) {
|
||||
return d.getUint32Property(DeviceWirelessPropertyWirelessCapabilities)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) GetPropertyLastScan() (int64, error) {
|
||||
return d.getInt64Property(DeviceWirelessPropertyLastScan)
|
||||
}
|
||||
|
||||
func (d *deviceWireless) MarshalJSON() ([]byte, error) {
|
||||
m, err := d.device.marshalMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m["AccessPoints"], _ = d.GetPropertyAccessPoints()
|
||||
m["HwAddress"], _ = d.GetPropertyHwAddress()
|
||||
m["PermHwAddress"], _ = d.GetPropertyPermHwAddress()
|
||||
m["Mode"], _ = d.GetPropertyMode()
|
||||
m["Bitrate"], _ = d.GetPropertyBitrate()
|
||||
m["ActiveAccessPoint"], _ = d.GetPropertyActiveAccessPoint()
|
||||
m["WirelessCapabilities"], _ = d.GetPropertyWirelessCapabilities()
|
||||
m["LastScan"], _ = d.GetPropertyLastScan()
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
DnsManagerInterface = NetworkManagerInterface + ".DnsManager"
|
||||
DnsManagerObjectPath = "/org/freedesktop/NetworkManager/DnsManager"
|
||||
|
||||
/* Property */
|
||||
DnsManagerPropertyMode = DnsManagerInterface + ".Mode" // readable s
|
||||
DnsManagerPropertyRcManager = DnsManagerInterface + ".RcManager" // readable s
|
||||
DnsManagerPropertyConfiguration = DnsManagerInterface + ".Configuration" // readable aa{sv}
|
||||
)
|
||||
|
||||
type DnsConfigurationData struct {
|
||||
Nameservers []string
|
||||
Priority int32
|
||||
Interface string
|
||||
Vpn bool
|
||||
}
|
||||
|
||||
type DnsManager interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
GetPropertyMode() (string, error)
|
||||
GetPropertyRcManager() (string, error)
|
||||
GetPropertyConfiguration() ([]DnsConfigurationData, error)
|
||||
}
|
||||
|
||||
type dnsManager struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func NewDnsManager() (DnsManager, error) {
|
||||
var d dnsManager
|
||||
return &d, d.init(NetworkManagerInterface, DnsManagerObjectPath)
|
||||
}
|
||||
|
||||
func (d *dnsManager) GetPath() dbus.ObjectPath {
|
||||
return d.obj.Path()
|
||||
}
|
||||
|
||||
func (d *dnsManager) GetPropertyMode() (string, error) {
|
||||
return d.getStringProperty(DnsManagerPropertyMode)
|
||||
}
|
||||
|
||||
func (d *dnsManager) GetPropertyRcManager() (string, error) {
|
||||
return d.getStringProperty(DnsManagerPropertyRcManager)
|
||||
}
|
||||
|
||||
func (d *dnsManager) GetPropertyConfiguration() ([]DnsConfigurationData, error) {
|
||||
configurations, err := d.getSliceMapStringVariantProperty(DnsManagerPropertyConfiguration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make([]DnsConfigurationData, len(configurations))
|
||||
for i, conf := range configurations {
|
||||
if serversVar, exist := conf["nameservers"]; exist {
|
||||
servers, ok := serversVar.Value().([]string)
|
||||
if !ok {
|
||||
return nil, errors.New("unexpected variant type for nameservers")
|
||||
}
|
||||
ret[i].Nameservers = servers
|
||||
}
|
||||
|
||||
if priorityVar, exist := conf["priority"]; exist {
|
||||
priority, ok := priorityVar.Value().(int32)
|
||||
if !ok {
|
||||
return nil, errors.New("unexpected variant type for priority")
|
||||
}
|
||||
ret[i].Priority = priority
|
||||
}
|
||||
|
||||
if interfaceVar, exist := conf["interface"]; exist {
|
||||
iface, ok := interfaceVar.Value().(string)
|
||||
if !ok {
|
||||
return nil, errors.New("unexpected variant type for interface")
|
||||
}
|
||||
ret[i].Interface = iface
|
||||
}
|
||||
|
||||
if vpnVar, exist := conf["vpn"]; exist {
|
||||
vpn, ok := vpnVar.Value().(bool)
|
||||
if !ok {
|
||||
return nil, errors.New("unexpected variant type for vpn")
|
||||
}
|
||||
ret[i].Vpn = vpn
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
IP4ConfigInterface = NetworkManagerInterface + ".IP4Config"
|
||||
|
||||
/* Properties */
|
||||
IP4ConfigPropertyAddresses = IP4ConfigInterface + ".Addresses" // readable aau
|
||||
IP4ConfigPropertyAddressData = IP4ConfigInterface + ".AddressData" // readable aa{sv}
|
||||
IP4ConfigPropertyGateway = IP4ConfigInterface + ".Gateway" // readable s
|
||||
IP4ConfigPropertyRoutes = IP4ConfigInterface + ".Routes" // readable aau
|
||||
IP4ConfigPropertyRouteData = IP4ConfigInterface + ".RouteData" // readable aa{sv}
|
||||
IP4ConfigPropertyNameservers = IP4ConfigInterface + ".Nameservers" // readable au
|
||||
IP4ConfigPropertyNameserverData = IP4ConfigInterface + ".NameserverData" // readable aa{sv}
|
||||
IP4ConfigPropertyDomains = IP4ConfigInterface + ".Domains" // readable as
|
||||
IP4ConfigPropertySearches = IP4ConfigInterface + ".Searches" // readable as
|
||||
IP4ConfigPropertyDnsOptions = IP4ConfigInterface + ".DnsOptions" // readable as
|
||||
IP4ConfigPropertyDnsPriority = IP4ConfigInterface + ".DnsPriority" // readable i
|
||||
IP4ConfigPropertyWinsServers = IP4ConfigInterface + ".WinsServers" // readable au
|
||||
IP4ConfigPropertyWinsServerData = IP4ConfigInterface + ".WinsServerData" // readable as
|
||||
)
|
||||
|
||||
// Deprecated: use IP4AddressData instead
|
||||
type IP4Address struct {
|
||||
Address string
|
||||
Prefix uint8
|
||||
Gateway string
|
||||
}
|
||||
|
||||
type IP4AddressData struct {
|
||||
Address string
|
||||
Prefix uint8
|
||||
}
|
||||
|
||||
// Deprecated: use IP4RouteData instead
|
||||
type IP4Route struct {
|
||||
Route string
|
||||
Prefix uint8
|
||||
NextHop string
|
||||
Metric uint8
|
||||
}
|
||||
|
||||
type IP4RouteData struct {
|
||||
Destination string
|
||||
Prefix uint8
|
||||
NextHop string
|
||||
Metric uint8
|
||||
AdditionalAttributes map[string]string
|
||||
}
|
||||
|
||||
type IP4NameserverData struct {
|
||||
Address string
|
||||
}
|
||||
|
||||
type IP4Config interface {
|
||||
// GetPropertyAddresses Array of arrays of IPv4 address/prefix/gateway. All 3 elements of each array are in network byte order. Essentially: [(addr, prefix, gateway), (addr, prefix, gateway), ...]
|
||||
// Deprecated: use AddressData and Gateway
|
||||
GetPropertyAddresses() ([]IP4Address, error)
|
||||
|
||||
// GetPropertyAddressData Array of IP address data objects. All addresses will include "address" (an IP address string), and "prefix" (a uint). Some addresses may include additional attributes.
|
||||
GetPropertyAddressData() ([]IP4AddressData, error)
|
||||
|
||||
// GetPropertyGateway The gateway in use.
|
||||
GetPropertyGateway() (string, error)
|
||||
|
||||
// GetPropertyRoutes Arrays of IPv4 route/prefix/next-hop/metric. All 4 elements of each tuple are in network byte order. 'route' and 'next hop' are IPv4 addresses, while prefix and metric are simple unsigned integers. Essentially: [(route, prefix, next-hop, metric), (route, prefix, next-hop, metric), ...]
|
||||
// Deprecated: use RouteData
|
||||
GetPropertyRoutes() ([]IP4Route, error)
|
||||
|
||||
// GetPropertyRouteData Array of IP route data objects. All routes will include "dest" (an IP address string) and "prefix" (a uint). Some routes may include "next-hop" (an IP address string), "metric" (a uint), and additional attributes.
|
||||
GetPropertyRouteData() ([]IP4RouteData, error)
|
||||
|
||||
// GetPropertyNameservers The nameservers in use.
|
||||
// Deprecated: use NameserverData
|
||||
GetPropertyNameservers() ([]string, error)
|
||||
|
||||
// GetPropertyNameserverData The nameservers in use. Currently only the value "address" is recognized (with an IP address string).
|
||||
GetPropertyNameserverData() ([]IP4NameserverData, error)
|
||||
|
||||
// GetPropertyDomains A list of domains this address belongs to.
|
||||
GetPropertyDomains() ([]string, error)
|
||||
|
||||
// GetPropertySearches A list of dns searches.
|
||||
GetPropertySearches() ([]string, error)
|
||||
|
||||
// GetPropertyDnsOptions A list of DNS options that modify the behavior of the DNS resolver. See resolv.conf(5) manual page for the list of supported options.
|
||||
GetPropertyDnsOptions() ([]string, error)
|
||||
|
||||
// GetPropertyDnsPriority The relative priority of DNS servers.
|
||||
GetPropertyDnsPriority() (uint32, error)
|
||||
|
||||
// GetPropertyWinsServerData The Windows Internet Name Service servers associated with the connection.
|
||||
GetPropertyWinsServerData() ([]string, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewIP4Config(objectPath dbus.ObjectPath) (IP4Config, error) {
|
||||
var c ip4Config
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type ip4Config struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
// Deprecated: use GetPropertyAddressData
|
||||
func (c *ip4Config) GetPropertyAddresses() ([]IP4Address, error) {
|
||||
addresses, err := c.getSliceSliceUint32Property(IP4ConfigPropertyAddresses)
|
||||
ret := make([]IP4Address, len(addresses))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, parts := range addresses {
|
||||
ret[i] = IP4Address{
|
||||
Address: ip4ToString(parts[0]),
|
||||
Prefix: uint8(parts[1]),
|
||||
Gateway: ip4ToString(parts[2]),
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyAddressData() ([]IP4AddressData, error) {
|
||||
addresses, err := c.getSliceMapStringVariantProperty(IP4ConfigPropertyAddressData)
|
||||
ret := make([]IP4AddressData, len(addresses))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, address := range addresses {
|
||||
prefix, ok := address["prefix"].Value().(uint32)
|
||||
if !ok {
|
||||
return ret, errors.New("unexpected variant type for address prefix")
|
||||
}
|
||||
|
||||
address, ok := address["address"].Value().(string)
|
||||
if !ok {
|
||||
return ret, errors.New("unexpected variant type for address")
|
||||
}
|
||||
|
||||
ret[i] = IP4AddressData{
|
||||
Address: address,
|
||||
Prefix: uint8(prefix),
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyGateway() (string, error) {
|
||||
return c.getStringProperty(IP4ConfigPropertyGateway)
|
||||
}
|
||||
|
||||
// Deprecated: use GetPropertyRouteData
|
||||
func (c *ip4Config) GetPropertyRoutes() ([]IP4Route, error) {
|
||||
routes, err := c.getSliceSliceUint32Property(IP4ConfigPropertyRoutes)
|
||||
ret := make([]IP4Route, len(routes))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, parts := range routes {
|
||||
ret[i] = IP4Route{
|
||||
Route: ip4ToString(parts[0]),
|
||||
Prefix: uint8(parts[1]),
|
||||
NextHop: ip4ToString(parts[2]),
|
||||
Metric: uint8(parts[3]),
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyRouteData() ([]IP4RouteData, error) {
|
||||
routesData, err := c.getSliceMapStringVariantProperty(IP4ConfigPropertyRouteData)
|
||||
routes := make([]IP4RouteData, len(routesData))
|
||||
|
||||
if err != nil {
|
||||
return routes, err
|
||||
}
|
||||
|
||||
for index, routeData := range routesData {
|
||||
|
||||
route := IP4RouteData{}
|
||||
|
||||
for routeDataAttributeName, routeDataAttribute := range routeData {
|
||||
switch routeDataAttributeName {
|
||||
case "dest":
|
||||
destination, ok := routeDataAttribute.Value().(string)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for dest")
|
||||
}
|
||||
route.Destination = destination
|
||||
case "prefix":
|
||||
prefix, ok := routeDataAttribute.Value().(uint32)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for prefix")
|
||||
}
|
||||
route.Prefix = uint8(prefix)
|
||||
case "next-hop":
|
||||
nextHop, ok := routeDataAttribute.Value().(string)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for next-hop")
|
||||
}
|
||||
route.NextHop = nextHop
|
||||
case "metric":
|
||||
metric, ok := routeDataAttribute.Value().(uint32)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for metric")
|
||||
}
|
||||
route.Metric = uint8(metric)
|
||||
default:
|
||||
if route.AdditionalAttributes == nil {
|
||||
route.AdditionalAttributes = make(map[string]string)
|
||||
}
|
||||
route.AdditionalAttributes[routeDataAttributeName] = routeDataAttribute.String()
|
||||
}
|
||||
}
|
||||
|
||||
routes[index] = route
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// Deprecated: use GetPropertyNameserverData
|
||||
func (c *ip4Config) GetPropertyNameservers() ([]string, error) {
|
||||
nameservers, err := c.getSliceUint32Property(IP4ConfigPropertyNameservers)
|
||||
ret := make([]string, len(nameservers))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, ns := range nameservers {
|
||||
ret[i] = ip4ToString(ns)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyNameserverData() ([]IP4NameserverData, error) {
|
||||
nameserversData, err := c.getSliceMapStringVariantProperty(IP4ConfigPropertyNameserverData)
|
||||
nameservers := make([]IP4NameserverData, 0, len(nameserversData))
|
||||
|
||||
if err != nil {
|
||||
return nameservers, err
|
||||
}
|
||||
|
||||
for _, nameserverData := range nameserversData {
|
||||
address, ok := nameserverData["address"].Value().(string)
|
||||
|
||||
if !ok {
|
||||
return nameservers, errors.New("unexpected variant type for address")
|
||||
}
|
||||
|
||||
nameserver := IP4NameserverData{
|
||||
Address: address,
|
||||
}
|
||||
|
||||
nameservers = append(nameservers, nameserver)
|
||||
}
|
||||
return nameservers, nil
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyDomains() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP4ConfigPropertyDomains)
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertySearches() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP4ConfigPropertySearches)
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyDnsOptions() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP4ConfigPropertyDnsOptions)
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyDnsPriority() (uint32, error) {
|
||||
return c.getUint32Property(IP4ConfigPropertyDnsPriority)
|
||||
}
|
||||
|
||||
func (c *ip4Config) GetPropertyWinsServerData() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP4ConfigPropertyWinsServerData)
|
||||
}
|
||||
|
||||
func (c *ip4Config) MarshalJSON() ([]byte, error) {
|
||||
Addresses, err := c.GetPropertyAddressData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Routes, err := c.GetPropertyRouteData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Nameservers, err := c.GetPropertyNameserverData()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
Domains, err := c.GetPropertyDomains()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"Addresses": Addresses,
|
||||
"Routes": Routes,
|
||||
"Nameservers": Nameservers,
|
||||
"Domains": Domains,
|
||||
})
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
IP6ConfigInterface = NetworkManagerInterface + ".IP6Config"
|
||||
|
||||
/* Properties */
|
||||
IP6ConfigPropertyAddresses = IP6ConfigInterface + ".Addresses" // readable a(ayuay)
|
||||
IP6ConfigPropertyAddressData = IP6ConfigInterface + ".AddressData" // readable aa{sv}
|
||||
IP6ConfigPropertyGateway = IP6ConfigInterface + ".Gateway" // readable s
|
||||
IP6ConfigPropertyRoutes = IP6ConfigInterface + ".Routes" // readable a(ayuayu)
|
||||
IP6ConfigPropertyRouteData = IP6ConfigInterface + ".RouteData" // readable aa{sv}
|
||||
IP6ConfigPropertyNameservers = IP6ConfigInterface + ".Nameservers" // readable aay
|
||||
IP6ConfigPropertyDomains = IP6ConfigInterface + ".Domains" // readable as
|
||||
IP6ConfigPropertySearches = IP6ConfigInterface + ".Searches" // readable as
|
||||
IP6ConfigPropertyDnsOptions = IP6ConfigInterface + ".DnsOptions" // readable as
|
||||
IP6ConfigPropertyDnsPriority = IP6ConfigInterface + ".DnsPriority" // readable i
|
||||
)
|
||||
|
||||
// Deprecated: use IP6AddressData instead
|
||||
type IP6Address struct {
|
||||
Address string
|
||||
Prefix uint8
|
||||
Gateway string
|
||||
}
|
||||
|
||||
type IP6AddressData struct {
|
||||
Address string
|
||||
Prefix uint8
|
||||
}
|
||||
|
||||
// Deprecated: use IP6RouteData instead
|
||||
type IP6Route struct {
|
||||
Route string
|
||||
Prefix uint8
|
||||
NextHop string
|
||||
Metric uint8
|
||||
}
|
||||
|
||||
type IP6RouteData struct {
|
||||
Destination string
|
||||
Prefix uint8
|
||||
NextHop string
|
||||
Metric uint8
|
||||
AdditionalAttributes map[string]string
|
||||
}
|
||||
|
||||
type IP6Config interface {
|
||||
|
||||
// GetPropertyAddressData Array of IP address data objects. All addresses will include "address" (an IP address string), and "prefix" (a uint). Some addresses may include additional attributes.
|
||||
GetPropertyAddressData() ([]IP6AddressData, error)
|
||||
|
||||
// GetPropertyGateway The gateway in use.
|
||||
GetPropertyGateway() (string, error)
|
||||
|
||||
// GetPropertyRouteData Array of IP route data objects. All routes will include "dest" (an IP address string) and "prefix" (a uint). Some routes may include "next-hop" (an IP address string), "metric" (a uint), and additional attributes.
|
||||
GetPropertyRouteData() ([]IP6RouteData, error)
|
||||
|
||||
// GetPropertyNameservers GetNameservers gets the nameservers in use.
|
||||
GetPropertyNameservers() ([][]byte, error)
|
||||
|
||||
// GetPropertyDomains A list of domains this address belongs to.
|
||||
GetPropertyDomains() ([]string, error)
|
||||
|
||||
// GetPropertySearches A list of dns searches.
|
||||
GetPropertySearches() ([]string, error)
|
||||
|
||||
// GetPropertyDnsOptions A list of DNS options that modify the behavior of the DNS resolver. See resolv.conf(5) manual page for the list of supported options.
|
||||
GetPropertyDnsOptions() ([]string, error)
|
||||
|
||||
// GetPropertyDnsPriority The relative priority of DNS servers.
|
||||
GetPropertyDnsPriority() (uint32, error)
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewIP6Config(objectPath dbus.ObjectPath) (IP6Config, error) {
|
||||
var c ip6Config
|
||||
return &c, c.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type ip6Config struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyAddressData() ([]IP6AddressData, error) {
|
||||
addresses, err := c.getSliceMapStringVariantProperty(IP6ConfigPropertyAddressData)
|
||||
ret := make([]IP6AddressData, len(addresses))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, address := range addresses {
|
||||
prefix, ok := address["prefix"].Value().(uint32)
|
||||
if !ok {
|
||||
return ret, errors.New("unexpected variant type for prefix")
|
||||
}
|
||||
|
||||
address, ok := address["address"].Value().(string)
|
||||
if !ok {
|
||||
return ret, errors.New("unexpected variant type for address")
|
||||
}
|
||||
|
||||
ret[i] = IP6AddressData{
|
||||
Address: address,
|
||||
Prefix: uint8(prefix),
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyGateway() (string, error) {
|
||||
return c.getStringProperty(IP6ConfigPropertyGateway)
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyRouteData() ([]IP6RouteData, error) {
|
||||
routesData, err := c.getSliceMapStringVariantProperty(IP6ConfigPropertyRouteData)
|
||||
routes := make([]IP6RouteData, len(routesData))
|
||||
|
||||
if err != nil {
|
||||
return routes, err
|
||||
}
|
||||
|
||||
for index, routeData := range routesData {
|
||||
|
||||
route := IP6RouteData{}
|
||||
|
||||
for routeDataAttributeName, routeDataAttribute := range routeData {
|
||||
switch routeDataAttributeName {
|
||||
case "dest":
|
||||
destination, ok := routeDataAttribute.Value().(string)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for dest")
|
||||
}
|
||||
route.Destination = destination
|
||||
case "prefix":
|
||||
prefix, ok := routeDataAttribute.Value().(uint32)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for prefix")
|
||||
}
|
||||
route.Prefix = uint8(prefix)
|
||||
case "next-hop":
|
||||
nextHop, ok := routeDataAttribute.Value().(string)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for next-hop")
|
||||
}
|
||||
route.NextHop = nextHop
|
||||
case "metric":
|
||||
metric, ok := routeDataAttribute.Value().(uint32)
|
||||
if !ok {
|
||||
return routes, errors.New("unexpected variant type for metric")
|
||||
}
|
||||
route.Metric = uint8(metric)
|
||||
default:
|
||||
if route.AdditionalAttributes == nil {
|
||||
route.AdditionalAttributes = make(map[string]string)
|
||||
}
|
||||
route.AdditionalAttributes[routeDataAttributeName] = routeDataAttribute.String()
|
||||
}
|
||||
}
|
||||
|
||||
routes[index] = route
|
||||
}
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyNameservers() ([][]byte, error) {
|
||||
nameservers, err := c.getSliceSliceByteProperty(IP6ConfigPropertyNameservers)
|
||||
ret := make([][]byte, len(nameservers))
|
||||
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
for i, nameserver := range nameservers {
|
||||
ret[i] = nameserver
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyDomains() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP6ConfigPropertyDomains)
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertySearches() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP6ConfigPropertySearches)
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyDnsOptions() ([]string, error) {
|
||||
return c.getSliceStringProperty(IP6ConfigPropertyDnsOptions)
|
||||
}
|
||||
|
||||
func (c *ip6Config) GetPropertyDnsPriority() (uint32, error) {
|
||||
return c.getUint32Property(IP6ConfigPropertyDnsPriority)
|
||||
}
|
||||
|
||||
func (c *ip6Config) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
m["Addresses"], _ = c.GetPropertyAddressData()
|
||||
m["Routes"], _ = c.GetPropertyRouteData()
|
||||
m["Nameservers"], _ = c.GetPropertyNameservers()
|
||||
m["Domains"], _ = c.GetPropertyDomains()
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Wifx Sàrl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Bellerophon Mobile
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+751
@@ -0,0 +1,751 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
NetworkManagerInterface = "org.freedesktop.NetworkManager"
|
||||
NetworkManagerObjectPath = "/org/freedesktop/NetworkManager"
|
||||
|
||||
/* Methods */
|
||||
NetworkManagerReload = NetworkManagerInterface + ".Reload"
|
||||
NetworkManagerGetDevices = NetworkManagerInterface + ".GetDevices"
|
||||
NetworkManagerGetAllDevices = NetworkManagerInterface + ".GetAllDevices"
|
||||
NetworkManagerGetDeviceByIpIface = NetworkManagerInterface + ".GetDeviceByIpIface"
|
||||
NetworkManagerActivateConnection = NetworkManagerInterface + ".ActivateConnection"
|
||||
NetworkManagerAddAndActivateConnection = NetworkManagerInterface + ".AddAndActivateConnection"
|
||||
NetworkManagerAddAndActivateConnection2 = NetworkManagerInterface + ".AddAndActivateConnection2"
|
||||
NetworkManagerDeactivateConnection = NetworkManagerInterface + ".DeactivateConnection"
|
||||
NetworkManagerSleep = NetworkManagerInterface + ".Sleep"
|
||||
NetworkManagerEnable = NetworkManagerInterface + ".Enable"
|
||||
NetworkManagerGetPermissions = NetworkManagerInterface + ".GetPermissions"
|
||||
NetworkManagerSetLogging = NetworkManagerInterface + ".SetLogging"
|
||||
NetworkManagerGetLogging = NetworkManagerInterface + ".GetLogging"
|
||||
NetworkManagerCheckConnectivity = NetworkManagerInterface + ".CheckConnectivity"
|
||||
NetworkManagerState = NetworkManagerInterface + ".state"
|
||||
NetworkManagerCheckpointCreate = NetworkManagerInterface + ".CheckpointCreate"
|
||||
NetworkManagerCheckpointDestroy = NetworkManagerInterface + ".CheckpointDestroy"
|
||||
NetworkManagerCheckpointRollback = NetworkManagerInterface + ".CheckpointRollback"
|
||||
NetworkManagerCheckpointAdjustRollbackTimeout = NetworkManagerInterface + ".CheckpointAdjustRollbackTimeout"
|
||||
|
||||
/* Property */
|
||||
NetworkManagerPropertyDevices = NetworkManagerInterface + ".Devices" // readable ao
|
||||
NetworkManagerPropertyAllDevices = NetworkManagerInterface + ".AllDevices" // readable ao
|
||||
NetworkManagerPropertyCheckpoints = NetworkManagerInterface + ".Checkpoints" // readable ao
|
||||
NetworkManagerPropertyNetworkingEnabled = NetworkManagerInterface + ".NetworkingEnabled" // readable b
|
||||
NetworkManagerPropertyWirelessEnabled = NetworkManagerInterface + ".WirelessEnabled" // readwrite b
|
||||
NetworkManagerPropertyWirelessHardwareEnabled = NetworkManagerInterface + ".WirelessHardwareEnabled" // readable b
|
||||
NetworkManagerPropertyWwanEnabled = NetworkManagerInterface + ".WwanEnabled" // readwrite b
|
||||
NetworkManagerPropertyWwanHardwareEnabled = NetworkManagerInterface + ".WwanHardwareEnabled" // readable b
|
||||
NetworkManagerPropertyWimaxEnabled = NetworkManagerInterface + ".WimaxEnabled" // readwrite b
|
||||
NetworkManagerPropertyWimaxHardwareEnabled = NetworkManagerInterface + ".WimaxHardwareEnabled" // readable b
|
||||
NetworkManagerPropertyActiveConnections = NetworkManagerInterface + ".ActiveConnections" // readable ao
|
||||
NetworkManagerPropertyPrimaryConnection = NetworkManagerInterface + ".PrimaryConnection" // readable o
|
||||
NetworkManagerPropertyPrimaryConnectionType = NetworkManagerInterface + ".PrimaryConnectionType" // readable s
|
||||
NetworkManagerPropertyMetered = NetworkManagerInterface + ".Metered" // readable u
|
||||
NetworkManagerPropertyActivatingConnection = NetworkManagerInterface + ".ActivatingConnection" // readable o
|
||||
NetworkManagerPropertyStartup = NetworkManagerInterface + ".Startup" // readable b
|
||||
NetworkManagerPropertyVersion = NetworkManagerInterface + ".Version" // readable s
|
||||
NetworkManagerPropertyCapabilities = NetworkManagerInterface + ".Capabilities" // readable au
|
||||
NetworkManagerPropertyState = NetworkManagerInterface + ".State" // readable u
|
||||
NetworkManagerPropertyConnectivity = NetworkManagerInterface + ".Connectivity" // readable u
|
||||
NetworkManagerPropertyConnectivityCheckAvailable = NetworkManagerInterface + ".ConnectivityCheckAvailable" // readable b
|
||||
NetworkManagerPropertyConnectivityCheckEnabled = NetworkManagerInterface + ".ConnectivityCheckEnabled" // readwrite b
|
||||
NetworkManagerPropertyGlobalDnsConfiguration = NetworkManagerInterface + ".GlobalDnsConfiguration" // readwrite a{sv}
|
||||
)
|
||||
|
||||
type NetworkManager interface {
|
||||
/* METHODS */
|
||||
|
||||
// Reload NetworkManager's configuration and perform certain updates, like flushing a cache or rewriting external state to disk. This is similar to sending SIGHUP to NetworkManager but it allows for more fine-grained control over what to reload (see flags). It also allows non-root access via PolicyKit and contrary to signals it is synchronous.
|
||||
// No flags (0x00) means to reload everything that is supported which is identical to sending a SIGHUP.
|
||||
// (0x01) means to reload the NetworkManager.conf configuration from disk. Note that this does not include connections, which can be reloaded via Setting's ReloadConnections.
|
||||
// (0x02) means to update DNS configuration, which usually involves writing /etc/resolv.conf anew.
|
||||
// (0x04) means to restart the DNS plugin. This is for example useful when using dnsmasq plugin, which uses additional configuration in /etc/NetworkManager/dnsmasq.d. If you edit those files, you can restart the DNS plugin. This action shortly interrupts name resolution. Note that flags may affect each other. For example, restarting the DNS plugin (0x04) implicitly updates DNS too (0x02). Or when reloading the configuration (0x01), changes to DNS setting also cause a DNS update (0x02). However, (0x01) does not involve restarting the DNS plugin (0x04) or update resolv.conf (0x02), unless the DNS related configuration changes in NetworkManager.conf.
|
||||
Reload(flags uint32) error
|
||||
|
||||
// GetDevices Get the list of realized network devices.
|
||||
GetDevices() ([]Device, error)
|
||||
|
||||
// GetAllDevices Get the list of all network devices.
|
||||
GetAllDevices() ([]Device, error)
|
||||
|
||||
// GetDeviceByIpIface Return the object path of the network device referenced by its IP interface name. Note that some devices (usually modems) only have an IP interface name when they are connected.
|
||||
GetDeviceByIpIface(interfaceId string) (Device, error)
|
||||
|
||||
// ActivateConnection Activate a connection using the supplied device.
|
||||
ActivateConnection(connection Connection, device Device, specificObject *dbus.Object) (ActiveConnection, error)
|
||||
|
||||
// AddAndActivateConnection Adds a new connection using the given details (if any) as a template (automatically filling in missing settings with the capabilities of the given device), then activate the new connection. Cannot be used for VPN connections at this time.
|
||||
AddAndActivateConnection(connection map[string]map[string]interface{}, device Device) (ActiveConnection, error)
|
||||
|
||||
// ActivateWirelessConnection requests activating access point to network device
|
||||
ActivateWirelessConnection(connection Connection, device Device, accessPoint AccessPoint) (ActiveConnection, error)
|
||||
|
||||
// AddAndActivateWirelessConnection adds a new connection profile to the network device it has been
|
||||
// passed. It then activates the connection to the passed access point. The first parameter contains
|
||||
// additional information for the connection (most probably the credentials).
|
||||
// Example contents for connection are:
|
||||
// connection := make(map[string]map[string]interface{})
|
||||
// connection["802-11-wireless"] = make(map[string]interface{})
|
||||
// connection["802-11-wireless"]["security"] = "802-11-wireless-security"
|
||||
// connection["802-11-wireless-security"] = make(map[string]interface{})
|
||||
// connection["802-11-wireless-security"]["key-mgmt"] = "wpa-psk"
|
||||
// connection["802-11-wireless-security"]["psk"] = password
|
||||
AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, device Device, accessPoint AccessPoint) (ActiveConnection, error)
|
||||
|
||||
// DeactivateConnection Deactivate an active connection.
|
||||
DeactivateConnection(connection ActiveConnection) error
|
||||
|
||||
// Sleep Control the NetworkManager daemon's sleep state. When asleep, all interfaces that it manages are deactivated. When awake, devices are available to be activated. This command should not be called directly by users or clients; it is intended for system suspend/resume tracking.
|
||||
// sleepnWake: Indicates whether the NetworkManager daemon should sleep or wake.
|
||||
Sleep(sleepNWake bool) error
|
||||
|
||||
// Enable Control whether overall networking is enabled or disabled. When disabled, all interfaces that NM manages are deactivated. When enabled, all managed interfaces are re-enabled and available to be activated. This command should be used by clients that provide to users the ability to enable/disable all networking.
|
||||
// enableNDisable: If FALSE, indicates that all networking should be disabled. If TRUE, indicates that NetworkManager should begin managing network devices.
|
||||
Enable(enableNDisable bool) error
|
||||
|
||||
// CheckConnectivity Re-check the network connectivity state.
|
||||
CheckConnectivity() error
|
||||
|
||||
// State The overall networking state as determined by the NetworkManager daemon, based on the state of network devices under its management.
|
||||
State() (NmState, error)
|
||||
|
||||
// CheckpointCreate Create a checkpoint of the current networking configuration for given interfaces. If rollback_timeout is not zero, a rollback is automatically performed after the given timeout.
|
||||
// devices: A list of device paths for which a checkpoint should be created. An empty list means all devices.
|
||||
// rollbackTimeout: The time in seconds until NetworkManager will automatically rollback to the checkpoint. Set to zero for infinite.
|
||||
// flags: Flags for the creation.
|
||||
// returns: On success, the new checkpoint.
|
||||
CheckpointCreate(devices []Device, rollbackTimeout uint32, flags uint32) (Checkpoint, error)
|
||||
|
||||
// CheckpointDestroy Destroy a previously created checkpoint.
|
||||
// checkpoint: The checkpoint to be destroyed. Set to empty to cancel all pending checkpoints.
|
||||
CheckpointDestroy(checkpoint Checkpoint) error
|
||||
|
||||
// CheckpointRollback Rollback a checkpoint before the timeout is reached.
|
||||
// checkpoint: The checkpoint to be rolled back.
|
||||
// result: On return, a dictionary of devices and results. Devices are represented by their original D-Bus path; each result is a RollbackResult.
|
||||
CheckpointRollback(checkpoint Checkpoint) (result map[dbus.ObjectPath]NmRollbackResult, err error)
|
||||
|
||||
// CheckpointAdjustRollbackTimeout Reset the timeout for rollback for the checkpoint.
|
||||
// Since: 1.12
|
||||
// addTimeout: number of seconds from ~now~ in which the timeout will expire. Set to 0 to disable the timeout. Note that the added seconds start counting from now, not "Created" timestamp or the previous expiration time. Note that the "Created" property of the checkpoint will stay unchanged by this call. However, the "RollbackTimeout" will be recalculated to give the approximate new expiration time. The new "RollbackTimeout" property will be approximate up to one second precision, which is the accuracy of the property.
|
||||
CheckpointAdjustRollbackTimeout(checkpoint Checkpoint, addTimeout uint32) error
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
// GetPropertyDevices The list of realized network devices. Realized devices are those which have backing resources (eg from the kernel or a management daemon like ModemManager, teamd, etc).
|
||||
GetPropertyDevices() ([]Device, error)
|
||||
|
||||
// GetPropertyAllDevices The list of both realized and un-realized network devices. Un-realized devices are software devices which do not yet have backing resources, but for which backing resources can be created if the device is activated.
|
||||
GetPropertyAllDevices() ([]Device, error)
|
||||
|
||||
// GetPropertyCheckpoints The list of active checkpoints.
|
||||
GetPropertyCheckpoints() ([]Checkpoint, error)
|
||||
|
||||
// GetPropertyNetworkingEnabled Indicates if overall networking is currently enabled or not. See the Enable() method.
|
||||
GetPropertyNetworkingEnabled() (bool, error)
|
||||
|
||||
// GetPropertyWirelessEnabled Indicates if wireless is currently enabled or not.
|
||||
GetPropertyWirelessEnabled() (bool, error)
|
||||
SetPropertyWirelessEnabled(bool) error
|
||||
|
||||
// GetPropertyWirelessHardwareEnabled Indicates if the wireless hardware is currently enabled, i.e. the state of the RF kill switch.
|
||||
GetPropertyWirelessHardwareEnabled() (bool, error)
|
||||
|
||||
// GetPropertyWwanEnabled Indicates if mobile broadband devices are currently enabled or not.
|
||||
GetPropertyWwanEnabled() (bool, error)
|
||||
|
||||
// GetPropertyWwanHardwareEnabled Indicates if the mobile broadband hardware is currently enabled, i.e. the state of the RF kill switch.
|
||||
GetPropertyWwanHardwareEnabled() (bool, error)
|
||||
|
||||
// GetPropertyWimaxEnabled Indicates if WiMAX devices are currently enabled or not.
|
||||
GetPropertyWimaxEnabled() (bool, error)
|
||||
|
||||
// GetPropertyWimaxHardwareEnabled Indicates if the WiMAX hardware is currently enabled, i.e. the state of the RF kill switch.
|
||||
GetPropertyWimaxHardwareEnabled() (bool, error)
|
||||
|
||||
// GetPropertyActiveConnections List of active connection object paths.
|
||||
GetPropertyActiveConnections() ([]ActiveConnection, error)
|
||||
|
||||
// GetPropertyPrimaryConnection The object path of the "primary" active connection being used to access the network. In particular, if there is no VPN active, or the VPN does not have the default route, then this indicates the connection that has the default route. If there is a VPN active with the default route, then this indicates the connection that contains the route to the VPN endpoint.
|
||||
GetPropertyPrimaryConnection() (ActiveConnection, error)
|
||||
|
||||
// GetPropertyPrimaryConnectionType The connection type of the "primary" active connection being used to access the network. This is the same as the Type property on the object indicated by PrimaryConnection.
|
||||
GetPropertyPrimaryConnectionType() (string, error)
|
||||
|
||||
// GetPropertyMetered Indicates whether the connectivity is metered. This is equivalent to the metered property of the device associated with the primary connection.
|
||||
GetPropertyMetered() (NmMetered, error)
|
||||
|
||||
// GetPropertyActivatingConnection The object path of an active connection that is currently being activated and which is expected to become the new PrimaryConnection when it finishes activating.
|
||||
GetPropertyActivatingConnection() (ActiveConnection, error)
|
||||
|
||||
// GetPropertyStartup Indicates whether NM is still starting up; this becomes FALSE when NM has finished attempting to activate every connection that it might be able to activate at startup.
|
||||
GetPropertyStartup() (bool, error)
|
||||
|
||||
// GetPropertyVersion NetworkManager version.
|
||||
GetPropertyVersion() (string, error)
|
||||
|
||||
// GetPropertyCapabilities The current set of capabilities. See NMCapability for currently defined capability numbers. The array is guaranteed to be sorted in ascending order without duplicates.
|
||||
GetPropertyCapabilities() ([]NmCapability, error)
|
||||
|
||||
// GetPropertyState The overall state of the NetworkManager daemon.
|
||||
// This takes state of all active connections and the connectivity state into account to produce a single indicator of the network accessibility status.
|
||||
// The graphical shells may use this property to provide network connection status indication and applications may use this to check if Internet connection is accessible. Shell that is able to cope with captive portals should use the "Connectivity" property to decide whether to present a captive portal authentication dialog.
|
||||
GetPropertyState() (NmState, error)
|
||||
|
||||
// GetPropertyConnectivity The result of the last connectivity check. The connectivity check is triggered automatically when a default connection becomes available, periodically and by calling a CheckConnectivity() method.
|
||||
// This property is in general useful for the graphical shell to determine whether the Internet access is being hijacked by an authentication gateway (a "captive portal"). In such case it would typically present a web browser window to give the user a chance to authenticate and call CheckConnectivity() when the user submits a form or dismisses the window.
|
||||
// To determine the whether the user is able to access the Internet without dealing with captive portals (e.g. to provide a network connection indicator or disable controls that require Internet access), the "State" property is more suitable.
|
||||
GetPropertyConnectivity() (NmConnectivity, error)
|
||||
|
||||
// GetPropertyConnectivityCheckAvailable Indicates whether connectivity checking service has been configured. This may return true even if the service is not currently enabled.
|
||||
// This is primarily intended for use in a privacy control panel, as a way to determine whether to show an option to enable/disable the feature.
|
||||
GetPropertyConnectivityCheckAvailable() (bool, error)
|
||||
|
||||
// GetPropertyConnectivityCheckEnabled Indicates whether connectivity checking is enabled. This property can also be written to to disable connectivity checking (as a privacy control panel might want to do).
|
||||
GetPropertyConnectivityCheckEnabled() (bool, error)
|
||||
|
||||
// Dictionary of global DNS settings where the key is one of "searches", "options" and "domains". The values for the "searches" and "options" keys are string arrays describing the list of search domains and resolver options, respectively. The value of the "domains" key is a second-level dictionary, where each key is a domain name, and each key's value is a third-level dictionary with the keys "servers" and "options". "servers" is a string array of DNS servers, "options" is a string array of domain-specific options.
|
||||
//GetPropertyGlobalDnsConfiguration() []interface{}
|
||||
|
||||
Subscribe() <-chan *dbus.Signal
|
||||
Unsubscribe()
|
||||
|
||||
MarshalJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func NewNetworkManager() (NetworkManager, error) {
|
||||
var nm networkManager
|
||||
return &nm, nm.init(NetworkManagerInterface, NetworkManagerObjectPath)
|
||||
}
|
||||
|
||||
type networkManager struct {
|
||||
dbusBase
|
||||
|
||||
sigChan chan *dbus.Signal
|
||||
}
|
||||
|
||||
func (nm *networkManager) Reload(flags uint32) error {
|
||||
return nm.call(NetworkManagerReload, flags)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetDevices() (devices []Device, err error) {
|
||||
var devicePaths []dbus.ObjectPath
|
||||
err = nm.callWithReturn(&devicePaths, NetworkManagerGetDevices)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
devices = make([]Device, len(devicePaths))
|
||||
|
||||
for i, path := range devicePaths {
|
||||
devices[i], err = DeviceFactory(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetAllDevices() (devices []Device, err error) {
|
||||
var devicePaths []dbus.ObjectPath
|
||||
|
||||
err = nm.callWithReturn(&devicePaths, NetworkManagerGetAllDevices)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
devices = make([]Device, len(devicePaths))
|
||||
|
||||
for i, path := range devicePaths {
|
||||
devices[i], err = DeviceFactory(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetDeviceByIpIface(interfaceId string) (device Device, err error) {
|
||||
var devicePath dbus.ObjectPath
|
||||
|
||||
err = nm.callWithReturn(&devicePath, NetworkManagerGetDeviceByIpIface, interfaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
device, err = DeviceFactory(devicePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) ActivateConnection(connection Connection, device Device, specificObject *dbus.Object) (ac ActiveConnection, err error) {
|
||||
var connectionPath dbus.ObjectPath
|
||||
|
||||
var devicePath dbus.ObjectPath
|
||||
if device != nil {
|
||||
devicePath = device.GetPath()
|
||||
} else {
|
||||
devicePath = "/"
|
||||
}
|
||||
|
||||
var specificObjectPath dbus.ObjectPath
|
||||
if specificObject != nil {
|
||||
specificObjectPath = specificObject.Path()
|
||||
} else {
|
||||
specificObjectPath = "/"
|
||||
}
|
||||
|
||||
err = nm.callWithReturn(&connectionPath, NetworkManagerActivateConnection, connection.GetPath(), devicePath, specificObjectPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ac, err = NewActiveConnection(connectionPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) AddAndActivateConnection(connection map[string]map[string]interface{}, d Device) (ac ActiveConnection, err error) {
|
||||
var opath1 dbus.ObjectPath
|
||||
var opath2 dbus.ObjectPath
|
||||
|
||||
var devicePath dbus.ObjectPath
|
||||
if d != nil {
|
||||
devicePath = d.GetPath()
|
||||
}
|
||||
|
||||
err = nm.callWithReturn2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, devicePath, dbus.ObjectPath("/"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ac, err = NewActiveConnection(opath2)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) ActivateWirelessConnection(c Connection, d Device, ap AccessPoint) (ac ActiveConnection, err error) {
|
||||
var opath dbus.ObjectPath
|
||||
err = nm.callWithReturn(&opath, NetworkManagerActivateConnection, c.GetPath(), d.GetPath(), ap.GetPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ac, err = NewActiveConnection(opath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) AddAndActivateWirelessConnection(connection map[string]map[string]interface{}, d Device, ap AccessPoint) (ac ActiveConnection, err error) {
|
||||
var opath1 dbus.ObjectPath
|
||||
var opath2 dbus.ObjectPath
|
||||
|
||||
err = nm.callWithReturn2(&opath1, &opath2, NetworkManagerAddAndActivateConnection, connection, d.GetPath(), ap.GetPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ac, err = NewActiveConnection(opath2)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) DeactivateConnection(c ActiveConnection) error {
|
||||
return nm.call(NetworkManagerDeactivateConnection, c.GetPath())
|
||||
}
|
||||
|
||||
func (nm *networkManager) Sleep(sleepNWake bool) error {
|
||||
return nm.call(NetworkManagerSleep, sleepNWake)
|
||||
}
|
||||
|
||||
func (nm *networkManager) Enable(enableNDisable bool) error {
|
||||
return nm.call(NetworkManagerEnable, enableNDisable)
|
||||
}
|
||||
|
||||
func (nm *networkManager) CheckConnectivity() error {
|
||||
return nm.call(NetworkManagerCheckConnectivity)
|
||||
}
|
||||
|
||||
func (nm *networkManager) State() (state NmState, err error) {
|
||||
err = nm.callWithReturn(&state, NetworkManagerState)
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) CheckpointCreate(devices []Device, rollbackTimeout uint32, flags uint32) (cp Checkpoint, err error) {
|
||||
|
||||
var devicePaths []dbus.ObjectPath
|
||||
if len(devices) > 0 {
|
||||
for _, device := range devices {
|
||||
devicePaths = append(devicePaths, device.GetPath())
|
||||
}
|
||||
}
|
||||
|
||||
var checkpointPath dbus.ObjectPath
|
||||
err = nm.callWithReturn(&checkpointPath, NetworkManagerCheckpointCreate, devicePaths, rollbackTimeout, flags)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cp, err = NewCheckpoint(checkpointPath)
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) CheckpointDestroy(checkpoint Checkpoint) error {
|
||||
if checkpoint == nil {
|
||||
return nm.call(NetworkManagerCheckpointDestroy)
|
||||
} else {
|
||||
return nm.call(NetworkManagerCheckpointDestroy, checkpoint.GetPath())
|
||||
}
|
||||
}
|
||||
|
||||
func (nm *networkManager) CheckpointRollback(checkpoint Checkpoint) (results map[dbus.ObjectPath]NmRollbackResult, err error) {
|
||||
|
||||
var ret map[dbus.ObjectPath]NmRollbackResult
|
||||
|
||||
err = nm.callWithReturn(&ret, NetworkManagerCheckpointRollback, checkpoint.GetPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
results = map[dbus.ObjectPath]NmRollbackResult{}
|
||||
for devicePath, result := range ret {
|
||||
results[devicePath] = result
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (nm *networkManager) CheckpointAdjustRollbackTimeout(checkpoint Checkpoint, addTimeout uint32) error {
|
||||
return nm.call(NetworkManagerCheckpointAdjustRollbackTimeout, checkpoint, addTimeout)
|
||||
}
|
||||
|
||||
/* PROPERTIES */
|
||||
|
||||
func (nm *networkManager) GetPropertyDevices() ([]Device, error) {
|
||||
devicesPaths, err := nm.getSliceObjectProperty(NetworkManagerPropertyDevices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
devices := make([]Device, len(devicesPaths))
|
||||
for i, path := range devicesPaths {
|
||||
devices[i], err = NewDevice(path)
|
||||
if err != nil {
|
||||
return devices, err
|
||||
}
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyAllDevices() ([]Device, error) {
|
||||
devicesPaths, err := nm.getSliceObjectProperty(NetworkManagerPropertyAllDevices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
devices := make([]Device, len(devicesPaths))
|
||||
for i, path := range devicesPaths {
|
||||
devices[i], err = NewDevice(path)
|
||||
if err != nil {
|
||||
return devices, err
|
||||
}
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyCheckpoints() ([]Checkpoint, error) {
|
||||
checkpointsPaths, err := nm.getSliceObjectProperty(NetworkManagerPropertyCheckpoints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checkpoints := make([]Checkpoint, len(checkpointsPaths))
|
||||
for i, path := range checkpointsPaths {
|
||||
checkpoints[i], err = NewCheckpoint(path)
|
||||
if err != nil {
|
||||
return checkpoints, err
|
||||
}
|
||||
}
|
||||
|
||||
return checkpoints, nil
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyNetworkingEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyNetworkingEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWirelessEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWirelessEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) SetPropertyWirelessEnabled(enabled bool) error {
|
||||
return nm.setProperty(NetworkManagerPropertyWirelessEnabled, enabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWirelessHardwareEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWirelessHardwareEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWwanEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWwanEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWwanHardwareEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWwanHardwareEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWimaxEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWimaxEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyWimaxHardwareEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyWimaxHardwareEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyActiveConnections() ([]ActiveConnection, error) {
|
||||
acPaths, err := nm.getSliceObjectProperty(NetworkManagerPropertyActiveConnections)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ac := make([]ActiveConnection, len(acPaths))
|
||||
for i, path := range acPaths {
|
||||
ac[i], err = NewActiveConnection(path)
|
||||
if err != nil {
|
||||
return ac, err
|
||||
}
|
||||
}
|
||||
|
||||
return ac, nil
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyPrimaryConnection() (ActiveConnection, error) {
|
||||
activeConnectionPath, err := nm.getObjectProperty(NetworkManagerPropertyPrimaryConnection)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewActiveConnection(activeConnectionPath)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyPrimaryConnectionType() (string, error) {
|
||||
return nm.getStringProperty(NetworkManagerPropertyPrimaryConnectionType)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyMetered() (NmMetered, error) {
|
||||
v, err := nm.getUint32Property(NetworkManagerPropertyMetered)
|
||||
return NmMetered(v), err
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyActivatingConnection() (ActiveConnection, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyStartup() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyStartup)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyVersion() (string, error) {
|
||||
return nm.getStringProperty(NetworkManagerPropertyVersion)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyCapabilities() ([]NmCapability, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyState() (NmState, error) {
|
||||
v, err := nm.getUint32Property(NetworkManagerPropertyState)
|
||||
return NmState(v), err
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyConnectivity() (NmConnectivity, error) {
|
||||
v, err := nm.getUint32Property(NetworkManagerPropertyConnectivity)
|
||||
return NmConnectivity(v), err
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyConnectivityCheckAvailable() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyConnectivityCheckAvailable)
|
||||
}
|
||||
|
||||
func (nm *networkManager) GetPropertyConnectivityCheckEnabled() (bool, error) {
|
||||
return nm.getBoolProperty(NetworkManagerPropertyConnectivityCheckEnabled)
|
||||
}
|
||||
|
||||
func (nm *networkManager) Subscribe() <-chan *dbus.Signal {
|
||||
if nm.sigChan != nil {
|
||||
return nm.sigChan
|
||||
}
|
||||
|
||||
nm.subscribeNamespace(NetworkManagerObjectPath)
|
||||
nm.sigChan = make(chan *dbus.Signal, 10)
|
||||
nm.conn.Signal(nm.sigChan)
|
||||
|
||||
return nm.sigChan
|
||||
}
|
||||
|
||||
func (nm *networkManager) Unsubscribe() {
|
||||
nm.conn.RemoveSignal(nm.sigChan)
|
||||
nm.sigChan = nil
|
||||
}
|
||||
|
||||
func (nm *networkManager) MarshalJSON() ([]byte, error) {
|
||||
|
||||
Devices, err := nm.GetPropertyDevices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
AllDevices, err := nm.GetPropertyAllDevices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Checkpoints, err := nm.GetPropertyCheckpoints()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
NetworkingEnabled, err := nm.GetPropertyNetworkingEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WirelessEnabled, err := nm.GetPropertyWirelessEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WirelessHardwareEnabled, err := nm.GetPropertyWirelessHardwareEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WwanEnabled, err := nm.GetPropertyWwanEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WwanHardwareEnabled, err := nm.GetPropertyWwanHardwareEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WimaxEnabled, err := nm.GetPropertyWimaxEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
WimaxHardwareEnabled, err := nm.GetPropertyWimaxHardwareEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ActiveConnections, err := nm.GetPropertyActiveConnections()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
PrimaryConnection, err := nm.GetPropertyPrimaryConnection()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
PrimaryConnectionType, err := nm.GetPropertyPrimaryConnectionType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Metered, err := nm.GetPropertyMetered()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ActivatingConnection, err := nm.GetPropertyActivatingConnection()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Startup, err := nm.GetPropertyStartup()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Version, err := nm.GetPropertyVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Capabilities, err := nm.GetPropertyCapabilities()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
State, err := nm.GetPropertyState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Connectivity, err := nm.GetPropertyConnectivity()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ConnectivityCheckAvailable, err := nm.GetPropertyConnectivityCheckAvailable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ConnectivityCheckEnabled, err := nm.GetPropertyConnectivityCheckEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"Devices": Devices,
|
||||
"AllDevices": AllDevices,
|
||||
"Checkpoints": Checkpoints,
|
||||
"NetworkingEnabled": NetworkingEnabled,
|
||||
"WirelessEnabled": WirelessEnabled,
|
||||
"WirelessHardwareEnabled": WirelessHardwareEnabled,
|
||||
"WwanEnabled": WwanEnabled,
|
||||
"WwanHardwareEnabled": WwanHardwareEnabled,
|
||||
"WimaxEnabled": WimaxEnabled,
|
||||
"WimaxHardwareEnabled": WimaxHardwareEnabled,
|
||||
"ActiveConnections": ActiveConnections,
|
||||
"PrimaryConnection": PrimaryConnection,
|
||||
"PrimaryConnectionType": PrimaryConnectionType,
|
||||
"Metered": Metered,
|
||||
"ActivatingConnection": ActivatingConnection,
|
||||
"Startup": Startup,
|
||||
"Version": Version,
|
||||
"Capabilities": Capabilities,
|
||||
"State": State,
|
||||
"Connectivity": Connectivity,
|
||||
"ConnectivityCheckAvailable": ConnectivityCheckAvailable,
|
||||
"ConnectivityCheckEnabled": ConnectivityCheckEnabled,
|
||||
})
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
[](https://pkg.go.dev/github.com/Wifx/gonetworkmanager)
|
||||
[](https://github.com/Wifx/gonetworkmanager/actions?query=workflow%3AGo)
|
||||
|
||||
gonetworkmanager
|
||||
================
|
||||
|
||||
Go D-Bus bindings for [NetworkManager](https://networkmanager.dev/).
|
||||
|
||||
## Usage
|
||||
|
||||
You can find some examples in the [examples](examples) directory.
|
||||
|
||||
## External documentations
|
||||
|
||||
- [NetworkManager D-Bus Spec](https://networkmanager.dev/docs/api/latest/spec.html)
|
||||
- [nm-settings-dbus](https://networkmanager.dev/docs/api/latest/nm-settings-dbus.html)
|
||||
|
||||
|
||||
## Backward compatibility
|
||||
|
||||
The library is most likely compatible with NetworkManager 0.9 to 1.40.
|
||||
|
||||
## Tests
|
||||
|
||||
Tested with NetworkManager 1.40.0.
|
||||
|
||||
There are no automated tests for this library. Tests are made manually on a best-effort basis. Unit tests PRs are welcome.
|
||||
|
||||
## Development and contributions
|
||||
|
||||
There is no active development workforce from the maintainer. PRs are welcome.
|
||||
|
||||
## Issues
|
||||
|
||||
Before reporting an issue, please test the scenario with nmcli (if possible) to ensure the problem comes from the library.
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
SettingsInterface = NetworkManagerInterface + ".Settings"
|
||||
SettingsObjectPath = NetworkManagerObjectPath + "/Settings"
|
||||
|
||||
/* Methods */
|
||||
SettingsListConnections = SettingsInterface + ".ListConnections"
|
||||
SettingsGetConnectionByUUID = SettingsInterface + ".GetConnectionByUuid"
|
||||
SettingsAddConnection = SettingsInterface + ".AddConnection"
|
||||
SettingsAddConnectionUnsaved = SettingsInterface + ".AddConnectionUnsaved"
|
||||
SettingsLoadConnections = SettingsInterface + ".LoadConnections"
|
||||
SettingsReloadConnections = SettingsInterface + ".ReloadConnections"
|
||||
SettingsSaveHostname = SettingsInterface + ".SaveHostname"
|
||||
|
||||
/* Properties */
|
||||
SettingsPropertyConnections = SettingsInterface + ".Connections" // readable ao
|
||||
SettingsPropertyHostname = SettingsInterface + ".Hostname" // readable s
|
||||
SettingsPropertyCanModify = SettingsInterface + ".CanModify" // readable b
|
||||
)
|
||||
|
||||
type Settings interface {
|
||||
// ListConnections gets list the saved network connections known to NetworkManager
|
||||
ListConnections() ([]Connection, error)
|
||||
|
||||
// ReloadConnections tells NetworkManager to reload all connection files from disk, including noticing any added or deleted connection files.
|
||||
ReloadConnections() error
|
||||
|
||||
// GetConnectionByUUID gets the connection, given that connection's UUID.
|
||||
GetConnectionByUUID(uuid string) (Connection, error)
|
||||
|
||||
// AddConnection adds new connection and save it to disk.
|
||||
AddConnection(settings ConnectionSettings) (Connection, error)
|
||||
|
||||
// AddConnectionUnsaved Add new connection but do not save it to disk immediately. This operation does not start the network connection unless (1) device is idle and able to connect to the network described by the new connection, and (2) the connection is allowed to be started automatically. Use the 'Save' method on the connection to save these changes to disk. Note that unsaved changes will be lost if the connection is reloaded from disk (either automatically on file change or due to an explicit ReloadConnections call).
|
||||
AddConnectionUnsaved(settings ConnectionSettings) (Connection, error)
|
||||
|
||||
// SaveHostname Save the hostname to persistent configuration.
|
||||
SaveHostname(hostname string) error
|
||||
|
||||
// GetPropertyCanModify If true, adding and modifying connections is supported.
|
||||
GetPropertyCanModify() (bool, error)
|
||||
|
||||
// GetPropertyHostname The machine hostname stored in persistent configuration.
|
||||
GetPropertyHostname() (string, error)
|
||||
}
|
||||
|
||||
func NewSettings() (Settings, error) {
|
||||
var s settings
|
||||
return &s, s.init(NetworkManagerInterface, SettingsObjectPath)
|
||||
}
|
||||
|
||||
type settings struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (s *settings) ListConnections() ([]Connection, error) {
|
||||
var connectionPaths []dbus.ObjectPath
|
||||
|
||||
err := s.callWithReturn(&connectionPaths, SettingsListConnections)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connections := make([]Connection, len(connectionPaths))
|
||||
|
||||
for i, path := range connectionPaths {
|
||||
connections[i], err = NewConnection(path)
|
||||
if err != nil {
|
||||
return connections, err
|
||||
}
|
||||
}
|
||||
|
||||
return connections, nil
|
||||
}
|
||||
|
||||
// ReloadConnections tells NetworkManager to reload (and apply) configuration files
|
||||
// from disk taking notice of any added or removed connections.
|
||||
func (s *settings) ReloadConnections() error {
|
||||
return s.call(SettingsReloadConnections)
|
||||
}
|
||||
|
||||
// GetConnectionByUUID gets the connection, given that connection's UUID.
|
||||
func (s *settings) GetConnectionByUUID(uuid string) (Connection, error) {
|
||||
var path dbus.ObjectPath
|
||||
err := s.callWithReturn(&path, SettingsGetConnectionByUUID, uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewConnection(path)
|
||||
}
|
||||
|
||||
func (s *settings) AddConnection(settings ConnectionSettings) (Connection, error) {
|
||||
var path dbus.ObjectPath
|
||||
err := s.callWithReturn(&path, SettingsAddConnection, settings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewConnection(path)
|
||||
}
|
||||
|
||||
func (s *settings) AddConnectionUnsaved(settings ConnectionSettings) (Connection, error) {
|
||||
var path dbus.ObjectPath
|
||||
err := s.callWithReturn(&path, SettingsAddConnectionUnsaved, settings)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewConnection(path)
|
||||
}
|
||||
|
||||
func (s *settings) SaveHostname(hostname string) error {
|
||||
return s.call(SettingsSaveHostname, hostname)
|
||||
}
|
||||
|
||||
func (s *settings) GetPropertyHostname() (string, error) {
|
||||
return s.getStringProperty(SettingsPropertyHostname)
|
||||
}
|
||||
|
||||
func (s *settings) GetPropertyCanModify() (bool, error) {
|
||||
return s.getBoolProperty(SettingsPropertyCanModify)
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
VpnConnectionInterface = NetworkManagerInterface + ".VPN.Connection"
|
||||
|
||||
/* Properties */
|
||||
VpnConnectionPropertyVpnState = VpnConnectionInterface + ".VpnState" // readable u
|
||||
VpnConnectionPropertyBanner = VpnConnectionInterface + ".Banner" // readable s
|
||||
)
|
||||
|
||||
type VpnConnection interface {
|
||||
GetPath() dbus.ObjectPath
|
||||
|
||||
// GetPropertyVpnState The VPN-specific state of the connection.
|
||||
GetPropertyVpnState() (NmVpnConnectionState, error)
|
||||
|
||||
// GetPropertyBanner The banner string of the VPN connection.
|
||||
GetPropertyBanner() (string, error)
|
||||
}
|
||||
|
||||
func NewVpnConnection(objectPath dbus.ObjectPath) (VpnConnection, error) {
|
||||
var a vpnConnection
|
||||
return &a, a.init(NetworkManagerInterface, objectPath)
|
||||
}
|
||||
|
||||
type vpnConnection struct {
|
||||
dbusBase
|
||||
}
|
||||
|
||||
func (a *vpnConnection) GetPath() dbus.ObjectPath {
|
||||
return a.obj.Path()
|
||||
}
|
||||
|
||||
func (a *vpnConnection) GetPropertyVpnState() (NmVpnConnectionState, error) {
|
||||
v, err := a.getUint32Property(VpnConnectionPropertyVpnState)
|
||||
return NmVpnConnectionState(v), err
|
||||
}
|
||||
|
||||
func (a *vpnConnection) GetPropertyBanner() (string, error) {
|
||||
return a.getStringProperty(VpnConnectionPropertyBanner)
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
package gonetworkmanager
|
||||
|
||||
//go:generate stringer -type=NmConnectivity
|
||||
type NmConnectivity uint32
|
||||
|
||||
const (
|
||||
NmConnectivityUnknown NmConnectivity = 0 // Network connectivity is unknown. This means the connectivity checks are disabled (e.g. on server installations) or has not run yet. The graphical shell should assume the Internet connection might be available and not present a captive portal window.
|
||||
NmConnectivityNone NmConnectivity = 1 // The host is not connected to any network. There's no active connection that contains a default route to the internet and thus it makes no sense to even attempt a connectivity check. The graphical shell should use this state to indicate the network connection is unavailable.
|
||||
NmConnectivityPortal NmConnectivity = 2 // The Internet connection is hijacked by a captive portal gateway. The graphical shell may open a sandboxed web browser window (because the captive portals typically attempt a man-in-the-middle attacks against the https connections) for the purpose of authenticating to a gateway and retrigger the connectivity check with CheckConnectivity() when the browser window is dismissed.
|
||||
NmConnectivityLimited NmConnectivity = 3 // The host is connected to a network, does not appear to be able to reach the full Internet, but a captive portal has not been detected.
|
||||
NmConnectivityFull NmConnectivity = 4 // The host is connected to a network, and appears to be able to reach the full Internet.
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmState
|
||||
type NmState uint32
|
||||
|
||||
const (
|
||||
NmStateUnknown NmState = 0 // Networking state is unknown. This indicates a daemon error that makes it unable to reasonably assess the state. In such event the applications are expected to assume Internet connectivity might be present and not disable controls that require network access. The graphical shells may hide the network accessibility indicator altogether since no meaningful status indication can be provided.
|
||||
NmStateAsleep NmState = 10 // Networking is not enabled, the system is being suspended or resumed from suspend.
|
||||
NmStateDisconnected NmState = 20 // There is no active network connection. The graphical shell should indicate no network connectivity and the applications should not attempt to access the network.
|
||||
NmStateDisconnecting NmState = 30 // Network connections are being cleaned up. The applications should tear down their network sessions.
|
||||
NmStateConnecting NmState = 40 // A network connection is being started The graphical shell should indicate the network is being connected while the applications should still make no attempts to connect the network.
|
||||
NmStateConnectedLocal NmState = 50 // There is only local IPv4 and/or IPv6 connectivity, but no default route to access the Internet. The graphical shell should indicate no network connectivity.
|
||||
NmStateConnectedSite NmState = 60 // There is only site-wide IPv4 and/or IPv6 connectivity. This means a default route is available, but the Internet connectivity check (see "Connectivity" property) did not succeed. The graphical shell should indicate limited network connectivity.
|
||||
NmStateConnectedGlobal NmState = 70 // There is global IPv4 and/or IPv6 Internet connectivity This means the Internet connectivity check succeeded, the graphical shell should indicate full network connectivity.
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmCheckpointCreateFlags
|
||||
type NmCheckpointCreateFlags uint32
|
||||
|
||||
const (
|
||||
NmCheckpointCreateFlagsNone NmCheckpointCreateFlags = 0 // no flags
|
||||
NmCheckpointCreateFlagsDestroyAll NmCheckpointCreateFlags = 0x01 // when creating a new checkpoint, destroy all existing ones.
|
||||
NmCheckpointCreateFlagsDeleteNewConnections NmCheckpointCreateFlags = 0x02 // upon rollback, delete any new connection added after the checkpoint (Since: 1.6)
|
||||
NmCheckpointCreateFlagsDisconnectNewDevices NmCheckpointCreateFlags = 0x04 // upon rollback, disconnect any new device appeared after the checkpoint (Since: 1.6)
|
||||
NmCheckpointCreateFlagsAllowOverlapping NmCheckpointCreateFlags = 0x08 // by default, creating a checkpoint fails if there are already existing checkoints that reference the same devices. With this flag, creation of such checkpoints is allowed, however, if an older checkpoint that references overlapping devices gets rolled back, it will automatically destroy this checkpoint during rollback. This allows to create several overlapping checkpoints in parallel, and rollback to them at will. With the special case that rolling back to an older checkpoint will invalidate all overlapping younger checkpoints. This opts-in that the checkpoint can be automatically destroyed by the rollback of an older checkpoint. (Since: 1.12)
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmCapability
|
||||
type NmCapability uint32
|
||||
|
||||
const (
|
||||
NmCapabilityTeam NmCapability = 1 // Teams can be managed
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmMetered
|
||||
type NmMetered uint32
|
||||
|
||||
const (
|
||||
NmMeteredUnknown NmMetered = 0 // The metered status is unknown
|
||||
NmMeteredYes NmMetered = 1 // Metered, the value was statically set
|
||||
NmMeteredNo NmMetered = 2 // Not metered, the value was statically set
|
||||
NmMeteredGuessYes NmMetered = 3 // Metered, the value was guessed
|
||||
NmMeteredGuessNo NmMetered = 4 // Not metered, the value was guessed
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmDeviceState
|
||||
type NmDeviceState uint32
|
||||
|
||||
const (
|
||||
NmDeviceStateUnknown NmDeviceState = 0 // the device's state is unknown
|
||||
NmDeviceStateUnmanaged NmDeviceState = 10 // the device is recognized, but not managed by NetworkManager
|
||||
NmDeviceStateUnavailable NmDeviceState = 20 // the device is managed by NetworkManager, but is not available for use. Reasons may include the wireless switched off, missing firmware, no ethernet carrier, missing supplicant or modem manager, etc.
|
||||
NmDeviceStateDisconnected NmDeviceState = 30 // the device can be activated, but is currently idle and not connected to a network.
|
||||
NmDeviceStatePrepare NmDeviceState = 40 // the device is preparing the connection to the network. This may include operations like changing the MAC address, setting physical link properties, and anything else required to connect to the requested network.
|
||||
NmDeviceStateConfig NmDeviceState = 50 // the device is connecting to the requested network. This may include operations like associating with the Wi-Fi AP, dialing the modem, connecting to the remote Bluetooth device, etc.
|
||||
NmDeviceStateNeedAuth NmDeviceState = 60 // the device requires more information to continue connecting to the requested network. This includes secrets like WiFi passphrases, login passwords, PIN codes, etc.
|
||||
NmDeviceStateIpConfig NmDeviceState = 70 // the device is requesting IPv4 and/or IPv6 addresses and routing information from the network.
|
||||
NmDeviceStateIpCheck NmDeviceState = 80 // the device is checking whether further action is required for the requested network connection. This may include checking whether only local network access is available, whether a captive portal is blocking access to the Internet, etc.
|
||||
NmDeviceStateSecondaries NmDeviceState = 90 // the device is waiting for a secondary connection (like a VPN) which must activated before the device can be activated
|
||||
NmDeviceStateActivated NmDeviceState = 100 // the device has a network connection, either local or global.
|
||||
NmDeviceStateDeactivating NmDeviceState = 110 // a disconnection from the current network connection was requested, and the device is cleaning up resources used for that connection. The network connection may still be valid.
|
||||
NmDeviceStateFailed NmDeviceState = 120 // the device failed to connect to the requested network and is cleaning up the connection request
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmActiveConnectionState
|
||||
type NmActiveConnectionState uint32
|
||||
|
||||
const (
|
||||
NmActiveConnectionStateUnknown NmActiveConnectionState = 0 // The state of the connection is unknown
|
||||
NmActiveConnectionStateActivating NmActiveConnectionState = 1 // A network connection is being prepared
|
||||
NmActiveConnectionStateActivated NmActiveConnectionState = 2 // There is a connection to the network
|
||||
NmActiveConnectionStateDeactivating NmActiveConnectionState = 3 // The network connection is being torn down and cleaned up
|
||||
NmActiveConnectionStateDeactivated NmActiveConnectionState = 4 // The network connection is disconnected and will be removed
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmActivationStateFlag
|
||||
type NmActivationStateFlag uint32
|
||||
|
||||
const (
|
||||
NmActivationStateFlagNone NmActivationStateFlag = 0x00 // an alias for numeric zero, no flags set.
|
||||
NmActivationStateFlagIsMaster NmActivationStateFlag = 0x01 // the device is a master.
|
||||
NmActivationStateFlagIsSlave NmActivationStateFlag = 0x02 // the device is a slave.
|
||||
NmActivationStateFlagLayer2Ready NmActivationStateFlag = 0x04 // layer2 is activated and ready.
|
||||
NmActivationStateFlagIp4Ready NmActivationStateFlag = 0x08 // IPv4 setting is completed.
|
||||
NmActivationStateFlagIp6Ready NmActivationStateFlag = 0x10 // IPv6 setting is completed.
|
||||
NmActivationStateFlagMasterHasSlaves NmActivationStateFlag = 0x20 // The master has any slave devices attached. This only makes sense if the device is a master.
|
||||
NmActivationStateFlagLifetimeBoundToProfileVisibility NmActivationStateFlag = 0x40 // the lifetime of the activation is bound to the visilibity of the connection profile, which in turn depends on "connection.permissions" and whether a session for the user exists. Since: 1.16
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmDeviceType
|
||||
type NmDeviceType uint32
|
||||
|
||||
const (
|
||||
NmDeviceTypeUnknown NmDeviceType = 0 // unknown device
|
||||
NmDeviceTypeGeneric NmDeviceType = 14 // generic support for unrecognized device types
|
||||
NmDeviceTypeEthernet NmDeviceType = 1 // a wired ethernet device
|
||||
NmDeviceTypeWifi NmDeviceType = 2 // an 802.11 Wi-Fi device
|
||||
NmDeviceTypeUnused1 NmDeviceType = 3 // not used
|
||||
NmDeviceTypeUnused2 NmDeviceType = 4 // not used
|
||||
NmDeviceTypeBt NmDeviceType = 5 // a Bluetooth device supporting PAN or DUN access protocols
|
||||
NmDeviceTypeOlpcMesh NmDeviceType = 6 // an OLPC XO mesh networking device
|
||||
NmDeviceTypeWimax NmDeviceType = 7 // an 802.16e Mobile WiMAX broadband device
|
||||
NmDeviceTypeModem NmDeviceType = 8 // a modem supporting analog telephone, CDMA/EVDO, GSM/UMTS, or LTE network access protocols
|
||||
NmDeviceTypeInfiniband NmDeviceType = 9 // an IP-over-InfiniBand device
|
||||
NmDeviceTypeBond NmDeviceType = 10 // a bond master interface
|
||||
NmDeviceTypeVlan NmDeviceType = 11 // an 802.1Q VLAN interface
|
||||
NmDeviceTypeAdsl NmDeviceType = 12 // ADSL modem
|
||||
NmDeviceTypeBridge NmDeviceType = 13 // a bridge master interface
|
||||
NmDeviceTypeTeam NmDeviceType = 15 // a team master interface
|
||||
NmDeviceTypeTun NmDeviceType = 16 // a TUN or TAP interface
|
||||
NmDeviceTypeIpTunnel NmDeviceType = 17 // a IP tunnel interface
|
||||
NmDeviceTypeMacvlan NmDeviceType = 18 // a MACVLAN interface
|
||||
NmDeviceTypeVxlan NmDeviceType = 19 // a VXLAN interface
|
||||
NmDeviceTypeVeth NmDeviceType = 20 // a VETH interface
|
||||
NmDeviceTypeMacsec NmDeviceType = 21 // a MACsec interface
|
||||
NmDeviceTypeDummy NmDeviceType = 22 // a dummy interface
|
||||
NmDeviceTypePpp NmDeviceType = 23 // a PPP interface
|
||||
NmDeviceTypeOvsInterface NmDeviceType = 24 // a Open vSwitch interface
|
||||
NmDeviceTypeOvsPort NmDeviceType = 25 // a Open vSwitch port
|
||||
NmDeviceTypeOvsBridge NmDeviceType = 26 // a Open vSwitch bridge
|
||||
NmDeviceTypeWpan NmDeviceType = 27 // a IEEE 802.15.4 (WPAN) MAC Layer Device
|
||||
NmDeviceType6lowpan NmDeviceType = 28 // 6LoWPAN interface
|
||||
NmDeviceTypeWireguard NmDeviceType = 29 // a WireGuard interface
|
||||
NmDeviceTypeWifiP2p NmDeviceType = 30 // an 802.11 Wi-Fi P2P device (Since: 1.16)
|
||||
)
|
||||
|
||||
//go:generate stringer -type=Nm80211APFlags
|
||||
type Nm80211APFlags uint32
|
||||
|
||||
const (
|
||||
Nm80211APFlagsNone Nm80211APFlags = 0x0
|
||||
Nm80211APFlagsPrivacy Nm80211APFlags = 0x1
|
||||
)
|
||||
|
||||
//go:generate stringer -type=Nm80211APSec
|
||||
type Nm80211APSec uint32
|
||||
|
||||
const (
|
||||
Nm80211APSecNone Nm80211APSec = 0x0
|
||||
Nm80211APSecPairWEP40 Nm80211APSec = 0x1
|
||||
Nm80211APSecPairWEP104 Nm80211APSec = 0x2
|
||||
Nm80211APSecPairTKIP Nm80211APSec = 0x4
|
||||
Nm80211APSecPairCCMP Nm80211APSec = 0x8
|
||||
Nm80211APSecGroupWEP40 Nm80211APSec = 0x10
|
||||
Nm80211APSecGroupWEP104 Nm80211APSec = 0x20
|
||||
Nm80211APSecGroupTKIP Nm80211APSec = 0x40
|
||||
Nm80211APSecGroupCCMP Nm80211APSec = 0x80
|
||||
Nm80211APSecKeyMgmtPSK Nm80211APSec = 0x100
|
||||
Nm80211APSecKeyMgmt8021X Nm80211APSec = 0x200
|
||||
Nm80211APSecKeyMgmtSAE Nm80211APSec = 0x400
|
||||
Nm80211APSecKeyMgmtOWE Nm80211APSec = 0x800
|
||||
Nm80211APSecKeyMgmtOWETM Nm80211APSec = 0x1000
|
||||
)
|
||||
|
||||
//go:generate stringer -type=Nm80211Mode
|
||||
type Nm80211Mode uint32
|
||||
|
||||
const (
|
||||
Nm80211ModeUnknown Nm80211Mode = 0
|
||||
Nm80211ModeAdhoc Nm80211Mode = 1
|
||||
Nm80211ModeInfra Nm80211Mode = 2
|
||||
Nm80211ModeAp Nm80211Mode = 3
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmActiveConnectionState
|
||||
type NmVpnConnectionState uint32
|
||||
|
||||
const (
|
||||
NmVpnConnectionUnknown = 0 //The state of the VPN connection is unknown.
|
||||
NmVpnConnectionPrepare = 1 //The VPN connection is preparing to connect.
|
||||
NmVpnConnectionNeedAuth = 2 //The VPN connection needs authorization credentials.
|
||||
NmVpnConnectionConnect = 3 //The VPN connection is being established.
|
||||
NmVpnConnectionIpConfigGet = 4 //The VPN connection is getting an IP address.
|
||||
NmVpnConnectionActivated = 5 //The VPN connection is active.
|
||||
NmVpnConnectionFailed = 6 //The VPN connection failed.
|
||||
NmVpnConnectionDisconnected = 7 //The VPN connection is disconnected.
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmDeviceStateReason
|
||||
type NmDeviceStateReason uint32
|
||||
|
||||
const (
|
||||
NmDeviceStateReasonNone = 0 // No reason given
|
||||
NmDeviceStateReasonUnknown = 1 // Unknown error
|
||||
NmDeviceStateReasonNowManaged = 2 // Device is now managed
|
||||
NmDeviceStateReasonNowUnmanaged = 3 // Device is now unmanaged
|
||||
NmDeviceStateReasonConfigFailed = 4 // The device could not be readied for configuration
|
||||
NmDeviceStateReasonIpConfigUnavailable = 5 // IP configuration could not be reserved (no available address, timeout, etc)
|
||||
NmDeviceStateReasonIpConfigExpired = 6 // The IP config is no longer valid
|
||||
NmDeviceStateReasonNoSecrets = 7 // Secrets were required, but not provided
|
||||
NmDeviceStateReasonSupplicantDisconnect = 8 // 802.1x supplicant disconnected
|
||||
NmDeviceStateReasonSupplicantConfigFailed = 9 // 802.1x supplicant configuration failed
|
||||
NmDeviceStateReasonSupplicantFailed = 10 // 802.1x supplicant failed
|
||||
NmDeviceStateReasonSupplicantTimeout = 11 // 802.1x supplicant took too long to authenticate
|
||||
NmDeviceStateReasonPppStartFailed = 12 // PPP service failed to start
|
||||
NmDeviceStateReasonPppDisconnect = 13 // PPP service disconnected
|
||||
NmDeviceStateReasonPppFailed = 14 // PPP failed
|
||||
NmDeviceStateReasonDhcpStartFailed = 15 // DHCP client failed to start
|
||||
NmDeviceStateReasonDhcpError = 16 // DHCP client error
|
||||
NmDeviceStateReasonDhcpFailed = 17 // DHCP client failed
|
||||
NmDeviceStateReasonSharedStartFailed = 18 // Shared connection service failed to start
|
||||
NmDeviceStateReasonSharedFailed = 19 // Shared connection service failed
|
||||
NmDeviceStateReasonAutoipStartFailed = 20 // AutoIP service failed to start
|
||||
NmDeviceStateReasonAutoipError = 21 // AutoIP service error
|
||||
NmDeviceStateReasonAutoipFailed = 22 // AutoIP service failed
|
||||
NmDeviceStateReasonModemBusy = 23 // The line is busy
|
||||
NmDeviceStateReasonModemNoDialTone = 24 // No dial tone
|
||||
NmDeviceStateReasonModemNoCarrier = 25 // No carrier could be established
|
||||
NmDeviceStateReasonModemDialTimeout = 26 // The dialing request timed out
|
||||
NmDeviceStateReasonModemDialFailed = 27 // The dialing attempt failed
|
||||
NmDeviceStateReasonModemInitFailed = 28 // Modem initialization failed
|
||||
NmDeviceStateReasonGsmApnFailed = 29 // Failed to select the specified APN
|
||||
NmDeviceStateReasonGsmRegistrationNotSearching = 30 // Not searching for networks
|
||||
NmDeviceStateReasonGsmRegistrationDenied = 31 // Network registration denied
|
||||
NmDeviceStateReasonGsmRegistrationTimeout = 32 // Network registration timed out
|
||||
NmDeviceStateReasonGsmRegistrationFailed = 33 // Failed to register with the requested network
|
||||
NmDeviceStateReasonGsmPinCheckFailed = 34 // PIN check failed
|
||||
NmDeviceStateReasonFirmwareMissing = 35 // Necessary firmware for the device may be missing
|
||||
NmDeviceStateReasonRemoved = 36 // The device was removed
|
||||
NmDeviceStateReasonSleeping = 37 // NetworkManager went to sleep
|
||||
NmDeviceStateReasonConnectionRemoved = 38 // The device's active connection disappeared
|
||||
NmDeviceStateReasonUserRequested = 39 // Device disconnected by user or client
|
||||
NmDeviceStateReasonCarrier = 40 // Carrier/link changed
|
||||
NmDeviceStateReasonConnectionAssumed = 41 // The device's existing connection was assumed
|
||||
NmDeviceStateReasonSupplicantAvailable = 42 // The supplicant is now available
|
||||
NmDeviceStateReasonModemNotFound = 43 // The modem could not be found
|
||||
NmDeviceStateReasonBtFailed = 44 // The Bluetooth connection failed or timed out
|
||||
NmDeviceStateReasonGsmSimNotInserted = 45 // GSM Modem's SIM Card not inserted
|
||||
NmDeviceStateReasonGsmSimPinRequired = 46 // GSM Modem's SIM Pin required
|
||||
NmDeviceStateReasonGsmSimPukRequired = 47 // GSM Modem's SIM Puk required
|
||||
NmDeviceStateReasonGsmSimWrong = 48 // GSM Modem's SIM wrong
|
||||
NmDeviceStateReasonInfinibandMode = 49 // InfiniBand device does not support connected mode
|
||||
NmDeviceStateReasonDependencyFailed = 50 // A dependency of the connection failed
|
||||
NmDeviceStateReasonBr2684Failed = 51 // Problem with the RFC 2684 Ethernet over ADSL bridge
|
||||
NmDeviceStateReasonModemManagerUnavailable = 52 // ModemManager not running
|
||||
NmDeviceStateReasonSsidNotFound = 53 // The Wi-Fi network could not be found
|
||||
NmDeviceStateReasonSecondaryConnectionFailed = 54 // A secondary connection of the base connection failed
|
||||
NmDeviceStateReasonDcbFcoeFailed = 55 // DCB or FCoE setup failed
|
||||
NmDeviceStateReasonTeamdControlFailed = 56 // teamd control failed
|
||||
NmDeviceStateReasonModemFailed = 57 // Modem failed or no longer available
|
||||
NmDeviceStateReasonModemAvailable = 58 // Modem now ready and available
|
||||
NmDeviceStateReasonSimPinIncorrect = 59 // SIM PIN was incorrect
|
||||
NmDeviceStateReasonNewActivation = 60 // New connection activation was enqueued
|
||||
NmDeviceStateReasonParentChanged = 61 // the device's parent changed
|
||||
NmDeviceStateReasonParentManagedChanged = 62 // the device parent's management changed
|
||||
NmDeviceStateReasonOvsdbFailed = 63 // problem communicating with Open vSwitch database
|
||||
NmDeviceStateReasonIpAddressDuplicate = 64 // a duplicate IP address was detected
|
||||
NmDeviceStateReasonIpMethodUnsupported = 65 // The selected IP method is not supported
|
||||
NmDeviceStateReasonSriovConfigurationFailed = 66 // configuration of SR-IOV parameters failed
|
||||
NmDeviceStateReasonPeerNotFound = 67 // The Wi-Fi P2P peer could not be found
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmActiveConnectionStateReason
|
||||
type NmActiveConnectionStateReason uint32
|
||||
|
||||
const (
|
||||
NmActiveConnectionStateReasonUnknown = 0 // The reason for the active connection state change is unknown.
|
||||
NmActiveConnectionStateReasonNone = 1 // No reason was given for the active connection state change.
|
||||
NmActiveConnectionStateReasonUserDisconnected = 2 // The active connection changed state because the user disconnected it.
|
||||
NmActiveConnectionStateReasonDeviceDisconnected = 3 // The active connection changed state because the device it was using was disconnected.
|
||||
NmActiveConnectionStateReasonServiceStopped = 4 // The service providing the VPN connection was stopped.
|
||||
NmActiveConnectionStateReasonIpConfigInvalid = 5 // The IP config of the active connection was invalid.
|
||||
NmActiveConnectionStateReasonConnectTimeout = 6 // The connection attempt to the VPN service timed out.
|
||||
NmActiveConnectionStateReasonServiceStartTimeout = 7 // A timeout occurred while starting the service providing the VPN connection.
|
||||
NmActiveConnectionStateReasonServiceStartFailed = 8 // Starting the service providing the VPN connection failed.
|
||||
NmActiveConnectionStateReasonNoSecrets = 9 // Necessary secrets for the connection were not provided.
|
||||
NmActiveConnectionStateReasonLoginFailed = 10 // Authentication to the server failed.
|
||||
NmActiveConnectionStateReasonConnectionRemoved = 11 // The connection was deleted from settings.
|
||||
NmActiveConnectionStateReasonDependencyFailed = 12 // Master connection of this connection failed to activate.
|
||||
NmActiveConnectionStateReasonDeviceRealizeFailed = 13 // Could not create the software device link.
|
||||
NmActiveConnectionStateReasonDeviceRemoved = 14 // The device this connection depended on disappeared.
|
||||
)
|
||||
|
||||
//go:generate stringer -type=NmRollbackResult
|
||||
type NmRollbackResult uint32
|
||||
|
||||
const (
|
||||
NmRollbackResultOk = 0 // the rollback succeeded.
|
||||
NmRollbackResultErrNoDevice = 1 // the device no longer exists.
|
||||
NmRollbackResultErrDeviceUnmanaged = 2 // the device is now unmanaged.
|
||||
NmRollbackResultErrFailed = 3 // other errors during rollback.
|
||||
)
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Code generated by "stringer -type=Nm80211APFlags"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[Nm80211APFlagsNone-0]
|
||||
_ = x[Nm80211APFlagsPrivacy-1]
|
||||
}
|
||||
|
||||
const _Nm80211APFlags_name = "Nm80211APFlagsNoneNm80211APFlagsPrivacy"
|
||||
|
||||
var _Nm80211APFlags_index = [...]uint8{0, 18, 39}
|
||||
|
||||
func (i Nm80211APFlags) String() string {
|
||||
if i >= Nm80211APFlags(len(_Nm80211APFlags_index)-1) {
|
||||
return "Nm80211APFlags(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Nm80211APFlags_name[_Nm80211APFlags_index[i]:_Nm80211APFlags_index[i+1]]
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Code generated by "stringer -type=Nm80211APSec"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[Nm80211APSecNone-0]
|
||||
_ = x[Nm80211APSecPairWEP40-1]
|
||||
_ = x[Nm80211APSecPairWEP104-2]
|
||||
_ = x[Nm80211APSecPairTKIP-4]
|
||||
_ = x[Nm80211APSecPairCCMP-8]
|
||||
_ = x[Nm80211APSecGroupWEP40-16]
|
||||
_ = x[Nm80211APSecGroupWEP104-32]
|
||||
_ = x[Nm80211APSecGroupTKIP-64]
|
||||
_ = x[Nm80211APSecGroupCCMP-128]
|
||||
_ = x[Nm80211APSecKeyMgmtPSK-256]
|
||||
_ = x[Nm80211APSecKeyMgmt8021X-512]
|
||||
_ = x[Nm80211APSecKeyMgmtSAE-1024]
|
||||
_ = x[Nm80211APSecKeyMgmtOWE-2048]
|
||||
_ = x[Nm80211APSecKeyMgmtOWETM-4096]
|
||||
}
|
||||
|
||||
const _Nm80211APSec_name = "Nm80211APSecNoneNm80211APSecPairWEP40Nm80211APSecPairWEP104Nm80211APSecPairTKIPNm80211APSecPairCCMPNm80211APSecGroupWEP40Nm80211APSecGroupWEP104Nm80211APSecGroupTKIPNm80211APSecGroupCCMPNm80211APSecKeyMgmtPSKNm80211APSecKeyMgmt8021XNm80211APSecKeyMgmtSAENm80211APSecKeyMgmtOWENm80211APSecKeyMgmtOWETM"
|
||||
|
||||
var _Nm80211APSec_map = map[Nm80211APSec]string{
|
||||
0: _Nm80211APSec_name[0:16],
|
||||
1: _Nm80211APSec_name[16:37],
|
||||
2: _Nm80211APSec_name[37:59],
|
||||
4: _Nm80211APSec_name[59:79],
|
||||
8: _Nm80211APSec_name[79:99],
|
||||
16: _Nm80211APSec_name[99:121],
|
||||
32: _Nm80211APSec_name[121:144],
|
||||
64: _Nm80211APSec_name[144:165],
|
||||
128: _Nm80211APSec_name[165:186],
|
||||
256: _Nm80211APSec_name[186:208],
|
||||
512: _Nm80211APSec_name[208:232],
|
||||
1024: _Nm80211APSec_name[232:254],
|
||||
2048: _Nm80211APSec_name[254:276],
|
||||
4096: _Nm80211APSec_name[276:300],
|
||||
}
|
||||
|
||||
func (i Nm80211APSec) String() string {
|
||||
if str, ok := _Nm80211APSec_map[i]; ok {
|
||||
return str
|
||||
}
|
||||
return "Nm80211APSec(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Code generated by "stringer -type=Nm80211Mode"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[Nm80211ModeUnknown-0]
|
||||
_ = x[Nm80211ModeAdhoc-1]
|
||||
_ = x[Nm80211ModeInfra-2]
|
||||
_ = x[Nm80211ModeAp-3]
|
||||
}
|
||||
|
||||
const _Nm80211Mode_name = "Nm80211ModeUnknownNm80211ModeAdhocNm80211ModeInfraNm80211ModeAp"
|
||||
|
||||
var _Nm80211Mode_index = [...]uint8{0, 18, 34, 50, 63}
|
||||
|
||||
func (i Nm80211Mode) String() string {
|
||||
if i >= Nm80211Mode(len(_Nm80211Mode_index)-1) {
|
||||
return "Nm80211Mode(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _Nm80211Mode_name[_Nm80211Mode_index[i]:_Nm80211Mode_index[i+1]]
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// Code generated by "stringer -type=NmActivationStateFlag"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmActivationStateFlagNone-0]
|
||||
_ = x[NmActivationStateFlagIsMaster-1]
|
||||
_ = x[NmActivationStateFlagIsSlave-2]
|
||||
_ = x[NmActivationStateFlagLayer2Ready-4]
|
||||
_ = x[NmActivationStateFlagIp4Ready-8]
|
||||
_ = x[NmActivationStateFlagIp6Ready-16]
|
||||
_ = x[NmActivationStateFlagMasterHasSlaves-32]
|
||||
_ = x[NmActivationStateFlagLifetimeBoundToProfileVisibility-64]
|
||||
}
|
||||
|
||||
const (
|
||||
_NmActivationStateFlag_name_0 = "NmActivationStateFlagNoneNmActivationStateFlagIsMasterNmActivationStateFlagIsSlave"
|
||||
_NmActivationStateFlag_name_1 = "NmActivationStateFlagLayer2Ready"
|
||||
_NmActivationStateFlag_name_2 = "NmActivationStateFlagIp4Ready"
|
||||
_NmActivationStateFlag_name_3 = "NmActivationStateFlagIp6Ready"
|
||||
_NmActivationStateFlag_name_4 = "NmActivationStateFlagMasterHasSlaves"
|
||||
_NmActivationStateFlag_name_5 = "NmActivationStateFlagLifetimeBoundToProfileVisibility"
|
||||
)
|
||||
|
||||
var (
|
||||
_NmActivationStateFlag_index_0 = [...]uint8{0, 25, 54, 82}
|
||||
)
|
||||
|
||||
func (i NmActivationStateFlag) String() string {
|
||||
switch {
|
||||
case 0 <= i && i <= 2:
|
||||
return _NmActivationStateFlag_name_0[_NmActivationStateFlag_index_0[i]:_NmActivationStateFlag_index_0[i+1]]
|
||||
case i == 4:
|
||||
return _NmActivationStateFlag_name_1
|
||||
case i == 8:
|
||||
return _NmActivationStateFlag_name_2
|
||||
case i == 16:
|
||||
return _NmActivationStateFlag_name_3
|
||||
case i == 32:
|
||||
return _NmActivationStateFlag_name_4
|
||||
case i == 64:
|
||||
return _NmActivationStateFlag_name_5
|
||||
default:
|
||||
return "NmActivationStateFlag(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type=NmActiveConnectionState"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmActiveConnectionStateUnknown-0]
|
||||
_ = x[NmActiveConnectionStateActivating-1]
|
||||
_ = x[NmActiveConnectionStateActivated-2]
|
||||
_ = x[NmActiveConnectionStateDeactivating-3]
|
||||
_ = x[NmActiveConnectionStateDeactivated-4]
|
||||
}
|
||||
|
||||
const _NmActiveConnectionState_name = "NmActiveConnectionStateUnknownNmActiveConnectionStateActivatingNmActiveConnectionStateActivatedNmActiveConnectionStateDeactivatingNmActiveConnectionStateDeactivated"
|
||||
|
||||
var _NmActiveConnectionState_index = [...]uint8{0, 30, 63, 95, 130, 164}
|
||||
|
||||
func (i NmActiveConnectionState) String() string {
|
||||
if i >= NmActiveConnectionState(len(_NmActiveConnectionState_index)-1) {
|
||||
return "NmActiveConnectionState(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _NmActiveConnectionState_name[_NmActiveConnectionState_index[i]:_NmActiveConnectionState_index[i+1]]
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// Code generated by "stringer -type=NmCapability"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmCapabilityTeam-1]
|
||||
}
|
||||
|
||||
const _NmCapability_name = "NmCapabilityTeam"
|
||||
|
||||
var _NmCapability_index = [...]uint8{0, 16}
|
||||
|
||||
func (i NmCapability) String() string {
|
||||
i -= 1
|
||||
if i >= NmCapability(len(_NmCapability_index)-1) {
|
||||
return "NmCapability(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||
}
|
||||
return _NmCapability_name[_NmCapability_index[i]:_NmCapability_index[i+1]]
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Code generated by "stringer -type=NmCheckpointCreateFlags"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmCheckpointCreateFlagsNone-0]
|
||||
_ = x[NmCheckpointCreateFlagsDestroyAll-1]
|
||||
_ = x[NmCheckpointCreateFlagsDeleteNewConnections-2]
|
||||
_ = x[NmCheckpointCreateFlagsDisconnectNewDevices-4]
|
||||
_ = x[NmCheckpointCreateFlagsAllowOverlapping-8]
|
||||
}
|
||||
|
||||
const (
|
||||
_NmCheckpointCreateFlags_name_0 = "NmCheckpointCreateFlagsNoneNmCheckpointCreateFlagsDestroyAllNmCheckpointCreateFlagsDeleteNewConnections"
|
||||
_NmCheckpointCreateFlags_name_1 = "NmCheckpointCreateFlagsDisconnectNewDevices"
|
||||
_NmCheckpointCreateFlags_name_2 = "NmCheckpointCreateFlagsAllowOverlapping"
|
||||
)
|
||||
|
||||
var (
|
||||
_NmCheckpointCreateFlags_index_0 = [...]uint8{0, 27, 60, 103}
|
||||
)
|
||||
|
||||
func (i NmCheckpointCreateFlags) String() string {
|
||||
switch {
|
||||
case 0 <= i && i <= 2:
|
||||
return _NmCheckpointCreateFlags_name_0[_NmCheckpointCreateFlags_index_0[i]:_NmCheckpointCreateFlags_index_0[i+1]]
|
||||
case i == 4:
|
||||
return _NmCheckpointCreateFlags_name_1
|
||||
case i == 8:
|
||||
return _NmCheckpointCreateFlags_name_2
|
||||
default:
|
||||
return "NmCheckpointCreateFlags(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type=NmConnectivity"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmConnectivityUnknown-0]
|
||||
_ = x[NmConnectivityNone-1]
|
||||
_ = x[NmConnectivityPortal-2]
|
||||
_ = x[NmConnectivityLimited-3]
|
||||
_ = x[NmConnectivityFull-4]
|
||||
}
|
||||
|
||||
const _NmConnectivity_name = "NmConnectivityUnknownNmConnectivityNoneNmConnectivityPortalNmConnectivityLimitedNmConnectivityFull"
|
||||
|
||||
var _NmConnectivity_index = [...]uint8{0, 21, 39, 59, 80, 98}
|
||||
|
||||
func (i NmConnectivity) String() string {
|
||||
if i >= NmConnectivity(len(_NmConnectivity_index)-1) {
|
||||
return "NmConnectivity(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _NmConnectivity_name[_NmConnectivity_index[i]:_NmConnectivity_index[i+1]]
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
// Code generated by "stringer -type=NmDeviceState"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmDeviceStateUnknown-0]
|
||||
_ = x[NmDeviceStateUnmanaged-10]
|
||||
_ = x[NmDeviceStateUnavailable-20]
|
||||
_ = x[NmDeviceStateDisconnected-30]
|
||||
_ = x[NmDeviceStatePrepare-40]
|
||||
_ = x[NmDeviceStateConfig-50]
|
||||
_ = x[NmDeviceStateNeedAuth-60]
|
||||
_ = x[NmDeviceStateIpConfig-70]
|
||||
_ = x[NmDeviceStateIpCheck-80]
|
||||
_ = x[NmDeviceStateSecondaries-90]
|
||||
_ = x[NmDeviceStateActivated-100]
|
||||
_ = x[NmDeviceStateDeactivating-110]
|
||||
_ = x[NmDeviceStateFailed-120]
|
||||
}
|
||||
|
||||
const _NmDeviceState_name = "NmDeviceStateUnknownNmDeviceStateUnmanagedNmDeviceStateUnavailableNmDeviceStateDisconnectedNmDeviceStatePrepareNmDeviceStateConfigNmDeviceStateNeedAuthNmDeviceStateIpConfigNmDeviceStateIpCheckNmDeviceStateSecondariesNmDeviceStateActivatedNmDeviceStateDeactivatingNmDeviceStateFailed"
|
||||
|
||||
var _NmDeviceState_map = map[NmDeviceState]string{
|
||||
0: _NmDeviceState_name[0:20],
|
||||
10: _NmDeviceState_name[20:42],
|
||||
20: _NmDeviceState_name[42:66],
|
||||
30: _NmDeviceState_name[66:91],
|
||||
40: _NmDeviceState_name[91:111],
|
||||
50: _NmDeviceState_name[111:130],
|
||||
60: _NmDeviceState_name[130:151],
|
||||
70: _NmDeviceState_name[151:172],
|
||||
80: _NmDeviceState_name[172:192],
|
||||
90: _NmDeviceState_name[192:216],
|
||||
100: _NmDeviceState_name[216:238],
|
||||
110: _NmDeviceState_name[238:263],
|
||||
120: _NmDeviceState_name[263:282],
|
||||
}
|
||||
|
||||
func (i NmDeviceState) String() string {
|
||||
if str, ok := _NmDeviceState_map[i]; ok {
|
||||
return str
|
||||
}
|
||||
return "NmDeviceState(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Code generated by "stringer -type=NmDeviceType"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmDeviceTypeUnknown-0]
|
||||
_ = x[NmDeviceTypeGeneric-14]
|
||||
_ = x[NmDeviceTypeEthernet-1]
|
||||
_ = x[NmDeviceTypeWifi-2]
|
||||
_ = x[NmDeviceTypeUnused1-3]
|
||||
_ = x[NmDeviceTypeUnused2-4]
|
||||
_ = x[NmDeviceTypeBt-5]
|
||||
_ = x[NmDeviceTypeOlpcMesh-6]
|
||||
_ = x[NmDeviceTypeWimax-7]
|
||||
_ = x[NmDeviceTypeModem-8]
|
||||
_ = x[NmDeviceTypeInfiniband-9]
|
||||
_ = x[NmDeviceTypeBond-10]
|
||||
_ = x[NmDeviceTypeVlan-11]
|
||||
_ = x[NmDeviceTypeAdsl-12]
|
||||
_ = x[NmDeviceTypeBridge-13]
|
||||
_ = x[NmDeviceTypeTeam-15]
|
||||
_ = x[NmDeviceTypeTun-16]
|
||||
_ = x[NmDeviceTypeIpTunnel-17]
|
||||
_ = x[NmDeviceTypeMacvlan-18]
|
||||
_ = x[NmDeviceTypeVxlan-19]
|
||||
_ = x[NmDeviceTypeVeth-20]
|
||||
_ = x[NmDeviceTypeMacsec-21]
|
||||
_ = x[NmDeviceTypeDummy-22]
|
||||
_ = x[NmDeviceTypePpp-23]
|
||||
_ = x[NmDeviceTypeOvsInterface-24]
|
||||
_ = x[NmDeviceTypeOvsPort-25]
|
||||
_ = x[NmDeviceTypeOvsBridge-26]
|
||||
_ = x[NmDeviceTypeWpan-27]
|
||||
_ = x[NmDeviceType6lowpan-28]
|
||||
_ = x[NmDeviceTypeWireguard-29]
|
||||
_ = x[NmDeviceTypeWifiP2p-30]
|
||||
}
|
||||
|
||||
const _NmDeviceType_name = "NmDeviceTypeUnknownNmDeviceTypeEthernetNmDeviceTypeWifiNmDeviceTypeUnused1NmDeviceTypeUnused2NmDeviceTypeBtNmDeviceTypeOlpcMeshNmDeviceTypeWimaxNmDeviceTypeModemNmDeviceTypeInfinibandNmDeviceTypeBondNmDeviceTypeVlanNmDeviceTypeAdslNmDeviceTypeBridgeNmDeviceTypeGenericNmDeviceTypeTeamNmDeviceTypeTunNmDeviceTypeIpTunnelNmDeviceTypeMacvlanNmDeviceTypeVxlanNmDeviceTypeVethNmDeviceTypeMacsecNmDeviceTypeDummyNmDeviceTypePppNmDeviceTypeOvsInterfaceNmDeviceTypeOvsPortNmDeviceTypeOvsBridgeNmDeviceTypeWpanNmDeviceType6lowpanNmDeviceTypeWireguardNmDeviceTypeWifiP2p"
|
||||
|
||||
var _NmDeviceType_index = [...]uint16{0, 19, 39, 55, 74, 93, 107, 127, 144, 161, 183, 199, 215, 231, 249, 268, 284, 299, 319, 338, 355, 371, 389, 406, 421, 445, 464, 485, 501, 520, 541, 560}
|
||||
|
||||
func (i NmDeviceType) String() string {
|
||||
if i >= NmDeviceType(len(_NmDeviceType_index)-1) {
|
||||
return "NmDeviceType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _NmDeviceType_name[_NmDeviceType_index[i]:_NmDeviceType_index[i+1]]
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Code generated by "stringer -type=NmMetered"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmMeteredUnknown-0]
|
||||
_ = x[NmMeteredYes-1]
|
||||
_ = x[NmMeteredNo-2]
|
||||
_ = x[NmMeteredGuessYes-3]
|
||||
_ = x[NmMeteredGuessNo-4]
|
||||
}
|
||||
|
||||
const _NmMetered_name = "NmMeteredUnknownNmMeteredYesNmMeteredNoNmMeteredGuessYesNmMeteredGuessNo"
|
||||
|
||||
var _NmMetered_index = [...]uint8{0, 16, 28, 39, 56, 72}
|
||||
|
||||
func (i NmMetered) String() string {
|
||||
if i >= NmMetered(len(_NmMetered_index)-1) {
|
||||
return "NmMetered(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _NmMetered_name[_NmMetered_index[i]:_NmMetered_index[i+1]]
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// Code generated by "stringer -type=NmState"; DO NOT EDIT.
|
||||
|
||||
package gonetworkmanager
|
||||
|
||||
import "strconv"
|
||||
|
||||
func _() {
|
||||
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||
// Re-run the stringer command to generate them again.
|
||||
var x [1]struct{}
|
||||
_ = x[NmStateUnknown-0]
|
||||
_ = x[NmStateAsleep-10]
|
||||
_ = x[NmStateDisconnected-20]
|
||||
_ = x[NmStateDisconnecting-30]
|
||||
_ = x[NmStateConnecting-40]
|
||||
_ = x[NmStateConnectedLocal-50]
|
||||
_ = x[NmStateConnectedSite-60]
|
||||
_ = x[NmStateConnectedGlobal-70]
|
||||
}
|
||||
|
||||
const (
|
||||
_NmState_name_0 = "NmStateUnknown"
|
||||
_NmState_name_1 = "NmStateAsleep"
|
||||
_NmState_name_2 = "NmStateDisconnected"
|
||||
_NmState_name_3 = "NmStateDisconnecting"
|
||||
_NmState_name_4 = "NmStateConnecting"
|
||||
_NmState_name_5 = "NmStateConnectedLocal"
|
||||
_NmState_name_6 = "NmStateConnectedSite"
|
||||
_NmState_name_7 = "NmStateConnectedGlobal"
|
||||
)
|
||||
|
||||
func (i NmState) String() string {
|
||||
switch {
|
||||
case i == 0:
|
||||
return _NmState_name_0
|
||||
case i == 10:
|
||||
return _NmState_name_1
|
||||
case i == 20:
|
||||
return _NmState_name_2
|
||||
case i == 30:
|
||||
return _NmState_name_3
|
||||
case i == 40:
|
||||
return _NmState_name_4
|
||||
case i == 50:
|
||||
return _NmState_name_5
|
||||
case i == 60:
|
||||
return _NmState_name_6
|
||||
case i == 70:
|
||||
return _NmState_name_7
|
||||
default:
|
||||
return "NmState(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
}
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
package gonetworkmanager
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
dbusMethodAddMatch = "org.freedesktop.DBus.AddMatch"
|
||||
)
|
||||
|
||||
type dbusBase struct {
|
||||
conn *dbus.Conn
|
||||
obj dbus.BusObject
|
||||
}
|
||||
|
||||
func (d *dbusBase) init(iface string, objectPath dbus.ObjectPath) error {
|
||||
var err error
|
||||
|
||||
d.conn, err = dbus.SystemBus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.obj = d.conn.Object(iface, objectPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dbusBase) call(method string, args ...interface{}) error {
|
||||
return d.obj.Call(method, 0, args...).Err
|
||||
}
|
||||
|
||||
func (d *dbusBase) callWithReturn(ret interface{}, method string, args ...interface{}) error {
|
||||
return d.obj.Call(method, 0, args...).Store(ret)
|
||||
}
|
||||
|
||||
func (d *dbusBase) callWithReturn2(ret1 interface{}, ret2 interface{}, method string, args ...interface{}) error {
|
||||
return d.obj.Call(method, 0, args...).Store(ret1, ret2)
|
||||
}
|
||||
|
||||
func (d *dbusBase) subscribe(iface, member string) {
|
||||
rule := fmt.Sprintf("type='signal',interface='%s',path='%s',member='%s'",
|
||||
iface, d.obj.Path(), NetworkManagerInterface)
|
||||
d.conn.BusObject().Call(dbusMethodAddMatch, 0, rule)
|
||||
}
|
||||
|
||||
func (d *dbusBase) subscribeNamespace(namespace string) {
|
||||
rule := fmt.Sprintf("type='signal',path_namespace='%s'", namespace)
|
||||
d.conn.BusObject().Call(dbusMethodAddMatch, 0, rule)
|
||||
}
|
||||
|
||||
func (d *dbusBase) getProperty(iface string) (interface{}, error) {
|
||||
variant, err := d.obj.GetProperty(iface)
|
||||
return variant.Value(), err
|
||||
}
|
||||
|
||||
func (d *dbusBase) setProperty(iface string, value interface{}) error {
|
||||
err := d.obj.SetProperty(iface, dbus.MakeVariant(value))
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *dbusBase) getObjectProperty(iface string) (value dbus.ObjectPath, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(dbus.ObjectPath)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceObjectProperty(iface string) (value []dbus.ObjectPath, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([]dbus.ObjectPath)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getBoolProperty(iface string) (value bool, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(bool)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getStringProperty(iface string) (value string, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(string)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceStringProperty(iface string) (value []string, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([]string)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceSliceByteProperty(iface string) (value [][]byte, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([][]byte)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getMapStringVariantProperty(iface string) (value map[string]dbus.Variant, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(map[string]dbus.Variant)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getUint8Property(iface string) (value uint8, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(uint8)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getUint32Property(iface string) (value uint32, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(uint32)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getInt32Property(iface string) (value int32, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(int32)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getInt64Property(iface string) (value int64, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(int64)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getUint64Property(iface string) (value uint64, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.(uint64)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceUint32Property(iface string) (value []uint32, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([]uint32)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceSliceUint32Property(iface string) (value [][]uint32, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([][]uint32)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceMapStringVariantProperty(iface string) (value []map[string]dbus.Variant, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([]map[string]dbus.Variant)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbusBase) getSliceByteProperty(iface string) (value []byte, err error) {
|
||||
prop, err := d.getProperty(iface)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
value, ok := prop.([]byte)
|
||||
if !ok {
|
||||
err = makeErrVariantType(iface)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func makeErrVariantType(iface string) error {
|
||||
return fmt.Errorf("unexpected variant type for '%s'", iface)
|
||||
}
|
||||
|
||||
func ip4ToString(ip uint32) string {
|
||||
bs := []byte{0, 0, 0, 0}
|
||||
binary.LittleEndian.PutUint32(bs, ip)
|
||||
return net.IP(bs).String()
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06))
|
||||
* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6))
|
||||
|
||||
## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29))
|
||||
|
||||
## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4))
|
||||
|
||||
### Fixes
|
||||
|
||||
* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior)
|
||||
|
||||
## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0))
|
||||
|
||||
## Changelog
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
We definitely welcome patches and contribution to this project!
|
||||
|
||||
### Tips
|
||||
|
||||
Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org).
|
||||
|
||||
Always try to include a test case! If it is not possible or not necessary,
|
||||
please explain why in the pull request description.
|
||||
|
||||
### Releasing
|
||||
|
||||
Commits that would precipitate a SemVer change, as described in the Conventional
|
||||
Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action)
|
||||
to create a release candidate pull request. Once submitted, `release-please`
|
||||
will create a release.
|
||||
|
||||
For tips on how to work with `release-please`, see its documentation.
|
||||
|
||||
### Legal requirements
|
||||
|
||||
In order to protect both you and ourselves, you will need to sign the
|
||||
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
||||
|
||||
You may have already signed it for other Google projects.
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
Paul Borman <borman@google.com>
|
||||
bmatsuo
|
||||
shawnps
|
||||
theory
|
||||
jboverfelt
|
||||
dsymonds
|
||||
cd1
|
||||
wallclockbuilder
|
||||
dansouza
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2009,2014 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
# uuid
|
||||
The uuid package generates and inspects UUIDs based on
|
||||
[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122)
|
||||
and DCE 1.1: Authentication and Security Services.
|
||||
|
||||
This package is based on the github.com/pborman/uuid package (previously named
|
||||
code.google.com/p/go-uuid). It differs from these earlier packages in that
|
||||
a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
||||
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
||||
|
||||
###### Install
|
||||
```sh
|
||||
go get github.com/google/uuid
|
||||
```
|
||||
|
||||
###### Documentation
|
||||
[](https://pkg.go.dev/github.com/google/uuid)
|
||||
|
||||
Full `go doc` style documentation for the package can be viewed online without
|
||||
installing this package by using the GoDoc site here:
|
||||
http://pkg.go.dev/github.com/google/uuid
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A Domain represents a Version 2 domain
|
||||
type Domain byte
|
||||
|
||||
// Domain constants for DCE Security (Version 2) UUIDs.
|
||||
const (
|
||||
Person = Domain(0)
|
||||
Group = Domain(1)
|
||||
Org = Domain(2)
|
||||
)
|
||||
|
||||
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
||||
//
|
||||
// The domain should be one of Person, Group or Org.
|
||||
// On a POSIX system the id should be the users UID for the Person
|
||||
// domain and the users GID for the Group. The meaning of id for
|
||||
// the domain Org or on non-POSIX systems is site defined.
|
||||
//
|
||||
// For a given domain/id pair the same token may be returned for up to
|
||||
// 7 minutes and 10 seconds.
|
||||
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||
uuid, err := NewUUID()
|
||||
if err == nil {
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
||||
uuid[9] = byte(domain)
|
||||
binary.BigEndian.PutUint32(uuid[0:], id)
|
||||
}
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||
// domain with the id returned by os.Getuid.
|
||||
//
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
func NewDCEPerson() (UUID, error) {
|
||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
}
|
||||
|
||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||
// domain with the id returned by os.Getgid.
|
||||
//
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
func NewDCEGroup() (UUID, error) {
|
||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
}
|
||||
|
||||
// Domain returns the domain for a Version 2 UUID. Domains are only defined
|
||||
// for Version 2 UUIDs.
|
||||
func (uuid UUID) Domain() Domain {
|
||||
return Domain(uuid[9])
|
||||
}
|
||||
|
||||
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
|
||||
// UUIDs.
|
||||
func (uuid UUID) ID() uint32 {
|
||||
return binary.BigEndian.Uint32(uuid[0:4])
|
||||
}
|
||||
|
||||
func (d Domain) String() string {
|
||||
switch d {
|
||||
case Person:
|
||||
return "Person"
|
||||
case Group:
|
||||
return "Group"
|
||||
case Org:
|
||||
return "Org"
|
||||
}
|
||||
return fmt.Sprintf("Domain%d", int(d))
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package uuid generates and inspects UUIDs.
|
||||
//
|
||||
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
|
||||
// Services.
|
||||
//
|
||||
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
|
||||
// maps or compared directly.
|
||||
package uuid
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Well known namespace IDs and UUIDs
|
||||
var (
|
||||
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
||||
Nil UUID // empty UUID, all zeros
|
||||
|
||||
// The Max UUID is special form of UUID that is specified to have all 128 bits set to 1.
|
||||
Max = UUID{
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
}
|
||||
)
|
||||
|
||||
// NewHash returns a new UUID derived from the hash of space concatenated with
|
||||
// data generated by h. The hash should be at least 16 byte in length. The
|
||||
// first 16 bytes of the hash are used to form the UUID. The version of the
|
||||
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
||||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:]) //nolint:errcheck
|
||||
h.Write(data) //nolint:errcheck
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
||||
return uuid
|
||||
}
|
||||
|
||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(md5.New(), space, data, 3)
|
||||
func NewMD5(space UUID, data []byte) UUID {
|
||||
return NewHash(md5.New(), space, data, 3)
|
||||
}
|
||||
|
||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(sha1.New(), space, data, 5)
|
||||
func NewSHA1(space UUID, data []byte) UUID {
|
||||
return NewHash(sha1.New(), space, data, 5)
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "fmt"
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (uuid UUID) MarshalText() ([]byte, error) {
|
||||
var js [36]byte
|
||||
encodeHex(js[:], uuid)
|
||||
return js[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalText(data []byte) error {
|
||||
id, err := ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*uuid = id
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (uuid UUID) MarshalBinary() ([]byte, error) {
|
||||
return uuid[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != 16 {
|
||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||
}
|
||||
copy(uuid[:], data)
|
||||
return nil
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeMu sync.Mutex
|
||||
ifname string // name of interface being used
|
||||
nodeID [6]byte // hardware for version 1 UUIDs
|
||||
zeroID [6]byte // nodeID with only 0's
|
||||
)
|
||||
|
||||
// NodeInterface returns the name of the interface from which the NodeID was
|
||||
// derived. The interface "user" is returned if the NodeID was set by
|
||||
// SetNodeID.
|
||||
func NodeInterface() string {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return ifname
|
||||
}
|
||||
|
||||
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
||||
// If name is "" then the first usable interface found will be used or a random
|
||||
// Node ID will be generated. If a named interface cannot be found then false
|
||||
// is returned.
|
||||
//
|
||||
// SetNodeInterface never fails when name is "".
|
||||
func SetNodeInterface(name string) bool {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return setNodeInterface(name)
|
||||
}
|
||||
|
||||
func setNodeInterface(name string) bool {
|
||||
iname, addr := getHardwareInterface(name) // null implementation for js
|
||||
if iname != "" && addr != nil {
|
||||
ifname = iname
|
||||
copy(nodeID[:], addr)
|
||||
return true
|
||||
}
|
||||
|
||||
// We found no interfaces with a valid hardware address. If name
|
||||
// does not specify a specific interface generate a random Node ID
|
||||
// (section 4.1.6)
|
||||
if name == "" {
|
||||
ifname = "random"
|
||||
randomBits(nodeID[:])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
||||
// if not already set.
|
||||
func NodeID() []byte {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
nid := nodeID
|
||||
return nid[:]
|
||||
}
|
||||
|
||||
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
||||
// of id are used. If id is less than 6 bytes then false is returned and the
|
||||
// Node ID is not set.
|
||||
func SetNodeID(id []byte) bool {
|
||||
if len(id) < 6 {
|
||||
return false
|
||||
}
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
copy(nodeID[:], id)
|
||||
ifname = "user"
|
||||
return true
|
||||
}
|
||||
|
||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) NodeID() []byte {
|
||||
var node [6]byte
|
||||
copy(node[:], uuid[10:])
|
||||
return node[:]
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build js
|
||||
|
||||
package uuid
|
||||
|
||||
// getHardwareInterface returns nil values for the JS version of the code.
|
||||
// This removes the "net" dependency, because it is not used in the browser.
|
||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !js
|
||||
|
||||
package uuid
|
||||
|
||||
import "net"
|
||||
|
||||
var interfaces []net.Interface // cached list of interfaces
|
||||
|
||||
// getHardwareInterface returns the name and hardware address of interface name.
|
||||
// If name is "" then the name and hardware address of one of the system's
|
||||
// interfaces is returned. If no interfaces are found (name does not exist or
|
||||
// there are no interfaces) then "", nil is returned.
|
||||
//
|
||||
// Only addresses of at least 6 bytes are returned.
|
||||
func getHardwareInterface(name string) (string, []byte) {
|
||||
if interfaces == nil {
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
for _, ifs := range interfaces {
|
||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||
return ifs.Name, ifs.HardwareAddr
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
// Copyright 2021 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var jsonNull = []byte("null")
|
||||
|
||||
// NullUUID represents a UUID that may be null.
|
||||
// NullUUID implements the SQL driver.Scanner interface so
|
||||
// it can be used as a scan destination:
|
||||
//
|
||||
// var u uuid.NullUUID
|
||||
// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u)
|
||||
// ...
|
||||
// if u.Valid {
|
||||
// // use u.UUID
|
||||
// } else {
|
||||
// // NULL value
|
||||
// }
|
||||
//
|
||||
type NullUUID struct {
|
||||
UUID UUID
|
||||
Valid bool // Valid is true if UUID is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the SQL driver.Scanner interface.
|
||||
func (nu *NullUUID) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
nu.UUID, nu.Valid = Nil, false
|
||||
return nil
|
||||
}
|
||||
|
||||
err := nu.UUID.Scan(value)
|
||||
if err != nil {
|
||||
nu.Valid = false
|
||||
return err
|
||||
}
|
||||
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (nu NullUUID) Value() (driver.Value, error) {
|
||||
if !nu.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
// Delegate to UUID Value function
|
||||
return nu.UUID.Value()
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (nu NullUUID) MarshalBinary() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return nu.UUID[:], nil
|
||||
}
|
||||
|
||||
return []byte(nil), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (nu *NullUUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != 16 {
|
||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||
}
|
||||
copy(nu.UUID[:], data)
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (nu NullUUID) MarshalText() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return nu.UUID.MarshalText()
|
||||
}
|
||||
|
||||
return jsonNull, nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (nu *NullUUID) UnmarshalText(data []byte) error {
|
||||
id, err := ParseBytes(data)
|
||||
if err != nil {
|
||||
nu.Valid = false
|
||||
return err
|
||||
}
|
||||
nu.UUID = id
|
||||
nu.Valid = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (nu NullUUID) MarshalJSON() ([]byte, error) {
|
||||
if nu.Valid {
|
||||
return json.Marshal(nu.UUID)
|
||||
}
|
||||
|
||||
return jsonNull, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (nu *NullUUID) UnmarshalJSON(data []byte) error {
|
||||
if bytes.Equal(data, jsonNull) {
|
||||
*nu = NullUUID{}
|
||||
return nil // valid null UUID
|
||||
}
|
||||
err := json.Unmarshal(data, &nu.UUID)
|
||||
nu.Valid = err == nil
|
||||
return err
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently.
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
switch src := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
|
||||
case string:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if src == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// see Parse for required string format
|
||||
u, err := Parse(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Scan: %v", err)
|
||||
}
|
||||
|
||||
*uuid = u
|
||||
|
||||
case []byte:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// assumes a simple slice of bytes if 16 bytes
|
||||
// otherwise attempts to parse
|
||||
if len(src) != 16 {
|
||||
return uuid.Scan(string(src))
|
||||
}
|
||||
copy((*uuid)[:], src)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements sql.Valuer so that UUIDs can be written to databases
|
||||
// transparently. Currently, UUIDs map to strings. Please consult
|
||||
// database-specific driver documentation for matching types.
|
||||
func (uuid UUID) Value() (driver.Value, error) {
|
||||
return uuid.String(), nil
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
||||
// 1582.
|
||||
type Time int64
|
||||
|
||||
const (
|
||||
lillian = 2299160 // Julian day of 15 Oct 1582
|
||||
unix = 2440587 // Julian day of 1 Jan 1970
|
||||
epoch = unix - lillian // Days between epochs
|
||||
g1582 = epoch * 86400 // seconds between epochs
|
||||
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
||||
)
|
||||
|
||||
var (
|
||||
timeMu sync.Mutex
|
||||
lasttime uint64 // last time we returned
|
||||
clockSeq uint16 // clock sequence for this run
|
||||
|
||||
timeNow = time.Now // for testing
|
||||
)
|
||||
|
||||
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
||||
// epoch of 1 Jan 1970.
|
||||
func (t Time) UnixTime() (sec, nsec int64) {
|
||||
sec = int64(t - g1582ns100)
|
||||
nsec = (sec % 10000000) * 100
|
||||
sec /= 10000000
|
||||
return sec, nsec
|
||||
}
|
||||
|
||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
||||
// is returned if the current time cannot be determined.
|
||||
func GetTime() (Time, uint16, error) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return getTime()
|
||||
}
|
||||
|
||||
func getTime() (Time, uint16, error) {
|
||||
t := timeNow()
|
||||
|
||||
// If we don't have a clock sequence already, set one.
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
now := uint64(t.UnixNano()/100) + g1582ns100
|
||||
|
||||
// If time has gone backwards with this clock sequence then we
|
||||
// increment the clock sequence
|
||||
if now <= lasttime {
|
||||
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
|
||||
}
|
||||
lasttime = now
|
||||
return Time(now), clockSeq, nil
|
||||
}
|
||||
|
||||
// ClockSequence returns the current clock sequence, generating one if not
|
||||
// already set. The clock sequence is only used for Version 1 UUIDs.
|
||||
//
|
||||
// The uuid package does not use global static storage for the clock sequence or
|
||||
// the last time a UUID was generated. Unless SetClockSequence is used, a new
|
||||
// random clock sequence is generated the first time a clock sequence is
|
||||
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
|
||||
func ClockSequence() int {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return clockSequence()
|
||||
}
|
||||
|
||||
func clockSequence() int {
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
return int(clockSeq & 0x3fff)
|
||||
}
|
||||
|
||||
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||
// -1 causes a new sequence to be generated.
|
||||
func SetClockSequence(seq int) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
setClockSequence(seq)
|
||||
}
|
||||
|
||||
func setClockSequence(seq int) {
|
||||
if seq == -1 {
|
||||
var b [2]byte
|
||||
randomBits(b[:]) // clock sequence
|
||||
seq = int(b[0])<<8 | int(b[1])
|
||||
}
|
||||
oldSeq := clockSeq
|
||||
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
||||
if oldSeq != clockSeq {
|
||||
lasttime = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
||||
// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs.
|
||||
func (uuid UUID) Time() Time {
|
||||
var t Time
|
||||
switch uuid.Version() {
|
||||
case 6:
|
||||
time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110
|
||||
t = Time(time)
|
||||
case 7:
|
||||
time := binary.BigEndian.Uint64(uuid[:8])
|
||||
t = Time((time>>16)*10000 + g1582ns100)
|
||||
default: // forward compatible
|
||||
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
||||
t = Time(time)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// ClockSequence returns the clock sequence encoded in uuid.
|
||||
// The clock sequence is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) ClockSequence() int {
|
||||
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
|
||||
}
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// randomBits completely fills slice b with random data.
|
||||
func randomBits(b []byte) {
|
||||
if _, err := io.ReadFull(rander, b); err != nil {
|
||||
panic(err.Error()) // rand should never fail
|
||||
}
|
||||
}
|
||||
|
||||
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
||||
var xvalues = [256]byte{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
}
|
||||
|
||||
// xtob converts hex characters x1 and x2 into a byte.
|
||||
func xtob(x1, x2 byte) (byte, bool) {
|
||||
b1 := xvalues[x1]
|
||||
b2 := xvalues[x2]
|
||||
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
||||
}
|
||||
-365
@@ -1,365 +0,0 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
||||
// 4122.
|
||||
type UUID [16]byte
|
||||
|
||||
// A Version represents a UUID's version.
|
||||
type Version byte
|
||||
|
||||
// A Variant represents a UUID's variant.
|
||||
type Variant byte
|
||||
|
||||
// Constants returned by Variant.
|
||||
const (
|
||||
Invalid = Variant(iota) // Invalid UUID
|
||||
RFC4122 // The variant specified in RFC4122
|
||||
Reserved // Reserved, NCS backward compatibility.
|
||||
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
||||
Future // Reserved for future definition.
|
||||
)
|
||||
|
||||
const randPoolSize = 16 * 16
|
||||
|
||||
var (
|
||||
rander = rand.Reader // random function
|
||||
poolEnabled = false
|
||||
poolMu sync.Mutex
|
||||
poolPos = randPoolSize // protected with poolMu
|
||||
pool [randPoolSize]byte // protected with poolMu
|
||||
)
|
||||
|
||||
type invalidLengthError struct{ len int }
|
||||
|
||||
func (err invalidLengthError) Error() string {
|
||||
return fmt.Sprintf("invalid UUID length: %d", err.len)
|
||||
}
|
||||
|
||||
// IsInvalidLengthError is matcher function for custom error invalidLengthError
|
||||
func IsInvalidLengthError(err error) bool {
|
||||
_, ok := err.(invalidLengthError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both
|
||||
// the standard UUID forms defined in RFC 4122
|
||||
// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition,
|
||||
// Parse accepts non-standard strings such as the raw hex encoding
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings,
|
||||
// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are
|
||||
// examined in the latter case. Parse should not be used to validate strings as
|
||||
// it parses non-standard encodings as indicated above.
|
||||
func Parse(s string) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(s) {
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36:
|
||||
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9:
|
||||
if !strings.EqualFold(s[:9], "urn:uuid:") {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
case 36 + 2:
|
||||
s = s[1:]
|
||||
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
case 32:
|
||||
var ok bool
|
||||
for i := range uuid {
|
||||
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, invalidLengthError{len(s)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v, ok := xtob(s[x], s[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
||||
func ParseBytes(b []byte) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(b) {
|
||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
b = b[1:]
|
||||
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
var ok bool
|
||||
for i := 0; i < 32; i += 2 {
|
||||
uuid[i/2], ok = xtob(b[i], b[i+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, invalidLengthError{len(b)}
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34,
|
||||
} {
|
||||
v, ok := xtob(b[x], b[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// MustParse is like Parse but panics if the string cannot be parsed.
|
||||
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
||||
func MustParse(s string) UUID {
|
||||
uuid, err := Parse(s)
|
||||
if err != nil {
|
||||
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
||||
// does not have a length of 16. The bytes are copied from the slice.
|
||||
func FromBytes(b []byte) (uuid UUID, err error) {
|
||||
err = uuid.UnmarshalBinary(b)
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// Must returns uuid if err is nil and panics otherwise.
|
||||
func Must(uuid UUID, err error) UUID {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// Validate returns an error if s is not a properly formatted UUID in one of the following formats:
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
// It returns an error if the format is invalid, otherwise nil.
|
||||
func Validate(s string) error {
|
||||
switch len(s) {
|
||||
// Standard UUID format
|
||||
case 36:
|
||||
|
||||
// UUID with "urn:uuid:" prefix
|
||||
case 36 + 9:
|
||||
if !strings.EqualFold(s[:9], "urn:uuid:") {
|
||||
return fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// UUID enclosed in braces
|
||||
case 36 + 2:
|
||||
if s[0] != '{' || s[len(s)-1] != '}' {
|
||||
return fmt.Errorf("invalid bracketed UUID format")
|
||||
}
|
||||
s = s[1 : len(s)-1]
|
||||
|
||||
// UUID without hyphens
|
||||
case 32:
|
||||
for i := 0; i < len(s); i += 2 {
|
||||
_, ok := xtob(s[i], s[i+1])
|
||||
if !ok {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return invalidLengthError{len(s)}
|
||||
}
|
||||
|
||||
// Check for standard UUID format
|
||||
if len(s) == 36 {
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} {
|
||||
if _, ok := xtob(s[x], s[x+1]); !ok {
|
||||
return errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// , or "" if uuid is invalid.
|
||||
func (uuid UUID) String() string {
|
||||
var buf [36]byte
|
||||
encodeHex(buf[:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
// URN returns the RFC 2141 URN form of uuid,
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
||||
func (uuid UUID) URN() string {
|
||||
var buf [36 + 9]byte
|
||||
copy(buf[:], "urn:uuid:")
|
||||
encodeHex(buf[9:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
func encodeHex(dst []byte, uuid UUID) {
|
||||
hex.Encode(dst, uuid[:4])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:13], uuid[4:6])
|
||||
dst[13] = '-'
|
||||
hex.Encode(dst[14:18], uuid[6:8])
|
||||
dst[18] = '-'
|
||||
hex.Encode(dst[19:23], uuid[8:10])
|
||||
dst[23] = '-'
|
||||
hex.Encode(dst[24:], uuid[10:])
|
||||
}
|
||||
|
||||
// Variant returns the variant encoded in uuid.
|
||||
func (uuid UUID) Variant() Variant {
|
||||
switch {
|
||||
case (uuid[8] & 0xc0) == 0x80:
|
||||
return RFC4122
|
||||
case (uuid[8] & 0xe0) == 0xc0:
|
||||
return Microsoft
|
||||
case (uuid[8] & 0xe0) == 0xe0:
|
||||
return Future
|
||||
default:
|
||||
return Reserved
|
||||
}
|
||||
}
|
||||
|
||||
// Version returns the version of uuid.
|
||||
func (uuid UUID) Version() Version {
|
||||
return Version(uuid[6] >> 4)
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
if v > 15 {
|
||||
return fmt.Sprintf("BAD_VERSION_%d", v)
|
||||
}
|
||||
return fmt.Sprintf("VERSION_%d", v)
|
||||
}
|
||||
|
||||
func (v Variant) String() string {
|
||||
switch v {
|
||||
case RFC4122:
|
||||
return "RFC4122"
|
||||
case Reserved:
|
||||
return "Reserved"
|
||||
case Microsoft:
|
||||
return "Microsoft"
|
||||
case Future:
|
||||
return "Future"
|
||||
case Invalid:
|
||||
return "Invalid"
|
||||
}
|
||||
return fmt.Sprintf("BadVariant%d", int(v))
|
||||
}
|
||||
|
||||
// SetRand sets the random number generator to r, which implements io.Reader.
|
||||
// If r.Read returns an error when the package requests random data then
|
||||
// a panic will be issued.
|
||||
//
|
||||
// Calling SetRand with nil sets the random number generator to the default
|
||||
// generator.
|
||||
func SetRand(r io.Reader) {
|
||||
if r == nil {
|
||||
rander = rand.Reader
|
||||
return
|
||||
}
|
||||
rander = r
|
||||
}
|
||||
|
||||
// EnableRandPool enables internal randomness pool used for Random
|
||||
// (Version 4) UUID generation. The pool contains random bytes read from
|
||||
// the random number generator on demand in batches. Enabling the pool
|
||||
// may improve the UUID generation throughput significantly.
|
||||
//
|
||||
// Since the pool is stored on the Go heap, this feature may be a bad fit
|
||||
// for security sensitive applications.
|
||||
//
|
||||
// Both EnableRandPool and DisableRandPool are not thread-safe and should
|
||||
// only be called when there is no possibility that New or any other
|
||||
// UUID Version 4 generation function will be called concurrently.
|
||||
func EnableRandPool() {
|
||||
poolEnabled = true
|
||||
}
|
||||
|
||||
// DisableRandPool disables the randomness pool if it was previously
|
||||
// enabled with EnableRandPool.
|
||||
//
|
||||
// Both EnableRandPool and DisableRandPool are not thread-safe and should
|
||||
// only be called when there is no possibility that New or any other
|
||||
// UUID Version 4 generation function will be called concurrently.
|
||||
func DisableRandPool() {
|
||||
poolEnabled = false
|
||||
defer poolMu.Unlock()
|
||||
poolMu.Lock()
|
||||
poolPos = randPoolSize
|
||||
}
|
||||
|
||||
// UUIDs is a slice of UUID types.
|
||||
type UUIDs []UUID
|
||||
|
||||
// Strings returns a string slice containing the string form of each UUID in uuids.
|
||||
func (uuids UUIDs) Strings() []string {
|
||||
var uuidStrs = make([]string, len(uuids))
|
||||
for i, uuid := range uuids {
|
||||
uuidStrs[i] = uuid.String()
|
||||
}
|
||||
return uuidStrs
|
||||
}
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||
// return the current NewUUID returns nil and an error.
|
||||
//
|
||||
// In most cases, New should be used.
|
||||
func NewUUID() (UUID, error) {
|
||||
var uuid UUID
|
||||
now, seq, err := GetTime()
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
timeLow := uint32(now & 0xffffffff)
|
||||
timeMid := uint16((now >> 32) & 0xffff)
|
||||
timeHi := uint16((now >> 48) & 0x0fff)
|
||||
timeHi |= 0x1000 // Version 1
|
||||
|
||||
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
||||
binary.BigEndian.PutUint16(uuid[4:], timeMid)
|
||||
binary.BigEndian.PutUint16(uuid[6:], timeHi)
|
||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
copy(uuid[10:], nodeID[:])
|
||||
nodeMu.Unlock()
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
-76
@@ -1,76 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "io"
|
||||
|
||||
// New creates a new random UUID or panics. New is equivalent to
|
||||
// the expression
|
||||
//
|
||||
// uuid.Must(uuid.NewRandom())
|
||||
func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewString creates a new random UUID and returns it as a string or panics.
|
||||
// NewString is equivalent to the expression
|
||||
//
|
||||
// uuid.New().String()
|
||||
func NewString() string {
|
||||
return Must(NewRandom()).String()
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// Uses the randomness pool if it was enabled with EnableRandPool.
|
||||
//
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||
// year and having one duplicate.
|
||||
func NewRandom() (UUID, error) {
|
||||
if !poolEnabled {
|
||||
return NewRandomFromReader(rander)
|
||||
}
|
||||
return newRandomFromPool()
|
||||
}
|
||||
|
||||
// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.
|
||||
func NewRandomFromReader(r io.Reader) (UUID, error) {
|
||||
var uuid UUID
|
||||
_, err := io.ReadFull(r, uuid[:])
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
func newRandomFromPool() (UUID, error) {
|
||||
var uuid UUID
|
||||
poolMu.Lock()
|
||||
if poolPos == randPoolSize {
|
||||
_, err := io.ReadFull(rander, pool[:])
|
||||
if err != nil {
|
||||
poolMu.Unlock()
|
||||
return Nil, err
|
||||
}
|
||||
poolPos = 0
|
||||
}
|
||||
copy(uuid[:], pool[poolPos:(poolPos+16)])
|
||||
poolPos += 16
|
||||
poolMu.Unlock()
|
||||
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
// Copyright 2023 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality.
|
||||
// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs.
|
||||
// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead.
|
||||
//
|
||||
// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6
|
||||
//
|
||||
// NewV6 returns a Version 6 UUID based on the current NodeID and clock
|
||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||
// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by
|
||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||
// return the current NewV6 returns Nil and an error.
|
||||
func NewV6() (UUID, error) {
|
||||
var uuid UUID
|
||||
now, seq, err := GetTime()
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| time_high |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| time_mid | time_low_and_version |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|clk_seq_hi_res | clk_seq_low | node (0-1) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| node (2-5) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
binary.BigEndian.PutUint64(uuid[0:], uint64(now))
|
||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||
|
||||
uuid[6] = 0x60 | (uuid[6] & 0x0F)
|
||||
uuid[8] = 0x80 | (uuid[8] & 0x3F)
|
||||
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
copy(uuid[10:], nodeID[:])
|
||||
nodeMu.Unlock()
|
||||
|
||||
return uuid, nil
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
// Copyright 2023 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// UUID version 7 features a time-ordered value field derived from the widely
|
||||
// implemented and well known Unix Epoch timestamp source,
|
||||
// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded.
|
||||
// As well as improved entropy characteristics over versions 1 or 6.
|
||||
//
|
||||
// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7
|
||||
//
|
||||
// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible.
|
||||
//
|
||||
// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch).
|
||||
// Uses the randomness pool if it was enabled with EnableRandPool.
|
||||
// On error, NewV7 returns Nil and an error
|
||||
func NewV7() (UUID, error) {
|
||||
uuid, err := NewRandom()
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
makeV7(uuid[:])
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch).
|
||||
// it use NewRandomFromReader fill random bits.
|
||||
// On error, NewV7FromReader returns Nil and an error.
|
||||
func NewV7FromReader(r io.Reader) (UUID, error) {
|
||||
uuid, err := NewRandomFromReader(r)
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
makeV7(uuid[:])
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6])
|
||||
// uuid[8] already has the right version number (Variant is 10)
|
||||
// see function NewV7 and NewV7FromReader
|
||||
func makeV7(uuid []byte) {
|
||||
/*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| unix_ts_ms |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| unix_ts_ms | ver | rand_a (12 bit seq) |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|var| rand_b |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| rand_b |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
_ = uuid[15] // bounds check
|
||||
|
||||
t, s := getV7Time()
|
||||
|
||||
uuid[0] = byte(t >> 40)
|
||||
uuid[1] = byte(t >> 32)
|
||||
uuid[2] = byte(t >> 24)
|
||||
uuid[3] = byte(t >> 16)
|
||||
uuid[4] = byte(t >> 8)
|
||||
uuid[5] = byte(t)
|
||||
|
||||
uuid[6] = 0x70 | (0x0F & byte(s>>8))
|
||||
uuid[7] = byte(s)
|
||||
}
|
||||
|
||||
// lastV7time is the last time we returned stored as:
|
||||
//
|
||||
// 52 bits of time in milliseconds since epoch
|
||||
// 12 bits of (fractional nanoseconds) >> 8
|
||||
var lastV7time int64
|
||||
|
||||
const nanoPerMilli = 1000000
|
||||
|
||||
// getV7Time returns the time in milliseconds and nanoseconds / 256.
|
||||
// The returned (milli << 12 + seq) is guarenteed to be greater than
|
||||
// (milli << 12 + seq) returned by any previous call to getV7Time.
|
||||
func getV7Time() (milli, seq int64) {
|
||||
timeMu.Lock()
|
||||
defer timeMu.Unlock()
|
||||
|
||||
nano := timeNow().UnixNano()
|
||||
milli = nano / nanoPerMilli
|
||||
// Sequence number is between 0 and 3906 (nanoPerMilli>>8)
|
||||
seq = (nano - milli*nanoPerMilli) >> 8
|
||||
now := milli<<12 + seq
|
||||
if now <= lastV7time {
|
||||
now = lastV7time + 1
|
||||
milli = now >> 12
|
||||
seq = now & 0xfff
|
||||
}
|
||||
lastV7time = now
|
||||
return milli, seq
|
||||
}
|
||||
Vendored
+3
-3
@@ -1,3 +1,6 @@
|
||||
# github.com/Wifx/gonetworkmanager/v2 v2.2.0
|
||||
## explicit; go 1.12
|
||||
github.com/Wifx/gonetworkmanager/v2
|
||||
# github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71
|
||||
## explicit; go 1.12
|
||||
github.com/go-gl/gl/v3.3-core/gl
|
||||
@@ -8,9 +11,6 @@ github.com/go-gl/mathgl/mgl32
|
||||
# github.com/godbus/dbus/v5 v5.1.0
|
||||
## explicit; go 1.12
|
||||
github.com/godbus/dbus/v5
|
||||
# github.com/google/uuid v1.6.0
|
||||
## explicit
|
||||
github.com/google/uuid
|
||||
# github.com/jinzhu/inflection v1.0.0
|
||||
## explicit
|
||||
github.com/jinzhu/inflection
|
||||
|
||||
Reference in New Issue
Block a user