1717/* Author: zerom, Ryu Woon Jung (Leon) */
1818
1919#if defined(__linux__)
20+ #include < unistd.h>
2021#include " protocol2_packet_handler.h"
2122#elif defined(__APPLE__)
23+ #include < unistd.h>
2224#include " protocol2_packet_handler.h"
2325#elif defined(_WIN32) || defined(_WIN64)
2426#define WINDLLEXPORT
27+ #include < Windows.h>
2528#include " protocol2_packet_handler.h"
2629#elif defined(ARDUINO) || defined(__OPENCR__) || defined(__OPENCM904__)
2730#include " ../../include/dynamixel_sdk/protocol2_packet_handler.h"
3134#include < string.h>
3235#include < stdlib.h>
3336
34- #define TXPACKET_MAX_LEN (4 *1024 )
35- #define RXPACKET_MAX_LEN (4 *1024 )
37+ #define TXPACKET_MAX_LEN (1 *1024 )
38+ #define RXPACKET_MAX_LEN (1 *1024 )
3639
3740// /////////////// for Protocol 2.0 Packet /////////////////
3841#define PKT_HEADER0 0
@@ -140,7 +143,7 @@ const char *Protocol2PacketHandler::getRxPacketError(uint8_t error)
140143unsigned short Protocol2PacketHandler::updateCRC (uint16_t crc_accum, uint8_t *data_blk_ptr, uint16_t data_blk_size)
141144{
142145 uint16_t i;
143- uint16_t crc_table[256 ] = {0x0000 ,
146+ static const uint16_t crc_table[256 ] = {0x0000 ,
144147 0x8005 , 0x800F , 0x000A , 0x801B , 0x001E , 0x0014 , 0x8011 ,
145148 0x8033 , 0x0036 , 0x003C , 0x8039 , 0x0028 , 0x802D , 0x8027 ,
146149 0x0022 , 0x8063 , 0x0066 , 0x006C , 0x8069 , 0x0078 , 0x807D ,
@@ -190,39 +193,48 @@ unsigned short Protocol2PacketHandler::updateCRC(uint16_t crc_accum, uint8_t *da
190193
191194void Protocol2PacketHandler::addStuffing (uint8_t *packet)
192195{
193- int i = 0 , index = 0 ;
194196 int packet_length_in = DXL_MAKEWORD (packet[PKT_LENGTH_L], packet[PKT_LENGTH_H]);
195197 int packet_length_out = packet_length_in;
196- uint8_t temp[TXPACKET_MAX_LEN] = {0 };
198+
199+ if (packet_length_in < 8 ) // INSTRUCTION, ADDR_L, ADDR_H, CRC16_L, CRC16_H + FF FF FD
200+ return ;
197201
198- for (uint16_t s = PKT_HEADER0; s <= PKT_LENGTH_H; s++)
199- temp[s] = packet[s]; // FF FF FD XX ID LEN_L LEN_H
200- // memcpy(temp, packet, PKT_LENGTH_H+1);
201- index = PKT_INSTRUCTION;
202- for (i = 0 ; i < packet_length_in - 2 ; i++) // except CRC
202+ uint8_t *packet_ptr;
203+ uint16_t packet_length_before_crc = packet_length_in - 2 ;
204+ for (uint16_t i = 3 ; i < packet_length_before_crc; i++)
203205 {
204- temp[index++] = packet[i+PKT_INSTRUCTION];
205- if (packet[i+PKT_INSTRUCTION] == 0xFD && packet[i+PKT_INSTRUCTION-1 ] == 0xFF && packet[i+PKT_INSTRUCTION-2 ] == 0xFF )
206- { // FF FF FD
207- temp[index++] = 0xFD ;
206+ packet_ptr = &packet[i+PKT_INSTRUCTION-2 ];
207+ if (packet_ptr[0 ] == 0xFF && packet_ptr[1 ] == 0xFF && packet_ptr[2 ] == 0xFD )
208208 packet_length_out++;
209+ }
210+
211+ if (packet_length_in == packet_length_out) // no stuffing required
212+ return ;
213+
214+ uint16_t out_index = packet_length_out + 6 - 2 ; // last index before crc
215+ uint16_t in_index = packet_length_in + 6 - 2 ; // last index before crc
216+ while (out_index != in_index)
217+ {
218+ if (packet[in_index] == 0xFD && packet[in_index-1 ] == 0xFF && packet[in_index-2 ] == 0xFF )
219+ {
220+ packet[out_index--] = 0xFD ; // byte stuffing
221+ if (out_index != in_index)
222+ {
223+ packet[out_index--] = packet[in_index--]; // FD
224+ packet[out_index--] = packet[in_index--]; // FF
225+ packet[out_index--] = packet[in_index--]; // FF
226+ }
227+ }
228+ else
229+ {
230+ packet[out_index--] = packet[in_index--];
209231 }
210232 }
211- temp[index++] = packet[PKT_INSTRUCTION+packet_length_in-2 ];
212- temp[index++] = packet[PKT_INSTRUCTION+packet_length_in-1 ];
213-
214-
215- // ////////////////////////
216- if (packet_length_in != packet_length_out)
217- packet = (uint8_t *)realloc (packet, index * sizeof (uint8_t ));
218233
219- // /////////////////////////
220-
221- for (uint16_t s = 0 ; s < index; s++)
222- packet[s] = temp[s];
223- // memcpy(packet, temp, index);
224234 packet[PKT_LENGTH_L] = DXL_LOBYTE (packet_length_out);
225235 packet[PKT_LENGTH_H] = DXL_HIBYTE (packet_length_out);
236+
237+ return ;
226238}
227239
228240void Protocol2PacketHandler::removeStuffing (uint8_t *packet)
@@ -393,6 +405,11 @@ int Protocol2PacketHandler::rxPacket(PortHandler *port, uint8_t *rxpacket)
393405 break ;
394406 }
395407 }
408+ #if defined(__linux__) || defined(__APPLE__)
409+ usleep (0 );
410+ #elif defined(_WIN32) || defined(_WIN64)
411+ Sleep (0 );
412+ #endif
396413 }
397414 port->is_using_ = false ;
398415
@@ -657,10 +674,12 @@ int Protocol2PacketHandler::readTx(PortHandler *port, uint8_t id, uint16_t addre
657674int Protocol2PacketHandler::readRx (PortHandler *port, uint8_t id, uint16_t length, uint8_t *data, uint8_t *error)
658675{
659676 int result = COMM_TX_FAIL;
660- uint8_t *rxpacket = (uint8_t *)malloc (RXPACKET_MAX_LEN );
677+ uint8_t *rxpacket = (uint8_t *)malloc (length + 11 + (length / 3 ) );
661678 // (length + 11 + (length/3)); // (length/3): consider stuffing
662- // uint8_t *rxpacket = new uint8_t[length + 11 + (length/3)]; // (length/3): consider stuffing
663-
679+
680+ if (rxpacket == NULL )
681+ return result;
682+
664683 do {
665684 result = rxPacket (port, rxpacket);
666685 } while (result == COMM_SUCCESS && rxpacket[PKT_ID] != id);
@@ -687,9 +706,12 @@ int Protocol2PacketHandler::readTxRx(PortHandler *port, uint8_t id, uint16_t add
687706 int result = COMM_TX_FAIL;
688707
689708 uint8_t txpacket[14 ] = {0 };
690- uint8_t *rxpacket = (uint8_t *)malloc (RXPACKET_MAX_LEN );
709+ uint8_t *rxpacket = (uint8_t *)malloc (length + 11 + (length / 3 ) );
691710 // (length + 11 + (length/3)); // (length/3): consider stuffing
692711
712+ if (rxpacket == NULL )
713+ return result;
714+
693715 if (id >= BROADCAST_ID)
694716 return COMM_NOT_AVAILABLE;
695717
@@ -788,8 +810,10 @@ int Protocol2PacketHandler::writeTxOnly(PortHandler *port, uint8_t id, uint16_t
788810{
789811 int result = COMM_TX_FAIL;
790812
791- uint8_t *txpacket = (uint8_t *)malloc (length+12 );
792- // uint8_t *txpacket = new uint8_t[length+12];
813+ uint8_t *txpacket = (uint8_t *)malloc (length + 12 + (length / 3 ));
814+
815+ if (txpacket == NULL )
816+ return result;
793817
794818 txpacket[PKT_ID] = id;
795819 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (length+5 );
@@ -814,10 +838,12 @@ int Protocol2PacketHandler::writeTxRx(PortHandler *port, uint8_t id, uint16_t ad
814838{
815839 int result = COMM_TX_FAIL;
816840
817- uint8_t *txpacket = (uint8_t *)malloc (length + 12 );
818- // uint8_t *txpacket = new uint8_t[length+12];
841+ uint8_t *txpacket = (uint8_t *)malloc (length + 12 + (length / 3 ));
819842 uint8_t rxpacket[11 ] = {0 };
820843
844+ if (txpacket == NULL )
845+ return result;
846+
821847 txpacket[PKT_ID] = id;
822848 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (length+5 );
823849 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (length+5 );
@@ -871,11 +897,13 @@ int Protocol2PacketHandler::write4ByteTxRx(PortHandler *port, uint8_t id, uint16
871897
872898int Protocol2PacketHandler::regWriteTxOnly (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data)
873899{
874- int result = COMM_TX_FAIL;
900+ int result = COMM_TX_FAIL;
875901
876- uint8_t *txpacket = (uint8_t *)malloc (length + 12 );
877- // uint8_t *txpacket = new uint8_t[length+12];
902+ uint8_t *txpacket = (uint8_t *)malloc (length + 12 + (length / 3 ));
878903
904+ if (txpacket == NULL )
905+ return result;
906+
879907 txpacket[PKT_ID] = id;
880908 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (length+5 );
881909 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (length+5 );
@@ -897,12 +925,14 @@ int Protocol2PacketHandler::regWriteTxOnly(PortHandler *port, uint8_t id, uint16
897925
898926int Protocol2PacketHandler::regWriteTxRx (PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error)
899927{
900- int result = COMM_TX_FAIL;
928+ int result = COMM_TX_FAIL;
901929
902- uint8_t *txpacket = (uint8_t *)malloc (length + 12 );
903- // uint8_t *txpacket = new uint8_t[length+12];
930+ uint8_t *txpacket = (uint8_t *)malloc (length + 12 + (length / 3 ));
904931 uint8_t rxpacket[11 ] = {0 };
905932
933+ if (txpacket == NULL )
934+ return result;
935+
906936 txpacket[PKT_ID] = id;
907937 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (length+5 );
908938 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (length+5 );
@@ -923,11 +953,14 @@ int Protocol2PacketHandler::regWriteTxRx(PortHandler *port, uint8_t id, uint16_t
923953
924954int Protocol2PacketHandler::syncReadTx (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length)
925955{
926- int result = COMM_TX_FAIL;
956+ int result = COMM_TX_FAIL;
927957
928- uint8_t *txpacket = (uint8_t *)malloc (param_length + 14 );
958+ uint8_t *txpacket = (uint8_t *)malloc (param_length + 14 + (param_length / 3 ) );
929959 // 14: HEADER0 HEADER1 HEADER2 RESERVED ID LEN_L LEN_H INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
930960
961+ if (txpacket == NULL )
962+ return result;
963+
931964 txpacket[PKT_ID] = BROADCAST_ID;
932965 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (param_length + 7 ); // 7: INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
933966 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (param_length + 7 ); // 7: INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
@@ -951,12 +984,14 @@ int Protocol2PacketHandler::syncReadTx(PortHandler *port, uint16_t start_address
951984
952985int Protocol2PacketHandler::syncWriteTxOnly (PortHandler *port, uint16_t start_address, uint16_t data_length, uint8_t *param, uint16_t param_length)
953986{
954- int result = COMM_TX_FAIL;
987+ int result = COMM_TX_FAIL;
955988
956- uint8_t *txpacket = (uint8_t *)malloc (param_length + 14 );
957- // uint8_t *txpacket = new uint8_t[param_length + 14];
989+ uint8_t *txpacket = (uint8_t *)malloc (param_length + 14 + (param_length / 3 ));
958990 // 14: HEADER0 HEADER1 HEADER2 RESERVED ID LEN_L LEN_H INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
959991
992+ if (txpacket == NULL )
993+ return result;
994+
960995 txpacket[PKT_ID] = BROADCAST_ID;
961996 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (param_length + 7 ); // 7: INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
962997 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (param_length + 7 ); // 7: INST START_ADDR_L START_ADDR_H DATA_LEN_L DATA_LEN_H CRC16_L CRC16_H
@@ -979,12 +1014,14 @@ int Protocol2PacketHandler::syncWriteTxOnly(PortHandler *port, uint16_t start_ad
9791014
9801015int Protocol2PacketHandler::bulkReadTx (PortHandler *port, uint8_t *param, uint16_t param_length)
9811016{
982- int result = COMM_TX_FAIL;
1017+ int result = COMM_TX_FAIL;
9831018
984- uint8_t *txpacket = (uint8_t *)malloc (param_length + 10 );
985- // uint8_t *txpacket = new uint8_t[param_length + 10];
1019+ uint8_t *txpacket = (uint8_t *)malloc (param_length + 10 + (param_length / 3 ));
9861020 // 10: HEADER0 HEADER1 HEADER2 RESERVED ID LEN_L LEN_H INST CRC16_L CRC16_H
9871021
1022+ if (txpacket == NULL )
1023+ return result;
1024+
9881025 txpacket[PKT_ID] = BROADCAST_ID;
9891026 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (param_length + 3 ); // 3: INST CRC16_L CRC16_H
9901027 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (param_length + 3 ); // 3: INST CRC16_L CRC16_H
@@ -1010,12 +1047,14 @@ int Protocol2PacketHandler::bulkReadTx(PortHandler *port, uint8_t *param, uint16
10101047
10111048int Protocol2PacketHandler::bulkWriteTxOnly (PortHandler *port, uint8_t *param, uint16_t param_length)
10121049{
1013- int result = COMM_TX_FAIL;
1050+ int result = COMM_TX_FAIL;
10141051
1015- uint8_t *txpacket = (uint8_t *)malloc (param_length + 10 );
1016- // uint8_t *txpacket = new uint8_t[param_length + 10];
1052+ uint8_t *txpacket = (uint8_t *)malloc (param_length + 10 + (param_length / 3 ));
10171053 // 10: HEADER0 HEADER1 HEADER2 RESERVED ID LEN_L LEN_H INST CRC16_L CRC16_H
10181054
1055+ if (txpacket == NULL )
1056+ return result;
1057+
10191058 txpacket[PKT_ID] = BROADCAST_ID;
10201059 txpacket[PKT_LENGTH_L] = DXL_LOBYTE (param_length + 3 ); // 3: INST CRC16_L CRC16_H
10211060 txpacket[PKT_LENGTH_H] = DXL_HIBYTE (param_length + 3 ); // 3: INST CRC16_L CRC16_H
0 commit comments