Initial commit

This commit is contained in:
Łukasz Moskała 2024-12-22 20:19:23 +01:00
commit 0b1065e993
6 changed files with 128 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
mqtt2exec

6
Makefile Normal file
View 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
View 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
View 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
View 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
View 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")
}