Skip to content

Commit 71079a6

Browse files
committed
Basic connect/disconnect/status implemented. Added configuration
1 parent 4765d78 commit 71079a6

File tree

8 files changed

+104
-60
lines changed

8 files changed

+104
-60
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# usb-modem-cli
2-
CLI tool for managing USB modems with HTTP API
2+
CLI tool for managing USB modems with HTTP API

args.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ package main
33
// CLI argument definitions
44
type (
55
SMSActionArgs struct {
6-
// Send *SMSSendArgs `validate:"-" subcommand:"send" help:"Send SMS"`
7-
// Read *SMSReadArgs `validate:"-" subcommand:"read" help:"Read SMS"`
6+
Send *SMSSendArgs `validate:"-" arg:"subcommand:send" help:"Send SMS"`
7+
Read *SMSReadArgs `validate:"-" arg:"subcommand:read" help:"Read SMS"`
88
}
99

10-
// SMSSendArgs struct {
11-
// PhoneNumber string `validate:"e164" arg:"-n,required" help:"Receiver's phone number"`
12-
// Message string `validate:"printascii" arg:"-m,required" help:"Message to be sent"`
13-
// }
10+
SMSSendArgs struct {
11+
PhoneNumber string `validate:"e164" arg:"-p,--phone,required" help:"Receiver's phone number"`
12+
Message string `validate:"printascii" arg:"-m,--msg,required" help:"Message to be sent"`
13+
}
1414

15-
// SMSReadArgs struct {
16-
// }
15+
SMSReadArgs struct {
16+
}
1717

1818
ConnectionArgs struct {
1919
Action string `arg:"positional,required" help:"up/down/status" validate:"oneof=up down status"`
2020
}
2121

2222
BaseArgs struct {
23-
Connection *ConnectionArgs `validate:"-" arg:"subcommand:conn" help:"Manage cell connection"`
24-
SMS *SMSActionArgs `validate:"-" arg:"subcommand:sms" help:"Manage SMS"`
25-
Ip string `validate:"ipv4" arg:"--ip" help:"Override IP in config file"`
23+
Connection *ConnectionArgs `validate:"-" arg:"subcommand:conn" help:"Manage cell connection"`
24+
SMS *SMSActionArgs `validate:"-" arg:"subcommand:sms" help:"Manage SMS"`
25+
Ip string `validate:"omitempty,ipv4" arg:"--ip" help:"Override IP in config file"`
26+
DisableColor bool `arg:"-p,--plain" help:"Disable color for better software interaction"`
2627
}
2728
)

drivers/8810ft.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type (
2222
}
2323

2424
pppConnected struct {
25-
Connected string `json:"ppp_connected"`
25+
Connected string `json:"ppp_status"`
2626
}
2727
)
2828

@@ -38,7 +38,7 @@ func newZTE8810FT(ip string) BaseModem {
3838
}
3939

4040
func (m *zte8810ft) getBaseURL(path string) *url.URL {
41-
return &url.URL{Scheme: "https", Host: m.ip, Path: path}
41+
return &url.URL{Scheme: "http", Host: m.ip, Path: path}
4242
}
4343

