src.dualinventive.com/go/cp3000-interface/internal/reset/reset.go

156 lines
4.1 KiB
Go

package reset
import (
"crypto/tls"
"fmt"
"math/rand"
"net/http"
"github.com/tiaguinho/gosoap"
"src.dualinventive.com/go/cp3000-interface/internal/storage"
"src.dualinventive.com/go/dinet"
"src.dualinventive.com/go/dinet/ditime"
"src.dualinventive.com/go/dinet/rpc"
)
const (
vodafoneM2MResetMethod = "submitSMSv2"
vodafoneM2MSuccessMajorCode = "000"
resetCommand = "RElKQkxQIE1DVS1TVEFUVVMgMkNGRkZGNzE1MA=="
)
// Reset contains helper functions for resetting CP3000 devices
type Reset struct {
vodafoneM2MSoapClient *gosoap.Client
messagingProxy dinet.ReadWriter
}
// New creates a new Reset struct which contains helper functions for resetting CP3000 devices
func New(certFile, keyFile, wsdlFile, userID, password string, msgProxyConn dinet.ReadWriter) (*Reset, error) {
tlsConfig, err := resetM2MTlsConfig(certFile, keyFile)
if err != nil {
return nil, err
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
httpClient := &http.Client{Transport: transport}
soap, err := gosoap.SoapClient(wsdlFile)
if err != nil {
return nil, err
}
soap.HttpClient = httpClient
soap.HeaderName = "m:gdspHeader"
soap.HeaderParams = gosoap.HeaderParams{
gosoap.Param{
Key: "gdspCredentials",
Value: gosoap.HeaderParams{
gosoap.Param{Key: "userId", Value: userID},
gosoap.Param{Key: "password", Value: password},
},
},
}
return &Reset{
vodafoneM2MSoapClient: soap,
messagingProxy: msgProxyConn,
}, nil
}
func resetM2MTlsConfig(certFile, keyFile string) (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
tlsConfig.BuildNameToCertificate()
return tlsConfig, nil
}
// Reset will reset a CP3000 device using the Vodafone m2m platform or via a reset SMS
func (r *Reset) Reset(d *storage.Device) error {
if d.VodafoneM2mAPIEnabled() {
return r.ResetM2M(d.IMSI)
}
deviceUID, err := d.DeviceUID()
if err != nil {
return err
}
return r.ResetSMS(deviceUID, d.TelephoneNR)
}
// ResetSMS will reset a CP3000 device using a reset SMS
func (r *Reset) ResetSMS(deviceUID, telephoneNR string) error {
err := r.messagingProxy.Send(&rpc.Msg{
Dinetrpc: rpc.CurrentDinetrpc,
ID: rand.Uint32(),
Time: ditime.Now(),
DeviceUID: deviceUID,
ClassMethod: rpc.ClassMethodMessageSms,
Type: rpc.MsgTypeRequest,
Params: rpc.NewParams([]rpc.MessageSms{
{
Destinations: []string{
telephoneNR,
},
Message: resetCommand,
},
}),
})
if err != nil {
return err
}
reply, err := r.messagingProxy.Recv()
if err != nil {
return err
}
if reply.Error != nil {
return reply.Error
}
return nil
}
// ResetM2M will reset a CP3000 device using the Vodafone m2m platform
func (r *Reset) ResetM2M(imsi string) error {
params := gosoap.Params{
gosoap.Param{Key: "deviceId", Value: imsi},
gosoap.Param{Key: "sourceId", Value: "310000206"},
gosoap.Param{Key: "messageData", Value: resetCommand},
gosoap.Param{Key: "messageType", Value: "Text"},
gosoap.Param{Key: "messageUDH", Value: "N"},
gosoap.Param{Key: "priority", Value: "3"},
gosoap.Param{Key: "validityPeriod", Value: "000100000000000R"},
gosoap.Param{Key: "replaceIfPresent", Value: "N"},
}
if err := r.vodafoneM2MSoapClient.Call(vodafoneM2MResetMethod, params); err != nil {
return err
}
var res SoapReturnValue
if err := r.vodafoneM2MSoapClient.Unmarshal(&res); err != nil {
return err
}
if !res.IsError() {
return nil
}
return res
}
// SoapReturnValue contains the data that the Vodafone soap API is returning
type SoapReturnValue struct {
MajorReturnCode string `xml:"return>returnCode>majorReturnCode"`
MinorReturnCode string `xml:"return>returnCode>minorReturnCode"`
}
// IsError returns true when the soap return value should be threaded as an error
func (s SoapReturnValue) IsError() bool {
return s.MajorReturnCode != vodafoneM2MSuccessMajorCode
}
// Error returns a descriptive error message
func (s SoapReturnValue) Error() string {
return fmt.Sprintf("soap error: %s:%s", s.MajorReturnCode, s.MinorReturnCode)
}