krista@2271
|
1 |
// This file is under GNU General Public License 3.0
|
krista@2271
|
2 |
// see LICENSE.txt
|
krista@2271
|
3 |
|
krista@2271
|
4 |
#include "pEp_internal.h"
|
krista@2271
|
5 |
|
krista@2271
|
6 |
#include <memory.h>
|
krista@2271
|
7 |
#include <assert.h>
|
krista@2271
|
8 |
|
krista@2271
|
9 |
#include "asn1_helper.h"
|
krista@2271
|
10 |
#include "../asn.1/DeviceGroup-Protocol.h"
|
krista@2271
|
11 |
|
krista@2271
|
12 |
// receive_sync_msg is defined in the sync_impl
|
krista@2271
|
13 |
|
krista@2271
|
14 |
PEP_STATUS receive_sync_msg(
|
krista@2271
|
15 |
PEP_SESSION session,
|
krista@2271
|
16 |
sync_msg_t *sync_msg,
|
krista@2271
|
17 |
time_t *timeout
|
krista@2271
|
18 |
);
|
krista@2271
|
19 |
|
krista@2271
|
20 |
DYNAMIC_API PEP_STATUS register_sync_callbacks(
|
krista@2271
|
21 |
PEP_SESSION session,
|
krista@2271
|
22 |
void *management,
|
krista@2271
|
23 |
messageToSend_t messageToSend,
|
krista@2271
|
24 |
notifyHandshake_t notifyHandshake,
|
krista@2271
|
25 |
inject_sync_msg_t inject_sync_msg,
|
krista@2271
|
26 |
retrieve_next_sync_msg_t retrieve_next_sync_msg
|
krista@2271
|
27 |
)
|
krista@2271
|
28 |
{
|
krista@2271
|
29 |
assert(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg);
|
krista@2271
|
30 |
if (!(session && management && messageToSend && notifyHandshake && inject_sync_msg && retrieve_next_sync_msg))
|
krista@2271
|
31 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
32 |
|
krista@2271
|
33 |
pEpUUID uuid;
|
krista@2271
|
34 |
uuid_generate_random(uuid);
|
krista@2271
|
35 |
uuid_unparse_upper(uuid, session->sync_uuid);
|
krista@2271
|
36 |
|
krista@2271
|
37 |
session->sync_management = management;
|
krista@2271
|
38 |
session->messageToSend = messageToSend;
|
krista@2271
|
39 |
session->notifyHandshake = notifyHandshake;
|
krista@2271
|
40 |
session->inject_sync_msg = inject_sync_msg;
|
krista@2271
|
41 |
session->retrieve_next_sync_msg = retrieve_next_sync_msg;
|
krista@2271
|
42 |
|
krista@2271
|
43 |
// start state machine
|
krista@2271
|
44 |
session->sync_state = InitState;
|
krista@2271
|
45 |
time_t unused = 0;
|
krista@2271
|
46 |
PEP_STATUS status = fsm_DeviceState_inject(session, Init, NULL, NULL, &unused);
|
krista@2271
|
47 |
if (status != PEP_STATUS_OK)
|
krista@2271
|
48 |
unregister_sync_callbacks(session);
|
krista@2271
|
49 |
|
krista@2271
|
50 |
return status;
|
krista@2271
|
51 |
}
|
krista@2271
|
52 |
|
krista@2271
|
53 |
DYNAMIC_API PEP_STATUS attach_sync_session(
|
krista@2271
|
54 |
PEP_SESSION session,
|
krista@2271
|
55 |
PEP_SESSION sync_session
|
krista@2271
|
56 |
)
|
krista@2271
|
57 |
{
|
krista@2271
|
58 |
assert(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg );
|
krista@2271
|
59 |
if (!(session && sync_session && sync_session->sync_management && sync_session->inject_sync_msg ))
|
krista@2271
|
60 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
61 |
|
krista@2271
|
62 |
session->sync_session = sync_session;
|
krista@2271
|
63 |
// memcpy(session->sync_uuid, sync_session->sync_uuid, 37);
|
krista@2271
|
64 |
|
krista@2271
|
65 |
// session->sync_management = sync_session->sync_management;
|
krista@2271
|
66 |
// session->inject_sync_msg = sync_session->inject_sync_msg;
|
krista@2271
|
67 |
|
krista@2271
|
68 |
return PEP_STATUS_OK;
|
krista@2271
|
69 |
}
|
krista@2271
|
70 |
|
krista@2271
|
71 |
DYNAMIC_API PEP_STATUS detach_sync_session(PEP_SESSION session)
|
krista@2271
|
72 |
{
|
krista@2271
|
73 |
assert(session);
|
krista@2271
|
74 |
if (!(session))
|
krista@2271
|
75 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
76 |
|
krista@2271
|
77 |
session->sync_session = session;
|
krista@2271
|
78 |
// memset(session->sync_uuid, 0, 37);
|
krista@2271
|
79 |
|
krista@2271
|
80 |
// session->sync_management = NULL;
|
krista@2271
|
81 |
// session->inject_sync_msg = NULL;
|
krista@2271
|
82 |
|
krista@2271
|
83 |
return PEP_STATUS_OK;
|
krista@2271
|
84 |
}
|
krista@2271
|
85 |
|
krista@2271
|
86 |
int call_inject_sync_msg(PEP_SESSION session, void *msg)
|
krista@2271
|
87 |
{
|
krista@2271
|
88 |
if(session->sync_session->inject_sync_msg &&
|
krista@2271
|
89 |
session->sync_session->sync_management)
|
krista@2271
|
90 |
return session->sync_session->inject_sync_msg(msg,
|
krista@2271
|
91 |
session->sync_session->sync_management);
|
krista@2271
|
92 |
else
|
krista@2271
|
93 |
return PEP_SYNC_NO_INJECT_CALLBACK;
|
krista@2271
|
94 |
}
|
krista@2271
|
95 |
|
krista@2271
|
96 |
DYNAMIC_API void unregister_sync_callbacks(PEP_SESSION session) {
|
krista@2271
|
97 |
// stop state machine
|
krista@2271
|
98 |
session->sync_state = DeviceState_state_NONE;
|
krista@2271
|
99 |
|
krista@2271
|
100 |
// unregister
|
krista@2271
|
101 |
session->sync_management = NULL;
|
krista@2271
|
102 |
session->messageToSend = NULL;
|
krista@2271
|
103 |
session->notifyHandshake = NULL;
|
krista@2271
|
104 |
session->inject_sync_msg = NULL;
|
krista@2271
|
105 |
session->retrieve_next_sync_msg = NULL;
|
krista@2271
|
106 |
}
|
krista@2271
|
107 |
|
krista@2271
|
108 |
DYNAMIC_API PEP_STATUS deliverHandshakeResult(
|
krista@2271
|
109 |
PEP_SESSION session,
|
krista@2271
|
110 |
Identity partner,
|
krista@2271
|
111 |
sync_handshake_result result
|
krista@2271
|
112 |
)
|
krista@2271
|
113 |
{
|
krista@2271
|
114 |
assert(session);
|
krista@2271
|
115 |
if (!session)
|
krista@2271
|
116 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
117 |
|
krista@2271
|
118 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@2271
|
119 |
|
krista@2271
|
120 |
DeviceState_event event;
|
krista@2271
|
121 |
bool need_partner = false;
|
krista@2271
|
122 |
|
krista@2271
|
123 |
switch (result) {
|
krista@2271
|
124 |
case SYNC_HANDSHAKE_CANCEL:
|
krista@2271
|
125 |
event = Cancel;
|
krista@2271
|
126 |
break;
|
krista@2271
|
127 |
case SYNC_HANDSHAKE_ACCEPTED:
|
krista@2271
|
128 |
{
|
krista@2271
|
129 |
event = HandshakeAccepted;
|
krista@2271
|
130 |
need_partner = true;
|
krista@2271
|
131 |
break;
|
krista@2271
|
132 |
}
|
krista@2271
|
133 |
case SYNC_HANDSHAKE_REJECTED:
|
krista@2271
|
134 |
{
|
krista@2271
|
135 |
event = HandshakeRejected;
|
krista@2271
|
136 |
need_partner = true;
|
krista@2271
|
137 |
break;
|
krista@2271
|
138 |
}
|
krista@2271
|
139 |
default:
|
krista@2271
|
140 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
141 |
}
|
krista@2271
|
142 |
|
krista@2271
|
143 |
pEp_identity *_partner = NULL;
|
krista@2271
|
144 |
if(need_partner){
|
krista@2271
|
145 |
_partner = identity_dup(partner);
|
krista@2271
|
146 |
if (_partner == NULL)
|
krista@2271
|
147 |
return PEP_OUT_OF_MEMORY;
|
krista@2271
|
148 |
}
|
krista@2271
|
149 |
status = inject_DeviceState_event(session, event, _partner, NULL);
|
krista@2271
|
150 |
|
krista@2271
|
151 |
return status;
|
krista@2271
|
152 |
}
|
krista@2271
|
153 |
|
krista@2271
|
154 |
DYNAMIC_API PEP_STATUS do_sync_protocol(
|
krista@2271
|
155 |
PEP_SESSION session,
|
krista@2271
|
156 |
void *obj
|
krista@2271
|
157 |
)
|
krista@2271
|
158 |
{
|
krista@2271
|
159 |
sync_msg_t *msg = NULL;
|
krista@2271
|
160 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@2271
|
161 |
time_t timeout = 0;
|
krista@2271
|
162 |
|
krista@2271
|
163 |
assert(session && session->retrieve_next_sync_msg);
|
krista@2271
|
164 |
assert(obj);
|
krista@2271
|
165 |
|
krista@2271
|
166 |
if (!(session && session->retrieve_next_sync_msg) || !obj)
|
krista@2271
|
167 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
168 |
|
krista@2271
|
169 |
log_event(session, "sync_protocol thread started", "pEp sync protocol", NULL, NULL);
|
krista@2271
|
170 |
|
krista@2271
|
171 |
session->sync_obj = obj;
|
krista@2271
|
172 |
|
krista@2271
|
173 |
while (true)
|
krista@2271
|
174 |
{
|
krista@2271
|
175 |
msg = (sync_msg_t *) session->retrieve_next_sync_msg(session->sync_management, &timeout);
|
krista@2271
|
176 |
if(msg == NULL && timeout == 0)
|
krista@2271
|
177 |
break;
|
krista@2271
|
178 |
else if(msg == NULL && timeout != 0){
|
krista@2271
|
179 |
status = fsm_DeviceState_inject(session, Timeout, NULL, NULL, &timeout);
|
krista@2271
|
180 |
#ifndef NDEBUG
|
krista@2271
|
181 |
char buffer[MAX_LINELENGTH];
|
krista@2271
|
182 |
memset(buffer, 0, MAX_LINELENGTH);
|
krista@2271
|
183 |
snprintf(buffer, MAX_LINELENGTH, "problem with timeout event : %d\n", (int) status);
|
krista@2271
|
184 |
log_event(session, buffer, "pEp sync protocol", NULL, NULL);
|
krista@2271
|
185 |
continue;
|
krista@2271
|
186 |
#endif
|
krista@2271
|
187 |
}
|
krista@2271
|
188 |
else {
|
krista@2271
|
189 |
status = receive_sync_msg(session, msg, &timeout);
|
krista@2271
|
190 |
if (status != PEP_STATUS_OK && status != PEP_MESSAGE_IGNORE) {
|
krista@2271
|
191 |
#ifndef NDEBUG
|
krista@2271
|
192 |
char buffer[MAX_LINELENGTH];
|
krista@2271
|
193 |
memset(buffer, 0, MAX_LINELENGTH);
|
krista@2271
|
194 |
snprintf(buffer, MAX_LINELENGTH, "problem with msg received: %d\n", (int) status);
|
krista@2271
|
195 |
log_event(session, buffer, "pEp sync protocol", NULL, NULL);
|
krista@2271
|
196 |
#endif
|
krista@2271
|
197 |
}
|
krista@2271
|
198 |
}
|
krista@2271
|
199 |
}
|
krista@2271
|
200 |
|
krista@2271
|
201 |
log_event(session, "sync_protocol thread shutdown", "pEp sync protocol", NULL, NULL);
|
krista@2271
|
202 |
|
krista@2271
|
203 |
session->sync_obj = NULL;
|
krista@2271
|
204 |
|
krista@2271
|
205 |
return PEP_STATUS_OK;
|
krista@2271
|
206 |
}
|
krista@2271
|
207 |
|
krista@2271
|
208 |
DYNAMIC_API PEP_STATUS decode_sync_msg(
|
krista@2271
|
209 |
const char *data,
|
krista@2271
|
210 |
size_t size,
|
krista@2271
|
211 |
char **text
|
krista@2271
|
212 |
)
|
krista@2271
|
213 |
{
|
krista@2271
|
214 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@2271
|
215 |
|
krista@2271
|
216 |
assert(data && text);
|
krista@2271
|
217 |
if (!(data && text))
|
krista@2271
|
218 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
219 |
|
krista@2271
|
220 |
*text = NULL;
|
krista@2271
|
221 |
|
krista@2271
|
222 |
DeviceGroup_Protocol_t *msg = NULL;
|
krista@2271
|
223 |
uper_decode_complete(NULL, &asn_DEF_DeviceGroup_Protocol, (void **) &msg,
|
krista@2271
|
224 |
data, size);
|
krista@2271
|
225 |
if (!msg)
|
krista@2271
|
226 |
return PEP_SYNC_ILLEGAL_MESSAGE;
|
krista@2271
|
227 |
|
krista@2271
|
228 |
growing_buf_t *dst = new_growing_buf();
|
krista@2271
|
229 |
if (!dst) {
|
krista@2271
|
230 |
status = PEP_OUT_OF_MEMORY;
|
krista@2271
|
231 |
goto the_end;
|
krista@2271
|
232 |
}
|
krista@2271
|
233 |
|
krista@2271
|
234 |
asn_enc_rval_t er = xer_encode(&asn_DEF_DeviceGroup_Protocol, msg,
|
krista@2271
|
235 |
XER_F_BASIC, (asn_app_consume_bytes_f *) consume_bytes, (void *) dst);
|
krista@2271
|
236 |
if (er.encoded == -1) {
|
krista@2271
|
237 |
status = PEP_CANNOT_ENCODE;
|
krista@2271
|
238 |
goto the_end;
|
krista@2271
|
239 |
}
|
krista@2271
|
240 |
|
krista@2271
|
241 |
*text = dst->data;
|
krista@2271
|
242 |
dst->data = NULL;
|
krista@2271
|
243 |
|
krista@2271
|
244 |
the_end:
|
krista@2271
|
245 |
free_growing_buf(dst);
|
krista@2271
|
246 |
ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
|
krista@2271
|
247 |
return status;
|
krista@2271
|
248 |
}
|
krista@2271
|
249 |
|
krista@2271
|
250 |
DYNAMIC_API PEP_STATUS encode_sync_msg(
|
krista@2271
|
251 |
const char *text,
|
krista@2271
|
252 |
char **data,
|
krista@2271
|
253 |
size_t *size
|
krista@2271
|
254 |
)
|
krista@2271
|
255 |
{
|
krista@2271
|
256 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@2271
|
257 |
|
krista@2271
|
258 |
assert(text && data && size);
|
krista@2271
|
259 |
if (!(text && data && size))
|
krista@2271
|
260 |
return PEP_ILLEGAL_VALUE;
|
krista@2271
|
261 |
|
krista@2271
|
262 |
*data = NULL;
|
krista@2271
|
263 |
*size = 0;
|
krista@2271
|
264 |
|
krista@2271
|
265 |
DeviceGroup_Protocol_t *msg = NULL;
|
krista@2271
|
266 |
asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_DeviceGroup_Protocol,
|
krista@2271
|
267 |
(void **) &msg, (const void *) text, strlen(text));
|
krista@2271
|
268 |
if (dr.code != RC_OK) {
|
krista@2271
|
269 |
status = PEP_SYNC_ILLEGAL_MESSAGE;
|
krista@2271
|
270 |
goto the_end;
|
krista@2271
|
271 |
}
|
krista@2271
|
272 |
|
krista@2271
|
273 |
char *payload = NULL;
|
krista@2271
|
274 |
ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_DeviceGroup_Protocol,
|
krista@2271
|
275 |
NULL, msg, (void **) &payload);
|
krista@2271
|
276 |
if (_size == -1) {
|
krista@2271
|
277 |
status = PEP_CANNOT_ENCODE;
|
krista@2271
|
278 |
goto the_end;
|
krista@2271
|
279 |
}
|
krista@2271
|
280 |
|
krista@2271
|
281 |
*data = payload;
|
krista@2271
|
282 |
*size = (size_t) _size;
|
krista@2271
|
283 |
|
krista@2271
|
284 |
the_end:
|
krista@2271
|
285 |
ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
|
krista@2271
|
286 |
return status;
|
krista@2271
|
287 |
}
|
krista@2271
|
288 |
|