github.com/la5nta/wl2k-go@v0.11.8/transport/ax25/agwpe/frame.go (about) 1 package agwpe 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io" 8 ) 9 10 type callsign [10]byte 11 12 func callsignFromString(s string) callsign { var c callsign; copy(c[:], s); return c } 13 14 func (c callsign) String() string { return strFromBytes(c[:]) } 15 16 func strFromBytes(b []byte) string { 17 idx := bytes.IndexByte(b[:], 0x00) 18 if idx < 0 { 19 return string(b) 20 } 21 return string(b[:idx]) 22 } 23 24 // header represents the fixed-size AGWPE header 25 type header struct { 26 Port uint8 // AGWPE Port 27 _ [3]byte // Reserved 28 DataKind kind // The frame code 29 _ byte // Reserved 30 PID uint8 // Frame PID 31 _ byte // Reserved 32 From callsign // From callsign 33 To callsign // To callsign 34 DataLen uint32 // Data length 35 _ uint32 // Reserved (User) 36 } 37 38 func (h *header) ReadFrom(r io.Reader) (int64, error) { 39 return int64(binary.Size(h)), binary.Read(r, binary.LittleEndian, h) 40 } 41 42 func (h header) WriteTo(w io.Writer) (int64, error) { 43 return int64(binary.Size(h)), binary.Write(w, binary.LittleEndian, h) 44 } 45 46 // frame represents the variable-size AGWPE frame 47 type frame struct { 48 header 49 Data []byte 50 } 51 52 func (f frame) String() string { 53 return fmt.Sprintf("Port: %d. Kind: %c. From: %v. To: %v, Data: %q", f.Port, f.DataKind, f.From, f.To, f.Data) 54 } 55 56 func (f frame) WriteTo(w io.Writer) (int64, error) { 57 f.DataLen = uint32(len(f.Data)) 58 n, err := f.header.WriteTo(w) 59 if err != nil { 60 return n, err 61 } 62 m, err := w.Write(f.Data) 63 return n + int64(m), err 64 } 65 66 func (f *frame) ReadFrom(r io.Reader) (int64, error) { 67 n, err := f.header.ReadFrom(r) 68 if err != nil { 69 return n, err 70 } 71 if cap(f.Data) < int(f.header.DataLen) { 72 f.Data = make([]byte, int(f.header.DataLen)) 73 } else { 74 f.Data = f.Data[:f.header.DataLen] 75 } 76 m, err := r.Read(f.Data) 77 switch { 78 case err != nil: 79 return n + int64(m), err 80 case m != len(f.Data): 81 return n + int64(m), io.ErrUnexpectedEOF 82 } 83 return n + int64(m), err 84 }