sim-modem/api/modem/internet/ic.go

157 lines
3.3 KiB
Go

package internet
import (
"fmt"
"io"
"log"
"os/exec"
"strings"
"gitea.unprism.ru/KRBL/sim-modem/api/modem/at"
)
type conn struct {
logger *log.Logger
port at.Port
pppPort string
isConnectExecuted bool
isInited bool
}
type Conn interface {
Init(pppPort string) error
Connect() error
Disconnect() error
IsConnected() bool // Check interface existance
Ping() error
io.Closer
}
func New(logger *log.Logger, port at.Port) Conn {
return &conn{
logger: logger,
port: port,
isConnectExecuted: false,
isInited: false,
}
}
func (c *conn) Init(pppPort string) error {
c.pppPort = pppPort
// Setup only setup
if err := c.setup(); err != nil {
return fmt.Errorf("setup: %w", err)
}
c.isInited = true
return nil
}
func (c *conn) Connect() error {
if !c.isInited {
return fmt.Errorf("internet submodule is not inited")
}
// Check is already connected
if c.isConnectExecuted {
return fmt.Errorf("already connected")
}
// Check signal
// if ok, err := utils.CheckService(c.port, c.logger); err != nil || !ok {
// if err != nil {
// return fmt.Errorf("check service: %w", err)
// }
// return fmt.Errorf("no service")
// }
resp, err := exec.Command("pon", pppConfigName).Output()
if err != nil {
return fmt.Errorf("execute pon cmd: %w", err)
}
if len(resp) > 0 {
c.logger.Println("pon response:", string(resp))
}
c.isConnectExecuted = true
// Set default route
c.logger.Println("\x1b[38;2;0;255;0mInternet connected.\x1b[38;2;255;255;255m")
return nil
}
func (c *conn) Disconnect() error {
// return nil // Temporary do not turn off inet
if !c.isConnectExecuted {
return nil
// return fmt.Errorf("internet is not connected")
}
c.isConnectExecuted = false
resp, err := exec.Command("poff", pppConfigName).Output()
if err != nil {
return fmt.Errorf("execute poff cmd: %w", err)
}
if len(resp) > 0 {
c.logger.Println("poff response:", string(resp))
}
c.isConnectExecuted = false
return nil
}
func (c *conn) Ping() error {
// Test - try to connect to Google DNS
// ping -I ppp0 8.8.8.8
resp, err := exec.Command("ping", "8.8.8.8").Output()
if err != nil {
c.logger.Println("Ping default interface cmd error:", err)
}
c.logger.Println("Ping default interface resp:", string(resp))
resp, err = exec.Command("ping", "-I", "ppp0", "8.8.8.8").Output()
if err != nil {
c.logger.Println("Ping ppp0 interface cmd error:", err)
}
c.logger.Println("Ping ppp0 interface resp:", string(resp))
if strings.Contains(string(resp), "Destination Host Unreachable") || strings.Contains(string(resp), "Destination Net Unreachable") {
return fmt.Errorf("ping response: %s", string(resp))
}
return nil
}
func (c *conn) IsConnected() bool {
if !c.isConnectExecuted {
return false
}
// Make "ifconfig" request
resp, err := exec.Command("ifconfig").Output()
if err != nil {
c.logger.Println("ifconfig cmd error:", err.Error())
return false
}
lines := strings.Split(string(resp), "\n")
for _, l := range lines {
if len(l) == 0 {
continue
}
if l[0] == ' ' {
continue
}
interfaceName := strings.Split(l, ":")[0]
if interfaceName == "ppp0" {
return true
}
}
return false // Did not found
}
func (c *conn) Close() error {
c.isInited = false
if err := c.Disconnect(); err != nil {
return fmt.Errorf("diconnect: %w", err)
}
return nil
}