diff options
Diffstat (limited to 'toxmsi/toxmsi_header.c')
-rw-r--r-- | toxmsi/toxmsi_header.c | 181 |
1 files changed, 181 insertions, 0 deletions
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 @@ | |||
1 | |||
2 | #ifdef HAVE_CONFIG_H | ||
3 | #include "config.h" | ||
4 | #endif /* HAVE_CONFIG_H */ | ||
5 | |||
6 | #include "toxmsi_message.h" | ||
7 | #include <string.h> | ||
8 | #include "../toxrtp/toxrtp_helper.h" | ||
9 | #include <assert.h> | ||
10 | #include "../toxcore/Lossless_UDP.h" | ||
11 | |||
12 | #define ALLOC_ADD_DATA(_tempval, _hdrlist, _fielddef, _msgvar, _alloctype) \ | ||
13 | _tempval = msi_search_field(_hdrlist, (const uint8_t*)_fielddef); \ | ||
14 | if ( _tempval ){ \ | ||
15 | _msgvar = calloc(sizeof(_alloctype), 1); \ | ||
16 | assert(_msgvar); \ | ||
17 | _msgvar->_header_value = _tempval; \ | ||
18 | } | ||
19 | |||
20 | uint8_t* msi_search_field ( msi_header_t* _list, const uint8_t* _field ) | ||
21 | { | ||
22 | assert(_list); | ||
23 | assert(_field); | ||
24 | |||
25 | msi_header_t* _iterator; | ||
26 | |||
27 | for ( _iterator = _list; | ||
28 | _iterator && strcmp((const char*)_iterator->_header_field, (const char*)_field) != 0; | ||
29 | _iterator = _iterator->next ); | ||
30 | |||
31 | if ( _iterator ){ | ||
32 | return t_strallcpy(_iterator->_header_value); | ||
33 | } else return NULL; | ||
34 | } | ||
35 | |||
36 | int msi_parse_headers ( msi_msg_t* _msg ) | ||
37 | { | ||
38 | assert(_msg); | ||
39 | |||
40 | if ( !_msg->_headers ) | ||
41 | return FAILURE; | ||
42 | |||
43 | msi_header_t* _list = _msg->_headers; | ||
44 | uint8_t* _field_current; | ||
45 | |||
46 | ALLOC_ADD_DATA(_field_current, _list, _CALL_ID_FIELD, _msg->_call_id, msi_header_call_id_t) | ||
47 | ALLOC_ADD_DATA(_field_current, _list, _VERSION_FIELD, _msg->_version, msi_header_version_t) | ||
48 | ALLOC_ADD_DATA(_field_current, _list, _REQUEST_FIELD, _msg->_request, msi_header_request_t) | ||
49 | ALLOC_ADD_DATA(_field_current, _list, _RESPONSE_FIELD, _msg->_response, msi_header_response_t) | ||
50 | ALLOC_ADD_DATA(_field_current, _list, _FRIENDID_FIELD, _msg->_friend_id, msi_header_friendid_t) | ||
51 | ALLOC_ADD_DATA(_field_current, _list, _CALLTYPE_FIELD, _msg->_call_type, msi_header_call_type_t) | ||
52 | ALLOC_ADD_DATA(_field_current, _list, _USERAGENT_FIELD, _msg->_user_agent, msi_header_user_agent_t) | ||
53 | ALLOC_ADD_DATA(_field_current, _list, _INFO_FIELD, _msg->_info, msi_header_info_t) | ||
54 | ALLOC_ADD_DATA(_field_current, _list, _REASON_FIELD, _msg->_reason, msi_header_reason_t) | ||
55 | |||
56 | /* Since we don't need the raw header anymore remove it */ | ||
57 | msi_header_t* _temp; | ||
58 | while ( _list ){ | ||
59 | _temp = _list->next; | ||
60 | free(_list->_header_field); | ||
61 | free(_list->_header_value); | ||
62 | free(_list); | ||
63 | _list = _temp; | ||
64 | } | ||
65 | |||
66 | _msg->_headers = NULL; | ||
67 | |||
68 | return SUCCESS; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * If you find better way of parsing values let me know | ||
73 | */ | ||
74 | msi_header_t* msi_add_new_header ( uint8_t* _value ) | ||
75 | { | ||
76 | if ( !_value ) | ||
77 | return NULL; | ||
78 | |||
79 | size_t _length = t_memlen(_value); | ||
80 | |||
81 | if ( !_length ) { | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | size_t _first_len = t_strfind(_value, (const uint8_t*)" "); | ||
86 | if ( !_first_len ){ | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | size_t _second_len = (_length - _first_len); | ||
91 | if ( !_second_len ){ | ||
92 | return NULL; | ||
93 | } | ||
94 | |||
95 | |||
96 | uint8_t* _identifier = calloc(sizeof (uint8_t), (_first_len + 1) ); | ||
97 | uint8_t* _data = calloc(sizeof (uint8_t), (_second_len + 1) ); | ||
98 | |||
99 | assert(_identifier); | ||
100 | assert(_data); | ||
101 | |||
102 | |||
103 | uint8_t* _p_it = _value; | ||
104 | size_t _num_it; | ||
105 | |||
106 | for ( _num_it = 0; *_p_it != ' '; _num_it++ ){ | ||
107 | _identifier[_num_it] = *_p_it; | ||
108 | ++_p_it; | ||
109 | } | ||
110 | _identifier[_num_it] = '\0'; | ||
111 | ++_p_it; | ||
112 | |||
113 | |||
114 | for ( _num_it = 0; *_p_it != '\r'; _num_it++ ){ | ||
115 | _data[_num_it] = *_p_it; | ||
116 | ++_p_it; | ||
117 | } | ||
118 | _data[_num_it] = '\r'; | ||
119 | _data[_num_it + 1] = '\0'; | ||
120 | |||
121 | msi_header_t* _retu = calloc(sizeof(msi_header_t), 1); | ||
122 | assert(_retu); | ||
123 | |||
124 | _retu->_header_field = _identifier; | ||
125 | _retu->_header_value = _data; | ||
126 | |||
127 | _retu->next = NULL; | ||
128 | |||
129 | return _retu; | ||
130 | } | ||
131 | |||
132 | msi_header_t* msi_parse_raw_data ( const uint8_t* _data ) | ||
133 | { | ||
134 | assert(_data); | ||
135 | |||
136 | uint8_t* _header_string; | ||
137 | |||
138 | _header_string = (uint8_t*) strtok ((char*)_data, _RAW_TERMINATOR); | ||
139 | |||
140 | msi_header_t* _head = msi_add_new_header(_header_string); | ||
141 | msi_header_t* _it = _head; | ||
142 | |||
143 | while ( _header_string && _it ){ | ||
144 | |||
145 | _header_string = (uint8_t*) strtok (NULL, _RAW_TERMINATOR); | ||
146 | _it->next = msi_add_new_header(_header_string); | ||
147 | if ( _it->next ){ | ||
148 | _it = _it->next; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* Iterate through list and remove all fault headers if any */ | ||
153 | |||
154 | msi_header_t* _tmp = _it; | ||
155 | |||
156 | for ( _it = _head; _it; _it = _it->next ){ | ||
157 | |||
158 | if ( !_it->_header_value || !_it->_header_field ) { | ||
159 | _tmp ->next = _it->next; | ||
160 | |||
161 | if ( _it->_header_field ) | ||
162 | free(_it->_header_field); | ||
163 | if ( _it->_header_value ) | ||
164 | free(_it->_header_value); | ||
165 | |||
166 | if ( _it == _head ){ | ||
167 | _head = _head->next; | ||
168 | } | ||
169 | |||
170 | free(_it); | ||
171 | _it = _tmp; | ||
172 | } else | ||
173 | _tmp = _it; | ||
174 | |||
175 | } | ||
176 | |||
177 | return _head; | ||
178 | } | ||
179 | |||
180 | |||
181 | |||