| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package main
- import (
- "crypto/aes"
- "crypto/cipher"
- "encoding/base64"
- "encoding/binary"
- "fmt"
- "github.com/imroc/req"
- "net"
- "time"
- )
- type serverLog struct {
- ID uint16 `json:"id"`
- Stamp time.Time `json:"stamp"`
- Log string `json:"log"`
- }
- type serverMsg struct {
- id uint16
- acc uint32
- light bool
- }
- var serverLogs = []serverLog{{0, time.Now(), "Server started..."}}
- func sendData(msg *serverMsg) {
- defer logPanic()
- c := config.Influx
- if c == nil {
- return
- }
- var light int
- if light = 0; msg.light { light = 1 }
- now := time.Now().UnixNano()
- data := fmt.Sprintf("accelerometer,board=%d value=%d %d\n", msg.id, msg.acc, now)
- data += fmt.Sprintf("light,board=%d value=%d %d", msg.id, light, now)
- auth := base64.StdEncoding.EncodeToString([]byte(c.Username+":"+c.Password))
- head := req.Header{
- "Authorization": "Basic " + auth,
- }
- r, err := req.Post(fmt.Sprintf("http://%s/write?db=%s", c.Domain, c.Database), head, data)
- if err != nil {
- errCheckPanic(err, "Failed send to influx server")
- }
- if r.Response().StatusCode > 300 {
- fmt.Printf("Influx server returned code %d\n", r.Response().StatusCode)
- }
- }
- func serveConnection(conn net.Conn) {
- defer logPanic()
- defer fmt.Printf("Connection closed %s\n", conn.RemoteAddr().String())
- defer conn.Close()
- fmt.Printf("Connection from %s\n", conn.RemoteAddr().String())
- buf := make([]byte, 4)
- for {
- _, err := conn.Read(buf)
- errCheckPanic(err, "Connection failed with %s", conn.RemoteAddr().String())
- id := binary.LittleEndian.Uint16(buf[:2])
- board, ok := config.Boards[id]
- if !ok {
- fmt.Printf("Connection with ID %d is not registerd\n", id)
- break
- }
- board.LastSeen = time.Now()
- msglen := binary.LittleEndian.Uint16(buf[2:])
- fmt.Printf("Connection from ID %d message length %d\n %x\n", id, msglen, buf)
- payload := make([]byte, msglen)
- _, err = conn.Read(payload)
- errCheckPanic(err, "Connection failed %s device #%d", conn.RemoteAddr().String(), id)
- fmt.Printf("Payload: %x\n", payload)
- message := make([]byte, msglen-16)
- block, err := aes.NewCipher(board.KEY)
- errCheckPanic(err, "Decryption failed %s device #%d", conn.RemoteAddr().String(), id)
- mode := cipher.NewCBCDecrypter(block, payload[:16])
- mode.CryptBlocks(message, payload[16:])
- fmt.Printf("Message: %x\n", message)
- msg := serverMsg{
- id,
- binary.LittleEndian.Uint32(message[:4]),
- message[4] != 0x00,
- }
- sendData(&msg)
- smessage := fmt.Sprintf("ACC: %d, LIGHT: %t", msg.acc, msg.light)
- serverLogs = append([]serverLog{{id, board.LastSeen, smessage}}, serverLogs...)
- if len(serverLogs) > 150 {
- serverLogs = serverLogs[:len(serverLogs)-1]
- }
- fmt.Printf("Message: %x\n%s\n", message, smessage)
- }
- }
- func serve(address string) {
- ln, err := net.Listen("tcp", address)
- errCheckExit(err,"Failed accept connection")
- defer ln.Close()
- fmt.Printf("Service socket ready at %s\n", address)
- for {
- conn, err := ln.Accept()
- errCheckExit(err,"Failed accept connection %s", conn.RemoteAddr().String())
- go serveConnection(conn)
- }
- }
|