diff --git a/0x02_location_services.go b/0x02_location_services.go index aa72049..065cb1e 100644 --- a/0x02_location_services.go +++ b/0x02_location_services.go @@ -101,12 +101,12 @@ func (s *LocationServices) HandleSNAC(ctx context.Context, db *bun.DB, snac *osc respSnac.Data.WriteUint16(0) // TODO: warning level tlvs := []*oscar.TLV{ - oscar.NewTLV(1, util.Dword(0x80)), // user class - // oscar.NewTLV(6, util.Dword(uint32(requestedUser.Status))), // user status + oscar.NewTLV(1, util.Dword(0)), // user class + oscar.NewTLV(6, util.Dword(uint32(requestedUser.Status))), // user status // oscar.NewTLV(0x0a, util.Dword(binary.BigEndian.Uint32([]byte(SRV_HOST)))), // user external IP oscar.NewTLV(0x0f, util.Dword(uint32(time.Since(requestedUser.LastActivityAt).Seconds()))), // idle time oscar.NewTLV(0x03, util.Dword(uint32(time.Now().Unix()))), // TODO: signon time - // oscar.NewTLV(0x05, util.Dword(uint32(requestedUser.CreatedAt.Unix()))), // member since + oscar.NewTLV(0x05, util.Dword(uint32(requestedUser.CreatedAt.Unix()))), // member since } respSnac.Data.WriteUint16(uint16(len(tlvs))) // number of TLVs @@ -116,16 +116,16 @@ func (s *LocationServices) HandleSNAC(ctx context.Context, db *bun.DB, snac *osc // General info (Profile) if requestType == 1 { - respSnac.Data.WriteBinary(oscar.NewTLV(1, util.LPString(requestedUser.ProfileEncoding))) - respSnac.Data.WriteBinary(oscar.NewTLV(2, util.LPString(requestedUser.Profile))) + respSnac.Data.WriteBinary(oscar.NewTLV(1, []byte(requestedUser.ProfileEncoding))) + respSnac.Data.WriteBinary(oscar.NewTLV(2, []byte(requestedUser.Profile))) } // Request Type 2 = online status, no TLVs // Away message if requestType == 3 { - respSnac.Data.WriteBinary(oscar.NewTLV(3, util.LPString(requestedUser.AwayMessageEncoding))) - respSnac.Data.WriteBinary(oscar.NewTLV(4, util.LPString(requestedUser.AwayMessage))) + respSnac.Data.WriteBinary(oscar.NewTLV(3, []byte(requestedUser.AwayMessageEncoding))) + respSnac.Data.WriteBinary(oscar.NewTLV(4, []byte(requestedUser.AwayMessage))) } // TODO: Request Type 4 - User capabilities diff --git a/util/util.go b/util/util.go index 441e077..15d958e 100644 --- a/util/util.go +++ b/util/util.go @@ -1,6 +1,7 @@ package util import ( + "encoding/binary" "encoding/hex" "fmt" "strconv" @@ -54,13 +55,21 @@ func PanicIfError(err error) { } func Word(x uint16) []byte { - return []byte{byte(x >> 8), byte(x & 0xf)} + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, x) + return b } func Dword(x uint32) []byte { - return []byte{byte(x >> 24), byte(x >> 16), byte(x >> 8), byte(x & 0xf)} + b := make([]byte, 4) + binary.BigEndian.PutUint32(b, x) + return b } func LPString(x string) []byte { + return append([]byte{uint8(len(x))}, []byte(x)...) +} + +func LPUint16String(x string) []byte { return append(Word(uint16(len(x))), []byte(x)...) } diff --git a/util/util_test.go b/util/util_test.go new file mode 100644 index 0000000..98b62dc --- /dev/null +++ b/util/util_test.go @@ -0,0 +1,43 @@ +package util + +import ( + "bytes" + "encoding/binary" + "testing" +) + +func TestLPString(t *testing.T) { + expected := []byte{4, 0x74, 0x6f, 0x6f, 0x66} + result := LPString("toof") + if !bytes.Equal(expected, result) { + t.Errorf("expected bytes to look like %+v, got %+v", expected, result) + } +} + +func TestLPUin16String(t *testing.T) { + expected := []byte{0, 4, 0x74, 0x6f, 0x6f, 0x66} + result := LPUint16String("toof") + if !bytes.Equal(expected, result) { + t.Errorf("expected bytes to look like %+v, got %+v", expected, result) + } +} + +func TestLPUStringLong(t *testing.T) { + str := `TEST of profile` + result := LPString(str) + + resultLength := uint8(result[0]) + if int(resultLength) != len(str) { + t.Errorf("expected length prefix to be %x but got %x", len(str), resultLength) + } +} + +func TestLPUint16StringLong(t *testing.T) { + str := `TEST of profile` + result := LPUint16String(str) + + resultLength := binary.BigEndian.Uint16(result[:2]) + if int(resultLength) != len(str) { + t.Errorf("expected length prefix to be %x but got %x", len(str), resultLength) + } +}