moved dbus.go to an internal utils package added context function parameter to initMusicCtrl and updated main.go to pass it updated calls.go, maps.go, music.go, and notifs.go to use utils package for getting a dus connection
152 lines
3.8 KiB
Go
152 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
"github.com/rs/zerolog/log"
|
|
"go.arsenm.dev/infinitime"
|
|
"go.arsenm.dev/itd/internal/utils"
|
|
|
|
)
|
|
|
|
func initCallNotifs(ctx context.Context, dev *infinitime.Device) error {
|
|
// Connect to system bus. This connection is for method calls.
|
|
conn, err := utils.NewSystemBusConn(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check if modem manager interface exists
|
|
exists, err := modemManagerExists(ctx, conn)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// If it does not exist, stop function
|
|
if !exists {
|
|
conn.Close()
|
|
return nil
|
|
}
|
|
|
|
// Connect to system bus. This connection is for monitoring.
|
|
monitorConn, err := utils.NewSystemBusConn(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Add match for new calls to monitor connection
|
|
err = monitorConn.AddMatchSignal(
|
|
dbus.WithMatchSender("org.freedesktop.ModemManager1"),
|
|
dbus.WithMatchInterface("org.freedesktop.ModemManager1.Modem.Voice"),
|
|
dbus.WithMatchMember("CallAdded"),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create channel to receive calls
|
|
callCh := make(chan *dbus.Message, 5)
|
|
// Notify channel upon received message
|
|
monitorConn.Eavesdrop(callCh)
|
|
|
|
var respHandlerOnce sync.Once
|
|
var callObj dbus.BusObject
|
|
|
|
go func() {
|
|
// For every message received
|
|
for event := range callCh {
|
|
// Get path to call object
|
|
callPath := event.Body[0].(dbus.ObjectPath)
|
|
// Get call object
|
|
callObj = conn.Object("org.freedesktop.ModemManager1", callPath)
|
|
|
|
// Get phone number from call object using method call connection
|
|
phoneNum, err := getPhoneNum(conn, callObj)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("Error getting phone number")
|
|
continue
|
|
}
|
|
|
|
// Send call notification to InfiniTime
|
|
resCh, err := dev.NotifyCall(phoneNum)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
go respHandlerOnce.Do(func() {
|
|
// Wait for PineTime response
|
|
for res := range resCh {
|
|
switch res {
|
|
case infinitime.CallStatusAccepted:
|
|
// Attempt to accept call
|
|
err = acceptCall(ctx, conn, callObj)
|
|
if err != nil {
|
|
log.Warn().Err(err).Msg("Error accepting call")
|
|
}
|
|
case infinitime.CallStatusDeclined:
|
|
// Attempt to decline call
|
|
err = declineCall(ctx, conn, callObj)
|
|
if err != nil {
|
|
log.Warn().Err(err).Msg("Error declining call")
|
|
}
|
|
case infinitime.CallStatusMuted:
|
|
// Warn about unimplemented muting
|
|
log.Warn().Msg("Muting calls is not implemented")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}()
|
|
|
|
log.Info().Msg("Relaying calls to InfiniTime")
|
|
return nil
|
|
}
|
|
|
|
func modemManagerExists(ctx context.Context, conn *dbus.Conn) (bool, error) {
|
|
var names []string
|
|
err := conn.BusObject().CallWithContext(
|
|
ctx, "org.freedesktop.DBus.ListNames", 0,
|
|
).Store(&names)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return strSlcContains(names, "org.freedesktop.ModemManager1"), nil
|
|
}
|
|
|
|
// getPhoneNum gets a phone number from a call object using a DBus connection
|
|
func getPhoneNum(conn *dbus.Conn, callObj dbus.BusObject) (string, error) {
|
|
var out string
|
|
// Get number property on DBus object and store return value in out
|
|
err := callObj.StoreProperty("org.freedesktop.ModemManager1.Call.Number", &out)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// getPhoneNum accepts a call using a DBus connection
|
|
func acceptCall(ctx context.Context, conn *dbus.Conn, callObj dbus.BusObject) error {
|
|
// Call Accept() method on DBus object
|
|
call := callObj.CallWithContext(
|
|
ctx, "org.freedesktop.ModemManager1.Call.Accept", 0,
|
|
)
|
|
if call.Err != nil {
|
|
return call.Err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getPhoneNum declines a call using a DBus connection
|
|
func declineCall(ctx context.Context, conn *dbus.Conn, callObj dbus.BusObject) error {
|
|
// Call Hangup() method on DBus object
|
|
call := callObj.CallWithContext(
|
|
ctx, "org.freedesktop.ModemManager1.Call.Hangup", 0,
|
|
)
|
|
if call.Err != nil {
|
|
return call.Err
|
|
}
|
|
return nil
|
|
}
|