Initial commit
This commit is contained in:
commit
0b1065e993
6 changed files with 128 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
mqtt2exec
|
6
Makefile
Normal file
6
Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
all: mqtt2exec
|
||||
.PHONY: mqtt2exec
|
||||
|
||||
mqtt2exec:
|
||||
GOOS=linux GOARCH=arm go build -o mqtt2exec
|
||||
arm-linux-gnueabihf-strip mqtt2exec
|
27
README.md
Normal file
27
README.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Setup
|
||||
|
||||
Root android with magisk
|
||||
|
||||
Install busybox
|
||||
|
||||
Create init script at `/data/adb/service.d/mqtt2exec.sh`
|
||||
|
||||
```shell
|
||||
#!/system/bin/sh
|
||||
/system/xbin/start-stop-daemon -S -b /system/xbin/mqtt2exec -- tcp://ENDPOINT:1883 CLIENT_ID USERNAME PASSWORD
|
||||
exit 0
|
||||
```
|
||||
|
||||
Set it as executable: `chmod +x /data/adb/service.d/mqtt2exec.sh`
|
||||
|
||||
Install binary:
|
||||
|
||||
```shell
|
||||
adb push mqtt2exec /storage/emulated/0/mqtt2exec
|
||||
adb shell
|
||||
su
|
||||
mv /storage/emulated/0/mqtt2exec /system/xbin/mqtt2exec
|
||||
chmod +x /system/xbin/mqtt2exec
|
||||
```
|
||||
|
||||
Reboot :)
|
10
go.mod
Normal file
10
go.mod
Normal file
|
@ -0,0 +1,10 @@
|
|||
module mqtt2exec
|
||||
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
)
|
8
go.sum
Normal file
8
go.sum
Normal file
|
@ -0,0 +1,8 @@
|
|||
github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
|
||||
github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
76
main.go
Normal file
76
main.go
Normal file
|
@ -0,0 +1,76 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
Command string
|
||||
Output string
|
||||
Error string
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
var msgchan = make(chan mqtt.Message, 4)
|
||||
|
||||
if len(os.Args) < 5 {
|
||||
log.Fatalf("Usage: %s <broker> <client_id> <username> <password>", os.Args[0])
|
||||
}
|
||||
opts := mqtt.NewClientOptions()
|
||||
opts.AddBroker(os.Args[1])
|
||||
opts.SetClientID(os.Args[2])
|
||||
opts.SetUsername(os.Args[3])
|
||||
opts.SetPassword(os.Args[4])
|
||||
opts.SetDefaultPublishHandler(func(client mqtt.Client, msg mqtt.Message) {
|
||||
msgchan <- msg
|
||||
})
|
||||
opts.OnConnect = connectHandler
|
||||
opts.SetKeepAlive(20 * time.Second)
|
||||
opts.SetAutoReconnect(true)
|
||||
opts.SetWill("mqtt2exec/"+os.Args[2]+"/state", "offline", 1, false)
|
||||
client := mqtt.NewClient(opts)
|
||||
sleep := 1 * time.Second
|
||||
for {
|
||||
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
||||
log.Printf("Initial connection failed: %s", token.Error())
|
||||
sleep *= 2
|
||||
time.Sleep(sleep)
|
||||
} else {
|
||||
log.Printf("Connected to broker: %s", os.Args[1])
|
||||
break
|
||||
}
|
||||
}
|
||||
for {
|
||||
msg := <-msgchan
|
||||
if msg.Topic() == "mqtt2exec/"+os.Args[2]+"/run" {
|
||||
cmd := exec.Command("/system/xbin/busybox", "ash", "-c", string(msg.Payload()))
|
||||
cmd.Stdin = nil
|
||||
out, err := cmd.CombinedOutput()
|
||||
result := Result{
|
||||
Command: string(msg.Payload()),
|
||||
Output: string(out),
|
||||
}
|
||||
if err != nil {
|
||||
result.Error = err.Error()
|
||||
}
|
||||
resultJSON, _ := json.Marshal(result)
|
||||
client.Publish("mqtt2exec/"+os.Args[2]+"/result", 0, false, resultJSON)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func connectHandler(c mqtt.Client) {
|
||||
token := c.Subscribe("mqtt2exec/"+os.Args[2]+"/run", 2, nil)
|
||||
token.Wait()
|
||||
if token.Error() != nil {
|
||||
log.Printf("mqtt2exec: Error subscribing to topic: %s", token.Error())
|
||||
}
|
||||
c.Publish("mqtt2exec/"+os.Args[2]+"/state", 1, false, "online")
|
||||
}
|
Loading…
Reference in a new issue