From faa392fecff8c4acf641559939d926604b8b8ad7 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Wed, 6 Mar 2024 18:22:34 +0800 Subject: [PATCH] add: alarm forward by smpp --- features/fm/smsforward.go | 149 +++++++++++++++++++++++++++++++++++++- features/fm/ucpcli.go | 60 +++++++++++++++ go.mod | 5 ++ go.sum | 14 ++++ 4 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 features/fm/ucpcli.go diff --git a/features/fm/smsforward.go b/features/fm/smsforward.go index c58e6e5d..6b3f3160 100644 --- a/features/fm/smsforward.go +++ b/features/fm/smsforward.go @@ -5,10 +5,14 @@ import ( "fmt" "net/http" "net/url" + "time" "ems.agt/lib/dborm" "ems.agt/lib/log" "ems.agt/restagent/config" + "github.com/linxGnu/gosmpp" + "github.com/linxGnu/gosmpp/data" + "github.com/linxGnu/gosmpp/pdu" ) func AlarmForwardBySMS(alarmData *Alarm) error { @@ -80,8 +84,8 @@ func AlarmForwardBySMS(alarmData *Alarm) error { // 解析响应 if resp.StatusCode == http.StatusOK { - log.Info("SMS sent successfully!") - operResult := fmt.Sprintf("SMS sent successfully!") + operResult := "SMS sent successfully!" + log.Info(operResult) forwardLog.OperResult = operResult affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) if err != nil && affected <= 0 { @@ -101,3 +105,144 @@ func AlarmForwardBySMS(alarmData *Alarm) error { } return nil } + +func AlarmForwardBySMPP(alarmData *Alarm) error { + log.Info("AlarmForwardBySMPP processing... ") + + auth := gosmpp.Auth{ + SMSC: config.GetYamlConfig().Alarm.SMSC.Addr, + SystemID: config.GetYamlConfig().Alarm.SMSC.UserName, + Password: config.GetYamlConfig().Alarm.SMSC.Password, + SystemType: "", + } + + // conn, err := gosmpp.NonTLSDialer(auth.SMSC) + // connection := gosmpp.NewConnection(conn) + + trans, err := gosmpp.NewSession( + gosmpp.TXConnector(gosmpp.NonTLSDialer, auth), + gosmpp.Settings{ + ReadTimeout: 2 * time.Second, + + OnPDU: func(p pdu.PDU, _ bool) { + log.Debug("%+v", p) + }, + + OnSubmitError: func(_ pdu.PDU, err error) { + log.Error(err) + }, + + OnRebindingError: func(err error) { + log.Error(err) + }, + + OnClosed: func(state gosmpp.State) { + log.Error(state) + }, + }, -1) + if err != nil { + log.Error(err) + return err + } + defer func() { + _ = trans.Close() + }() + + toUsers, err := dborm.XormGetAlarmForward("SMS") + if err != nil { + log.Error("Failed to XormGetAlarmForward:", err) + return err + } else if toUsers == nil { + err := errors.New("not found forward phone number") + log.Error(err) + return err + } + // sending SMS(s) + for _, toUser := range *toUsers { + forwardLog := &dborm.AlarmForwardLog{ + NeType: alarmData.NeType, + NeID: alarmData.NeId, + AlarmID: alarmData.AlarmId, + AlarmTitle: alarmData.AlarmTitle, + AlarmSeq: alarmData.AlarmSeq, + EventTime: alarmData.EventTime, + ToUser: toUser, + } + message := alarmData.AlarmTitle + "from" + alarmData.NeType + alarmData.NeId + "at" + alarmData.EventTime + if err = trans.Transceiver().Submit(newSubmitSM(toUser, message)); err != nil { + operResult := fmt.Sprintf("Failed to submit short message:%v", err) + log.Error(operResult) + forwardLog.OperResult = operResult + } else { + operResult := "SMS sent successfully!" + log.Trace(operResult) + forwardLog.OperResult = operResult + } + + affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) + if err != nil && affected <= 0 { + log.Error("Failed to insert data:", err) + continue + } + } + return nil +} + +func handlePDU() func(pdu.PDU) (pdu.PDU, bool) { + return func(p pdu.PDU) (pdu.PDU, bool) { + switch pd := p.(type) { + case *pdu.Unbind: + log.Trace("Unbind Received") + return pd.GetResponse(), true + + case *pdu.UnbindResp: + log.Trace("UnbindResp Received") + + case *pdu.SubmitSMResp: + log.Trace("SubmitSMResp Received") + + case *pdu.GenericNack: + log.Trace("GenericNack Received") + + case *pdu.EnquireLinkResp: + fmt.Println("EnquireLinkResp Received") + + case *pdu.EnquireLink: + log.Trace("EnquireLink Received") + return pd.GetResponse(), false + + case *pdu.DataSM: + log.Trace("DataSM receiver") + return pd.GetResponse(), false + + case *pdu.DeliverSM: + log.Trace("DeliverSM receiver") + return pd.GetResponse(), false + } + return nil, false + } +} + +func newSubmitSM(phoneNumber string, message string) *pdu.SubmitSM { + // build up submitSM + srcAddr := pdu.NewAddress() + srcAddr.SetTon(5) + srcAddr.SetNpi(0) + _ = srcAddr.SetAddress("alarm notification:") + + destAddr := pdu.NewAddress() + destAddr.SetTon(1) + destAddr.SetNpi(1) + _ = destAddr.SetAddress(phoneNumber) + + submitSM := pdu.NewSubmitSM().(*pdu.SubmitSM) + submitSM.SourceAddr = srcAddr + submitSM.DestAddr = destAddr + _ = submitSM.Message.SetMessageWithEncoding(message, data.UCS2) + submitSM.ProtocolID = 0 + submitSM.RegisteredDelivery = 1 + submitSM.ReplaceIfPresentFlag = 0 + submitSM.EsmClass = 0 + + return submitSM +} diff --git a/features/fm/ucpcli.go b/features/fm/ucpcli.go new file mode 100644 index 00000000..4a49f5d2 --- /dev/null +++ b/features/fm/ucpcli.go @@ -0,0 +1,60 @@ +package fm + +import ( + "fmt" + "strings" + + "ems.agt/lib/log" + "ems.agt/restagent/config" + "github.com/chzyer/readline" + "github.com/go-gsm/ucp" +) + +func AlarmForwardBySMSC(alarmData *Alarm) error { + opt := &ucp.Options{ + Addr: config.GetYamlConfig().Alarm.SMSC.Addr, + User: config.GetYamlConfig().Alarm.SMSC.UserName, + Password: config.GetYamlConfig().Alarm.SMSC.Password, + AccessCode: "", + } + + client := ucp.New(opt) + if err := client.Connect(); err != nil { + log.Error("Failed to connect:", err) + return err + } + defer client.Close() + + reader, _ := readline.New(">>> ") + defer reader.Close() + + for { + fmt.Print(">>> ") + lines, _ := reader.Readline() + fields := strings.Fields(lines) + + if len(fields) == 1 { + // exit CLI + if fields[0] == "exit" { + return nil + } + // display help message + if fields[0] == "help" { + log.Trace("\n\tSend a 'message' to 'receiver' with a 'sender' mask\n\t>>> sender receiver message\n\n\tExit the cli\n\t>>> exit\n") + } + } + + // sender receiver message... + if len(fields) >= 3 { + sender := fields[0] + receiver := fields[1] + message := strings.Join(fields[2:], " ") + ids, err := client.Send(sender, receiver, message) + if err != nil { + log.Error(err) + } else { + log.Debug("%v", ids) + } + } + } +} diff --git a/go.mod b/go.mod index 36c6a251..acd7b48b 100644 --- a/go.mod +++ b/go.mod @@ -42,8 +42,13 @@ require ( ) require ( + github.com/chzyer/readline v1.5.1 // indirect github.com/creack/pty v1.1.9 // indirect github.com/go-admin-team/go-admin-core v1.3.12-0.20221121065133-27b7dbe27a8f // indirect + github.com/go-gsm/charset v1.0.0 // indirect + github.com/go-gsm/ucp v0.0.1 // indirect + github.com/linxGnu/gosmpp v0.2.0 // indirect + golang.org/x/time v0.1.0 // indirect ) require ( diff --git a/go.sum b/go.sum index 00b3ebeb..42347f57 100644 --- a/go.sum +++ b/go.sum @@ -96,8 +96,12 @@ github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -173,6 +177,10 @@ github.com/go-forks/fsnotify v1.4.7/go.mod h1:AU8mot+GznW5+B4jRJHxKg/2EeO+jMORGR github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gsm/charset v1.0.0 h1:6k6LOKHtxgCPXE15X0unRewjOksyhmHBIp6x7qLQ6Ls= +github.com/go-gsm/charset v1.0.0/go.mod h1:sC8+2VpAM2sZDlxv11MxWIZiuf8MipOgM/hCYsRQRps= +github.com/go-gsm/ucp v0.0.1 h1:vM5ly5iRNGMGGiVx4K3+puF9AhpwkC76BkiV9LFv0bw= +github.com/go-gsm/ucp v0.0.1/go.mod h1:58/PrXWFcmaQyZ5p/Dp2YiCnhlVx0HdKXFGmqiVO/mI= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -451,6 +459,8 @@ github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/gosmpp v0.2.0 h1:GVZdnO8pUsOrhFF092RQ2II+6RW5F2kLDlbCH+NBp7s= +github.com/linxGnu/gosmpp v0.2.0/go.mod h1:UpJwpDhL0yq05gUqaLwZ8+Qc7qy1pl35EjxWtRLW6ks= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -812,6 +822,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -941,6 +952,7 @@ golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -975,6 +987,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=