4444
func (m *zte8810ft) getNewRequest(method string, url *url.URL) *http.Request {
@@ -113,7 +113,6 @@ func (m *zte8810ft) DisconnectCell() error {
113113
request := m.getNewRequest("GET", u)
114114

115115
resp, err := httpClient.Do(request)
116-
117116
// Process errors
118117
switch {
119118
case err != nil:
@@ -141,49 +140,57 @@ func (m *zte8810ft) DisconnectCell() error {
141140
return nil
142141
}
143142

144-
func (m *zte8810ft) GetCellConnStatus() (bool, error) {
143+
func (m *zte8810ft) GetCellConnStatus() (*LinkStatus, error) {
145144
// Lines 251-258
146145
// /goform/goform_get_cmd_process?isTest=False&cmd=ppp_connected,multi_data=1&sms_received_flag_flag=0&sts_received_flag_flag=0&_=<curr_time>
147146

148147
// Build URL
149148
u := m.getBaseURL("/goform/goform_get_cmd_process")
150149
query := u.Query()
151150
query.Add("isTest", "False")
152-
query.Add("cmd", "ppp_connected")
151+
query.Add("cmd", "ppp_status")
153152
query.Add("multi_data", "1")
154153
query.Add("sms_received_flag_flag", "0")
155154
query.Add("sts_received_flag_flag", "0")
156155
query.Add("_", strconv.FormatInt((time.Now().UnixMilli)(), 10))
157156
u.RawQuery = query.Encode()
158157

159-
request := m.getNewRequest("POST", u)
158+
request := m.getNewRequest("GET", u)
160159

161160
resp, err := httpClient.Do(request)
162161

163162
// Process errors
164163
switch {
165164
case err != nil:
166-
return false, ActionError{Action: "status", Err: err}
165+
return nil, ActionError{Action: "status", Err: err}
167166
case resp.StatusCode != 200:
168-
return false, ActionError{Action: "status", Err: fmt.Errorf("response status %d", resp.StatusCode)}
167+
return nil, ActionError{Action: "status", Err: fmt.Errorf("response status %d", resp.StatusCode)}
169168
}
170169

171170
// Read the response
172171
defer resp.Body.Close()
173172
body, err := io.ReadAll(resp.Body)
174173
if err != nil {
175-
return false, ErrUnknown
174+
return nil, ErrUnknown
176175
}
177176

178177
result := new(pppConnected)
179178
if err := json.Unmarshal(body, result); err != nil {
180-
return false, ActionError{Action: "status", Err: UnmarshalError{RawData: &body, Err: err}}
179+
return nil, ActionError{Action: "status", Err: UnmarshalError{RawData: &body, Err: err}}
181180
}
182181

183182
// Process the result
184-
if result.Connected != "ppp_connected" {
185-
return false, nil
183+
switch result.Connected {
184+
case "ppp_connected":
185+
return &LinkStatus{Up: true}, nil
186+
case "ppp_connecting":
187+
return &LinkStatus{Connecting: true}, nil
188+
case "ppp_disconnecting":
189+
return &LinkStatus{Disconnecting: true}, nil
190+
case "ppp_disconnected":
191+
return &LinkStatus{Down: true}, nil
192+
default:
193+
// Unknown link status occurred
194+
return nil, ErrUnknown
186195
}
187-
188-
return true, nil
189196
}

drivers/common.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type (
1414
ModemCell interface {
1515
BaseModem
1616

17-
GetCellConnStatus() (bool, error)
17+
GetCellConnStatus() (*LinkStatus, error)
1818
ConnectCell() error
1919
DisconnectCell() error
2020
}
@@ -32,6 +32,14 @@ type (
3232
Sender string
3333
Message string
3434
}
35+
36+
// Link statuses
37+
LinkStatus struct {
38+
Up bool
39+
Down bool
40+
Connecting bool
41+
Disconnecting bool
42+
}
3543
)
3644

3745
var drivers map[string]func(ip string) BaseModem = map[string]func(ip string) BaseModem{}

drivers/dummy.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package drivers
22

3-
import "fmt"
4-
53
// DO NOT USE DIRECTLY
64
type (
75
dummy struct {
@@ -14,7 +12,7 @@ func init() {
1412
}
1513

1614
func newDummy(ip string) BaseModem {
17-
fmt.Println("Dummy driver enabled!")
15+
// fmt.Println("Dummy driver enabled!")
1816
return &dummy{ip: ip}
1917
}
2018

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ require (
1414
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
1515
github.com/go-playground/locales v0.14.1 // indirect
1616
github.com/go-playground/universal-translator v0.18.1 // indirect
17+
github.com/gookit/color v1.3.2 // indirect
1718
github.com/hashicorp/hcl v1.0.0 // indirect
19+
github.com/i582/cfmt v1.4.0 // indirect
1820
github.com/leodido/go-urn v1.4.0 // indirect
1921
github.com/magiconair/properties v1.8.7 // indirect
2022
github.com/mitchellh/mapstructure v1.5.0 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4
2222
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
2323
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
2424
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
25+
github.com/gookit/color v1.3.2 h1:WO8+16ZZtx+HlOb6cueziUAF8VtALZKRr/jOvuDk0X0=
26+
github.com/gookit/color v1.3.2/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
2527
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
2628
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
29+
github.com/i582/cfmt v1.4.0 h1:DNugs+dvy3xjJSUk9Oita0udy1YVQh2vDP6cWYhDCIQ=
30+
github.com/i582/cfmt v1.4.0/go.mod h1:tpHWAxhE4Y7yy7sliaNe0pnnEs1SZe67KLljyOlEYI8=
2731
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
2832
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
2933
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=

mcli.go

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/alexflint/go-arg"
88
"github.com/brokenCursor/usb-modem-cli/drivers"
99
"github.com/go-playground/validator/v10"
10+
"github.com/i582/cfmt/cmd/cfmt"
1011
"github.com/spf13/viper"
1112
)
1213

@@ -32,16 +33,20 @@ func init() {
3233
config.SetConfigType("yaml")
3334

3435
sep := string(os.PathSeparator)
35-
config.AddConfigPath(dir + sep + "modem-cli" + sep + "config.yaml")
36+
config.AddConfigPath(dir + sep + "modem-cli")
3637

3738
config.SetDefault("modem.model", "dummy")
3839
config.SetDefault("modem.ip", "127.0.0.1")
3940

41+
err = config.ReadInConfig()
42+
if err != nil { // Handle errors reading the config file
43+
panic(fmt.Errorf("fatal error config file: %w", err))
44+
}
4045
}
4146

4247
func main() {
4348
if err := run(); err != nil {
44-
fmt.Fprintf(os.Stderr, "error: %v\n", err)
49+
cfmt.Fprintf(os.Stderr, "{{error:}}::red %v\n", err)
4550
}
4651
}
4752

@@ -54,16 +59,20 @@ func run() error {
5459
model := modemConfig.GetString("model")
5560
ip := modemConfig.GetString("ip")
5661

57-
// if args.Ip != "" {
58-
// ip = args.Ip
59-
// }
60-
6162
if err := validate.Struct(args); err != nil {
6263
// TODO: add actual error output
63-
fmt.Printf("%s\n%v\n", err.Error(), ip)
6464
parser.Fail("invalid value for \"--ip\" ")
6565
}
6666

67+
if args.DisableColor {
68+
cfmt.DisableColors()
69+
}
70+
71+
// If IP has been overridden
72+
if len(args.Ip) > 0 {
73+
ip = args.Ip
74+
}
75+
6776
modem, err := drivers.GetModemDriver(model, ip)
6877
if err != nil {
6978
return err
@@ -82,40 +91,55 @@ func run() error {
8291
}
8392

8493
switch args.Connection.Action {
94+
case "up":
95+
err := cell.ConnectCell()
96+
97+
if err != nil {
98+
return err
99+
}
100+
case "down":
101+
err := cell.DisconnectCell()
102+
103+
if err != nil {
104+
return err
105+
}
85106
case "status":
86-
isConnected, err := cell.GetCellConnStatus()
107+
status, err := cell.GetCellConnStatus()
87108

88109
if err != nil {
89110
return err
90111
}
91112

92-
if isConnected {
93-
fmt.Println("Status: up")
94-
} else {
95-
fmt.Println("Status: down")
113+
// Process and output status
114+
switch {
115+
case status.Up:
116+
cfmt.Println("Status: {{up}}::green|bold")
117+
case status.Down:
118+
cfmt.Println("Status: {{down}}::red|bold")
119+
case status.Connecting:
120+
cfmt.Println("Status: {{connecting}}::yellow|bold")
121+
case status.Disconnecting:
122+
cfmt.Println("Status: {{disconnecting}}::#FA8100|bold")
123+
}
124+
}
125+
case args.SMS != nil:
126+
// None of this is implemented :)
127+
sms, ok := modem.(drivers.ModemSMS)
128+
if !ok {
129+
return DriverSupportError{Driver: modem, Function: "SMS"}
130+
}
131+
132+
switch {
133+
case args.SMS.Send != nil:
134+
err := validate.Struct(args.SMS.Send)
135+
if err != nil {
136+
parser.FailSubcommand("Unknown action", "sms")
96137
}
97-
return nil
138+
sms.SendSMS(args.SMS.Send.PhoneNumber, args.SMS.Send.PhoneNumber)
98139
}
99-
// case args.SMS != nil:
100-
// // None of this is implemented :)
101-
// sms, ok := modem.(drivers.ModemSMS)
102-
// if !ok {
103-
// return DriverSupportError{Driver: modem, Function: "SMS"}
104-
// }
105-
106-
// switch {
107-
// case args.SMS.Read != nil:
108-
// err := validate.Struct(args.SMS.Send)
109-
// if err != nil {
110-
// parser.FailSubcommand("Unknown action", "sms")
111-
// }
112-
// sms.SendSMS(args.SMS.Send.PhoneNumber, args.SMS.Send.PhoneNumber)
113-
// }
114140
case parser.Subcommand() == nil:
115141
parser.Fail("Missing or unknown command")
116142
}
117143

118-
fmt.Printf("Modem cmd: %s\n", args.Ip)
119-
120144
return nil
121145
}

0 commit comments

Comments
 (0)