package n9m import ( "bytes" "encoding/json" "fmt" "log" "github.com/icza/bitio" "github.com/tidwall/gjson" ) // Extract fields from JSON func (e *Package) SaveJsonFields() { if value, exist := e.Payload["MODULE"]; exist { e.Json.Module = value.(string) } else { e.Json.Module = "" } if value, exist := e.Payload["KEY"]; exist { e.Json.Key = value.(string) } else { e.Json.Key = "" } if value, exist := e.Payload["OPERATION"]; exist { e.Json.Operation = value.(string) } else { e.Json.Operation = "" } if value, exist := e.Payload["RESPONSE"]; exist { e.Json.Response = value.(map[string]interface{}) } else { e.Json.Response = make(map[string]interface{}) } if value, exist := e.Payload["PARAMETER"]; exist { e.Json.Parameters = value.(map[string]interface{}) } else if value, exist := e.Payload["PARAMETERS"]; exist { e.Json.Parameters = value.(map[string]interface{}) } else { e.Json.Parameters = make(map[string]interface{}) } } // Read package func (e *Package) ReadPackage() bool { if len(e.Accum) < 12 { return false } r := bitio.NewReader(bytes.NewBuffer(e.Accum)) e.Version = r.TryReadBits(2) e.Encription = r.TryReadBits(1) e.Mark = r.TryReadBits(1) e.CC = r.TryReadBits(4) e.PayloadType = r.TryReadBits(8) e.SSRC = r.TryReadBits(16) // log.Println(e.PayloadType) is_special := e.Encription == 1 && e.Mark == 1 if is_special { r.TryReadBits(8 * 4) e.PayloadLen = r.TryReadBits(8) r.TryReadBits(3 * 8) if uint64(len(e.Accum)) < e.PayloadLen+12 { return false } } else { e.PayloadLen = r.TryReadBits(32) // WTF: e.CC is useless for i := uint64(0); i < 1; i++ { e.CSRC[i] = r.TryReadBits(32) } } numOfBytes := 0 rawbytes := []byte{} if e.PayloadLen != 0 { if e.PayloadLen > 1000000 { log.Printf("%v\n", e) log.Panicln("CORRUPTED PACKAGE") } rawbytes = make([]byte, e.PayloadLen) numOfBytes, _ = r.Read(rawbytes) } if numOfBytes != int(e.PayloadLen) { return false } e.Raw = e.Accum[:12+e.PayloadLen] e.Accum = e.Accum[12+e.PayloadLen:] e.RawPayload = rawbytes var ok bool e.GPayload = gjson.Parse(string(rawbytes)) e.Payload, ok = e.GPayload.Value().(map[string]interface{}) if !ok { e.Payload = gjson.Parse("{}").Value().(map[string]interface{}) } e.SaveJsonFields() return e.PayloadLen > 0 } func (e *Package) PackPackage() []byte { e.SaveJsonFields() b := &bytes.Buffer{} w := bitio.NewWriter(b) w.TryWriteBits(e.Version, 2) w.TryWriteBits(e.Encription, 1) w.TryWriteBits(e.Mark, 1) w.TryWriteBits(e.CC, 4) w.TryWriteBits(e.PayloadType, 8) w.TryWriteBits(e.SSRC, 16) conv, err := json.Marshal(e.Payload) if err != nil { fmt.Println(err) return nil } e.PayloadLen = uint64(len(conv)) if e.PayloadLen != 0 { e.PayloadLen++ } w.TryWriteBits(e.PayloadLen, 32) // WTF: e.CC is useless for i := uint64(0); i < 1; i++ { w.TryWriteBits(e.CSRC[i], 32) } if e.PayloadLen != 0 { w.Write(conv) w.Write([]byte{0}) } w.Close() return b.Bytes() } func (e *Package) PackRawPackage() []byte { b := &bytes.Buffer{} w := bitio.NewWriter(b) w.TryWriteBits(e.Version, 2) w.TryWriteBits(e.Encription, 1) w.TryWriteBits(e.Mark, 1) w.TryWriteBits(e.CC, 4) w.TryWriteBits(e.PayloadType, 8) w.TryWriteBits(e.SSRC, 16) e.PayloadLen = uint64(len(e.RawPayload) + 1) w.TryWriteBits(e.PayloadLen, 32) // WTF: e.CC is useless for i := uint64(0); i < 1; i++ { w.TryWriteBits(e.CSRC[i], 32) } if e.PayloadLen != 0 { w.Write(e.RawPayload) w.Write([]byte{0}) } w.Close() return b.Bytes() }