main.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. //go:generate reform --gofmt=false models
  2. package main
  3. import (
  4. "database/sql"
  5. "devel.mephi.ru/dyokunev/cardlogger-parser/models"
  6. "fmt"
  7. "net"
  8. "time"
  9. )
  10. func checkError(err error) {
  11. if err != nil {
  12. panic(err)
  13. }
  14. }
  15. type stage int
  16. const (
  17. STAGE_IDLE stage = 0
  18. STAGE_KEEPALIVE stage = 1
  19. STAGE_STARTING stage = 2
  20. STAGE_GETTINGVALUE stage = 3
  21. )
  22. type status struct {
  23. Stage stage
  24. Pos byte
  25. T byte
  26. Value [3]int
  27. }
  28. func gotKeepAlive(port int) {
  29. //fmt.Println("gotKeepAlive(): port == ", port)
  30. keepaliveRecord, err := models.KeepaliveRecordSQL.First(port)
  31. if err != nil && err != sql.ErrNoRows {
  32. fmt.Println("SQL error: ", err)
  33. }
  34. keepaliveRecord.UpdatedAt = time.Now()
  35. err = keepaliveRecord.Save()
  36. if err != nil {
  37. fmt.Println("SQL error: ", err)
  38. }
  39. }
  40. func gotValue(port int, valueA [3]int) {
  41. //fmt.Println("gotValue(): port == ", port, "; valueA == ", valueA)
  42. if valueA[0] != valueA[1] || valueA[1] != valueA[2] {
  43. fmt.Println("values doesn't match: ", valueA, "; port == ", port)
  44. }
  45. err := models.LogRecord{
  46. Port: port,
  47. Value: valueA[0],
  48. CreatedAt: time.Now(),
  49. }.Create()
  50. if err != nil {
  51. fmt.Println("SQL error: ", err)
  52. }
  53. }
  54. func main() {
  55. addr, err := net.ResolveUDPAddr("udp", ":36400")
  56. checkError(err)
  57. conn, err := net.ListenUDP("udp", addr)
  58. checkError(err)
  59. defer conn.Close()
  60. buf := make([]byte, 1024)
  61. curStatusMap := make(map[int]status)
  62. considerChar := func(port int, c byte) {
  63. curStatus := curStatusMap[port]
  64. defer func() { /*fmt.Println("curStatus ->", curStatus);*/ curStatusMap[port] = curStatus }()
  65. switch curStatus.Stage {
  66. case STAGE_IDLE:
  67. switch c {
  68. case 0xfe:
  69. curStatus.Stage = STAGE_KEEPALIVE
  70. case 0xff:
  71. curStatus.Stage = STAGE_STARTING
  72. default:
  73. goto errorReset
  74. }
  75. curStatus.Pos = 1
  76. case STAGE_KEEPALIVE:
  77. if c != 0xfe {
  78. goto errorReset
  79. }
  80. curStatus.Pos++
  81. if curStatus.Pos == 4 {
  82. gotKeepAlive(port)
  83. goto reset
  84. }
  85. return
  86. case STAGE_STARTING:
  87. if c != 0xff-curStatus.Pos {
  88. goto errorReset
  89. }
  90. curStatus.Pos++
  91. if curStatus.Pos == 4 {
  92. curStatus.Pos = 0
  93. curStatus.Stage = STAGE_GETTINGVALUE
  94. return
  95. }
  96. case STAGE_GETTINGVALUE:
  97. curStatus.Value[curStatus.T] |= int(c) << (curStatus.Pos * 8)
  98. curStatus.Pos++
  99. if curStatus.Pos != 4 {
  100. return
  101. }
  102. curStatus.Pos = 0
  103. curStatus.T++
  104. if curStatus.T != 3 {
  105. return
  106. }
  107. gotValue(port, curStatus.Value)
  108. goto reset
  109. default:
  110. panic(fmt.Errorf("Unknown stage: %v", curStatus.Stage))
  111. }
  112. return
  113. errorReset:
  114. fmt.Println("got invalid char (", c, ") from port ", port ,", reset (curStatus == ", curStatus, ").")
  115. reset:
  116. // fmt.Println("reset")
  117. curStatus = status{}
  118. }
  119. for {
  120. n, addr, err := conn.ReadFromUDP(buf)
  121. for i := 0; i < n; i++ {
  122. considerChar(addr.Port, buf[i])
  123. }
  124. if err != nil {
  125. fmt.Println("Error: ", err)
  126. }
  127. }
  128. return
  129. }