package data import ( "encoding/binary" "fmt" "net" "time" log "github.com/sirupsen/logrus" ) // SocketMSGType kind of packages type SocketMSGType uint32 const ( SocketMSGTypeRequest SocketMSGType = (1 << 0) SocketMSGTypeResponse SocketMSGType = (1 << 1) SocketMSGTypeClient SocketMSGType = (1 << 2) SocketMSGTypeStats SocketMSGType = (1 << 3) ) func (a SocketMSGType) Is(b SocketMSGType) bool { log.Debugf("SocketType: %x & %x = %x -> %b", a, b, (a & b), (a&b) > 0) return (a & b) > 0 } // SocketMSG package of wifictld format type SocketMSG struct { Types SocketMSGType Client *WifiClient } func NewSocketMSG(obj []byte) (*SocketMSG, error) { msg := &SocketMSG{} if err := msg.Unmarshal(obj); err != nil { return nil, err } return msg, nil } func (msg *SocketMSG) Marshal() ([]byte, error) { obj := make([]byte, MaxDataGramSize) pos := 0 binary.BigEndian.PutUint32(obj[pos:(pos+4)], uint32(msg.Types)) pos += 4 if msg.Types.Is(SocketMSGTypeClient) { obj[pos] = msg.Client.Addr[0] pos++ obj[pos] = msg.Client.Addr[1] pos++ obj[pos] = msg.Client.Addr[2] pos++ obj[pos] = msg.Client.Addr[3] pos++ obj[pos] = msg.Client.Addr[4] pos++ obj[pos] = msg.Client.Addr[5] pos++ binary.BigEndian.PutUint32(obj[pos:(pos+4)], uint32(msg.Client.Time.Unix())) pos += 4 binary.BigEndian.PutUint16(obj[pos:(pos+2)], msg.Client.TryProbe) pos += 2 binary.BigEndian.PutUint16(obj[pos:(pos+2)], msg.Client.TryAuth) pos += 2 if msg.Client.Connected { obj[pos] = byte(1) } pos++ if msg.Client.Authed { obj[pos] = byte(1) } pos++ binary.BigEndian.PutUint16(obj[pos:(pos+2)], msg.Client.FreqHighest) pos += 2 binary.BigEndian.PutUint16(obj[pos:(pos+2)], uint16(msg.Client.SignalLowFreq)) pos += 2 binary.BigEndian.PutUint16(obj[pos:(pos+2)], uint16(msg.Client.SignalHighFreq)) //pos += 2 } return obj, nil } func (msg *SocketMSG) Unmarshal(obj []byte) error { log.Debugf("hex unmarshal: %x", obj) pos := 0 msg.Types = SocketMSGType(binary.BigEndian.Uint32(obj[pos:(pos + 4)])) pos += 4 if msg.Types.Is(SocketMSGTypeClient) { msg.Client = &WifiClient{ Addr: net.HardwareAddr(obj[pos:(pos + 6)]), Time: time.Unix(int64(binary.BigEndian.Uint32(obj[(pos+6):(pos+10)])), 0), TryProbe: binary.BigEndian.Uint16(obj[(pos + 10):(pos + 12)]), TryAuth: binary.BigEndian.Uint16(obj[(pos + 12):(pos + 14)]), Connected: (obj[(pos+14)] == 1), Authed: (obj[(pos+15)] == 1), FreqHighest: binary.BigEndian.Uint16(obj[(pos + 16):(pos + 18)]), SignalLowFreq: int16(binary.BigEndian.Uint16(obj[(pos + 18):(pos + 20)])), SignalHighFreq: int16(binary.BigEndian.Uint16(obj[(pos + 20):(pos + 22)])), } //pos += 22 } return nil } func (msg *SocketMSG) String() string { answer := "" if msg.Types.Is(SocketMSGTypeRequest) { answer += "request " } if msg.Types.Is(SocketMSGTypeResponse) { answer += "response " } if msg.Types.Is(SocketMSGTypeClient) { answer += fmt.Sprintf("client(mac=%s freq=%d ssi_l=%d ssi_h=%d tprobe=%d tauth=%d authed=%v time=%s) ", msg.Client.Addr, msg.Client.FreqHighest, msg.Client.SignalLowFreq, msg.Client.SignalHighFreq, msg.Client.TryProbe, msg.Client.TryAuth, msg.Client.Authed, msg.Client.Time.String()) } return answer }