From da727875ac954b13ecb16521d255499511bb7424 Mon Sep 17 00:00:00 2001 From: mannol Date: Sun, 13 Oct 2013 16:16:47 +0200 Subject: tox A/V: RTP/MSI implementation --- toxmsi/toxmsi_header.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 toxmsi/toxmsi_header.c (limited to 'toxmsi/toxmsi_header.c') diff --git a/toxmsi/toxmsi_header.c b/toxmsi/toxmsi_header.c new file mode 100644 index 00000000..448ebc7f --- /dev/null +++ b/toxmsi/toxmsi_header.c @@ -0,0 +1,181 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "toxmsi_message.h" +#include +#include "../toxrtp/toxrtp_helper.h" +#include +#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; +} + + + -- cgit v1.2.3