From 0fd389bdaa0386d8351f35ebdd09d721b7fa8011 Mon Sep 17 00:00:00 2001 From: fakeyanss Date: Fri, 23 Jun 2023 22:04:37 +0800 Subject: [PATCH] [fix] segment marker error. #16 --- internal/api/api.go | 102 ++++++++++++++++++++++++++++ internal/config/asset.go | 8 +-- internal/protocol/model/msg_0800.go | 2 +- internal/protocol/msg_processor.go | 2 +- main.go | 92 +------------------------ 5 files changed, 110 insertions(+), 96 deletions(-) create mode 100644 internal/api/api.go diff --git a/internal/api/api.go b/internal/api/api.go new file mode 100644 index 0000000..410aaa6 --- /dev/null +++ b/internal/api/api.go @@ -0,0 +1,102 @@ +package api + +import ( + "net/http" + "os" + + "github.com/gin-gonic/gin" + "github.com/mitchellh/mapstructure" + "github.com/rs/zerolog/log" + + "github.com/fakeyanss/jt808-server-go/internal/config" + "github.com/fakeyanss/jt808-server-go/internal/protocol/model" + "github.com/fakeyanss/jt808-server-go/internal/server" + "github.com/fakeyanss/jt808-server-go/internal/storage" +) + +func Run(serv *server.TCPServer, cfg *config.Config) { + // web server structure + gin.SetMode(gin.ReleaseMode) + router := gin.Default() + cache := storage.GetDeviceCache() + geoCache := storage.GetGeoCache() + + router.GET("/device", func(c *gin.Context) { + c.JSON(http.StatusOK, cache.ListDevice()) + }) + + router.GET("/device/:phone/geo", func(c *gin.Context) { + phone := c.Param("phone") + + device, err := cache.GetDeviceByPhone(phone) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + return + } + + res := make(map[string]any) + err = mapstructure.Decode(device, &res) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + return + } + gis, err := geoCache.GetGeoLatestByPhone(phone) + if err != nil { + return + } + res["gis"] = gis + + c.JSON(http.StatusOK, res) + }) + + router.GET("/device/:phone/params", func(c *gin.Context) { + phone := c.Param("phone") + device, err := cache.GetDeviceByPhone(phone) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + return + } + session, err := storage.GetSession(device.SessionID) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + } + header := model.GenMsgHeader(device, 0x8104, session.GetNextSerialNum()) + msg := model.Msg8104{ + Header: header, + } + serv.Send(session.ID, &msg) + // todo: read channel from process 0104 msg + }) + + router.PUT("/device/:phone/params", func(c *gin.Context) { + phone := c.Param("phone") + params := model.DeviceParams{} + if err := c.ShouldBind(¶ms); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + } + device, err := cache.GetDeviceByPhone(phone) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + return + } + session, err := storage.GetSession(device.SessionID) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) + } + header := model.GenMsgHeader(device, 0x8103, session.GetNextSerialNum()) + msg := model.Msg8103{ + Header: header, + Parameters: ¶ms, + } + serv.Send(session.ID, &msg) + }) + + httpAddr := ":" + cfg.Server.Port.HTTPPort + + log.Debug().Msgf("Listening and serving HTTP on :%s", cfg.Server.Port.HTTPPort) + err := router.Run(httpAddr) + if err != nil { + log.Error().Err(err).Str("addr", httpAddr).Msg("Fail to run gin router") + os.Exit(1) + } +} diff --git a/internal/config/asset.go b/internal/config/asset.go index ac5cabe..c124187 100644 --- a/internal/config/asset.go +++ b/internal/config/asset.go @@ -94,7 +94,7 @@ func configsBannerTxt() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "configs/banner.txt", size: 509, mode: os.FileMode(420), modTime: time.Unix(1678892343, 0)} + info := bindataFileInfo{name: "configs/banner.txt", size: 509, mode: os.FileMode(420), modTime: time.Unix(1678162039, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -114,12 +114,12 @@ func configsDefaultYaml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "configs/default.yaml", size: 385, mode: os.FileMode(420), modTime: time.Unix(1678892343, 0)} + info := bindataFileInfo{name: "configs/default.yaml", size: 385, mode: os.FileMode(420), modTime: time.Unix(1678936086, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _testClientConfigsDefaultYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x94\xbd\x72\xdb\x38\x10\xc7\x7b\x3e\x05\x86\xae\x25\x93\xfa\x38\x51\xe8\xe4\xcf\xf1\x8d\x67\xce\x63\xfb\xae\x38\x8d\x0b\x18\x5c\xc1\x38\x41\x58\x0e\x00\x6a\x4e\x77\xf6\x1b\xc4\x45\x8a\x74\xc9\xa4\x4d\x91\x32\x55\x3e\x26\x2f\x63\xbb\xcd\x2b\x64\x48\x90\x8a\x64\x9b\x72\xc9\xfd\xfd\xf7\xbf\xc0\x2e\x96\x0a\x05\x0d\x08\xe1\xa8\x2d\x2a\xd8\xd7\xec\x52\x01\x25\xce\xe4\x10\x10\x32\x91\x4f\x42\x99\x91\xda\x8d\xec\xef\x16\x35\x25\x13\xa6\x6c\x11\x54\x28\x8e\x61\x0e\x8a\x92\x70\x6f\x7f\xe7\xcf\xc3\xd0\xc7\xf6\xa4\x01\xee\xd0\x2c\x28\x09\xdb\xdb\x0a\x85\xdd\xae\xc8\x81\x2c\x2c\xc3\x7f\x5c\x12\x25\x2d\xae\x24\x68\xd7\x12\xd8\x56\x28\x0a\xc1\x8c\xfd\x7b\x26\xff\x83\x3f\x26\xa7\xa8\x94\xd4\x82\x92\x7e\xe4\xc3\x3b\x8c\x4f\xf3\xcc\xae\x90\xb8\x93\x78\x34\x12\xab\x09\x83\x20\xf0\xb6\xc5\xe5\x34\x9b\x3d\x53\x2d\xf4\xd7\xe6\xb9\x31\xa0\xf9\x82\x92\xd8\x07\x74\x91\x42\x88\x81\x19\x3a\x18\xa5\xa9\xa1\x24\x54\xc8\x99\xba\x42\xeb\x68\x12\x25\x51\x58\x0a\xb6\xd6\x25\x71\x3c\x6c\x77\x7a\xc3\x76\x6f\xd8\x8e\xe3\x88\xf6\x2b\x5d\x0a\x73\xc9\xc1\x5b\xca\xf4\x14\x04\x25\xe1\x38\x6a\x0d\x2f\xfe\x1f\xdc\x78\x1f\x39\x03\xb9\x1a\x8f\xfb\x37\x75\x81\xec\x0a\x35\x78\x16\x77\x23\x8f\x93\x8a\xae\xb3\xb8\xd3\xed\xf5\x7f\x1b\x24\xcb\x4c\xc5\x5c\x45\xef\x3e\x7f\x1c\x8d\x47\xad\xbf\xcb\xec\xda\xfb\x11\x2f\xd3\x2b\x62\xd0\x21\x47\xf5\x17\x18\x2b\x8b\x21\x87\x9d\x28\xee\x7a\xe6\x0c\xd3\xf6\xa4\x10\x50\x12\x9e\xef\x9e\xf8\xe8\x14\x20\x63\x4a\xce\x81\x92\x4e\x44\xb6\xc8\xdd\xf7\x77\x0f\x9f\xbe\xdc\xbf\xfe\xf0\xf0\xf6\xfd\x8f\xaf\xaf\xee\x6f\xdf\xdc\x7d\xbb\xb5\xb5\xf9\x5c\x6a\x0e\x47\x6b\x9d\xe8\x54\x87\xe2\xd2\x2d\xd6\x49\x6f\xf5\xb8\xbb\xa8\xd0\xd4\xb4\x3c\x71\xd1\xad\x9b\x5f\x5d\x3e\x04\xf4\x8d\x2e\xc6\xe5\x24\xea\x53\xc8\xd0\xb8\x23\xed\xc0\xcc\x99\xa2\x24\x8e\x4a\x2c\x6a\x1d\x21\x8c\xf3\x33\xc7\x5c\x6e\xbd\x6f\x74\x1d\x87\x15\xa9\x3d\x9a\x30\x73\xd2\xe5\x29\x9c\x2f\x32\x78\x26\x57\x8b\x66\x8a\x19\x18\xe6\xa4\x16\x0d\xd6\x02\x70\x5f\x73\xb3\xc8\x36\x95\x47\x96\x36\xa0\x83\x1c\xd4\xd9\xc2\x3a\x98\x35\x08\x46\xca\x81\xd1\xcc\xa1\xd9\x28\xdb\x43\x34\xc7\xc8\xa7\xd0\x54\x68\x62\x50\xbb\x42\xd5\xc0\x67\x32\xdd\x40\x2f\x19\x9f\x6e\xc0\xa9\x91\x73\x30\x1b\x04\x3c\xb7\x0e\x67\x1b\x04\x22\xb3\xc7\x9b\x67\x78\x09\x32\xc5\xfc\x05\x91\x50\xa8\x99\x7d\xc9\x4a\x30\x25\x15\xe0\x0b\xaa\xe2\x52\x4d\x73\xaf\xdf\x1b\x7d\xf4\xc0\x96\xeb\x90\x5c\x94\x3b\x71\x3d\x8c\x9e\x3c\xb3\xf5\x65\xba\x8e\xc7\x51\x6b\x50\xa9\xe3\x64\x29\x67\xca\x3d\x51\xd7\x0b\x56\xb6\xbb\x2e\x6d\x33\x80\x67\x17\x94\x90\xb4\xfc\xa5\x97\xab\xb5\x56\x72\x1c\xb7\x3a\x17\xcb\xaf\xee\x38\x6a\xf5\xfd\x67\x18\x04\x55\x6a\x10\xfc\x0c\x00\x00\xff\xff\x4b\x85\x47\xbb\x6c\x06\x00\x00") +var _testClientConfigsDefaultYaml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x94\xbd\x72\xe3\x36\x10\xc7\x7b\x3d\x05\x86\xae\x25\x13\xb2\x64\x51\xe8\xe4\xcf\x71\xc6\x33\xf1\xd8\x4e\x8a\x68\x5c\xc0\xe0\x0a\x46\x04\x61\x39\x00\xa8\x89\x12\xfb\x0d\xe2\x22\x45\xba\xbb\xb9\xf6\x8a\x2b\xaf\xba\x8f\xb9\x97\xb1\xdd\xde\x2b\xdc\x90\x10\x75\x92\x2d\xca\x25\xf7\xf7\xdf\xff\x02\x8b\x5d\x6a\x94\xac\x41\x88\x40\xe3\x50\xc3\xa1\xe1\xd7\x1a\x18\xf1\x36\x87\x06\x21\x23\xf5\x22\x94\x59\x65\xfc\xc0\xfd\xe2\xd0\x30\x32\xe2\xda\x15\x41\x8d\xf2\x14\xa6\xa0\x19\x89\x0e\x0e\xf7\x7e\x3b\x8e\x42\xec\x40\x59\x10\x1e\xed\x8c\x91\xa8\xb5\xad\x51\xba\xed\x39\x39\x52\x85\x65\xf4\xa7\x4f\xe2\xa4\x29\xb4\x02\xe3\x9b\x12\x5b\x1a\x65\x21\x98\xf0\xbf\x2e\xd4\xdf\xf0\xeb\xe8\x1c\xb5\x56\x46\x32\xd2\x8d\x43\x78\x8f\x8b\x71\x9e\xb9\x25\x42\xdb\x49\x40\x03\xb9\x9c\xd0\x6b\x04\xd7\xe2\x6e\x86\x4f\xd6\x14\x8b\xc2\xad\x45\x6e\x2d\x18\x31\x63\x84\x86\x80\x29\x52\x08\xd9\x22\x16\x26\xe8\x61\x90\xa6\x96\x91\x48\xa3\xe0\xfa\x06\x9d\x67\x49\x9c\xc4\xd1\x3a\x09\xa5\xfd\x56\xbb\xd3\x6f\x75\xfa\x2d\x4a\x63\xd6\x5d\xe8\xd6\xaa\xba\xb4\x45\x77\x77\x17\xaa\x14\xa6\x4a\x40\x28\xad\xd2\x73\x90\x8c\x44\xc3\xb8\xd9\xbf\xfa\xa7\x77\x17\x5c\xd4\x04\xd4\x72\x9c\x76\xef\xaa\x63\x64\x37\x68\x20\x30\xba\x13\x07\x9c\xcc\xe9\x2a\xa3\xed\x9d\x4e\x77\xb7\x97\x2c\x32\x35\xf7\x73\xfa\xf0\xe9\xc3\x60\x38\x68\xfe\x51\x66\x57\xde\xcf\x78\x99\x3e\x27\x16\x3d\x0a\xd4\xbf\x83\x75\xaa\x98\x85\xa8\x1d\xd3\x7e\x60\xde\x72\xe3\xce\x0a\x01\x23\xd1\xe5\xfe\x59\x88\x8e\x01\x32\xae\xd5\x14\x18\x69\xc7\x64\x8b\x3c\x7c\x7b\xfb\xf4\xf1\xf3\xe3\x7f\xef\x9f\xde\xbc\xfb\xfe\xe5\xdf\xc7\xfb\xff\x1f\xbe\xde\xbb\xca\x7c\xaa\x8c\x80\x93\x95\x4e\xb4\xe7\x87\x12\xca\xcf\x56\x49\x67\xf9\xb8\xfb\xa8\xd1\x56\xb4\x3c\x71\xd1\xad\xbb\x9f\x5d\x3e\x06\x0c\x8d\x2e\x1e\xd5\x2b\x34\xe7\x90\xa1\xf5\x27\xc6\x83\x9d\x72\xcd\x08\x8d\x4b\x2c\x2b\x1d\x21\x5c\x88\x0b\xcf\x7d\xee\x82\x6f\x7c\x4b\xa3\x39\xa9\x3c\xea\x30\xf7\xca\xe7\x29\x5c\xce\x32\x58\x93\x6b\x64\x3d\xc5\x0c\x2c\xf7\xca\xc8\x1a\x6b\x09\x78\x68\x84\x9d\x65\x9b\xca\x23\x4f\x6b\xd0\x51\x0e\xfa\x62\xe6\x3c\x4c\x6a\x04\x03\xed\xc1\x1a\xee\xd1\x6e\x94\x1d\x20\xda\x53\x14\x63\xa8\x2b\x34\xb2\x68\x7c\xa1\xaa\xe1\x13\x95\x6e\xa0\xd7\x5c\x8c\x37\xe0\xd4\xaa\x29\xd8\x0d\x02\x91\x3b\x8f\x93\x0d\x02\x99\xb9\xd3\xcd\x6f\x78\x0d\x2a\xc5\xfc\x15\x91\xd4\x68\xb8\x7b\xcd\x4a\x72\xad\x34\xe0\x2b\xaa\xe2\x52\x75\xef\x5e\xcd\x1b\x7b\x36\x60\x8b\x75\x48\xae\xca\x9d\xb8\xed\xc7\x2f\xc6\x6c\x75\x99\x6e\xe9\x30\x6e\xf6\xe6\x6a\x9a\x2c\xe4\x5c\xfb\x17\xea\x6a\xc1\xca\x76\x57\xa5\x5d\x06\xb0\x76\x41\x09\x49\xcb\x3f\x7f\xb9\x5a\x2b\x25\x87\xb4\xd9\xbe\x5a\x7c\xed\x0c\xe3\x66\x37\x7c\x46\x8d\x1f\x01\x00\x00\xff\xff\xc7\xcb\xf6\x42\x89\x06\x00\x00") func testClientConfigsDefaultYamlBytes() ([]byte, error) { return bindataRead( @@ -134,7 +134,7 @@ func testClientConfigsDefaultYaml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "test/client/configs/default.yaml", size: 1644, mode: os.FileMode(420), modTime: time.Unix(1679711868, 0)} + info := bindataFileInfo{name: "test/client/configs/default.yaml", size: 1673, mode: os.FileMode(420), modTime: time.Unix(1687527729, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/internal/protocol/model/msg_0800.go b/internal/protocol/model/msg_0800.go index 6da35dc..a7ea632 100644 --- a/internal/protocol/model/msg_0800.go +++ b/internal/protocol/model/msg_0800.go @@ -19,6 +19,6 @@ func (m *Msg0800) GetHeader() *MsgHeader { return m.Header } -func (m *Msg0800) GenOutgoing(incoming JT808Msg) error { +func (m *Msg0800) GenOutgoing(_ JT808Msg) error { return nil } diff --git a/internal/protocol/msg_processor.go b/internal/protocol/msg_processor.go index 06a5b31..9969bc7 100644 --- a/internal/protocol/msg_processor.go +++ b/internal/protocol/msg_processor.go @@ -145,7 +145,7 @@ func (mp *JT808MsgProcessor) Process(ctx context.Context, pkt *model.PacketData) } // process segment packet - if !pkt.SegCompleted { + if pkt.Header.IsFragmented() && !pkt.SegCompleted { return processSegmentPacket(ctx, pkt) } diff --git a/main.go b/main.go index 5863b4f..11423c8 100644 --- a/main.go +++ b/main.go @@ -3,17 +3,13 @@ package main import ( "flag" "fmt" - "net/http" "os" - "github.com/gin-gonic/gin" - "github.com/mitchellh/mapstructure" "github.com/rs/zerolog/log" + "github.com/fakeyanss/jt808-server-go/internal/api" "github.com/fakeyanss/jt808-server-go/internal/config" - "github.com/fakeyanss/jt808-server-go/internal/protocol/model" "github.com/fakeyanss/jt808-server-go/internal/server" - "github.com/fakeyanss/jt808-server-go/internal/storage" "github.com/fakeyanss/jt808-server-go/pkg/logger" "github.com/fakeyanss/jt808-server-go/pkg/routines" ) @@ -50,91 +46,7 @@ func main() { } routines.GoSafe(func() { serv.Start() }) - // web server structure - gin.SetMode(gin.ReleaseMode) - router := gin.Default() - cache := storage.GetDeviceCache() - geoCache := storage.GetGeoCache() - - router.GET("/device", func(c *gin.Context) { - c.JSON(http.StatusOK, cache.ListDevice()) - }) - - router.GET("/device/:phone/geo", func(c *gin.Context) { - phone := c.Param("phone") - - device, err := cache.GetDeviceByPhone(phone) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - return - } - - res := make(map[string]any) - err = mapstructure.Decode(device, &res) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - return - } - gis, err := geoCache.GetGeoLatestByPhone(phone) - if err != nil { - return - } - res["gis"] = gis - - c.JSON(http.StatusOK, res) - }) - - router.GET("/device/:phone/params", func(c *gin.Context) { - phone := c.Param("phone") - device, err := cache.GetDeviceByPhone(phone) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - return - } - session, err := storage.GetSession(device.SessionID) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - } - header := model.GenMsgHeader(device, 0x8104, session.GetNextSerialNum()) - msg := model.Msg8104{ - Header: header, - } - serv.Send(session.ID, &msg) - // todo: read channel from process 0104 msg - }) - - router.PUT("/device/:phone/params", func(c *gin.Context) { - phone := c.Param("phone") - params := model.DeviceParams{} - if err := c.ShouldBind(¶ms); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - } - device, err := cache.GetDeviceByPhone(phone) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - return - } - session, err := storage.GetSession(device.SessionID) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()}) - } - header := model.GenMsgHeader(device, 0x8103, session.GetNextSerialNum()) - msg := model.Msg8103{ - Header: header, - Parameters: ¶ms, - } - serv.Send(session.ID, &msg) - }) - - httpAddr := ":" + cfg.Server.Port.HTTPPort - routines.GoSafe(func() { - log.Debug().Msgf("Listening and serving HTTP on :%s", cfg.Server.Port.HTTPPort) - err = router.Run(httpAddr) - if err != nil { - log.Error().Err(err).Str("addr", httpAddr).Msg("Fail to run gin router") - os.Exit(1) - } - }) + routines.GoSafe(func() { api.Run(serv, cfg) }) select {} // block here }