Skip to content

Commit

Permalink
Add sending reply
Browse files Browse the repository at this point in the history
  • Loading branch information
xylo04 committed Nov 1, 2020
1 parent 64a87aa commit c480745
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 4 deletions.
43 changes: 41 additions & 2 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package wsjtx
import (
"bytes"
"encoding/binary"
"math"
)

func encodeHeartbeat(msg HeartbeatMessage) ([]byte, error) {
Expand All @@ -23,6 +24,21 @@ func encodeClear(msg ClearMessage) ([]byte, error) {
return e.finish()
}

func encodeReply(msg ReplyMessage) ([]byte, error) {
e := newEncoder()
e.encodeUint32(replyNum)
e.encodeUtf8(msg.Id)
e.encodeUint32(msg.Time)
e.encodeInt32(msg.Snr)
e.encodeFloat64(msg.DeltaTimeSec)
e.encodeUint32(msg.DeltaFrequencyHz)
e.encodeUtf8(msg.Mode)
e.encodeUtf8(msg.Message)
e.encodeBool(msg.LowConfidence)
e.encodeUint8(msg.Modifiers)
return e.finish()
}

func encodeClose(msg CloseMessage) ([]byte, error) {
e := newEncoder()
e.encodeUint32(closeNum)
Expand All @@ -42,14 +58,37 @@ func newEncoder() encoder {
return e
}

func (e encoder) encodeUint8(num uint8) {
e.buf.WriteByte(num)
}

func (e encoder) encodeUint32(num uint32) {
bin := make([]byte, 4)
binary.BigEndian.PutUint32(bin, num)
e.buf.Write(bin)
}

func (e encoder) encodeUint8(num uint8) {
e.buf.WriteByte(num)
func (e encoder) encodeUint64(num uint64) {
bin := make([]byte, 8)
binary.BigEndian.PutUint64(bin, num)
e.buf.Write(bin)
}

func (e encoder) encodeBool(b bool) {
if b {
e.encodeUint8(1)
} else {
e.encodeUint8(0)
}

}

func (e encoder) encodeInt32(num int32) {
e.encodeUint32(uint32(num))
}

func (e encoder) encodeFloat64(num float64) {
e.encodeUint64(math.Float64bits(num))
}

func (e encoder) encodeUtf8(str string) {
Expand Down
46 changes: 44 additions & 2 deletions encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ func Test_encodeHeartbeat(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
got, err := encodeHeartbeat(tt.args.msg)
if (err != nil) != tt.wantErr {
t.Errorf("encodeClear() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("encodeHeartbeat() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("encodeClear() got = %v, want %v", got, tt.want)
t.Errorf("encodeHeartbeat() got = %v, want %v", got, tt.want)
}
})
}
Expand Down Expand Up @@ -74,6 +74,48 @@ func Test_encodeClear(t *testing.T) {
}
}

func Test_encodeReply(t *testing.T) {
type args struct {
msg ReplyMessage
}
wantBin, _ := hex.DecodeString("adbccbda00000002000000040000000657534a542d580259baf8fffffffb3fc99999a000000000000516000000017e0000000e4a4132454a50204e3442502037330000")
tests := []struct {
name string
args args
want []byte
wantErr bool
}{
{
name: "encodeReply",
args: args{msg: ReplyMessage{
Id: "WSJT-X",
Time: 39435000,
Snr: -5,
DeltaTimeSec: 0.20000000298023224,
DeltaFrequencyHz: 1302,
Mode: "~",
Message: "JA2EJP N4BP 73",
LowConfidence: false,
Modifiers: 0,
}},
want: wantBin,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := encodeReply(tt.args.msg)
if (err != nil) != tt.wantErr {
t.Errorf("encodeReply() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("encodeReply() got = %v, want %v", got, tt.want)
}
})
}
}

func Test_encodeClose(t *testing.T) {
type args struct {
msg CloseMessage
Expand Down
27 changes: 27 additions & 0 deletions messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,33 @@ type ClearMessage struct {

const clearNum = 3

/*
In order for a server to provide a useful cooperative service
to WSJT-X it is possible for it to initiate a QSO by sending
this message to a client. WSJT-X filters this message and only
acts upon it if the message exactly describes a prior decode
and that decode is a CQ or QRZ message. The action taken is
exactly equivalent to the user double clicking the message in
the "Band activity" window.
In only.
https://sourceforge.net/p/wsjt/wsjtx/ci/8f99fcce/tree/Network/NetworkMessage.hpp#l253
*/
type ReplyMessage struct {
Id string `json:"id"`
Time uint32 `json:"time"`
Snr int32 `json:"snr"`
DeltaTimeSec float64 `json:"deltaTime"`
DeltaFrequencyHz uint32 `json:"deltaFrequency"`
Mode string `json:"mode"`
Message string `json:"message"`
LowConfidence bool `json:"lowConfidence"`
Modifiers uint8 `json:"modifiers"`
}

const replyNum = 4

/*
The QSO logged message is sent when the WSJT-X user accepts the "Log QSO" dialog by clicking
the "OK" button.
Expand Down
8 changes: 8 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ func (s *Server) Clear(msg ClearMessage) error {
return err
}

// Initiate a reply to an earlier decode. The decode message must have started
// with CQ or QRZ.
func (s *Server) Reply(msg ReplyMessage) error {
msgBytes, _ := encodeReply(msg)
_, err := s.conn.WriteTo(msgBytes, s.remoteAddr)
return err
}

// Send a message to WSJT-X to close the program.
func (s *Server) Close(msg CloseMessage) error {
msgBytes, _ := encodeClose(msg)
Expand Down

0 comments on commit c480745

Please sign in to comment.