Witness: PIDL_dissect_ipv6address()
[metze/wireshark/wip.git] / echld / echld-util.c
1 /* echld-util.c
2  *  utility for echld
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org>
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #include "config.h"
28
29 #include "echld-int.h"
30 #include "echld-util.h"
31
32 #include <glib.h>
33
34 struct _ping {
35         struct timeval tv;
36         echld_ping_cb_t cb;
37         void* cb_data;
38 };
39
40 static long timevaldiff(struct timeval *starttime, struct timeval *finishtime) {
41   long msec;
42   msec=(finishtime->tv_sec-starttime->tv_sec)*1000;
43   msec+=(finishtime->tv_usec-starttime->tv_usec)/1000;
44   return msec;
45 }
46
47 static gboolean pong(echld_msg_type_t type, GByteArray* ba _U_, void* data) {
48         struct _ping* p = (struct _ping*)data;
49         struct timeval t;
50         long ret = -1;
51         gettimeofday(&t,NULL);
52
53         
54         switch (type) {
55                 case ECHLD_PONG:
56                         ret = timevaldiff(&(p->tv),&t);
57                         break;
58                 default:
59                         ret = -1;
60                         break;
61         }
62
63         if (p->cb) p->cb(ret, p->cb_data);
64
65         g_free(p);
66
67         return TRUE;
68 }
69
70
71 extern echld_state_t echld_ping(int chld_id, echld_ping_cb_t pcb, void* cb_data) {
72         struct _ping* p = g_new0(struct _ping,1);
73
74         p->cb = pcb;
75         p->cb_data = cb_data;
76         gettimeofday(&(p->tv),NULL);
77
78         return echld_reqh(chld_id, ECHLD_PING, 0, NULL, pong, p);
79 }
80
81
82 struct _get_param {
83         const char* name;
84         echld_param_cb_t cb;
85         void* cb_data;
86         echld_bool_t (*dec)(enc_msg_t*, char**, char**);
87         echld_bool_t (*dec_err)(enc_msg_t*, int* , char**);
88         const char** err_msg;
89 };
90
91 #define CHNULL ((char*)NULL)
92
93 static gboolean got_param(echld_msg_type_t type, GByteArray* ba _U_, void* data) {
94         struct _get_param* g = (struct _get_param*)data;
95         char* err_msg;
96
97         switch (type) {
98                 case ECHLD_PARAM: 
99                         if (g->cb) {
100                                 char* param;
101                                 char* value;
102                                 g->dec(ba,&param,&value);
103                                 g->cb(param,value,NULL,g->cb_data);
104
105                         }
106                         break;
107                 case ECHLD_ERROR: {
108                         int errnum;
109                         g->dec_err(ba,&errnum,&err_msg);
110                         g->cb(NULL,NULL,err_msg,g->cb_data);
111                         break;
112                 }
113                 default:
114                         err_msg = g_strdup_printf("other type='%s'",TY(type));
115                         g->cb(NULL,NULL,err_msg,g->cb_data);
116                         g_free(err_msg);
117                         break;
118         }
119
120         g_free(g);
121         return TRUE;
122 }
123
124 extern echld_state_t echld_get_param(int chld_id, const char* param, echld_param_cb_t acb, void* cb_data) {
125         struct _get_param* g = g_new0(struct _get_param,1);
126         echld_parent_encoder_t* enc; 
127         parent_decoder_t* dec;
128         enc_msg_t* em;
129
130         echld_get_all_codecs(NULL, NULL, &enc, &dec);
131
132         em = enc->get_param(param);
133
134         g->name = param;
135         g->cb = acb;
136         g->cb_data = cb_data;
137         g->dec = dec->param;
138         g->dec_err = dec->error;
139
140         return echld_reqh(chld_id, ECHLD_GET_PARAM, 0, em, got_param, g);
141 }
142
143 extern echld_state_t echld_set_param(int chld_id, const char* param, const char* value, echld_param_cb_t acb, void* cb_data) {
144         struct _get_param* g = g_new0(struct _get_param,1);
145         echld_parent_encoder_t* enc; 
146         parent_decoder_t* dec;
147         enc_msg_t* em;
148
149         echld_get_all_codecs(NULL, NULL, &enc, &dec);
150
151         em = enc->set_param(param,value);
152
153         g->name = param;
154         g->cb = acb;
155         g->cb_data = cb_data;
156         g->dec = dec->param;
157         g->dec_err = dec->error;
158
159         return echld_reqh(chld_id, ECHLD_SET_PARAM, 0, em, got_param, g);
160 }
161
162 typedef struct _close {
163         echld_close_cb_t cb;
164         void* cb_data;
165 } close_t;
166
167 static gboolean closed(echld_msg_type_t type, GByteArray* ba, void* data) {
168         close_t* c = (close_t*)data;
169         parent_decoder_t* dec;
170         char* err_msg;
171
172         echld_get_all_codecs(NULL, NULL, NULL, &dec);
173
174         switch (type) {
175                 case ECHLD_CLOSING: {
176                         if (c->cb) {
177                                 c->cb(NULL,c->cb_data);
178                         }
179                         break;
180                 }
181                 case ECHLD_ERROR: {
182                         int errnum;
183
184                         if ( dec->error(ba, &errnum ,&err_msg) ) {
185                                 c->cb(err_msg,c->cb_data);
186                                 g_free(err_msg);
187                         } else {
188                                 c->cb("Canot decode error message",c->cb_data);
189                         }
190                         break;
191                 }
192                 default:
193                         err_msg = g_strdup_printf("other type='%s'",TY(type));
194                         c->cb(err_msg,c->cb_data);
195                         g_free(err_msg);
196                         break;
197         }
198
199         g_free(c);
200         return TRUE;
201
202 }
203  
204 echld_state_t echld_close(int child_id, echld_close_cb_t pcb, void* cb_data) {
205         close_t* c = g_new0(close_t,1);
206         c->cb = pcb;
207         c->cb_data = cb_data;
208
209         return echld_reqh(child_id,ECHLD_CLOSE_CHILD, 0, NULL, closed, c);
210 }
211
212