mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
268 lines
6.8 KiB
C
268 lines
6.8 KiB
C
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif /* HAVE_CONFIG_H */
|
||
|
|
||
|
#include "toxmsi_message.h"
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "../toxrtp/toxrtp_helper.h"
|
||
|
#include <assert.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#define ALLOCATE_HEADER(_header_type, _var, _m_header_value) \
|
||
|
_var = calloc( sizeof(_header_type), 1 ); \
|
||
|
assert(_var); \
|
||
|
_var->_header_value = t_strallcpy((const uint8_t*)_m_header_value);
|
||
|
|
||
|
#define DEALLOCATE_HEADER(_header) \
|
||
|
if ( _header && _header->_header_value ) { \
|
||
|
free( _header->_header_value ); \
|
||
|
free( _header ); }
|
||
|
|
||
|
#define SET_HEADER(_header_type, _var, _m_header_value) \
|
||
|
if ( _var ){ \
|
||
|
free(_var->_header_value); \
|
||
|
free(_var);} \
|
||
|
ALLOCATE_HEADER( _header_type, _var, _m_header_value )
|
||
|
|
||
|
|
||
|
/* Sets empty message
|
||
|
*/
|
||
|
void set_msg ( msi_msg_t* _msg )
|
||
|
{
|
||
|
_msg->_call_type = NULL;
|
||
|
_msg->_version = NULL;
|
||
|
_msg->_request = NULL;
|
||
|
_msg->_response = NULL;
|
||
|
_msg->_friend_id = NULL;
|
||
|
_msg->_user_agent = NULL;
|
||
|
_msg->_call_id = NULL;
|
||
|
_msg->_reason = NULL;
|
||
|
_msg->_info = NULL;
|
||
|
_msg->_next = NULL;
|
||
|
_msg->_headers = NULL;
|
||
|
}
|
||
|
|
||
|
void msi_free_msg ( msi_msg_t* _msg )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
|
||
|
DEALLOCATE_HEADER(_msg->_call_type);
|
||
|
DEALLOCATE_HEADER(_msg->_friend_id);
|
||
|
DEALLOCATE_HEADER(_msg->_request);
|
||
|
DEALLOCATE_HEADER(_msg->_response);
|
||
|
DEALLOCATE_HEADER(_msg->_user_agent);
|
||
|
DEALLOCATE_HEADER(_msg->_version);
|
||
|
DEALLOCATE_HEADER(_msg->_info);
|
||
|
DEALLOCATE_HEADER(_msg->_reason);
|
||
|
DEALLOCATE_HEADER(_msg->_call_id);
|
||
|
|
||
|
free(_msg);
|
||
|
}
|
||
|
|
||
|
void append_header_to_string ( uint8_t* _dest, const uint8_t* _header_field, const uint8_t* _header_value )
|
||
|
{
|
||
|
assert(_dest);
|
||
|
assert(_header_value);
|
||
|
assert(_header_field);
|
||
|
|
||
|
size_t _dest_len = t_memlen(_dest);
|
||
|
|
||
|
uint8_t* _storage_iterator = _dest + _dest_len;
|
||
|
const uint8_t* _header_fit = _header_field;
|
||
|
const uint8_t* _header_val = _header_value;
|
||
|
const uint8_t* _term_it = (const uint8_t*) _RAW_TERMINATOR;
|
||
|
|
||
|
while ( *_header_fit ){
|
||
|
*_storage_iterator = *_header_fit;
|
||
|
++_header_fit;
|
||
|
++_storage_iterator;
|
||
|
}
|
||
|
|
||
|
*_storage_iterator = ' '; /* place space */
|
||
|
++_storage_iterator;
|
||
|
|
||
|
while ( *_header_val ){
|
||
|
*_storage_iterator = *_header_val;
|
||
|
++_header_val;
|
||
|
++_storage_iterator;
|
||
|
}
|
||
|
|
||
|
while ( *_term_it ){
|
||
|
*_storage_iterator = *_term_it;
|
||
|
++_term_it;
|
||
|
++_storage_iterator;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
msi_msg_t* msi_parse_msg ( const uint8_t* _data )
|
||
|
{
|
||
|
assert(_data);
|
||
|
|
||
|
msi_msg_t* _retu = calloc ( sizeof ( msi_msg_t ), 1 );
|
||
|
assert(_retu);
|
||
|
|
||
|
set_msg(_retu);
|
||
|
|
||
|
_retu->_headers = msi_parse_raw_data ( _data );
|
||
|
|
||
|
if ( msi_parse_headers (_retu) == FAILURE ) {
|
||
|
msi_free_msg(_retu);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if ( !_retu->_version || strcmp((const char*)_retu->_version->_header_value, VERSION_STRING) != 0 ){
|
||
|
msi_free_msg(_retu);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return _retu;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t* msi_msg_to_string ( msi_msg_t* _msg )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
|
||
|
uint8_t* _retu = calloc(sizeof(uint8_t), MSI_MAXMSG_SIZE );
|
||
|
assert(_retu);
|
||
|
|
||
|
t_memset(_retu, '\0', MSI_MAXMSG_SIZE);
|
||
|
|
||
|
if ( _msg->_version ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_VERSION_FIELD, _msg->_version->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_request ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_REQUEST_FIELD, _msg->_request->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_response ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_RESPONSE_FIELD, _msg->_response->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_friend_id ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_FRIENDID_FIELD, _msg->_friend_id->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_call_type ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_CALLTYPE_FIELD, _msg->_call_type->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_user_agent ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_USERAGENT_FIELD, _msg->_user_agent->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_info ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_INFO_FIELD, _msg->_info->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_call_id ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_CALL_ID_FIELD, _msg->_call_id->_header_value);
|
||
|
}
|
||
|
|
||
|
if ( _msg->_reason ){
|
||
|
append_header_to_string(_retu, (const uint8_t*)_REASON_FIELD, _msg->_reason->_header_value);
|
||
|
}
|
||
|
|
||
|
return _retu;
|
||
|
}
|
||
|
|
||
|
msi_msg_t* msi_msg_new ( uint8_t _type, const uint8_t* _typeid )
|
||
|
{
|
||
|
msi_msg_t* _retu = calloc ( sizeof ( msi_msg_t ), 1 );
|
||
|
assert(_retu);
|
||
|
|
||
|
set_msg(_retu);
|
||
|
|
||
|
if ( _type == TYPE_REQUEST ){
|
||
|
ALLOCATE_HEADER( msi_header_request_t, _retu->_request, _typeid )
|
||
|
_retu->_response = NULL;
|
||
|
|
||
|
} else if ( _type == TYPE_RESPONSE ) {
|
||
|
ALLOCATE_HEADER( msi_header_response_t, _retu->_response, _typeid )
|
||
|
_retu->_request = NULL;
|
||
|
|
||
|
} else {
|
||
|
msi_free_msg(_retu);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
ALLOCATE_HEADER( msi_header_version_t, _retu->_version, VERSION_STRING)
|
||
|
|
||
|
_retu->_friend_id = NULL;
|
||
|
_retu->_call_type = NULL;
|
||
|
_retu->_user_agent = NULL;
|
||
|
_retu->_info = NULL;
|
||
|
|
||
|
_retu->_next = NULL;
|
||
|
|
||
|
return _retu;
|
||
|
}
|
||
|
|
||
|
uint8_t* msi_genterate_call_id ( uint8_t* _storage, size_t _len )
|
||
|
{
|
||
|
assert(_storage);
|
||
|
|
||
|
static const char _alphanum[] =
|
||
|
"0123456789"
|
||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||
|
"abcdefghijklmnopqrstuvwxyz"; /* avoids warning */
|
||
|
|
||
|
uint8_t _val = 0;
|
||
|
size_t _it;
|
||
|
|
||
|
/* Generate random values 1-255 */
|
||
|
for ( _it = 0; _it < _len; _it ++ ) {
|
||
|
while ( !_val ) _val = (uint8_t) _alphanum[ t_random(61) ];
|
||
|
|
||
|
_storage[_it] = _val;
|
||
|
_val = 0;
|
||
|
}
|
||
|
|
||
|
return _storage;
|
||
|
}
|
||
|
|
||
|
/* HEADER SETTING
|
||
|
*/
|
||
|
|
||
|
void msi_msg_set_call_type ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
assert(_header_field);
|
||
|
|
||
|
SET_HEADER(msi_header_call_type_t, _msg->_call_type, _header_field)
|
||
|
}
|
||
|
void msi_msg_set_user_agent ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
assert(_header_field);
|
||
|
|
||
|
SET_HEADER(msi_header_user_agent_t, _msg->_user_agent, _header_field)
|
||
|
}
|
||
|
void msi_msg_set_friend_id ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
assert(_header_field);
|
||
|
|
||
|
SET_HEADER(msi_header_friendid_t, _msg->_friend_id, _header_field)
|
||
|
}
|
||
|
void msi_msg_set_info ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
}
|
||
|
void msi_msg_set_reason ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
assert(_header_field);
|
||
|
|
||
|
SET_HEADER(msi_header_reason_t, _msg->_reason, _header_field)
|
||
|
}
|
||
|
void msi_msg_set_call_id ( msi_msg_t* _msg, const uint8_t* _header_field )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
assert(_header_field);
|
||
|
|
||
|
SET_HEADER(msi_header_call_id_t, _msg->_call_id, _header_field)
|
||
|
}
|