nex-go/rmc.go
2018-09-25 10:10:20 -04:00

108 lines
2.6 KiB
Go

package nex
import (
"bytes"
"encoding/binary"
"fmt"
"os"
)
// RMCRequestHeader represents a RMC protocol request header
type RMCRequestHeader struct {
Size uint32
ProtocolID uint8
CallID uint32
MethodID uint32
}
// RMCRequest represents a RMC protocol request
type RMCRequest struct {
Header RMCRequestHeader
Parameters []byte
}
// NewRMCRequest returns a new RMCRequest
func NewRMCRequest(Data []byte) RMCRequest {
buffer := bytes.NewReader(Data)
var Header RMCRequestHeader
if err := binary.Read(buffer, binary.LittleEndian, &Header); err != nil {
fmt.Println(err)
}
return RMCRequest{
Header: Header,
Parameters: Data[13:],
}
}
// RMCResponse represents a RMC protocol response
type RMCResponse struct {
Size uint32
ProtocolID int
Success int
Body interface{}
CallID uint32
}
// RMCSuccess represents a successful RMC payload
type RMCSuccess struct {
MethodID uint32
Data []byte
}
// RMCError represents a RMC error payload
type RMCError struct {
ErrorCode uint32
}
// NewRMCResponse returns a new RMCResponse
func NewRMCResponse(ProtocolID int, CallID uint32) RMCResponse {
return RMCResponse{
ProtocolID: ProtocolID,
CallID: CallID,
}
}
// SetSuccess sets the RMCResponse payload to an instance of RMCSuccess
func (Response *RMCResponse) SetSuccess(MethodID uint32, Data []byte) {
Response.Success = 1
Response.Body = RMCSuccess{MethodID | 0x8000, Data}
Response.Size = uint32(14 + len(Data))
}
// SetError sets the RMCResponse payload to an instance of RMCError
func (Response *RMCResponse) SetError(ErrorCode uint32) {
Response.Success = 0
Response.Body = RMCError{ErrorCode}
Response.Size = 14
}
// Bytes converts a RMCResponse struct into a usable byte array
func (Response *RMCResponse) Bytes() []byte {
data := bytes.NewBuffer(make([]byte, 0, Response.Size+1))
binary.Write(data, binary.LittleEndian, uint32(Response.Size))
binary.Write(data, binary.LittleEndian, byte(Response.ProtocolID))
binary.Write(data, binary.LittleEndian, byte(Response.Success))
if Response.Success == 1 {
body := Response.Body.(RMCSuccess)
binary.Write(data, binary.LittleEndian, uint32(Response.CallID))
binary.Write(data, binary.LittleEndian, uint32(body.MethodID))
binary.Write(data, binary.LittleEndian, body.Data)
} else if Response.Success == 0 {
body := Response.Body.(RMCError)
binary.Write(data, binary.LittleEndian, uint32(body.ErrorCode))
binary.Write(data, binary.LittleEndian, uint32(Response.CallID))
} else {
fmt.Println("Invalid RMC success type", Response.Success)
os.Exit(1)
}
return data.Bytes()
}