@@ -23,11 +23,13 @@ const (
2323 PullData
2424 PullResp
2525 PullACK
26+ TXACK
2627)
2728
2829// Protocol versions
2930const (
3031 ProtocolVersion1 uint8 = 0x01
32+ ProtocolVersion2 uint8 = 0x02
3133)
3234
3335// Errors
@@ -51,7 +53,7 @@ func (p PushDataPacket) MarshalBinary() ([]byte, error) {
5153 }
5254
5355 out := make ([]byte , 4 , len (pb )+ 12 )
54- out [0 ] = ProtocolVersion1
56+ out [0 ] = ProtocolVersion2
5557 binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
5658 out [3 ] = byte (PushData )
5759 out = append (out , p .GatewayMAC [0 :len (p .GatewayMAC )]... )
@@ -67,7 +69,7 @@ func (p *PushDataPacket) UnmarshalBinary(data []byte) error {
6769 if data [3 ] != byte (PushData ) {
6870 return errors .New ("gateway: identifier mismatch (PUSH_DATA expected)" )
6971 }
70- if data [0 ] != ProtocolVersion1 {
72+ if data [0 ] != ProtocolVersion2 {
7173 return ErrInvalidProtocolVersion
7274 }
7375
@@ -88,7 +90,7 @@ type PushACKPacket struct {
8890// MarshalBinary marshals the object in binary form.
8991func (p PushACKPacket ) MarshalBinary () ([]byte , error ) {
9092 out := make ([]byte , 4 )
91- out [0 ] = ProtocolVersion1
93+ out [0 ] = ProtocolVersion2
9294 binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
9395 out [3 ] = byte (PushACK )
9496 return out , nil
@@ -102,7 +104,7 @@ func (p *PushACKPacket) UnmarshalBinary(data []byte) error {
102104 if data [3 ] != byte (PushACK ) {
103105 return errors .New ("gateway: identifier mismatch (PUSH_ACK expected)" )
104106 }
105- if data [0 ] != ProtocolVersion1 {
107+ if data [0 ] != ProtocolVersion2 {
106108 return ErrInvalidProtocolVersion
107109 }
108110 p .RandomToken = binary .LittleEndian .Uint16 (data [1 :3 ])
@@ -118,7 +120,7 @@ type PullDataPacket struct {
118120// MarshalBinary marshals the object in binary form.
119121func (p PullDataPacket ) MarshalBinary () ([]byte , error ) {
120122 out := make ([]byte , 4 , 12 )
121- out [0 ] = ProtocolVersion1
123+ out [0 ] = ProtocolVersion2
122124 binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
123125 out [3 ] = byte (PullData )
124126 out = append (out , p .GatewayMAC [0 :len (p .GatewayMAC )]... )
@@ -133,7 +135,7 @@ func (p *PullDataPacket) UnmarshalBinary(data []byte) error {
133135 if data [3 ] != byte (PullData ) {
134136 return errors .New ("gateway: identifier mismatch (PULL_DATA expected)" )
135137 }
136- if data [0 ] != ProtocolVersion1 {
138+ if data [0 ] != ProtocolVersion2 {
137139 return ErrInvalidProtocolVersion
138140 }
139141 p .RandomToken = binary .LittleEndian .Uint16 (data [1 :3 ])
@@ -152,7 +154,7 @@ type PullACKPacket struct {
152154// MarshalBinary marshals the object in binary form.
153155func (p PullACKPacket ) MarshalBinary () ([]byte , error ) {
154156 out := make ([]byte , 4 )
155- out [0 ] = ProtocolVersion1
157+ out [0 ] = ProtocolVersion2
156158 binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
157159 out [3 ] = byte (PullACK )
158160 return out , nil
@@ -166,7 +168,7 @@ func (p *PullACKPacket) UnmarshalBinary(data []byte) error {
166168 if data [3 ] != byte (PullACK ) {
167169 return errors .New ("gateway: identifier mismatch (PULL_ACK expected)" )
168170 }
169- if data [0 ] != ProtocolVersion1 {
171+ if data [0 ] != ProtocolVersion2 {
170172 return ErrInvalidProtocolVersion
171173 }
172174 p .RandomToken = binary .LittleEndian .Uint16 (data [1 :3 ])
@@ -187,7 +189,7 @@ func (p PullRespPacket) MarshalBinary() ([]byte, error) {
187189 return nil , err
188190 }
189191 out := make ([]byte , 4 , 4 + len (pb ))
190- out [0 ] = ProtocolVersion1
192+ out [0 ] = ProtocolVersion2
191193 binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
192194 out [3 ] = byte (PullResp )
193195 out = append (out , pb ... )
@@ -202,13 +204,70 @@ func (p *PullRespPacket) UnmarshalBinary(data []byte) error {
202204 if data [3 ] != byte (PullResp ) {
203205 return errors .New ("gateway: identifier mismatch (PULL_RESP expected)" )
204206 }
205- if data [0 ] != ProtocolVersion1 {
207+ if data [0 ] != ProtocolVersion2 {
206208 return ErrInvalidProtocolVersion
207209 }
208210 p .RandomToken = binary .LittleEndian .Uint16 (data [1 :3 ])
209211 return json .Unmarshal (data [4 :], & p .Payload )
210212}
211213
214+ // TXACKPacket is used by the gateway to send a feedback to the server
215+ // to inform if a downlink request has been accepted or rejected by the
216+ // gateway.
217+ type TXACKPacket struct {
218+ RandomToken uint16
219+ Payload * TXACKPayload
220+ }
221+
222+ // MarshalBinary marshals the object into binary form.
223+ func (p TXACKPacket ) MarshalBinary () ([]byte , error ) {
224+ var pb []byte
225+ if p .Payload != nil {
226+ var err error
227+ pb , err = json .Marshal (p .Payload )
228+ if err != nil {
229+ return nil , err
230+ }
231+ }
232+
233+ out := make ([]byte , 4 , 4 + len (pb ))
234+ out [0 ] = ProtocolVersion2
235+ binary .LittleEndian .PutUint16 (out [1 :3 ], p .RandomToken )
236+ out [3 ] = byte (TXACK )
237+ out = append (out , pb ... )
238+ return out , nil
239+ }
240+
241+ // UnmarshalBinary decodes the object from binary form.
242+ func (p * TXACKPacket ) UnmarshalBinary (data []byte ) error {
243+ if len (data ) < 4 {
244+ return errors .New ("gateway: at least 4 bytes of data are expected" )
245+ }
246+ if data [3 ] != byte (TXACK ) {
247+ return errors .New ("gateway: identifier mismatch (TXACK expected)" )
248+ }
249+ if data [0 ] != ProtocolVersion2 {
250+ return ErrInvalidProtocolVersion
251+ }
252+ p .RandomToken = binary .LittleEndian .Uint16 (data [1 :3 ])
253+ if len (data ) > 4 {
254+ p .Payload = & TXACKPayload {}
255+ return json .Unmarshal (data [4 :], p .Payload )
256+ }
257+ return nil
258+ }
259+
260+ // TXACKPayload contains the TXACKPacket payload.
261+ type TXACKPayload struct {
262+ TXPKACK TXPKACK `json:"txpk_ack"`
263+ }
264+
265+ // TXPKACK contains the status information of the associated PULL_RESP
266+ // packet.
267+ type TXPKACK struct {
268+ Error string `json:"error"`
269+ }
270+
212271// PushDataPayload represents the upstream JSON data structure.
213272type PushDataPayload struct {
214273 RXPK []RXPK `json:"rxpk,omitempty"`
@@ -339,7 +398,7 @@ func GetPacketType(data []byte) (PacketType, error) {
339398 return PacketType (0 ), errors .New ("gateway: at least 4 bytes of data are expected" )
340399 }
341400
342- if data [0 ] != ProtocolVersion1 {
401+ if data [0 ] != ProtocolVersion2 {
343402 return PacketType (0 ), ErrInvalidProtocolVersion
344403 }
345404
0 commit comments