8
8
import java .util .ArrayList ;
9
9
import java .util .List ;
10
10
11
- import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .*;
11
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_ARTOO_INPUT_REPORT_MESSAGE ;
12
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_CABLE_CAM_OPTIONS ;
13
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_CABLE_CAM_WAYPOINT ;
14
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_FOLLOW_OPTIONS ;
15
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_GET_BUTTON_SETTING ;
16
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_GOPRO_RECORD ;
17
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_GOPRO_REQUEST_STATE ;
18
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_GOPRO_SET_REQUEST ;
19
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_GOPRO_STATE ;
20
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_MESSAGE_GET_CURRENT_SHOT ;
21
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_MESSAGE_LOCATION ;
22
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_MESSAGE_RECORD_POSITION ;
23
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_MESSAGE_SET_CURRENT_SHOT ;
24
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_MESSAGE_SHOT_MANAGER_ERROR ;
25
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_SET_BUTTON_SETTING ;
26
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_SHOT_ERROR ;
27
+ import static com .o3dr .services .android .lib .drone .companion .solo .tlv .TLVMessageTypes .TYPE_SOLO_SHOT_OPTIONS ;
12
28
13
29
/**
14
30
* Utility class to generate tlv packet from received bytes.
@@ -37,42 +53,52 @@ public static List<TLVPacket> parseTLVPacket(ByteBuffer packetBuffer) {
37
53
final ByteOrder originalOrder = packetBuffer .order ();
38
54
packetBuffer .order (TLVPacket .TLV_BYTE_ORDER );
39
55
40
- while (packetBuffer .remaining () > 0 ) {
41
- int messageType = -1 ;
42
- try {
56
+ int messageType = -1 ;
57
+ try {
58
+
59
+ while (packetBuffer .remaining () >= TLVPacket .MIN_TLV_PACKET_SIZE ) {
43
60
messageType = packetBuffer .getInt ();
44
61
final int messageLength = packetBuffer .getInt ();
45
- Log .d (TAG , String .format ("Received message %d of with value of length %d. Remaining buffer size is %d" , messageType , messageLength , packetBuffer .remaining ()));
62
+
63
+ int remaining = packetBuffer .remaining ();
64
+ Log .d (TAG , String .format ("Received message %d of with value of length %d. Remaining buffer size is %d" , messageType , messageLength , remaining ));
65
+
66
+ if (messageLength > remaining ) {
67
+ break ;
68
+ }
69
+
70
+ TLVPacket packet = null ;
71
+ packetBuffer .mark ();
46
72
47
73
switch (messageType ) {
48
74
case TYPE_SOLO_MESSAGE_GET_CURRENT_SHOT :
49
75
case TYPE_SOLO_MESSAGE_SET_CURRENT_SHOT : {
50
76
final int shotType = packetBuffer .getInt ();
51
77
if (messageType == TYPE_SOLO_MESSAGE_GET_CURRENT_SHOT )
52
- packetList . add ( new SoloMessageShotGetter (shotType ) );
78
+ packet = new SoloMessageShotGetter (shotType );
53
79
else
54
- packetList . add ( new SoloMessageShotSetter (shotType ) );
80
+ packet = new SoloMessageShotSetter (shotType );
55
81
break ;
56
82
}
57
83
58
84
case TYPE_SOLO_MESSAGE_LOCATION : {
59
85
final double latitude = packetBuffer .getDouble ();
60
86
final double longitude = packetBuffer .getDouble ();
61
87
final float altitude = packetBuffer .getFloat ();
62
- packetList . add ( new SoloMessageLocation (latitude , longitude , altitude ) );
88
+ packet = new SoloMessageLocation (latitude , longitude , altitude );
63
89
break ;
64
90
}
65
91
66
92
case TYPE_SOLO_MESSAGE_RECORD_POSITION : {
67
- packetList . add ( new SoloMessageRecordPosition () );
93
+ packet = new SoloMessageRecordPosition ();
68
94
break ;
69
95
}
70
96
71
97
case TYPE_SOLO_CABLE_CAM_OPTIONS : {
72
98
final short camInterpolation = packetBuffer .getShort ();
73
99
final short yawDirectionClockwise = packetBuffer .getShort ();
74
100
final float cruiseSpeed = packetBuffer .getFloat ();
75
- packetList . add ( new SoloCableCamOptions (camInterpolation , yawDirectionClockwise , cruiseSpeed ) );
101
+ packet = new SoloCableCamOptions (camInterpolation , yawDirectionClockwise , cruiseSpeed );
76
102
break ;
77
103
}
78
104
@@ -83,35 +109,35 @@ public static List<TLVPacket> parseTLVPacket(ByteBuffer packetBuffer) {
83
109
final int shotType = packetBuffer .getInt ();
84
110
final int flightMode = packetBuffer .getInt ();
85
111
if (messageType == TYPE_SOLO_GET_BUTTON_SETTING )
86
- packetList . add ( new SoloButtonSettingGetter (button , event , shotType , flightMode ) );
112
+ packet = new SoloButtonSettingGetter (button , event , shotType , flightMode );
87
113
else
88
- packetList . add ( new SoloButtonSettingSetter (button , event , shotType , flightMode ) );
114
+ packet = new SoloButtonSettingSetter (button , event , shotType , flightMode );
89
115
break ;
90
116
}
91
117
92
118
case TYPE_SOLO_FOLLOW_OPTIONS : {
93
119
final float cruiseSpeed = packetBuffer .getFloat ();
94
120
final int lookAtValue = packetBuffer .getInt ();
95
- packetList . add ( new SoloFollowOptions (cruiseSpeed , lookAtValue ) );
121
+ packet = new SoloFollowOptions (cruiseSpeed , lookAtValue );
96
122
break ;
97
123
}
98
124
99
125
case TYPE_SOLO_SHOT_OPTIONS : {
100
126
final float cruiseSpeed = packetBuffer .getFloat ();
101
- packetList . add ( new SoloShotOptions (cruiseSpeed ) );
127
+ packet = new SoloShotOptions (cruiseSpeed );
102
128
break ;
103
129
}
104
130
105
131
case TYPE_SOLO_SHOT_ERROR : {
106
132
final int errorType = packetBuffer .getInt ();
107
- packetList . add ( new SoloShotError (errorType ) );
133
+ packet = new SoloShotError (errorType );
108
134
break ;
109
135
}
110
136
111
137
case TYPE_SOLO_MESSAGE_SHOT_MANAGER_ERROR : {
112
138
final byte [] exceptionData = new byte [messageLength ];
113
139
packetBuffer .get (exceptionData );
114
- packetList . add ( new SoloMessageShotManagerError (new String (exceptionData ) ));
140
+ packet = new SoloMessageShotManagerError (new String (exceptionData ));
115
141
break ;
116
142
}
117
143
@@ -122,7 +148,7 @@ public static List<TLVPacket> parseTLVPacket(ByteBuffer packetBuffer) {
122
148
final float degreesYaw = packetBuffer .getFloat ();
123
149
final float pitch = packetBuffer .getFloat ();
124
150
125
- packetList . add ( new SoloCableCamWaypoint (latitude , longitude , altitude , degreesYaw , pitch ) );
151
+ packet = new SoloCableCamWaypoint (latitude , longitude , altitude , degreesYaw , pitch );
126
152
break ;
127
153
}
128
154
@@ -132,39 +158,47 @@ public static List<TLVPacket> parseTLVPacket(ByteBuffer packetBuffer) {
132
158
final short gimbalRate = packetBuffer .getShort ();
133
159
final short battery = packetBuffer .getShort ();
134
160
135
- packetList . add ( new ControllerMessageInputReport (timestamp , gimbalY , gimbalRate , battery ) );
161
+ packet = new ControllerMessageInputReport (timestamp , gimbalY , gimbalRate , battery );
136
162
break ;
137
163
}
138
164
139
165
case TYPE_SOLO_GOPRO_SET_REQUEST : {
140
166
@ SoloGoproConstants .RequestCommand final short command = packetBuffer .getShort ();
141
167
@ SoloGoproConstants .RequestCommandValue final short value = packetBuffer .getShort ();
142
- packetList . add ( new SoloGoproSetRequest (command , value ) );
168
+ packet = new SoloGoproSetRequest (command , value );
143
169
break ;
144
170
}
145
171
146
172
case TYPE_SOLO_GOPRO_RECORD : {
147
173
@ SoloGoproConstants .RecordCommand final int command = packetBuffer .getInt ();
148
- packetList . add ( new SoloGoproRecord (command ) );
174
+ packet = new SoloGoproRecord (command );
149
175
break ;
150
176
}
151
177
152
178
case TYPE_SOLO_GOPRO_STATE : {
153
- packetList . add ( new SoloGoproState (packetBuffer ) );
179
+ packet = new SoloGoproState (packetBuffer );
154
180
break ;
155
181
}
156
182
157
183
case TYPE_SOLO_GOPRO_REQUEST_STATE : {
158
- packetList . add ( new SoloGoproRequestState () );
184
+ packet = new SoloGoproRequestState ();
159
185
break ;
160
186
}
161
187
162
188
default :
163
189
break ;
164
190
}
165
- } catch (BufferUnderflowException e ) {
166
- Log .e (TAG , "Invalid data for tlv packet of type " + messageType );
191
+
192
+ if (packet != null && packet .getMessageLength () == messageLength ) {
193
+ packetList .add (packet );
194
+ } else {
195
+ packetBuffer .reset ();
196
+ packetBuffer .position (packetBuffer .position () + messageLength );
197
+ }
167
198
}
199
+
200
+ } catch (BufferUnderflowException e ) {
201
+ Log .e (TAG , "Invalid data for tlv packet of type " + messageType );
168
202
}
169
203
170
204
packetBuffer .order (originalOrder );
0 commit comments