mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
182 lines
4.6 KiB
C
182 lines
4.6 KiB
C
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include "config.h"
|
||
|
#endif /* HAVE_CONFIG_H */
|
||
|
|
||
|
#include "toxmsi_message.h"
|
||
|
#include <string.h>
|
||
|
#include "../toxrtp/toxrtp_helper.h"
|
||
|
#include <assert.h>
|
||
|
#include "../toxcore/Lossless_UDP.h"
|
||
|
|
||
|
#define ALLOC_ADD_DATA(_tempval, _hdrlist, _fielddef, _msgvar, _alloctype) \
|
||
|
_tempval = msi_search_field(_hdrlist, (const uint8_t*)_fielddef); \
|
||
|
if ( _tempval ){ \
|
||
|
_msgvar = calloc(sizeof(_alloctype), 1); \
|
||
|
assert(_msgvar); \
|
||
|
_msgvar->_header_value = _tempval; \
|
||
|
}
|
||
|
|
||
|
uint8_t* msi_search_field ( msi_header_t* _list, const uint8_t* _field )
|
||
|
{
|
||
|
assert(_list);
|
||
|
assert(_field);
|
||
|
|
||
|
msi_header_t* _iterator;
|
||
|
|
||
|
for ( _iterator = _list;
|
||
|
_iterator && strcmp((const char*)_iterator->_header_field, (const char*)_field) != 0;
|
||
|
_iterator = _iterator->next );
|
||
|
|
||
|
if ( _iterator ){
|
||
|
return t_strallcpy(_iterator->_header_value);
|
||
|
} else return NULL;
|
||
|
}
|
||
|
|
||
|
int msi_parse_headers ( msi_msg_t* _msg )
|
||
|
{
|
||
|
assert(_msg);
|
||
|
|
||
|
if ( !_msg->_headers )
|
||
|
return FAILURE;
|
||
|
|
||
|
msi_header_t* _list = _msg->_headers;
|
||
|
uint8_t* _field_current;
|
||
|
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _CALL_ID_FIELD, _msg->_call_id, msi_header_call_id_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _VERSION_FIELD, _msg->_version, msi_header_version_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _REQUEST_FIELD, _msg->_request, msi_header_request_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _RESPONSE_FIELD, _msg->_response, msi_header_response_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _FRIENDID_FIELD, _msg->_friend_id, msi_header_friendid_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _CALLTYPE_FIELD, _msg->_call_type, msi_header_call_type_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _USERAGENT_FIELD, _msg->_user_agent, msi_header_user_agent_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _INFO_FIELD, _msg->_info, msi_header_info_t)
|
||
|
ALLOC_ADD_DATA(_field_current, _list, _REASON_FIELD, _msg->_reason, msi_header_reason_t)
|
||
|
|
||
|
/* Since we don't need the raw header anymore remove it */
|
||
|
msi_header_t* _temp;
|
||
|
while ( _list ){
|
||
|
_temp = _list->next;
|
||
|
free(_list->_header_field);
|
||
|
free(_list->_header_value);
|
||
|
free(_list);
|
||
|
_list = _temp;
|
||
|
}
|
||
|
|
||
|
_msg->_headers = NULL;
|
||
|
|
||
|
return SUCCESS;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If you find better way of parsing values let me know
|
||
|
*/
|
||
|
msi_header_t* msi_add_new_header ( uint8_t* _value )
|
||
|
{
|
||
|
if ( !_value )
|
||
|
return NULL;
|
||
|
|
||
|
size_t _length = t_memlen(_value);
|
||
|
|
||
|
if ( !_length ) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
size_t _first_len = t_strfind(_value, (const uint8_t*)" ");
|
||
|
if ( !_first_len ){
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
size_t _second_len = (_length - _first_len);
|
||
|
if ( !_second_len ){
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t* _identifier = calloc(sizeof (uint8_t), (_first_len + 1) );
|
||
|
uint8_t* _data = calloc(sizeof (uint8_t), (_second_len + 1) );
|
||
|
|
||
|
assert(_identifier);
|
||
|
assert(_data);
|
||
|
|
||
|
|
||
|
uint8_t* _p_it = _value;
|
||
|
size_t _num_it;
|
||
|
|
||
|
for ( _num_it = 0; *_p_it != ' '; _num_it++ ){
|
||
|
_identifier[_num_it] = *_p_it;
|
||
|
++_p_it;
|
||
|
}
|
||
|
_identifier[_num_it] = '\0';
|
||
|
++_p_it;
|
||
|
|
||
|
|
||
|
for ( _num_it = 0; *_p_it != '\r'; _num_it++ ){
|
||
|
_data[_num_it] = *_p_it;
|
||
|
++_p_it;
|
||
|
}
|
||
|
_data[_num_it] = '\r';
|
||
|
_data[_num_it + 1] = '\0';
|
||
|
|
||
|
msi_header_t* _retu = calloc(sizeof(msi_header_t), 1);
|
||
|
assert(_retu);
|
||
|
|
||
|
_retu->_header_field = _identifier;
|
||
|
_retu->_header_value = _data;
|
||
|
|
||
|
_retu->next = NULL;
|
||
|
|
||
|
return _retu;
|
||
|
}
|
||
|
|
||
|
msi_header_t* msi_parse_raw_data ( const uint8_t* _data )
|
||
|
{
|
||
|
assert(_data);
|
||
|
|
||
|
uint8_t* _header_string;
|
||
|
|
||
|
_header_string = (uint8_t*) strtok ((char*)_data, _RAW_TERMINATOR);
|
||
|
|
||
|
msi_header_t* _head = msi_add_new_header(_header_string);
|
||
|
msi_header_t* _it = _head;
|
||
|
|
||
|
while ( _header_string && _it ){
|
||
|
|
||
|
_header_string = (uint8_t*) strtok (NULL, _RAW_TERMINATOR);
|
||
|
_it->next = msi_add_new_header(_header_string);
|
||
|
if ( _it->next ){
|
||
|
_it = _it->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Iterate through list and remove all fault headers if any */
|
||
|
|
||
|
msi_header_t* _tmp = _it;
|
||
|
|
||
|
for ( _it = _head; _it; _it = _it->next ){
|
||
|
|
||
|
if ( !_it->_header_value || !_it->_header_field ) {
|
||
|
_tmp ->next = _it->next;
|
||
|
|
||
|
if ( _it->_header_field )
|
||
|
free(_it->_header_field);
|
||
|
if ( _it->_header_value )
|
||
|
free(_it->_header_value);
|
||
|
|
||
|
if ( _it == _head ){
|
||
|
_head = _head->next;
|
||
|
}
|
||
|
|
||
|
free(_it);
|
||
|
_it = _tmp;
|
||
|
} else
|
||
|
_tmp = _it;
|
||
|
|
||
|
}
|
||
|
|
||
|
return _head;
|
||
|
}
|
||
|
|
||
|
|
||
|
|