Fix memory leak
[platform/core/connectivity/asp-manager.git] / src / asp-session-peer.c
1 #include "gfsm.h"
2 #include "asp-session-peer.h"
3 #include "asp-session-peer-interface.h"
4 #include "asp-coordination-protocol.h"
5 #include "asp-manager-util.h"
6
7 #define ASP_SESS_PEER_FSM_TRACE_ENTER()
8 #define ASP_SESS_PEER_FSM_TRACE_LEAVE()
9
10 #define ASP_SESS_PEER_HEADER "SESSION_PEER_FSM"
11
12 typedef struct asp_sess_peer {
13         gfsm_context_s *context;
14         GSocketAddress *p_sock_addr;
15         guint8 seq_num;
16         guint8 retry;
17         guint timer_id;
18         void *p_sending_msg_data;
19         GTree *p_sess_tree;
20 } asp_sess_peer_s;
21
22 typedef struct asp_sess_peer_key {
23         guint8 ip_addr[16];
24         guint8 ip_addr_len;
25         guint16 port;
26 } asp_sess_peer_key_s;
27
28 typedef struct asp_sess_peer_sess_key {
29         guint32 sess_id;
30         guint8 sess_mac[6];
31 } asp_sess_peer_sess_key_s;
32
33 enum asp_sess_peer_state_t {
34         ASP_S_PEER_STATE_INIT,
35         ASP_S_PEER_STATE_CREATED,
36         ASP_S_PEER_STATE_VERSION_SENT,
37         ASP_S_PEER_STATE_WAIT_VERSION,
38         ASP_S_PEER_STATE_WAIT_ACK,
39         ASP_S_PEER_STATE_OPENED,
40         ASP_S_PEER_STATE_IDLE,
41         /*    ASP_S_PEER_STATE_REQ_SENT, */
42         ASP_S_PEER_STATE_CLOSED,
43         ASP_S_PEER_STATE_MAX,
44 };
45
46 enum asp_sess_peer_event_t {
47         ASP_S_PEER_EVENT_START,
48         ASP_S_PEER_EVENT_ADD_SESSION,
49         ASP_S_PEER_EVENT_DEL_SESSION,
50         ASP_S_PEER_EVENT_SEND_REQ,
51         ASP_S_PEER_EVENT_SEND_ACK,
52         ASP_S_PEER_EVENT_SEND_NACK,
53         ASP_S_PEER_EVENT_RECV_VERSION,
54         ASP_S_PEER_EVENT_RECV_REQ,
55         ASP_S_PEER_EVENT_RECV_ACK,
56         ASP_S_PEER_EVENT_RECV_NACK,
57         ASP_S_PEER_EVENT_TIMEOUT,
58         ASP_S_PEER_EVENT_CLOSE,
59         ASP_S_PEER_EVENT_MAX,
60 };
61
62 static asp_sess_peer_s *_asp_sess_peer_create_peer(GSocketAddress *p_sock_addr);
63 static void _asp_sess_peer_destroy_peer(void *p_peer);
64 static asp_sess_peer_s *_asp_sess_peer_tree_find_peer(GSocketAddress
65                 *p_sock_addr);
66 static gboolean _asp_sess_peer_tree_insert_peer(GSocketAddress *p_sock_addr,
67                 asp_sess_peer_s *p_peer);
68 /*static gboolean _asp_sess_peer_tree_remove_peer(GSocketAddress* p_sock_addr); */
69 static gint _asp_sess_peer_tree_compare_cb(gconstpointer a, gconstpointer b,
70                 gpointer p_user_data);
71 static void _asp_sess_peer_tree_key_destructor_cb(gpointer a);
72 static void _asp_sess_peer_tree_value_destructor_cb(gpointer a);
73 static void *asp_sess_peer_dup_msg_data(void *p_msg);
74 static void _asp_sess_peer_set_sending_msg_data(asp_sess_peer_s *p_peer,
75                 void *p_msg);
76 static asp_sess_peer_sess_key_s *_asp_sess_peer_sess_tree_create_key(
77         guint8 session_mac[], guint32 session_id);
78 static gint _asp_sess_peer_sess_tree_compare_cb(gconstpointer a,
79                 gconstpointer b, gpointer user_data);
80 static void _asp_sess_peer_sess_tree_key_destructor_cb(gpointer p_data);
81 static void _asp_sess_peer_sess_tree_value_destructor_cb(gpointer p_value);
82 static void _asp_sess_peer_stop_timer(asp_sess_peer_s *p_peer);
83 static void _asp_sess_peer_start_timer(asp_sess_peer_s *p_peer, guint sec);
84
85 static gboolean _asp_sess_peer_send_req(GSocketAddress *p_sock_addr,
86                                         void *p_msg);
87 static gboolean _asp_sess_peer_send_ack(GSocketAddress *p_sock_addr,
88                                         void *p_msg);
89 static gboolean _asp_sess_peer_send_nack(GSocketAddress *p_sock_addr,
90                 void *p_msg);
91
92 static gboolean _asp_sess_peer_recv_req(GSocketAddress *p_sock_addr,
93                                         void *p_msg);
94 static gboolean _asp_sess_peer_recv_ack(GSocketAddress *p_sock_addr,
95                                         void *p_msg);
96 static gboolean _asp_sess_peer_recv_nack(GSocketAddress *p_sock_addr,
97                 void *p_msg);
98
99 static gboolean _asp_sess_peer_recv_version(GSocketAddress *p_sock_addr,
100                 void *p_msg);
101 static void _asp_sess_peer_send_nack_to_protocol(GSocketAddress *p_sock_addr,
102                 guint8 seq_num, guint8 reason);
103
104 void _asp_sess_peer_state_init_entry_action(void *p_context_data);
105 static void _asp_sess_peer_state_init_exit_action(void *p_context_data);
106 static gfsm_state_id_t _asp_sess_peer_state_init_reaction_start(
107         void *p_context_data, void *p_event_data);
108
109 static void _asp_sess_peer_state_created_entry_action(void *p_context_data);
110 static void _asp_sess_peer_state_created_exit_action(void *p_context_data);
111 static gfsm_state_id_t _asp_sess_peer_state_created_reaction_add_session(
112         void *p_context_data, void *p_event_data);
113 static gfsm_state_id_t _asp_sess_peer_state_created_reaction_del_session(
114         void *p_context_data, void *p_event_data);
115 static gfsm_state_id_t _asp_sess_peer_state_created_reaction_close(
116         void *p_context_data, void *p_event_data);
117 static gfsm_state_id_t _asp_sess_peer_state_created_reaction_send_ack(
118         void *p_context_data, void *p_event_data);
119 static gfsm_state_id_t _asp_sess_peer_state_created_reaction_send_nack(
120         void *p_context_data, void *p_event_data);
121
122 static void _asp_sess_peer_state_version_sent_entry_action(
123         void *p_context_data);
124 static void _asp_sess_peer_state_version_sent_exit_action(void *p_context_data);
125 /*static gfsm_state_id_t asp_sess_peer_state_version_sent_reaction_send_req (void* p_context_data, void* p_event_data); */
126 /*static gfsm_state_id_t asp_sess_peer_state_version_sent_reaction_recv_version (void* p_context_data, void* p_event_data); */
127 /*static gfsm_state_id_t asp_sess_peer_state_version_sent_reaction_recv_req (void* p_context_data, void* p_event_data); */
128 static gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_recv_ack(
129         void *p_context_data, void *p_event_data);
130 static gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_recv_nack(
131         void *p_context_data, void *p_event_data);
132 static gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_timeout(
133         void *p_context_data, void *p_event_data);
134
135 static void _asp_sess_peer_state_wait_version_entry_action(
136         void *p_context_data);
137 static void _asp_sess_peer_state_wait_version_exit_action(void *p_context_data);
138 /*static gfsm_state_id_t asp_sess_peer_state_wait_version_reaction_send_req (void* p_context_data, void* p_event_data); */
139 static gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_recv_version(
140         void *p_context_data, void *p_event_data);
141 static gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_recv_req(
142         void *p_context_data, void *p_event_data);
143 /*static gfsm_state_id_t asp_sess_peer_state_wait_version_reaction_recv_ack (void* p_context_data, void* p_event_data); */
144 /*static gfsm_state_id_t asp_sess_peer_state_wait_version_reaction_recv_nack (void* p_context_data, void* p_event_data); */
145 static gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_timeout(
146         void *p_context_data, void *p_event_data);
147
148 static void _asp_sess_peer_state_opened_entry_action(void *p_context_data);
149 static void _asp_sess_peer_state_opened_exit_action(void *p_context_data);
150 static gfsm_state_id_t _asp_sess_peer_state_opened_reaction_recv_version(
151         void *p_context_data, void *p_event_data);
152 static gfsm_state_id_t _asp_sess_peer_state_opened_reaction_recv_req(
153         void *p_context_data, void *p_event_data);
154
155 static void _asp_sess_peer_state_idle_entry_action(void *p_context_data);
156 static void _asp_sess_peer_state_idle_exit_action(void *p_context_data);
157 static gfsm_state_id_t _asp_sess_peer_state_idle_reaction_send_req(
158         void *p_context_data, void *p_event_data);
159
160 static void _asp_sess_peer_state_wait_ack_entry_action(void *p_context_data);
161 static void _asp_sess_peer_state_wait_ack_exit_action(void *p_context_data);
162 /*static gfsm_state_id_t asp_sess_peer_state_wait_ack_reaction_send_req (void* p_context_data, void* p_event_data); */
163 static gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_recv_ack(
164         void *p_context_data, void *p_event_data);
165 static gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_recv_nack(
166         void *p_context_data, void *p_event_data);
167 static gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_timeout(
168         void *p_context_data, void *p_event_data);
169
170 static void _asp_sess_peer_state_close_entry_action(void *p_context_data);
171 static void _asp_sess_peer_state_close_exit_action(void *p_context_data);
172
173 static void asp_sess_peer_fsm_init();
174
175 static gfsm_s *asm_sess_peer_fsm;
176 static gfsm_state_s *asp_sess_peer_state_init;
177 static gfsm_state_s *asp_sess_peer_state_created;
178 static gfsm_state_s *asp_sess_peer_state_version_sent;
179 static gfsm_state_s *asp_sess_peer_state_wait_version;
180 static gfsm_state_s *asp_sess_peer_state_opened;
181 static gfsm_state_s *asp_sess_peer_state_idle;
182 /*static gfsm_state_s asp_sess_peer_state_req_sent; */
183 static gfsm_state_s *asp_sess_peer_state_wait_ack;
184 static gfsm_state_s *asp_sess_peer_state_closed;
185 static GTree *gp_peer_tree = 0;
186
187 void asp_sess_peer_init()
188 {
189         INFO_MSG;
190
191         gp_peer_tree = g_tree_new_full(_asp_sess_peer_tree_compare_cb, NULL,
192                                        _asp_sess_peer_tree_key_destructor_cb, _asp_sess_peer_tree_value_destructor_cb);
193
194         asp_sess_peer_fsm_init();
195
196         asp_coordination_protocol_init();
197 }
198
199 void asp_sess_peer_destroy()
200 {
201         INFO_MSG;
202
203         gfsm_destroy_fsm(asm_sess_peer_fsm);
204         g_tree_destroy(gp_peer_tree);
205         gp_peer_tree = 0;
206 }
207
208 gboolean asp_sess_peer_send_msg(GSocketAddress *p_sock_addr, void *p_msg)
209 {
210         INFO_MSG;
211
212         asp_coord_header_s *p_header = (asp_coord_header_s *)p_msg;
213
214         switch (p_header->opcode) {
215         case ASP_OPCODE_REQUEST_SESSION:
216                 ASP_LOGD("%s asp_sess_peer_send_msg, ASP_OPCODE_REQUEST_SESSION session_id:%d",
217                          ROLE, ((asp_request_session_s *)p_msg)->session_id);
218                 return _asp_sess_peer_send_req(p_sock_addr, p_msg);
219         case ASP_OPCODE_ADDED_SESSION:
220         /*FALL THROUGH */
221         case ASP_OPCODE_REJECTED_SESSION:
222         /*FALL THROUGH */
223         case ASP_OPCODE_REMOVE_SESSION:
224         /*FALL THROUGH */
225         case ASP_OPCODE_ALLOWED_PORT:
226         /*FALL THROUGH */
227         case ASP_OPCODE_DEFERRED_SESSION:
228                 return _asp_sess_peer_send_req(p_sock_addr, p_msg);
229         case ASP_OPCODE_VERSION:
230                 return FALSE;
231         case ASP_OPCODE_ACK:
232                 return _asp_sess_peer_send_ack(p_sock_addr, p_msg);
233         case ASP_OPCODE_NACK:
234                 return _asp_sess_peer_send_nack(p_sock_addr, p_msg);
235         default:
236                 return FALSE;
237         }
238
239         return TRUE;
240 }
241
242 gboolean asp_sess_peer_recv_msg(GSocketAddress *p_sock_addr, void *p_msg)
243 {
244         INFO_MSG;
245
246         asp_coord_header_s *p_header = (asp_coord_header_s *)p_msg;
247
248         switch (p_header->opcode) {
249         case ASP_OPCODE_REQUEST_SESSION:
250         /*FALL THROUGH */
251         case ASP_OPCODE_ADDED_SESSION:
252         /*FALL THROUGH */
253         case ASP_OPCODE_REJECTED_SESSION:
254         /*FALL THROUGH */
255         case ASP_OPCODE_REMOVE_SESSION:
256         /*FALL THROUGH */
257         case ASP_OPCODE_ALLOWED_PORT:
258         /*FALL THROUGH */
259         case ASP_OPCODE_DEFERRED_SESSION:
260                 return _asp_sess_peer_recv_req(p_sock_addr, p_msg);
261         case ASP_OPCODE_VERSION:
262                 return _asp_sess_peer_recv_version(p_sock_addr, p_msg);
263         case ASP_OPCODE_ACK:
264                 return _asp_sess_peer_recv_ack(p_sock_addr, p_msg);
265         case ASP_OPCODE_NACK:
266                 return _asp_sess_peer_recv_nack(p_sock_addr, p_msg);
267         default:
268                 _asp_sess_peer_send_nack_to_protocol(p_sock_addr, p_header->seq_num,
269                                                      ASP_NACK_REASON_INVALID_OPCODE);
270                 return FALSE;
271         }
272
273         return TRUE;
274 }
275
276 gboolean _asp_sess_peer_send_req(GSocketAddress *p_sock_addr, void *p_msg)
277 {
278         INFO_MSG;
279
280         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
281
282         if (NULL == p_peer) {
283                 p_peer = _asp_sess_peer_create_peer(p_sock_addr);
284                 g_assert(p_peer);
285
286                 gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_START,
287                                    NULL, NULL));
288         }
289
290         if (p_peer && p_peer->context)
291                 gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_SEND_REQ,
292                                 asp_sess_peer_dup_msg_data(p_msg), g_free));
293
294         return TRUE;
295 }
296
297 gboolean _asp_sess_peer_send_ack(GSocketAddress *p_sock_addr, void *p_msg)
298 {
299         INFO_MSG;
300
301         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
302
303         if (NULL == p_peer)
304                 return FALSE;
305
306         gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_SEND_ACK,
307                            asp_sess_peer_dup_msg_data(p_msg), g_free));
308
309         return TRUE;
310 }
311
312 gboolean _asp_sess_peer_send_nack(GSocketAddress *p_sock_addr, void *p_msg)
313 {
314         INFO_MSG;
315
316         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
317
318         if (NULL == p_peer)
319                 return FALSE;
320
321         gfsm_process_event(&(p_peer->context),
322                            gfsm_create_event(ASP_S_PEER_EVENT_SEND_NACK, asp_sess_peer_dup_msg_data(p_msg),
323                                              g_free));
324
325         return TRUE;
326 }
327
328 gboolean _asp_sess_peer_recv_version(GSocketAddress *p_sock_addr, void *p_msg)
329 {
330         INFO_MSG;
331
332         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
333
334         if (NULL == p_peer) {
335                 p_peer = _asp_sess_peer_create_peer(p_sock_addr);
336
337                 g_assert(p_peer);
338
339                 asp_ack_s ack;
340                 ack.opcode = ASP_OPCODE_ACK;
341                 ack.seq_num = ((asp_version_s *)p_msg)->seq_num;
342                 asp_coordination_protocol_send_msg(p_sock_addr, &ack);
343
344                 gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_START,
345                                    NULL, NULL));
346         } else {
347                 asp_ack_s ack;
348                 ack.opcode = ASP_OPCODE_ACK;
349                 ack.seq_num = ((asp_version_s *)p_msg)->seq_num;
350                 asp_coordination_protocol_send_msg(p_sock_addr, &ack);
351         }
352
353         if (p_peer && p_peer->context)
354                 gfsm_process_event(&(p_peer->context),
355                                 gfsm_create_event(ASP_S_PEER_EVENT_RECV_VERSION,
356                                                 asp_sess_peer_dup_msg_data(p_msg), g_free));
357
358         return TRUE;
359 }
360
361 gboolean _asp_sess_peer_recv_req(GSocketAddress *p_sock_addr, void *p_msg)
362 {
363         INFO_MSG;
364
365         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
366         asp_coord_header_s *p_header = (asp_coord_header_s *)p_msg;
367
368         if (NULL == p_peer) {
369                 _asp_sess_peer_send_nack_to_protocol(p_sock_addr, p_header->seq_num,
370                                                      ASP_NACK_REASON_NO_SESSION_EXIST);
371                 return FALSE;
372         }
373
374         gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_RECV_REQ,
375                            asp_sess_peer_dup_msg_data(p_msg), g_free));
376
377         return TRUE;
378 }
379
380 gboolean _asp_sess_peer_recv_ack(GSocketAddress *p_sock_addr, void *p_msg)
381 {
382         INFO_MSG;
383
384         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
385
386         if (NULL == p_peer)
387                 return FALSE;
388
389         asp_request_header_s *p_header = (asp_request_header_s *)
390                                          p_peer->p_sending_msg_data;
391         ASP_LOGD("%s _asp_sess_peer_recv_ack, opcode:%d session_id:%d", ROLE,
392                  p_header->opcode, p_header->session_id);
393
394         gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_RECV_ACK,
395                            asp_sess_peer_dup_msg_data(p_msg), g_free));
396
397         return TRUE;
398 }
399
400 gboolean _asp_sess_peer_recv_nack(GSocketAddress *p_sock_addr, void *p_msg)
401 {
402         INFO_MSG;
403
404         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
405
406         if (NULL == p_peer)
407                 return FALSE;
408
409         gfsm_process_event(&(p_peer->context),
410                            gfsm_create_event(ASP_S_PEER_EVENT_RECV_NACK, asp_sess_peer_dup_msg_data(p_msg),
411                                              g_free));
412
413         return TRUE;
414 }
415
416 gboolean asp_sess_peer_add_session(GSocketAddress *p_sock_addr,
417                                    guint8 session_mac[], guint32 session_id)
418 {
419         INFO_MSG;
420
421         asp_sess_peer_s *p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
422
423         if (NULL == p_peer) {
424                 ASP_LOGD("create peer");
425                 p_peer = _asp_sess_peer_create_peer(p_sock_addr);
426                 g_assert(p_peer);
427
428                 gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_START,
429                                    NULL, NULL));
430         }
431         if (p_peer && p_peer->context)
432                 gfsm_process_event(&(p_peer->context),
433                                 gfsm_create_event(ASP_S_PEER_EVENT_ADD_SESSION,
434                                                 _asp_sess_peer_sess_tree_create_key(session_mac, session_id), g_free));
435
436         return TRUE;
437 }
438
439 gboolean asp_sess_peer_del_session(GSocketAddress *p_sock_addr,
440                                    guint8 session_mac[], guint32 session_id)
441 {
442         INFO_MSG;
443
444         asp_sess_peer_s *p_peer = NULL;
445
446         if (p_sock_addr == NULL)
447                 return TRUE;
448
449         p_peer = _asp_sess_peer_tree_find_peer(p_sock_addr);
450         if (NULL == p_peer)
451                 return TRUE;
452
453         /*asp_sess_peer_remove_session(p_peer,session_mac,sessiond_id); */
454         gfsm_process_event(&(p_peer->context),
455                            gfsm_create_event(ASP_S_PEER_EVENT_DEL_SESSION,
456                                              _asp_sess_peer_sess_tree_create_key(session_mac, session_id), g_free));
457
458         return TRUE;
459 }
460
461 asp_sess_peer_key_s *_asp_sess_peer_tree_create_peer_key(
462         GSocketAddress *p_sock_addr)
463 {
464         INFO_MSG;
465
466         GInetSocketAddress *p_inet_sock_addr = G_INET_SOCKET_ADDRESS(p_sock_addr);
467
468         g_assert(p_inet_sock_addr);
469
470         GInetAddress *p_inet_addr = g_inet_socket_address_get_address(p_inet_sock_addr);
471
472         g_assert(p_inet_addr);
473
474         asp_sess_peer_key_s *p_key = (asp_sess_peer_key_s *) g_malloc(sizeof(
475                                              asp_sess_peer_key_s));
476
477         g_assert(p_key);
478
479         p_key->ip_addr_len = g_inet_address_get_native_size(p_inet_addr);
480
481         memcpy(p_key->ip_addr, g_inet_address_to_bytes(p_inet_addr),
482                p_key->ip_addr_len);
483
484         p_key->port = g_inet_socket_address_get_port(p_inet_sock_addr);
485
486         /*g_object_unref(p_inet_addr); // */
487
488         return p_key;
489 }
490
491 asp_sess_peer_s *_asp_sess_peer_tree_find_peer(GSocketAddress *p_sock_addr)
492 {
493         INFO_MSG;
494
495         asp_sess_peer_key_s *p_key = _asp_sess_peer_tree_create_peer_key(p_sock_addr);
496
497         g_assert(p_key);
498
499         return (asp_sess_peer_s *) g_tree_lookup(gp_peer_tree, p_key);
500 }
501
502 gboolean _asp_sess_peer_tree_insert_peer(GSocketAddress *p_sock_addr,
503                 asp_sess_peer_s *p_peer)
504 {
505         INFO_MSG;
506
507         asp_sess_peer_key_s *p_key = _asp_sess_peer_tree_create_peer_key(p_sock_addr);
508
509         g_assert(p_key);
510
511         g_tree_insert(gp_peer_tree, p_key, p_peer);
512
513         return TRUE;
514 }
515
516 /* not used
517 gboolean _asp_sess_peer_tree_remove_peer(GSocketAddress* p_sock_addr)
518 {
519     asp_sess_peer_key_s* p_key = _asp_sess_peer_tree_create_peer_key(p_sock_addr);
520
521     g_assert(p_key);
522
523     g_tree_remove(gp_peer_tree, p_key);
524
525     return TRUE;
526 }
527 */
528
529 gint _asp_sess_peer_tree_compare_cb(gconstpointer a, gconstpointer b,
530                                     gpointer p_user_data)
531 {
532         asp_sess_peer_key_s *p_l = (asp_sess_peer_key_s *) a;
533         asp_sess_peer_key_s *p_r = (asp_sess_peer_key_s *) b;
534
535         g_assert(p_l->ip_addr_len == 4 || p_l->ip_addr_len == 16);
536
537         if (p_l->port < p_r->port)
538                 return -1;
539         else if (p_l->port > p_r->port)
540                 return 1;
541         else if (p_l->ip_addr_len < p_r->ip_addr_len)
542                 return -1;
543         else if (p_l->ip_addr_len > p_r->ip_addr_len)
544                 return 1;
545         else
546                 return memcmp(p_l->ip_addr, p_r->ip_addr, p_l->ip_addr_len);
547 }
548
549 void _asp_sess_peer_tree_key_destructor_cb(gpointer a)
550 {
551         g_free(a);
552 }
553
554 void _asp_sess_peer_tree_value_destructor_cb(gpointer a)
555 {
556         g_free(a);
557 }
558
559 asp_sess_peer_s *_asp_sess_peer_create_peer(GSocketAddress *p_sock_addr)
560 {
561         INFO_MSG;
562
563         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) g_malloc(sizeof(asp_sess_peer_s));
564
565         g_assert(p_peer);
566
567         p_peer->p_sock_addr = (GSocketAddress *) g_object_ref(p_sock_addr);
568         p_peer->seq_num = 0;
569         p_peer->retry = 0;
570         p_peer->timer_id = 0;
571         p_peer->p_sending_msg_data = 0;
572         p_peer->p_sess_tree = g_tree_new_full(_asp_sess_peer_sess_tree_compare_cb,
573                                               NULL,     /* ??? */
574                                               _asp_sess_peer_sess_tree_key_destructor_cb,
575                                               _asp_sess_peer_sess_tree_value_destructor_cb);
576
577         ASP_LOGD("insert peer");
578         _asp_sess_peer_tree_insert_peer(p_sock_addr, p_peer);
579
580         p_peer->context = gfsm_create_context(asm_sess_peer_fsm,
581                                               _asp_sess_peer_destroy_peer, p_peer);
582
583         return p_peer;
584 }
585
586 void _asp_sess_peer_destroy_peer(void *p_context_data)
587 {
588         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
589
590         INFO_MSG;
591         if (p_peer->p_sock_addr) {
592                 g_object_unref(p_peer->p_sock_addr);
593                 p_peer->p_sock_addr = 0;
594         }
595
596         if (p_peer->p_sending_msg_data) {
597                 g_free(p_peer->p_sending_msg_data);
598                 p_peer->p_sending_msg_data = 0;
599         }
600
601         if (p_peer->p_sess_tree) {
602                 g_tree_destroy(p_peer->p_sess_tree);
603                 p_peer->p_sess_tree = 0;
604         }
605
606         g_free(p_peer);
607 }
608
609 void _asp_sess_peer_set_sending_msg_data(asp_sess_peer_s *p_peer, void *p_msg)
610 {
611         INFO_MSG;
612
613         asp_coord_header_s *p_header = (asp_coord_header_s *)p_msg;
614
615         if (p_peer->p_sending_msg_data)
616                 g_free(p_peer->p_sending_msg_data);
617
618         p_peer->retry = 0;
619
620         p_header->seq_num = p_peer->seq_num;
621
622         p_peer->p_sending_msg_data = p_msg;
623 }
624
625 void _asp_sess_peer_clear_sending_msg_data(asp_sess_peer_s *p_peer)
626 {
627         INFO_MSG;
628
629         if (p_peer->p_sending_msg_data) {
630                 g_free(p_peer->p_sending_msg_data);
631                 p_peer->p_sending_msg_data = 0;
632         }
633 }
634
635 void _asp_sess_peer_forward_req_to_sessmgmt(asp_sess_peer_s *p_peer,
636                 void *p_msg_data)
637 {
638         asp_session_recv_req(p_peer->p_sock_addr, p_msg_data);
639 }
640
641 void _asp_sess_peer_forward_ack_to_sessmgmt(asp_sess_peer_s *p_peer,
642                 void *p_msg_data)
643 {
644         asp_request_header_s *p_header = (asp_request_header_s *)
645                                          p_peer->p_sending_msg_data;
646         asp_session_recv_ack(p_peer->p_sock_addr, p_header->session_mac,
647                              p_header->session_id, p_msg_data);
648 }
649
650 void _asp_sess_peer_forward_nack_to_sessmgmt(asp_sess_peer_s *p_peer,
651                 void *p_msg_data)
652 {
653         asp_request_header_s *p_header = (asp_request_header_s *)
654                                          p_peer->p_sending_msg_data;
655         asp_session_recv_nack(p_peer->p_sock_addr, p_header->session_mac,
656                               p_header->session_id, p_msg_data);
657 }
658
659 gboolean _asp_sess_peer_notify_timeout_cb(gpointer p_user_data)
660 {
661         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_user_data;
662
663         p_peer->timer_id = 0;
664
665         gfsm_process_event(&(p_peer->context), gfsm_create_event(ASP_S_PEER_EVENT_TIMEOUT,
666                            NULL, NULL));
667
668         return FALSE;
669 }
670
671 void _asp_sess_peer_start_timer(asp_sess_peer_s *p_peer, guint sec)
672 {
673         INFO_MSG;
674
675         if (p_peer->timer_id != 0)
676                 _asp_sess_peer_stop_timer(p_peer);
677
678         p_peer->timer_id = g_timeout_add_seconds(sec, _asp_sess_peer_notify_timeout_cb,
679                            p_peer);
680 }
681
682 void _asp_sess_peer_stop_timer(asp_sess_peer_s *p_peer)
683 {
684         INFO_MSG;
685
686         if (p_peer->timer_id != 0) {
687                 g_source_remove(p_peer->timer_id);
688                 p_peer->timer_id = 0;
689         }
690 }
691
692 void _asp_sess_peer_increase_seq_num(asp_sess_peer_s *p_peer)
693 {
694         ++p_peer->retry;
695 }
696
697 asp_sess_peer_sess_key_s *_asp_sess_peer_sess_tree_create_key(
698         guint8 session_mac[], guint32 session_id)
699 {
700         INFO_MSG;
701         asp_sess_peer_sess_key_s *p_key = (asp_sess_peer_sess_key_s *) g_malloc(sizeof(
702                         asp_sess_peer_sess_key_s));
703
704         g_assert(p_key);
705
706         p_key->sess_id = session_id;
707         memcpy(p_key->sess_mac, session_mac, 6);
708
709         return p_key;
710 }
711
712 void _asp_sess_peer_insert_session(asp_sess_peer_s *p_peer,
713                                    asp_sess_peer_sess_key_s *p_key)
714 {
715         asp_sess_peer_sess_key_s *p_value = (asp_sess_peer_sess_key_s *) g_tree_lookup(
716                         p_peer->p_sess_tree, p_key);
717
718         if (p_value)
719                 return;
720
721         g_tree_insert(p_peer->p_sess_tree, p_key, p_key);
722 }
723
724 void _asp_sess_peer_remove_session(asp_sess_peer_s *p_peer,
725                                    asp_sess_peer_sess_key_s *p_key)
726 {
727         g_tree_remove(p_peer->p_sess_tree, p_key);
728 }
729
730 gint _asp_sess_peer_sess_tree_compare_cb(gconstpointer a, gconstpointer b,
731                 gpointer user_data)
732 {
733         INFO_MSG;
734         asp_sess_peer_sess_key_s *p_l = (asp_sess_peer_sess_key_s *) a;
735         asp_sess_peer_sess_key_s *p_r = (asp_sess_peer_sess_key_s *) b;
736
737         if (p_l->sess_id < p_r->sess_id)
738                 return -1;
739         else if (p_l->sess_id > p_r->sess_id)
740                 return 1;
741         else                                            /*equal */
742                 return memcmp(p_l->sess_mac, p_r->sess_mac, 6);
743 }
744
745 void _asp_sess_peer_sess_tree_key_destructor_cb(gpointer p_data)
746 {
747         INFO_MSG;
748         asp_sess_peer_sess_key_s *p_key = (asp_sess_peer_sess_key_s *) p_data;
749         asp_session_peer_destroyed(p_key->sess_mac, p_key->sess_id);
750         g_free(p_key);
751 }
752
753 void _asp_sess_peer_sess_tree_value_destructor_cb(gpointer p_value)
754 {
755         INFO_MSG;
756         /*do nothing. */
757         /*p_key and p_value is same pointer. */
758 }
759
760 void *_asp_sess_peer_dup_request_session(void *p_msg)
761 {
762         asp_request_session_s *p_dup_msg = (asp_request_session_s *)g_malloc(sizeof(
763                         asp_request_session_s));
764         memcpy(p_dup_msg, p_msg, sizeof(asp_request_session_s));
765
766         return p_dup_msg;
767 }
768
769 void *_asp_sess_peer_dup_msg_added_session(void *p_msg)
770 {
771         asp_added_session_s *p_dup_msg = (asp_added_session_s *)g_malloc(sizeof(
772                         asp_added_session_s));
773         memcpy(p_dup_msg, p_msg, sizeof(asp_added_session_s));
774
775         return p_dup_msg;
776 }
777
778 void *_asp_sess_peer_dup_msg_rejected_session(void *p_msg)
779 {
780         asp_rejected_session_s *p_dup_msg = (asp_rejected_session_s *)g_malloc(sizeof(
781                         asp_rejected_session_s));
782         memcpy(p_dup_msg, p_msg, sizeof(asp_rejected_session_s));
783
784         return p_dup_msg;
785 }
786
787 void *_asp_sess_peer_dup_msg_remove_session(void *p_msg)
788 {
789         asp_remove_session_s *p_dup_msg = (asp_remove_session_s *)g_malloc(sizeof(
790                         asp_remove_session_s));
791         memcpy(p_dup_msg, p_msg, sizeof(asp_remove_session_s));
792
793         return p_dup_msg;
794 }
795
796 void *_asp_sess_peer_dup_msg_allowed_port(void *p_msg)
797 {
798         asp_allowed_port_s *p_dup_msg = (asp_allowed_port_s *)g_malloc(sizeof(
799                                                 asp_allowed_port_s));
800         memcpy(p_dup_msg, p_msg, sizeof(asp_allowed_port_s));
801
802         return p_dup_msg;
803 }
804
805 void *_asp_sess_peer_dup_msg_version(void *p_msg)
806 {
807         asp_version_s *p_dup_msg = (asp_version_s *)g_malloc(sizeof(asp_version_s));
808         memcpy(p_dup_msg, p_msg, sizeof(asp_version_s));
809
810         return p_dup_msg;
811 }
812
813 void *_asp_sess_peer_dup_msg_deferred_session(void *p_msg)
814 {
815         asp_deferred_session_s *p_dup_msg = (asp_deferred_session_s *)g_malloc(sizeof(
816                         asp_deferred_session_s));
817         memcpy(p_dup_msg, p_msg, sizeof(asp_deferred_session_s));
818
819         printf("_asp_sess_peer_dup_msg_deferred_session, session_id:%d\n",
820                p_dup_msg->session_id);
821         return p_dup_msg;
822 }
823
824 void *_asp_sess_peer_dup_msg_ack(void *p_msg)
825 {
826         asp_ack_s *p_dup_msg = (asp_ack_s *)g_malloc(sizeof(asp_ack_s));
827         memcpy(p_dup_msg, p_msg, sizeof(asp_ack_s));
828         return p_dup_msg;
829 }
830
831 void *_asp_sess_peer_dup_msg_nack(void *p_msg)
832 {
833         asp_nack_s *p_dup_msg = (asp_nack_s *)g_malloc(sizeof(asp_nack_s));
834         memcpy(p_dup_msg, p_msg, sizeof(asp_nack_s));
835         return p_dup_msg;
836 }
837
838 void *asp_sess_peer_dup_msg_data(void *p_msg)
839 {
840         asp_coord_header_s *p_header = (asp_coord_header_s *)p_msg;
841         void *ret = NULL;
842
843         switch (p_header->opcode) {
844         case ASP_OPCODE_REQUEST_SESSION:
845                 ret = _asp_sess_peer_dup_request_session(p_msg);
846                 break;
847         case ASP_OPCODE_ADDED_SESSION:
848                 ret = _asp_sess_peer_dup_msg_added_session(p_msg);
849                 break;
850         case ASP_OPCODE_REJECTED_SESSION:
851                 ret = _asp_sess_peer_dup_msg_rejected_session(p_msg);
852                 break;
853         case ASP_OPCODE_REMOVE_SESSION:
854                 ret = _asp_sess_peer_dup_msg_remove_session(p_msg);
855                 break;
856         case ASP_OPCODE_ALLOWED_PORT:
857                 ret = _asp_sess_peer_dup_msg_allowed_port(p_msg);
858                 break;
859         case ASP_OPCODE_VERSION:
860                 ret = _asp_sess_peer_dup_msg_version(p_msg);
861                 break;
862         case ASP_OPCODE_DEFERRED_SESSION:
863                 ret = _asp_sess_peer_dup_msg_deferred_session(p_msg);
864                 break;
865         case ASP_OPCODE_ACK:
866                 ret = _asp_sess_peer_dup_msg_ack(p_msg);
867                 break;
868         case ASP_OPCODE_NACK:
869                 ret = _asp_sess_peer_dup_msg_nack(p_msg);
870                 break;
871         }
872
873         return (void *)ret;
874 }
875
876 void _asp_sess_peer_send_nack_to_protocol(GSocketAddress *p_sock_addr,
877                 guint8 seq_num, guint8 reason)
878 {
879         asp_nack_s nack_msg;
880
881         nack_msg.opcode = ASP_OPCODE_NACK;
882         nack_msg.seq_num = seq_num;;
883         nack_msg.reason = reason;
884
885         asp_coordination_protocol_send_msg(p_sock_addr, &nack_msg);
886 }
887
888 const char *_asp_sess_peer_fsm_get_state_name_cb(gfsm_state_id_t state_id)
889 {
890         const char *ret_val = NULL;
891
892         switch (state_id) {
893         case ASP_S_PEER_STATE_INIT:
894                 ret_val = "ASP_S_PEER_STATE_INIT";
895                 break;
896         case ASP_S_PEER_STATE_CREATED:
897                 ret_val = "ASP_S_PEER_STATE_CREATED";
898                 break;
899         case ASP_S_PEER_STATE_VERSION_SENT:
900                 ret_val = "ASP_S_PEER_STATE_VERSION_SENT";
901                 break;
902         case ASP_S_PEER_STATE_WAIT_VERSION:
903                 ret_val = "ASP_S_PEER_STATE_WAIT_VERSION";
904                 break;
905         case ASP_S_PEER_STATE_WAIT_ACK:
906                 ret_val = "ASP_S_PEER_STATE_WAIT_ACK";
907                 break;
908         case ASP_S_PEER_STATE_OPENED:
909                 ret_val = "ASP_S_PEER_STATE_OPENED";
910                 break;
911         case ASP_S_PEER_STATE_IDLE:
912                 ret_val = "ASP_S_PEER_STATE_IDLE";
913                 break;
914         /*
915         case ASP_S_PEER_STATE_REQ_SENT:
916                 ret_val = "ASP_S_PEER_STATE_REQ_SENT";
917                 break;
918         */
919         case ASP_S_PEER_STATE_CLOSED:
920                 ret_val = "ASP_S_PEER_STATE_CLOSED";
921                 break;
922         default:
923                 ret_val = "ASP_S_PEER_STATE_MAX";
924                 break;
925         }
926
927         return ret_val;
928 }
929
930 const char *_asp_sess_peer_gfsm_get_event_name_cb(gfsm_event_id_t event_id)
931 {
932         const char *ret_val = NULL;
933
934         switch (event_id) {
935         case ASP_S_PEER_EVENT_START:
936                 ret_val = "ASP_S_PEER_EVENT_START";
937                 break;
938         case ASP_S_PEER_EVENT_ADD_SESSION:
939                 ret_val = "ASP_S_PEER_EVENT_ADD_SESSION";
940                 break;
941         case ASP_S_PEER_EVENT_DEL_SESSION:
942                 ret_val = "ASP_S_PEER_EVENT_DEL_SESSION";
943                 break;
944         case ASP_S_PEER_EVENT_SEND_REQ:
945                 ret_val = "ASP_S_PEER_EVENT_SEND_REQ";
946                 break;
947         case ASP_S_PEER_EVENT_SEND_ACK:
948                 ret_val = "ASP_S_PEER_EVENT_SEND_ACK";
949                 break;
950         case ASP_S_PEER_EVENT_SEND_NACK:
951                 ret_val = "ASP_S_PEER_EVENT_SEND_NACK";
952                 break;
953         case ASP_S_PEER_EVENT_RECV_VERSION:
954                 ret_val = "ASP_S_PEER_EVENT_RECV_VERSION";
955                 break;
956         case ASP_S_PEER_EVENT_RECV_REQ:
957                 ret_val = "ASP_S_PEER_EVENT_RECV_REQ";
958                 break;
959         case ASP_S_PEER_EVENT_RECV_ACK:
960                 ret_val = "ASP_S_PEER_EVENT_RECV_ACK";
961                 break;
962         case ASP_S_PEER_EVENT_RECV_NACK:
963                 ret_val = "ASP_S_PEER_EVENT_RECV_NACK";
964                 break;
965         case ASP_S_PEER_EVENT_TIMEOUT:
966                 ret_val = "ASP_S_PEER_EVENT_TIMEOUT";
967                 break;
968         case ASP_S_PEER_EVENT_CLOSE:
969                 ret_val = "ASP_S_PEER_EVENT_CLOSE";
970                 break;
971         default:
972                 ret_val = "ASP_S_PEER_EVENT_MAX";
973                 break;
974         }
975
976         return ret_val;
977 }
978
979 int _asp_sess_peer_fsm_log_func(const char *format, ...)
980 {
981         gchar buffer[256];
982         va_list args;
983         va_start(args, format);
984         g_vsnprintf(buffer, 255, format, args);
985         va_end(args);
986
987         ASP_LOGD("%s", buffer);
988
989         return 0;
990 }
991
992 void asp_sess_peer_fsm_init()
993 {
994         INFO_MSG;
995
996         asm_sess_peer_fsm = gfsm_create_fsm(ASP_S_PEER_STATE_MAX, ASP_S_PEER_EVENT_MAX,
997                                             ASP_S_PEER_STATE_INIT);
998
999         asp_sess_peer_state_init = gfsm_create_state(ASP_S_PEER_STATE_INIT,
1000                                    asm_sess_peer_fsm, _asp_sess_peer_state_init_entry_action,
1001                                    _asp_sess_peer_state_init_exit_action);
1002         gfsm_add_reaction(asp_sess_peer_state_init, ASP_S_PEER_EVENT_START,
1003                           _asp_sess_peer_state_init_reaction_start);
1004
1005         asp_sess_peer_state_created = gfsm_create_state(ASP_S_PEER_STATE_CREATED,
1006                                       asm_sess_peer_fsm, _asp_sess_peer_state_created_entry_action,
1007                                       _asp_sess_peer_state_created_exit_action);
1008         gfsm_add_reaction(asp_sess_peer_state_created, ASP_S_PEER_EVENT_ADD_SESSION,
1009                           _asp_sess_peer_state_created_reaction_add_session);
1010         gfsm_add_reaction(asp_sess_peer_state_created, ASP_S_PEER_EVENT_DEL_SESSION,
1011                           _asp_sess_peer_state_created_reaction_del_session);
1012         gfsm_add_reaction(asp_sess_peer_state_created, ASP_S_PEER_EVENT_CLOSE,
1013                           _asp_sess_peer_state_created_reaction_close);
1014         gfsm_add_reaction(asp_sess_peer_state_created, ASP_S_PEER_EVENT_SEND_ACK,
1015                           _asp_sess_peer_state_created_reaction_send_ack);
1016         gfsm_add_reaction(asp_sess_peer_state_created, ASP_S_PEER_EVENT_SEND_NACK,
1017                           _asp_sess_peer_state_created_reaction_send_nack);
1018
1019         asp_sess_peer_state_version_sent = gfsm_create_state(
1020                         ASP_S_PEER_STATE_VERSION_SENT, asm_sess_peer_fsm,
1021                         _asp_sess_peer_state_version_sent_entry_action,
1022                         _asp_sess_peer_state_version_sent_exit_action);
1023         gfsm_set_parent_state(asp_sess_peer_state_version_sent,
1024                               asp_sess_peer_state_created);
1025         gfsm_add_reaction(asp_sess_peer_state_version_sent,
1026                           ASP_S_PEER_EVENT_ADD_SESSION, gfsm_deferral_reaction);
1027         gfsm_add_reaction(asp_sess_peer_state_version_sent,
1028                           ASP_S_PEER_EVENT_DEL_SESSION, gfsm_deferral_reaction);
1029         gfsm_add_reaction(asp_sess_peer_state_version_sent, ASP_S_PEER_EVENT_SEND_REQ,
1030                           gfsm_deferral_reaction);
1031         gfsm_add_reaction(asp_sess_peer_state_version_sent,
1032                           ASP_S_PEER_EVENT_RECV_VERSION, gfsm_deferral_reaction);
1033         gfsm_add_reaction(asp_sess_peer_state_version_sent, ASP_S_PEER_EVENT_RECV_REQ,
1034                           gfsm_deferral_reaction);
1035         gfsm_add_reaction(asp_sess_peer_state_version_sent, ASP_S_PEER_EVENT_RECV_ACK,
1036                           _asp_sess_peer_state_version_sent_reaction_recv_ack);
1037         gfsm_add_reaction(asp_sess_peer_state_version_sent, ASP_S_PEER_EVENT_RECV_NACK,
1038                           _asp_sess_peer_state_version_sent_reaction_recv_nack);
1039         gfsm_add_reaction(asp_sess_peer_state_version_sent, ASP_S_PEER_EVENT_TIMEOUT,
1040                           _asp_sess_peer_state_version_sent_reaction_timeout);
1041
1042         asp_sess_peer_state_wait_version = gfsm_create_state(
1043                         ASP_S_PEER_STATE_WAIT_VERSION, asm_sess_peer_fsm,
1044                         _asp_sess_peer_state_wait_version_entry_action,
1045                         _asp_sess_peer_state_wait_version_exit_action);
1046         gfsm_set_parent_state(asp_sess_peer_state_wait_version,
1047                               asp_sess_peer_state_created);
1048         gfsm_add_reaction(asp_sess_peer_state_wait_version,
1049                           ASP_S_PEER_EVENT_ADD_SESSION, gfsm_deferral_reaction);
1050         gfsm_add_reaction(asp_sess_peer_state_wait_version,
1051                           ASP_S_PEER_EVENT_DEL_SESSION, gfsm_deferral_reaction);
1052         gfsm_add_reaction(asp_sess_peer_state_wait_version, ASP_S_PEER_EVENT_SEND_REQ,
1053                           gfsm_deferral_reaction);
1054         gfsm_add_reaction(asp_sess_peer_state_wait_version,
1055                           ASP_S_PEER_EVENT_RECV_VERSION,
1056                           _asp_sess_peer_state_wait_version_reaction_recv_version);
1057         gfsm_add_reaction(asp_sess_peer_state_wait_version, ASP_S_PEER_EVENT_RECV_REQ,
1058                           _asp_sess_peer_state_wait_version_reaction_recv_req);
1059         gfsm_add_reaction(asp_sess_peer_state_wait_version, ASP_S_PEER_EVENT_TIMEOUT,
1060                           _asp_sess_peer_state_wait_version_reaction_timeout);
1061
1062         asp_sess_peer_state_opened = gfsm_create_state(ASP_S_PEER_STATE_OPENED,
1063                                      asm_sess_peer_fsm, _asp_sess_peer_state_opened_entry_action,
1064                                      _asp_sess_peer_state_opened_exit_action);
1065         gfsm_set_parent_state(asp_sess_peer_state_opened, asp_sess_peer_state_created);
1066         gfsm_add_reaction(asp_sess_peer_state_opened, ASP_S_PEER_EVENT_RECV_VERSION,
1067                           _asp_sess_peer_state_opened_reaction_recv_version);
1068         gfsm_add_reaction(asp_sess_peer_state_opened, ASP_S_PEER_EVENT_RECV_REQ,
1069                           _asp_sess_peer_state_opened_reaction_recv_req);
1070
1071         asp_sess_peer_state_idle = gfsm_create_state(ASP_S_PEER_STATE_IDLE,
1072                                    asm_sess_peer_fsm, _asp_sess_peer_state_idle_entry_action,
1073                                    _asp_sess_peer_state_idle_exit_action);
1074         gfsm_set_parent_state(asp_sess_peer_state_idle, asp_sess_peer_state_opened);
1075         gfsm_add_reaction(asp_sess_peer_state_idle, ASP_S_PEER_EVENT_SEND_REQ,
1076                           _asp_sess_peer_state_idle_reaction_send_req);
1077
1078         asp_sess_peer_state_wait_ack = gfsm_create_state(ASP_S_PEER_STATE_WAIT_ACK,
1079                                        asm_sess_peer_fsm, _asp_sess_peer_state_wait_ack_entry_action,
1080                                        _asp_sess_peer_state_wait_ack_exit_action);
1081         gfsm_set_parent_state(asp_sess_peer_state_wait_ack, asp_sess_peer_state_opened);
1082         gfsm_add_reaction(asp_sess_peer_state_wait_ack, ASP_S_PEER_EVENT_SEND_REQ,
1083                           gfsm_deferral_reaction);
1084         gfsm_add_reaction(asp_sess_peer_state_wait_ack, ASP_S_PEER_EVENT_RECV_ACK,
1085                           _asp_sess_peer_state_wait_ack_reaction_recv_ack);
1086         gfsm_add_reaction(asp_sess_peer_state_wait_ack, ASP_S_PEER_EVENT_RECV_NACK,
1087                           _asp_sess_peer_state_wait_ack_reaction_recv_nack);
1088         gfsm_add_reaction(asp_sess_peer_state_wait_ack, ASP_S_PEER_EVENT_TIMEOUT,
1089                           _asp_sess_peer_state_wait_ack_reaction_timeout);
1090
1091         asp_sess_peer_state_closed = gfsm_create_state(ASP_S_PEER_STATE_CLOSED,
1092                                      asm_sess_peer_fsm, _asp_sess_peer_state_close_entry_action,
1093                                      _asp_sess_peer_state_close_exit_action);
1094         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_init);
1095         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_created);
1096         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_version_sent);
1097         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_wait_version);
1098         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_opened);
1099         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_idle);
1100         /*gfsm_add_state(&asm_sess_peer_fsm,&asp_sess_peer_state_req_sent); */
1101         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_wait_ack);
1102         gfsm_add_state(asm_sess_peer_fsm, asp_sess_peer_state_closed);
1103
1104         gfsm_set_logger(asm_sess_peer_fsm, _asp_sess_peer_fsm_log_func,
1105                         ASP_SESS_PEER_HEADER,
1106                         _asp_sess_peer_fsm_get_state_name_cb,
1107                         _asp_sess_peer_gfsm_get_event_name_cb);
1108 }
1109
1110 void _asp_sess_peer_state_init_entry_action(void *p_context_data)
1111 {
1112         INFO_MSG;
1113
1114         ASP_SESS_PEER_FSM_TRACE_ENTER();
1115
1116         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1117
1118         /*p_peer->seq_num = 0; */
1119         /*p_peer->p_sending_msg_data = NULL; */
1120
1121         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1122 }
1123
1124 void _asp_sess_peer_state_init_exit_action(void *p_context_data)
1125 {
1126         INFO_MSG;
1127
1128         ASP_SESS_PEER_FSM_TRACE_ENTER();
1129
1130         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1131
1132         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1133 }
1134
1135 gfsm_state_id_t _asp_sess_peer_state_init_reaction_start(void *p_context_data,
1136                 void *p_event_data)
1137 {
1138         INFO_MSG;
1139
1140         ASP_SESS_PEER_FSM_TRACE_ENTER();
1141
1142         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1143
1144         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1145
1146         return ASP_S_PEER_STATE_VERSION_SENT;
1147 }
1148
1149 void _asp_sess_peer_state_created_entry_action(void *p_context_data)
1150 {
1151         INFO_MSG;
1152
1153         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1154 }
1155
1156 void _asp_sess_peer_state_created_exit_action(void *p_context_data)
1157 {
1158         INFO_MSG;
1159
1160         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1161 }
1162
1163 gfsm_state_id_t _asp_sess_peer_state_created_reaction_add_session(
1164         void *p_context_data, void *p_event_data)
1165 {
1166         INFO_MSG;
1167
1168         ASP_SESS_PEER_FSM_TRACE_ENTER();
1169
1170         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1171         asp_sess_peer_sess_key_s *p_key = (asp_sess_peer_sess_key_s *) p_event_data;
1172
1173         _asp_sess_peer_insert_session(p_peer, p_key);
1174
1175         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1176
1177         return GFSM_DISCARD_EVENT;
1178 }
1179
1180 gfsm_state_id_t _asp_sess_peer_state_created_reaction_del_session(
1181         void *p_context_data, void *p_event_data)
1182 {
1183         INFO_MSG;
1184
1185         ASP_SESS_PEER_FSM_TRACE_ENTER();
1186
1187         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1188         asp_sess_peer_sess_key_s *p_key = (asp_sess_peer_sess_key_s *) p_event_data;
1189
1190         _asp_sess_peer_remove_session(p_peer, p_key);
1191
1192         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1193
1194         return GFSM_DISCARD_EVENT;
1195 }
1196
1197 gfsm_state_id_t _asp_sess_peer_state_created_reaction_close(
1198         void *p_context_data, void *p_event_data)
1199 {
1200         INFO_MSG;
1201
1202         ASP_SESS_PEER_FSM_TRACE_ENTER();
1203
1204         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1205
1206         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1207
1208         return ASP_S_PEER_STATE_CLOSED;
1209 }
1210
1211 gfsm_state_id_t _asp_sess_peer_state_created_reaction_send_ack(
1212         void *p_context_data, void *p_event_data)
1213 {
1214         INFO_MSG;
1215
1216         ASP_SESS_PEER_FSM_TRACE_ENTER();
1217
1218         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1219
1220         asp_coordination_protocol_send_msg(p_peer->p_sock_addr, p_event_data);
1221
1222         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1223
1224         return GFSM_DISCARD_EVENT;
1225 }
1226
1227 gfsm_state_id_t _asp_sess_peer_state_created_reaction_send_nack(
1228         void *p_context_data, void *p_event_data)
1229 {
1230         INFO_MSG;
1231
1232         ASP_SESS_PEER_FSM_TRACE_ENTER();
1233
1234         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1235
1236         asp_coordination_protocol_send_msg(p_peer->p_sock_addr, p_event_data);
1237
1238         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1239
1240         return GFSM_DISCARD_EVENT;
1241 }
1242
1243 void _asp_sess_peer_state_version_sent_entry_action(void *p_context_data)
1244 {
1245         INFO_MSG;
1246
1247         ASP_SESS_PEER_FSM_TRACE_ENTER();
1248
1249         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1250         asp_version_s *p_msg_version = (asp_version_s *)g_malloc(sizeof(
1251                                                asp_version_s));
1252
1253         p_msg_version->opcode = ASP_OPCODE_VERSION;
1254         p_msg_version->seq_num = p_peer->seq_num;
1255         p_msg_version->coordination_version = 0;
1256         p_msg_version->vendor_information_length = 0;
1257         p_msg_version->vendor_information = 0;
1258
1259         _asp_sess_peer_set_sending_msg_data(p_peer, p_msg_version);
1260
1261         asp_coordination_protocol_send_msg(p_peer->p_sock_addr, p_msg_version);
1262
1263         _asp_sess_peer_start_timer(p_peer, 1);
1264
1265         ASP_SESS_PEER_FSM_TRACE_LEAVE();
1266 }
1267
1268 void _asp_sess_peer_state_version_sent_exit_action(void *p_context_data)
1269 {
1270         INFO_MSG;
1271
1272         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1273
1274         _asp_sess_peer_clear_sending_msg_data(p_peer);
1275         _asp_sess_peer_stop_timer(p_peer);
1276 }
1277
1278 gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_recv_ack(
1279         void *p_context_data, void *p_event_data)
1280 {
1281         INFO_MSG;
1282
1283         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1284         asp_ack_s *p_ack = (asp_ack_s *)p_event_data;
1285
1286         if (p_peer->seq_num != p_ack->seq_num)
1287                 return GFSM_DISCARD_EVENT;
1288
1289         _asp_sess_peer_increase_seq_num(p_peer);
1290
1291         return ASP_S_PEER_STATE_WAIT_VERSION;
1292 }
1293
1294 gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_recv_nack(
1295         void *p_context_data, void *p_event_data)
1296 {
1297         INFO_MSG;
1298
1299         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1300         asp_nack_s *p_nack = (asp_nack_s *)p_event_data;
1301
1302         if (p_peer->seq_num != p_nack->seq_num)
1303                 return GFSM_DISCARD_EVENT;
1304
1305         return ASP_S_PEER_STATE_CLOSED;
1306 }
1307
1308 gfsm_state_id_t _asp_sess_peer_state_version_sent_reaction_timeout(
1309         void *p_context_data, void *p_event_data)
1310 {
1311         INFO_MSG;
1312
1313         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1314
1315         return ASP_S_PEER_STATE_VERSION_SENT;
1316 }
1317
1318 void _asp_sess_peer_state_wait_version_entry_action(void *p_context_data)
1319 {
1320         INFO_MSG;
1321
1322         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1323
1324         _asp_sess_peer_start_timer(p_peer, 10);
1325 }
1326
1327 void _asp_sess_peer_state_wait_version_exit_action(void *p_context_data)
1328 {
1329         INFO_MSG;
1330
1331         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1332
1333         _asp_sess_peer_stop_timer(p_peer);
1334 }
1335
1336 gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_recv_version(
1337         void *p_context_data, void *p_event_data)
1338 {
1339         INFO_MSG;
1340
1341         /*    asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1342         /*    asp_coord_header_s* p_header = (asp_coord_header_s*)p_event_data; */
1343
1344         return ASP_S_PEER_STATE_IDLE;
1345 }
1346
1347 gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_recv_req(
1348         void *p_context_data, void *p_event_data)
1349 {
1350         INFO_MSG;
1351
1352         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1353         asp_coord_header_s *p_header = (asp_coord_header_s *)p_event_data;
1354
1355         _asp_sess_peer_send_nack_to_protocol(p_peer->p_sock_addr, p_header->seq_num,
1356                                              ASP_NACK_REASON_NO_SESSION_EXIST);
1357
1358         return GFSM_DISCARD_EVENT;
1359 }
1360
1361 gfsm_state_id_t _asp_sess_peer_state_wait_version_reaction_timeout(
1362         void *p_context_data, void *p_event_data)
1363 {
1364         INFO_MSG;
1365
1366         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1367         return ASP_S_PEER_STATE_CLOSED;
1368 }
1369
1370 void _asp_sess_peer_state_opened_entry_action(void *p_context_data)
1371 {
1372         INFO_MSG;
1373
1374         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1375 }
1376
1377 void _asp_sess_peer_state_opened_exit_action(void *p_context_data)
1378 {
1379         INFO_MSG;
1380
1381         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1382 }
1383
1384 gfsm_state_id_t _asp_sess_peer_state_opened_reaction_recv_version(
1385         void *p_context_data, void *p_event_data)
1386 {
1387         INFO_MSG;
1388
1389         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1390         /*_asp_sess_peer_forward_req_to_sessmgmt(p_peer,p_event_data); */
1391
1392         return GFSM_DISCARD_EVENT;
1393 }
1394
1395 gfsm_state_id_t _asp_sess_peer_state_opened_reaction_recv_req(
1396         void *p_context_data, void *p_event_data)
1397 {
1398         INFO_MSG;
1399
1400         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1401         _asp_sess_peer_forward_req_to_sessmgmt(p_peer, p_event_data);
1402
1403         return GFSM_DISCARD_EVENT;
1404 }
1405
1406 void _asp_sess_peer_state_idle_entry_action(void *p_context_data)
1407 {
1408         INFO_MSG;
1409
1410         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1411 }
1412
1413 void _asp_sess_peer_state_idle_exit_action(void *p_context_data)
1414 {
1415         INFO_MSG;
1416
1417         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1418 }
1419
1420 gfsm_state_id_t _asp_sess_peer_state_idle_reaction_send_req(
1421         void *p_context_data, void *p_event_data)
1422 {
1423         INFO_MSG;
1424
1425         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1426         void *p_msg_data = asp_sess_peer_dup_msg_data(p_event_data);
1427
1428         /*asp_sess_peer_add_sess_list(p_msg_data); */
1429         _asp_sess_peer_set_sending_msg_data(p_peer, p_msg_data);
1430
1431         asp_coordination_protocol_send_msg(p_peer->p_sock_addr, p_msg_data);
1432
1433         return ASP_S_PEER_STATE_WAIT_ACK;
1434 }
1435
1436 void _asp_sess_peer_state_wait_ack_entry_action(void *p_context_data)
1437 {
1438         INFO_MSG;
1439
1440         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1441
1442         _asp_sess_peer_start_timer(p_peer, 1);
1443 }
1444
1445 void _asp_sess_peer_state_wait_ack_exit_action(void *p_context_data)
1446 {
1447         INFO_MSG;
1448
1449         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1450
1451         _asp_sess_peer_stop_timer(p_peer);
1452 }
1453
1454 gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_recv_ack(
1455         void *p_context_data, void *p_event_data)
1456 {
1457         INFO_MSG;
1458
1459         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1460         asp_ack_s *p_ack = (asp_ack_s *)p_event_data;
1461
1462         if (p_ack->seq_num != p_peer->seq_num)
1463                 return GFSM_DISCARD_EVENT;
1464
1465         _asp_sess_peer_increase_seq_num(p_peer);
1466
1467         _asp_sess_peer_forward_ack_to_sessmgmt(p_peer, p_event_data);
1468
1469         _asp_sess_peer_clear_sending_msg_data(p_peer);
1470
1471         return ASP_S_PEER_STATE_IDLE;
1472 }
1473
1474 gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_recv_nack(
1475         void *p_context_data, void *p_event_data)
1476 {
1477         INFO_MSG;
1478
1479         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1480         asp_nack_s *p_nack = (asp_nack_s *)p_event_data;
1481
1482         if (p_nack->seq_num != p_peer->seq_num)
1483                 return GFSM_DISCARD_EVENT;
1484
1485         _asp_sess_peer_forward_nack_to_sessmgmt(p_peer, p_event_data);
1486
1487         _asp_sess_peer_clear_sending_msg_data(p_peer);
1488
1489         return ASP_S_PEER_STATE_IDLE;
1490 }
1491
1492 gfsm_state_id_t _asp_sess_peer_state_wait_ack_reaction_timeout(
1493         void *p_context_data, void *p_event_data)
1494 {
1495         INFO_MSG;
1496
1497         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1498
1499         if (p_peer->retry < 5) {
1500                 ++p_peer->retry;
1501                 asp_coordination_protocol_send_msg(p_peer->p_sock_addr,
1502                                                    p_peer->p_sending_msg_data);
1503                 return ASP_S_PEER_STATE_WAIT_ACK;
1504         } else {
1505                 p_peer->retry = 0;
1506                 _asp_sess_peer_clear_sending_msg_data(p_peer);
1507                 return ASP_S_PEER_STATE_CLOSED;
1508         }
1509 }
1510
1511 void _asp_sess_peer_state_close_entry_action(void *p_context_data)
1512 {
1513         INFO_MSG;
1514
1515         asp_sess_peer_s *p_peer = (asp_sess_peer_s *) p_context_data;
1516
1517         if (!p_peer) {
1518                 ASP_LOGD("p_peer is null");
1519                 return;
1520         }
1521         ASP_LOGD("context[%p]", p_peer->context);
1522         gfsm_destroy_context(p_peer->context);
1523 }
1524
1525 void _asp_sess_peer_state_close_exit_action(void *p_context_data)
1526 {
1527         INFO_MSG;
1528
1529         /*asp_sess_peer_s* p_peer = (asp_sess_peer_s*)p_context_data; */
1530 }