@@ -95,44 +95,56 @@ func (communication *Communication) sendFrame(msg string) error {
95
95
if dataLen == 0 {
96
96
return nil
97
97
}
98
- send := func (header []byte , readFrom * bytes.Buffer ) error {
99
- buf := newBuffer ()
100
- buf .Write (header )
101
- buf .Write (readFrom .Next (writeReportSize - buf .Len ()))
102
- for buf .Len () < writeReportSize {
103
- buf .WriteByte (0xee )
104
- }
105
- x := buf .Bytes () // needs to be in a var: https://github.com/golang/go/issues/14210#issuecomment-346402945
106
- _ , err := communication .device .Write (x )
107
- return errp .WithMessage (errp .WithStack (err ), "Failed to send message" )
98
+
99
+ outLen := 64
100
+ // 57 payload bytes fit in first frame, 59 in rest
101
+ if dataLen > 57 {
102
+ contLen := dataLen - 57
103
+ outLen += ((contLen + 59 - 1 ) / 59 ) * 64
108
104
}
105
+
109
106
readBuffer := bytes .NewBufferString (msg )
107
+ out := newBuffer ()
108
+ out .Grow (outLen )
109
+
110
110
// init frame
111
- header := newBuffer ()
112
- if err := binary .Write (header , binary .BigEndian , cid ); err != nil {
111
+ if err := binary .Write (out , binary .BigEndian , cid ); err != nil {
113
112
return errp .WithStack (err )
114
113
}
115
- if err := binary .Write (header , binary .BigEndian , communication .cmd ); err != nil {
114
+ if err := binary .Write (out , binary .BigEndian , communication .cmd ); err != nil {
116
115
return errp .WithStack (err )
117
116
}
118
- if err := binary .Write (header , binary .BigEndian , uint16 (dataLen & 0xFFFF )); err != nil {
117
+ if err := binary .Write (out , binary .BigEndian , uint16 (dataLen & 0xFFFF )); err != nil {
119
118
return errp .WithStack (err )
120
119
}
121
- if err := send (header .Bytes (), readBuffer ); err != nil {
122
- return err
123
- }
120
+ // init frame has a 7 byte header
121
+ out .Write (readBuffer .Next (writeReportSize - 7 ))
122
+
123
+ // cont frames
124
124
for seq := 0 ; readBuffer .Len () > 0 ; seq ++ {
125
- // cont frame
126
- header = newBuffer ()
127
- if err := binary .Write (header , binary .BigEndian , cid ); err != nil {
125
+ if err := binary .Write (out , binary .BigEndian , cid ); err != nil {
128
126
return errp .WithStack (err )
129
127
}
130
- if err := binary .Write (header , binary .BigEndian , uint8 (seq )); err != nil {
128
+ if err := binary .Write (out , binary .BigEndian , uint8 (seq )); err != nil {
131
129
return errp .WithStack (err )
132
130
}
133
- if err := send (header .Bytes (), readBuffer ); err != nil {
134
- return err
131
+ // cont frame has a 5 byte header
132
+ out .Write (readBuffer .Next (writeReportSize - 5 ))
133
+ }
134
+
135
+ // Make out buffer multiple of 64 bytes
136
+ for i := out .Len () % 64 ; i < writeReportSize ; i ++ {
137
+ out .WriteByte (0xEE )
138
+ }
139
+
140
+ // Write out packets, write as many bytes as possible in each iteration
141
+ for out .Len () > 0 {
142
+ x := out .Bytes () // needs to be in a var: https://github.com/golang/go/issues/14210#issuecomment-346402945
143
+ n , err := communication .device .Write (x )
144
+ if err != nil {
145
+ return errp .WithMessage (errp .WithStack (err ), "Failed to send message" )
135
146
}
147
+ out .Next (n )
136
148
}
137
149
return nil
138
150
}
0 commit comments