commit 41cd8e9bb8ef05c1d9aea474587974e0cce4ec17 Author: crusader Date: Tue Aug 6 09:54:55 2019 +0900 Initial commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2f01cfb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}", + "env": {}, + "args": [] + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..afdafe2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "editor.tabSize": 2, + "editor.insertSpaces": true, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.autoClosingBrackets": "languageDefined", + "editor.trimAutoWhitespace": true, + "files.trimTrailingWhitespace": true, + "files.trimFinalNewlines": true, + "git.ignoreLimitWarning": true, + + "prettier.singleQuote": true, + + "files.exclude": { + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true + } +} diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 0000000..6217f53 --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "log" + "net" + "os" + "os/signal" + "syscall" + + "git.loafle.net/outsourcing/kiast-drone-collector/pkg/drone" +) + +func main() { + laddr, err := net.ResolveTCPAddr("tcp", ":48879") + if nil != err { + log.Fatalln(err) + } + listener, err := net.ListenTCP("tcp", laddr) + if nil != err { + log.Fatalln(err) + } + log.Println("listening on", listener.Addr()) + + // Make a new service and send it into the background. + service := drone.NewService() + go service.Serve(listener) + + // Handle SIGINT and SIGTERM. + ch := make(chan os.Signal) + signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) + log.Println(<-ch) + + // Stop the service gracefully. + service.Stop() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d605cae --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.loafle.net/outsourcing/kiast-drone-collector + +go 1.12 diff --git a/pkg/drone/protocol.go b/pkg/drone/protocol.go new file mode 100644 index 0000000..a43202a --- /dev/null +++ b/pkg/drone/protocol.go @@ -0,0 +1,13 @@ +package drone + +type DroneGPS struct { + Date string + Time string + Latitude string + Longitude string + Altitude string + Speed string + Direction string + Fixed string + LTEStatus string +} diff --git a/pkg/drone/service.go b/pkg/drone/service.go new file mode 100644 index 0000000..3eb0255 --- /dev/null +++ b/pkg/drone/service.go @@ -0,0 +1,95 @@ +package drone + +import ( + "log" + "net" + "sync" + "time" +) + +// An uninteresting service. +type Service struct { + ch chan bool + waitGroup *sync.WaitGroup +} + +// Make a new Service. +func NewService() *Service { + s := &Service{ + ch: make(chan bool), + waitGroup: &sync.WaitGroup{}, + } + s.waitGroup.Add(1) + return s +} + +// Accept connections and spawn a goroutine to serve each one. Stop listening +// if anything is received on the service's channel. +func (s *Service) Serve(listener *net.TCPListener) { + defer s.waitGroup.Done() + for { + select { + case <-s.ch: + log.Println("stopping listening on", listener.Addr()) + listener.Close() + return + default: + } + listener.SetDeadline(time.Now().Add(1e9)) + conn, err := listener.AcceptTCP() + if nil != err { + if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { + continue + } + log.Println(err) + } + log.Println(conn.RemoteAddr(), "connected") + s.waitGroup.Add(1) + go s.serve(conn) + } +} + +// Stop the service by closing the service's channel. Block until the service +// is really stopped. +func (s *Service) Stop() { + close(s.ch) + s.waitGroup.Wait() +} + +// Serve a connection by reading and writing what was read. That's right, this +// is an echo service. Stop reading and writing if anything is received on the +// service's channel but only after writing what was read. +func (s *Service) serve(conn *net.TCPConn) { + defer conn.Close() + defer s.waitGroup.Done() + for { + select { + case <-s.ch: + log.Println("disconnecting", conn.RemoteAddr()) + return + default: + } + conn.SetDeadline(time.Now().Add(1e9)) + buf := make([]byte, 4096) + if _, err := conn.Read(buf); nil != err { + if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { + continue + } + log.Println(err) + return + } + + // fixed + // $$GPS, 년월일, 시분초, 위도, 경도, 고도, 속도, 방향, A, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기 + // $$GPS,20190718,050519,37396586,126968913,798,0,0,A,2,255,255,-53,13,17-44,19-43,6-42,28-41 + + // unfixed + // $$GPS,,,,,,,, V, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기 + // $$GPS,,,,,,,,V,2,255,255,-53,4,17-44,19-42,6-40,28-40 + + // if _, err := conn.Write(buf); nil != err { + // log.Println(err) + // return + // } + } +}