2017-02-17 15:20:52 -04:00
/* PacketsHandler.cpp -- Packets Handler class for XBee:
Serialize , deserialize , fragment and reassemly mavlink
messages ( packets and std messages ) - - */
/* ------------------------------------------------------------------------- */
/* February 06, 2017 -- @Copyright Aymen Soussia. All rights reserved. */
/* (aymen.soussia@gmail.com) */
# include"PacketsHandler.h"
namespace Mist
{
namespace Xbee
{
//*****************************************************************************
PacketsHandler : : PacketsHandler ( ) :
MAX_PACEKT_SIZE ( 64000 ) ,
XBEE_NETWORK_MTU ( 250 ) ,
FRAGMENT_HEADER_SIZE ( 6 ) ,
MAX_TIME_TO_SEND_PACKET ( 30000 ) ,
START_DLIMITER ( static_cast < unsigned char > ( 0x7E ) ) ,
device_64_bits_address_ ( " 12345678 " ) ,
loaded_SL_ ( false ) ,
loaded_SH_ ( false ) ,
optimum_MT_NBR_ ( 3 ) ,
delay_interframes_ ( 100 * 1000 )
{
}
//*****************************************************************************
PacketsHandler : : ~ PacketsHandler ( )
{
}
//*****************************************************************************
bool PacketsHandler : : Init ( SerialDevice * serial_device ,
Thread_Safe_Deque * in_packets )
{
serial_device_ = serial_device ;
if ( ! Load_Database_Addresses ( ) )
return false ;
// TO DO node dicov
Send_SL_and_SH_Commands ( ) ;
in_packets_ = in_packets ;
return true ;
}
//*****************************************************************************
bool PacketsHandler : : Init_Device_ID ( )
{
if ( Get_Local_Address ( ) )
return true ;
else
return false ;
}
//*****************************************************************************
void PacketsHandler : : Run ( )
{
quit_ . store ( false ) ;
while ( ! quit_ . load ( ) )
{
Process_Out_Standard_Messages ( ) ;
Process_Out_Packets ( ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Handle_Mavlink_Message ( const mavros_msgs : : Mavlink : : ConstPtr & mavlink_msg )
{
std : : shared_ptr < std : : string > serialized_packet =
std : : make_shared < std : : string > ( ) ;
Serialize_Mavlink_Message ( mavlink_msg , serialized_packet ) ;
if ( serialized_packet - > size ( ) > XBEE_NETWORK_MTU & & serialized_packet - > size ( ) < = MAX_PACEKT_SIZE )
{
std : : shared_ptr < std : : vector < std : : shared_ptr < std : : string > > > fragmented_packet =
std : : make_shared < std : : vector < std : : shared_ptr < std : : string > > > ( ) ;
std : : size_t offset = 0 ;
std : : size_t NBR_of_bytes = 0 ;
std : : size_t NBR_of_fragments = std : : ceil (
static_cast < float > ( serialized_packet - > size ( ) ) / XBEE_NETWORK_MTU ) ;
for ( uint8_t i = 0 ; i < NBR_of_fragments ; i + + )
{
fragmented_packet - > push_back ( std : : make_shared < std : : string > ( ) ) ;
NBR_of_bytes = std : : min ( XBEE_NETWORK_MTU , serialized_packet - > size ( ) - offset ) ;
Insert_Fragment_Header ( false , fragmented_packet - > at ( i ) , mavlink_msg - > msgid , i , offset ) ;
fragmented_packet - > at ( i ) - > append ( serialized_packet - > c_str ( ) + offset , NBR_of_bytes ) ;
offset + = NBR_of_bytes ;
}
out_packets_ . Push_Back ( { mavlink_msg - > msgid , fragmented_packet } ) ;
}
else if ( serialized_packet - > size ( ) < XBEE_NETWORK_MTU )
{
serialized_packet - > insert ( 0 , 1 , ' S ' ) ;
out_std_messages_ . Push_Back ( serialized_packet ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Process_Fragment ( std : : shared_ptr < std : : string > fragment )
{
uint8_t packet_ID = fragment - > at ( 1 ) ;
uint8_t node_8_bits_address = fragment - > at ( 2 ) ;
uint8_t fragment_ID = fragment - > at ( 3 ) ;
uint16_t offset = static_cast < uint16_t > (
static_cast < uint16_t > ( static_cast < unsigned char > ( fragment - > at ( 4 ) ) ) < < 8 |
static_cast < uint16_t > ( static_cast < unsigned char > ( fragment - > at ( 5 ) ) ) ) ;
assembly_map_it_ = packets_assembly_map_ . find ( node_8_bits_address ) ;
if ( assembly_map_it_ ! = packets_assembly_map_ . end ( ) )
{
if ( assembly_map_it_ - > second . packet_ID_ = = packet_ID )
{
std : : set < uint8_t > : : iterator it = assembly_map_it_ - > second . received_fragments_IDs_ . find ( fragment_ID ) ;
if ( it = = assembly_map_it_ - > second . received_fragments_IDs_ . end ( ) )
{
if ( assembly_map_it_ - > second . received_fragments_IDs_ . size ( ) = = 0 )
assembly_map_it_ - > second . time_since_creation_ = std : : clock ( ) ;
Insert_Fragment_In_Packet_Buffer ( & assembly_map_it_ - > second . packet_buffer_ , fragment - > c_str ( ) , offset , fragment - > size ( ) ) ;
assembly_map_it_ - > second . received_fragments_IDs_ . insert ( fragment_ID ) ;
}
}
else
{
assembly_map_it_ - > second = { } ;
assembly_map_it_ - > second . packet_ID_ = packet_ID ;
Insert_Fragment_In_Packet_Buffer ( & assembly_map_it_ - > second . packet_buffer_ , fragment - > c_str ( ) , offset , fragment - > size ( ) ) ;
assembly_map_it_ - > second . received_fragments_IDs_ . insert ( fragment_ID ) ;
assembly_map_it_ - > second . time_since_creation_ = std : : clock ( ) ;
}
}
else
{
Add_New_Node_To_Network ( node_8_bits_address ) ;
assembly_map_it_ = packets_assembly_map_ . find ( node_8_bits_address ) ;
assembly_map_it_ - > second . packet_ID_ = packet_ID ;
Insert_Fragment_In_Packet_Buffer ( & assembly_map_it_ - > second . packet_buffer_ , fragment - > c_str ( ) , offset , fragment - > size ( ) ) ;
assembly_map_it_ - > second . received_fragments_IDs_ . insert ( fragment_ID ) ;
assembly_map_it_ - > second . time_since_creation_ = std : : clock ( ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Insert_Fragment_In_Packet_Buffer ( std : : string * buffer , const char * fragment , const uint16_t offset , const std : : size_t length ) // TO DO delete length
{
if ( offset > = buffer - > size ( ) )
buffer - > append ( fragment + FRAGMENT_HEADER_SIZE , length - FRAGMENT_HEADER_SIZE ) ;
else
buffer - > insert ( offset , fragment + FRAGMENT_HEADER_SIZE , length - FRAGMENT_HEADER_SIZE ) ;
}
//*****************************************************************************
void PacketsHandler : : Process_Ping_Or_Acknowledgement ( std : : shared_ptr < std : : string > frame ) // TO DO change useless std::shared_ptr<std::string> frame args to ->c_str()
{
uint8_t packet_ID = frame - > at ( 12 ) ;
uint8_t node_8_bits_address = frame - > at ( 13 ) ;
if ( frame - > at ( 11 ) = = ' A ' )
{
/*std::lock_guard<std::mutex> guard(mutex_);
connected_network_nodes_it_ = connected_network_nodes_ . find ( node_8_bits_address ) ;
if ( connected_network_nodes_it_ = = connected_network_nodes_ . end ( ) )
{
Add_New_Node_To_Network ( node_8_bits_address ) ;
connected_network_nodes_it_ = connected_network_nodes_ . find ( node_8_bits_address ) ;
}
if ( packet_ID = = current_processed_packet_ID_ )
{
if ( frame - > size ( ) < 15 )
connected_network_nodes_it_ - > second = true ;
else
{
for ( uint8_t i = 14 ; i < frame - > size ( ) ; i + + )
fragments_indexes_to_transmit_ . insert ( frame - > at ( i ) ) ;
}
} */
}
else if ( frame - > at ( 11 ) = = ' P ' )
{
assembly_map_it_ = packets_assembly_map_ . find ( node_8_bits_address ) ;
if ( assembly_map_it_ = = packets_assembly_map_ . end ( ) )
{
Add_New_Node_To_Network ( node_8_bits_address ) ;
assembly_map_it_ = packets_assembly_map_ . find ( node_8_bits_address ) ;
assembly_map_it_ - > second . packet_ID_ = packet_ID ;
assembly_map_it_ - > second . time_since_creation_ = std : : clock ( ) ;
}
if ( assembly_map_it_ - > second . packet_ID_ = = packet_ID )
{
std : : string Acknowledgement = " A " ;
Acknowledgement . push_back ( packet_ID ) ;
Acknowledgement . push_back ( device_address_ ) ;
uint8_t packet_size = frame - > at ( 14 ) ;
if ( assembly_map_it_ - > second . received_fragments_IDs_ . size ( ) = = packet_size )
{
in_packets_ - > Push_Back ( std : : make_shared < std : : string > ( assembly_map_it_ - > second . packet_buffer_ ) ) ;
assembly_map_it_ - > second . packet_buffer_ . clear ( ) ;
assembly_map_it_ - > second . received_fragments_IDs_ . clear ( ) ;
assembly_map_it_ - > second . time_since_creation_ = 0 ;
}
else
{
std : : set < uint8_t > : : iterator it = assembly_map_it_ - > second . received_fragments_IDs_ . begin ( ) ;
uint8_t j = 0 ;
while ( j < = packet_size - 1 )
{
if ( j ! = * it )
Acknowledgement . push_back ( j ) ;
else if ( it ! = std : : prev ( assembly_map_it_ - > second . received_fragments_IDs_ . end ( ) ) )
it + + ;
j + + ;
}
}
std : : string Ack_frame ;
Generate_Transmit_Request_Frame ( Acknowledgement . c_str ( ) , & Ack_frame , Acknowledgement . size ( ) ) ; // TO Do send as unicast
serial_device_ - > Send_Frame ( Ack_frame ) ;
usleep ( delay_interframes_ ) ;
}
else
{
assembly_map_it_ - > second = { } ;
assembly_map_it_ - > second . packet_ID_ = packet_ID ;
}
}
}
//*****************************************************************************
void PacketsHandler : : Add_New_Node_To_Network ( const uint8_t new_node_address )
{
std : : set < uint8_t > empty_set ;
packets_assembly_map_ . insert ( std : : pair < uint8_t , Reassembly_Packet_S > ( new_node_address , { } ) ) ;
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
connected_network_nodes_ . insert ( std : : pair < uint8_t , bool > ( new_node_address , false ) ) ;
}
//*****************************************************************************
void PacketsHandler : : Process_Command_Response ( const char * command_response )
{
if ( command_response [ 0 ] = = ' N ' & & command_response [ 1 ] = = ' D ' )
{
uint64_t new_node_address = 0 ;
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
if ( command_response [ 2 ] = = static_cast < unsigned char > ( 0 ) ) // TO DO check this
{
new_node_address = static_cast < uint64_t > ( // TO DO correct this
static_cast < unsigned char > ( command_response [ 5 ] ) < < 56 |
static_cast < unsigned char > ( command_response [ 6 ] ) < < 48 |
static_cast < unsigned char > ( command_response [ 7 ] ) < < 40 |
static_cast < unsigned char > ( command_response [ 8 ] ) < < 32 |
static_cast < unsigned char > ( command_response [ 9 ] ) < < 24 |
static_cast < unsigned char > ( command_response [ 10 ] ) < < 16 |
static_cast < unsigned char > ( command_response [ 11 ] ) < < 8 |
static_cast < unsigned char > ( command_response [ 12 ] ) ) ;
}
database_addresses_it_ = database_addresses_ . find ( new_node_address ) ;
if ( database_addresses_it_ ! = database_addresses_ . end ( ) )
device_address_ = database_addresses_it_ - > second ;
else
std : : cout < < " Remote Node Not in Database " < < std : : endl ;
}
else if ( command_response [ 0 ] = = ' S ' & & command_response [ 1 ] = = ' H ' )
{
if ( command_response [ 2 ] = = static_cast < unsigned char > ( 0 ) ) // TO DO check this
{
loaded_SH_ = true ;
for ( std : : size_t i = 0 ; i < 4 ; i + + )
device_64_bits_address_ [ i ] = command_response [ 3 + i ] ;
}
}
else if ( command_response [ 0 ] = = ' S ' & & command_response [ 1 ] = = ' L ' )
{
if ( command_response [ 2 ] = = static_cast < unsigned char > ( 0 ) ) // TO DO check this
{
loaded_SL_ = true ;
for ( std : : size_t i = 0 ; i < 4 ; i + + )
device_64_bits_address_ [ 4 + i ] = command_response [ 3 + i ] ;
}
}
}
//*****************************************************************************
void PacketsHandler : : Quit ( )
{
quit_ . store ( true ) ;
}
//*****************************************************************************
void PacketsHandler : : Serialize_Mavlink_Message ( const mavros_msgs : : Mavlink : : ConstPtr &
mavlink_msg , std : : shared_ptr < std : : string > serialized_packet )
{
serialized_packet - > push_back ( mavlink_msg - > sysid ) ;
serialized_packet - > push_back ( mavlink_msg - > msgid ) ;
std : : string bytes = " 12345678 " ;
for ( std : : size_t j = 0 ; j < mavlink_msg - > payload64 . size ( ) ; j + + )
{
for ( std : : size_t i = 0 ; i < 8 ; i + + )
bytes [ 7 - i ] = ( mavlink_msg - > payload64 . at ( j ) > > ( i * 8 ) ) ;
serialized_packet - > append ( bytes ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Insert_Fragment_Header ( bool single_fragment ,
std : : shared_ptr < std : : string > fragment , const uint8_t packet_ID ,
const uint8_t fragment_ID , const uint16_t offset )
{
if ( ! single_fragment )
{
fragment - > push_back ( ' F ' ) ;
fragment - > push_back ( packet_ID ) ;
fragment - > push_back ( device_address_ ) ;
fragment - > push_back ( fragment_ID ) ;
fragment - > push_back ( offset > > ( 1 * 8 ) ) ;
fragment - > push_back ( offset > > ( 0 * 8 ) ) ;
}
else
fragment - > push_back ( ' S ' ) ;
}
//*****************************************************************************
void PacketsHandler : : Delete_Packets_With_Time_Out ( )
{
for ( auto & iterator : packets_assembly_map_ )
{
if ( std : : clock_t ( ) - iterator . second . time_since_creation_ > MAX_TIME_TO_SEND_PACKET & & iterator . second . time_since_creation_ ! = 0 )
iterator . second = { } ;
}
}
//*****************************************************************************
void PacketsHandler : : Process_Out_Standard_Messages ( )
{
std : : size_t deque_size = out_std_messages_ . Get_Size ( ) ;
if ( deque_size > 0 )
{
std : : string frame ;
std : : shared_ptr < std : : string > out_message ;
for ( std : : size_t i = 0 ; i < deque_size ; i + + )
{
frame . clear ( ) ;
out_message = out_std_messages_ . Pop_Front ( ) ;
Generate_Transmit_Request_Frame ( out_message - > c_str ( ) , & frame , out_message - > size ( ) ) ;
serial_device_ - > Send_Frame ( frame ) ;
usleep ( delay_interframes_ ) ;
}
}
}
//*****************************************************************************
void PacketsHandler : : Process_Out_Packets ( )
{
std : : size_t deque_size = out_packets_ . Get_Size ( ) ;
if ( deque_size > 0 )
{
Out_Packet_S out_packet ;
for ( std : : size_t i = 0 ; i < deque_size ; i + + )
{
Process_Out_Standard_Messages ( ) ;
out_packet = out_packets_ . Pop_Front ( ) ;
Send_Packet ( out_packet ) ;
}
}
}
//*****************************************************************************
void PacketsHandler : : Send_Packet ( const Out_Packet_S & packet )
{
std : : size_t NBR_of_transmission = 0 ;
std : : vector < std : : string > frames ;
Init_Network_Nodes_For_New_Transmission ( packet . packet_ID_ , & frames , packet . packet_buffer_ ) ;
std : : clock_t elapsed_time = std : : clock ( ) ;
//while (NBR_of_transmission <= optimum_MT_NBR_ && !Check_Packet_Transmitted_To_All_Nodes())
//{
//NBR_of_transmission++;
Transmit_Fragments ( frames ) ;
// TO DO usleep(flow_control_time)
// TO DO clear fragments_IDs_to_transmit_set
Send_End_Of_Packet_Ping ( packet . packet_ID_ , packet . packet_buffer_ - > size ( ) ) ;
// TO DO sleep after ping
//}
elapsed_time = std : : clock ( ) - elapsed_time ;
Adjust_Optimum_MT_Number ( elapsed_time , NBR_of_transmission ) ;
}
//*****************************************************************************
void PacketsHandler : : Send_End_Of_Packet_Ping ( const uint8_t packet_ID , const uint8_t total_NBR_of_fragments )
{
std : : string ping_message = " P " ;
std : : string ping_frame ;
ping_message . push_back ( packet_ID ) ;
ping_message . push_back ( device_address_ ) ;
ping_message . push_back ( total_NBR_of_fragments ) ;
Generate_Transmit_Request_Frame ( ping_message . c_str ( ) , & ping_frame , ping_message . size ( ) ) ;
serial_device_ - > Send_Frame ( ping_frame ) ;
usleep ( delay_interframes_ ) ;
}
//*****************************************************************************
bool PacketsHandler : : Load_Database_Addresses ( )
{
2017-02-17 18:05:45 -04:00
const std : : string FILE_PATH = " ~/ROS_WS/src/xbeemav/Resources/database.xml " ;
2017-02-17 15:20:52 -04:00
if ( ! boost : : filesystem : : exists ( FILE_PATH ) )
{
std : : cout < < " database.xml Not Found. " < < std : : endl ;
return false ;
}
ptree pt ;
boost : : property_tree : : read_xml ( FILE_PATH , pt ) ;
std : : string short_address ;
std : : string address_64_bits ;
unsigned int short_address_int ;
uint64_t address_64_bits_int ;
BOOST_FOREACH ( ptree : : value_type const & v , pt . get_child ( " Addresses " ) )
{
if ( v . first = = " Device " )
{
short_address = v . second . get < std : : string > ( " <xmlattr>.Address " ) ;
address_64_bits = v . second . data ( ) ;
if ( sscanf ( short_address . c_str ( ) , " %3u " , & short_address_int ) < 0 )
{
std : : cout < < " Short Address Error. Please Check database.xml For Possible Errors. " < < std : : endl ;
return false ;
}
if ( sscanf ( address_64_bits . c_str ( ) , " % " SCNx64 , & address_64_bits_int ) < 0 )
{
std : : cout < < " 64 bits Address Error. Please Check database.xml For Possible Errors. " < < std : : endl ;
return false ;
}
database_addresses_ . insert ( std : : pair < uint64_t , uint8_t > ( address_64_bits_int , static_cast < uint8_t > ( short_address_int ) ) ) ;
}
}
return true ;
}
//*****************************************************************************
bool PacketsHandler : : Get_Local_Address ( )
{
const useconds_t ONE_SECOND = 1 * 1000 * 1000 ; /* 1s = 1 * 10⁶ microseconds. */
usleep ( ONE_SECOND ) ;
if ( loaded_SH_ & & loaded_SL_ )
{
uint64_t local_64_bits_address = (
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 0 ] ) ) < < 56 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 1 ] ) ) < < 48 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 2 ] ) ) < < 40 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 3 ] ) ) < < 32 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 4 ] ) ) < < 24 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 5 ] ) ) < < 16 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 6 ] ) ) < < 8 |
static_cast < uint64_t > ( static_cast < unsigned char > ( device_64_bits_address_ [ 7 ] ) ) ) ;
database_addresses_it_ = database_addresses_ . find ( local_64_bits_address ) ;
if ( database_addresses_it_ ! = database_addresses_ . end ( ) )
{
device_address_ = database_addresses_it_ - > second ;
std : : cout < < " Loaded Short Device Address : " < < static_cast < int > ( device_address_ ) < < std : : endl ;
return true ;
}
else
{
std : : cout < < " Local Address Not Found In Database. Please Add The Xbee Address to database.xml. " < < std : : endl ;
return false ;
}
}
else
{
Send_SL_and_SH_Commands ( ) ;
return false ;
}
}
//*****************************************************************************
bool PacketsHandler : : Check_Packet_Transmitted_To_All_Nodes ( )
{
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
if ( connected_network_nodes_ . size ( ) = = 0 )
return false ;
for ( auto it : connected_network_nodes_ )
{
if ( ! it . second )
return false ;
}
return true ;
}
//*****************************************************************************
void PacketsHandler : : Init_Network_Nodes_For_New_Transmission ( const uint8_t packet_ID , std : : vector < std : : string > * frames , std : : shared_ptr < std : : vector < std : : shared_ptr < std : : string > > > packet )
{
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
fragments_indexes_to_transmit_ . clear ( ) ;
for ( auto it : connected_network_nodes_ )
it . second = false ;
current_processed_packet_ID_ = packet_ID ;
for ( uint8_t i = 0 ; i < packet - > size ( ) ; i + + )
{
frames - > push_back ( " " ) ;
fragments_indexes_to_transmit_ . insert ( i ) ;
Generate_Transmit_Request_Frame ( packet - > at ( i ) - > c_str ( ) , & frames - > at ( i ) , packet - > at ( i ) - > size ( ) ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Transmit_Fragments ( const std : : vector < std : : string > & frames )
{
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
for ( auto index : fragments_indexes_to_transmit_ )
{
serial_device_ - > Send_Frame ( frames . at ( index ) ) ;
usleep ( delay_interframes_ ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Adjust_Optimum_MT_Number ( const std : : clock_t elapsed_time ,
const std : : size_t NBR_of_transmission )
{
if ( NBR_of_transmission < optimum_MT_NBR_ )
optimum_MT_NBR_ = NBR_of_transmission ;
else if ( NBR_of_transmission = = optimum_MT_NBR_ )
{
std : : lock_guard < std : : mutex > guard ( mutex_ ) ;
if ( elapsed_time < = MAX_TIME_TO_SEND_PACKET & & fragments_indexes_to_transmit_ . size ( ) > 0 )
optimum_MT_NBR_ + + ;
}
}
//*****************************************************************************
void PacketsHandler : : Send_SL_and_SH_Commands ( )
{
std : : string command ;
std : : string frame ;
command = " SL " ;
Generate_AT_Command ( command . c_str ( ) , & frame ) ;
serial_device_ - > Send_Frame ( frame ) ;
command = " SH " ;
frame = " " ;
Generate_AT_Command ( command . c_str ( ) , & frame ) ;
serial_device_ - > Send_Frame ( frame ) ;
}
//*****************************************************************************
void PacketsHandler : : Deserialize_Mavlink_Message ( const char * bytes ,
mavros_msgs : : Mavlink * mavlink_msg , const std : : size_t msg_size )
{
mavlink_msg - > sysid = bytes [ 0 ] ;
mavlink_msg - > msgid = bytes [ 1 ] ;
uint64_t current_int64 = 0 ;
for ( std : : size_t i = 2 ; i < msg_size ; i + = 8 )
{
current_int64 = (
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i ] ) ) < < 56 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 1 ] ) ) < < 48 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 2 ] ) ) < < 40 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 3 ] ) ) < < 32 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 4 ] ) ) < < 24 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 5 ] ) ) < < 16 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 6 ] ) ) < < 8 |
static_cast < uint64_t > ( static_cast < unsigned char > ( bytes [ i + 7 ] ) ) ) ;
mavlink_msg - > payload64 . push_back ( current_int64 ) ;
}
}
//*****************************************************************************
inline void PacketsHandler : : Generate_Transmit_Request_Frame (
const char * message ,
std : : string * frame ,
const std : : size_t message_size ,
const unsigned char frame_ID ,
const std : : string & destination_adssress ,
const std : : string & short_destination_adress ,
const std : : string & broadcast_radius ,
const std : : string & options )
{
const unsigned char FAME_TYPE = static_cast < unsigned char > ( 0x10 ) ; /* Transmit Request Frame */
std : : string frame_parameters ;
std : : string bytes_frame_parameters ;
frame_parameters . append ( destination_adssress ) ;
frame_parameters . append ( short_destination_adress ) ;
frame_parameters . append ( broadcast_radius ) ;
frame_parameters . append ( options ) ;
Convert_HEX_To_Bytes ( frame_parameters , & bytes_frame_parameters ) ;
frame - > push_back ( FAME_TYPE ) ;
frame - > push_back ( frame_ID ) ;
frame - > append ( bytes_frame_parameters ) ;
frame - > append ( message , message_size ) ;
Calculate_and_Append_Checksum ( frame ) ;
Add_Length_and_Start_Delimiter ( frame ) ;
}
//*****************************************************************************
inline void PacketsHandler : : Add_Length_and_Start_Delimiter (
std : : string * frame )
{
const unsigned short FIVE_BYTES = 5 ;
char temporary_buffer [ FIVE_BYTES ] ;
unsigned char temporary_char ;
int Hex_frame_length_1 ;
int Hex_frame_length_2 ;
std : : string header ;
int frame_length = frame - > size ( ) - 1 ; /* frame_length = frame_size - checksum byte */
header . push_back ( START_DLIMITER ) ;
sprintf ( temporary_buffer , " %04X " , frame_length ) ;
sscanf ( temporary_buffer , " %02X%02X " , & Hex_frame_length_1 ,
& Hex_frame_length_2 ) ;
temporary_char = static_cast < unsigned char > ( Hex_frame_length_1 ) ;
header . push_back ( temporary_char ) ;
temporary_char = static_cast < unsigned char > ( Hex_frame_length_2 ) ;
header . push_back ( temporary_char ) ;
frame - > insert ( 0 , header ) ;
}
//*****************************************************************************
inline void PacketsHandler : : Calculate_and_Append_Checksum (
std : : string * frame )
{
unsigned short bytes_sum = 0 ;
unsigned lowest_8_bits = 0 ;
unsigned short checksum = 0 ;
unsigned char checksum_byte ;
for ( unsigned short i = 0 ; i < frame - > size ( ) ; i + + )
bytes_sum + = static_cast < unsigned short > ( frame - > at ( i ) ) ;
lowest_8_bits = bytes_sum & 0xFF ;
checksum = 0xFF - lowest_8_bits ;
checksum_byte = static_cast < unsigned char > ( checksum ) ;
frame - > push_back ( checksum_byte ) ;
}
//*****************************************************************************
inline void PacketsHandler : : Convert_HEX_To_Bytes (
const std : : string & HEX_data , std : : string * converted_data )
{
const unsigned short TWO_BYTES = 2 ;
char temporary_buffer [ TWO_BYTES ] ;
unsigned char temporary_char ;
int temporary_HEX ;
for ( unsigned short i = 0 ; i < = HEX_data . size ( ) - TWO_BYTES ;
i + = TWO_BYTES )
{
memcpy ( temporary_buffer , HEX_data . c_str ( ) + i , TWO_BYTES ) ;
sscanf ( temporary_buffer , " %02X " , & temporary_HEX ) ;
temporary_char = static_cast < unsigned char > ( temporary_HEX ) ;
converted_data - > push_back ( temporary_char ) ;
}
}
//*****************************************************************************
void PacketsHandler : : Generate_AT_Command ( const char * command ,
std : : string * frame ,
const unsigned char frame_ID )
{
const unsigned char FAME_TYPE = static_cast < unsigned char > ( 0x09 ) ; /* AT Command Frame */
std : : string temporary_parameter_value ;
frame - > push_back ( FAME_TYPE ) ;
frame - > push_back ( frame_ID ) ;
frame - > append ( command ) ;
Calculate_and_Append_Checksum ( frame ) ;
Add_Length_and_Start_Delimiter ( frame ) ;
}
}
}