Mercurial > hg > freeDiameter
comparison contrib/test_Gx/main_gx.c @ 1257:55d0867dd8b8
Added a basic Gx implementation in contrib (untested) -- reported working but may need some adaptation
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Sun, 11 May 2014 22:34:48 +0800 |
parents | |
children | fd398055521c |
comparison
equal
deleted
inserted
replaced
1256:bd6b40c9f731 | 1257:55d0867dd8b8 |
---|---|
1 /**************** | |
2 Contributed by: Krishnan Srinivasan <hsirk_6@yahoo.com> | |
3 License: to be specified. | |
4 TODO: | |
5 | |
6 ****************/ | |
7 | |
8 | |
9 #include <freeDiameter/extension.h> | |
10 #include <signal.h> | |
11 #include <time.h> | |
12 #define AUTH_APP_ID 16777238 | |
13 #define VENDOR_ID_3GPP 10415 | |
14 /* The content of this file follows the same structure as dict_base_proto.c */ | |
15 | |
16 #define CHECK_dict_new( _type, _data, _parent, _ref ) \ | |
17 CHECK_FCT( fd_dict_new( fd_g_config->cnf_dict, (_type), (_data), (_parent), (_ref)) ); | |
18 | |
19 #define CHECK_dict_search( _type, _criteria, _what, _result ) \ | |
20 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, (_type), (_criteria), (_what), (_result), ENOENT) ); | |
21 | |
22 void dump_sess_eyec(struct session *sess, const char *); | |
23 struct local_rules_definition { | |
24 char *avp_name; | |
25 enum rule_position position; | |
26 int min; | |
27 int max; | |
28 }; | |
29 | |
30 #define RULE_ORDER( _position ) ((((_position) == RULE_FIXED_HEAD) || ((_position) == RULE_FIXED_TAIL)) ? 1 : 0 ) | |
31 | |
32 #define PARSE_loc_rules( _rulearray, _parent) { \ | |
33 int __ar; \ | |
34 for (__ar=0; __ar < sizeof(_rulearray) / sizeof((_rulearray)[0]); __ar++) { \ | |
35 struct dict_rule_data __data = { NULL, \ | |
36 (_rulearray)[__ar].position, \ | |
37 0, \ | |
38 (_rulearray)[__ar].min, \ | |
39 (_rulearray)[__ar].max}; \ | |
40 __data.rule_order = RULE_ORDER(__data.rule_position); \ | |
41 CHECK_FCT( fd_dict_search( \ | |
42 fd_g_config->cnf_dict, \ | |
43 DICT_AVP, \ | |
44 AVP_BY_NAME, \ | |
45 (_rulearray)[__ar].avp_name, \ | |
46 &__data.rule_avp, 0 ) ); \ | |
47 if ( !__data.rule_avp ) { \ | |
48 TRACE_DEBUG(INFO, "AVP Not found: '%s'", (_rulearray)[__ar].avp_name ); \ | |
49 return ENOENT; \ | |
50 } \ | |
51 CHECK_FCT_DO( fd_dict_new( fd_g_config->cnf_dict, DICT_RULE, &__data, _parent, NULL), \ | |
52 { \ | |
53 TRACE_DEBUG(INFO, "Error on rule with AVP '%s'", \ | |
54 (_rulearray)[__ar].avp_name ); \ | |
55 return EINVAL; \ | |
56 } ); \ | |
57 } \ | |
58 } | |
59 | |
60 #define enumval_def_u32( _val_, _str_ ) \ | |
61 { _str_, { .u32 = _val_ }} | |
62 | |
63 #define enumval_def_os( _len_, _val_, _str_ ) \ | |
64 { _str_, { .os = { .data = (unsigned char *)_val_, .len = _len_ }}} | |
65 | |
66 | |
67 | |
68 static int ccr_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act); | |
69 static int reauth_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act); | |
70 static int cca_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act); | |
71 static struct disp_hdl * ccr_cb_hdl = NULL; /* handler for ccr req cb */ | |
72 static struct disp_hdl * cca_cb_hdl = NULL; /* handler for cca req cb */ | |
73 static struct disp_hdl * reauth_cb_hdl = NULL; /* handler for cca req cb */ | |
74 | |
75 struct dict_object *ccr_cmd = NULL; | |
76 struct dict_object *cca_cmd = NULL; | |
77 struct dict_object *dataobj_re_auth_request_type = NULL; | |
78 struct dict_object * origin_host = NULL; | |
79 struct dict_object * origin_realm = NULL; | |
80 struct dict_object * dest_host = NULL; | |
81 struct dict_object * dest_realm = NULL; | |
82 struct dict_object *reauth_cmd = NULL; | |
83 struct dict_object * auth_app_id = NULL; | |
84 struct dict_object * service_cxt_id = NULL ; | |
85 struct dict_object * cc_req_type = NULL; | |
86 struct dict_object * cc_req_num = NULL; | |
87 struct dict_object * bearer_usage = NULL; | |
88 struct dict_object * pflt_oper = NULL; | |
89 struct dict_object * pflt_info = NULL; | |
90 struct dict_object * pflt_id = NULL; | |
91 struct dict_object * gx_inf; | |
92 struct dict_object * term_cause = NULL; | |
93 | |
94 struct session *g_sess = NULL; | |
95 struct session_handler *g_hdlr = NULL; | |
96 | |
97 enum gx_state { | |
98 STATE_INIT = 0, | |
99 STATE_INTERMEDIATE , | |
100 STATE_FINAL | |
101 }; | |
102 struct gx_sm_t { | |
103 enum gx_state state; | |
104 pthread_t tid; | |
105 struct fifo *events; | |
106 pthread_mutex_t p_sm_mtx; | |
107 int req_num; | |
108 struct session *sess; | |
109 } g_gx_sm; | |
110 | |
111 int snd_ccr_msg(struct gx_sm_t **gx_sm , struct dict_object *cmd_r ) ; | |
112 | |
113 void sig_hdlr(void); | |
114 | |
115 void *gx_sm_th(void *sm); | |
116 #define press_key_continue() { printf("%s %d\n", __FUNCTION__, __LINE__);} | |
117 static int app_gx_entry(char * conffile) | |
118 { | |
119 // TRACE_ENTRY("%p", conffile); | |
120 { | |
121 application_id_t dcca_id = AUTH_APP_ID; | |
122 application_id_t ccr_id = 272; | |
123 application_id_t cca_id = 272; | |
124 application_id_t reauth_id = 258; | |
125 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_ID, &dcca_id, &gx_inf, ENOENT)); | |
126 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_R, &ccr_id, &ccr_cmd, ENOENT)); | |
127 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_A, &cca_id, &cca_cmd, ENOENT)); | |
128 // CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_R, &reauth_id, &reauth_cmd, ENOENT)); | |
129 | |
130 } | |
131 | |
132 /* Applications section */ | |
133 #if 0 | |
134 { | |
135 // Gx interface | |
136 { | |
137 struct dict_application_data data = { AUTH_APP_ID, "3GPP-Gx Application" }; | |
138 CHECK_dict_new( DICT_APPLICATION, &data, NULL, &gx_inf); | |
139 | |
140 } | |
141 | |
142 } | |
143 #endif | |
144 | |
145 | |
146 // Do registeration and init stuff | |
147 { | |
148 struct disp_when data; | |
149 | |
150 TRACE_DEBUG(FULL, "Initializing dispatch callbacks for Gx interface"); | |
151 | |
152 memset(&data, 0, sizeof(data)); | |
153 data.app = gx_inf; | |
154 data.command = ccr_cmd; | |
155 /* Now specific handler for CCR-CMD */ | |
156 CHECK_FCT( fd_disp_register( ccr_cb, DISP_HOW_CC, &data, NULL, &ccr_cb_hdl ) ); | |
157 | |
158 | |
159 memset(&data, 0, sizeof(data)); | |
160 data.app = gx_inf; | |
161 data.command = cca_cmd; | |
162 | |
163 CHECK_FCT( fd_disp_register( cca_cb, DISP_HOW_CC, &data, NULL, &cca_cb_hdl ) ); | |
164 | |
165 #ifdef REAUTH | |
166 CHECK_FCT(fd_dict_search(fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, | |
167 "Re-Auth-Request", &reauth_cmd, ENOENT)); | |
168 memset(&data, 0, sizeof(data)); | |
169 data.app = gx_inf; | |
170 data.command = reauth_cmd; | |
171 printf("register REAUTH\n"); | |
172 CHECK_FCT( fd_disp_register( reauth_cb, DISP_HOW_CC, &data, NULL, &reauth_cb_hdl ) ); | |
173 #endif | |
174 | |
175 | |
176 } | |
177 | |
178 | |
179 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
180 DICT_AVP, AVP_BY_NAME, | |
181 "Origin-Host", | |
182 &origin_host, | |
183 ENOENT) ); | |
184 | |
185 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
186 DICT_AVP, | |
187 AVP_BY_NAME, | |
188 "Origin-Realm", | |
189 &origin_realm, | |
190 ENOENT) ); | |
191 | |
192 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
193 DICT_AVP, | |
194 AVP_BY_NAME, | |
195 "Destination-Host", | |
196 &dest_host, | |
197 ENOENT) ); | |
198 | |
199 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
200 DICT_AVP, | |
201 AVP_BY_NAME, | |
202 "Destination-Realm", | |
203 &dest_realm, | |
204 ENOENT) ); | |
205 | |
206 | |
207 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
208 DICT_AVP, | |
209 AVP_BY_NAME, | |
210 "Auth-Application-Id", | |
211 &auth_app_id, | |
212 ENOENT) ); | |
213 | |
214 | |
215 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
216 DICT_AVP, | |
217 AVP_BY_NAME, | |
218 "Service-Context-Id", | |
219 &service_cxt_id, | |
220 ENOENT) ); | |
221 | |
222 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
223 DICT_AVP, | |
224 AVP_BY_NAME, | |
225 "CC-Request-Type", | |
226 &cc_req_type, | |
227 ENOENT) ); | |
228 | |
229 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
230 DICT_AVP, | |
231 AVP_BY_NAME, | |
232 "Termination-Cause", | |
233 &term_cause, | |
234 ENOENT) ); | |
235 | |
236 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
237 DICT_AVP, | |
238 AVP_BY_NAME, | |
239 "CC-Request-Number", | |
240 &cc_req_num, | |
241 ENOENT) ); | |
242 { | |
243 struct dict_avp_request req = { VENDOR_ID_3GPP, 0, "Bearer-Usage"}; | |
244 | |
245 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
246 DICT_AVP, | |
247 AVP_BY_NAME_AND_VENDOR, | |
248 &req, | |
249 &bearer_usage, | |
250 ENOENT) ); | |
251 } | |
252 { | |
253 struct dict_avp_request req = { VENDOR_ID_3GPP, 0, "Packet-Filter-Operation"}; | |
254 | |
255 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
256 DICT_AVP, | |
257 AVP_BY_NAME_AND_VENDOR, | |
258 &req, | |
259 &pflt_oper, | |
260 ENOENT) ); | |
261 } | |
262 { | |
263 struct dict_avp_request req = { VENDOR_ID_3GPP, 0, "Packet-Filter-Information"}; | |
264 | |
265 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
266 DICT_AVP, | |
267 AVP_BY_NAME_AND_VENDOR, | |
268 &req, | |
269 &pflt_info, | |
270 ENOENT) ); | |
271 } | |
272 { | |
273 struct dict_avp_request req = { VENDOR_ID_3GPP, 0, "Packet-Filter-Identifier"}; | |
274 | |
275 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, | |
276 DICT_AVP, | |
277 AVP_BY_NAME_AND_VENDOR, | |
278 &req, | |
279 &pflt_id, | |
280 ENOENT) ); | |
281 } | |
282 | |
283 CHECK_FCT(fd_sess_handler_create( &g_hdlr, free, NULL)); | |
284 CHECK_FCT( fd_fifo_new(&g_gx_sm.events)); | |
285 CHECK_FCT( fd_disp_app_support( gx_inf, NULL, 1 , 0)); | |
286 | |
287 CHECK_FCT( fd_event_trig_regcb(SIGUSR1, "app_gx", sig_hdlr ) ); | |
288 | |
289 | |
290 TRACE_DEBUG(INFO, "Extension 'Dictionary definitions for DCCA (rfc4006)' initialized"); | |
291 return 0; | |
292 } | |
293 | |
294 void * gx_sm_th(void *sm) | |
295 { | |
296 struct gx_sm_t *gx_sm = (struct gx_sm_t *) sm; | |
297 struct timespec tout; | |
298 int evt_code; | |
299 | |
300 CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); | |
301 tout.tv_sec =+ 60 ; | |
302 | |
303 while(1) { | |
304 | |
305 fd_event_timedget(gx_sm->events, &tout , ETIMEDOUT, &evt_code, NULL, NULL ); | |
306 CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); | |
307 printf("in tout sec %d\n", tout.tv_sec); | |
308 if(evt_code == ETIMEDOUT) { | |
309 | |
310 snd_ccr_msg(&gx_sm, ccr_cmd); | |
311 gx_sm->req_num++ ; | |
312 gx_sm->state = STATE_INTERMEDIATE; | |
313 CHECK_SYS_DO( clock_gettime( CLOCK_REALTIME, &tout), goto out); | |
314 tout.tv_sec += 30 ; | |
315 | |
316 } | |
317 // printf("press enter\n"); | |
318 // getchar(); | |
319 } | |
320 | |
321 out: | |
322 return NULL; | |
323 } | |
324 //TBD | |
325 int init_gx_sm(struct gx_sm_t *sm) | |
326 { | |
327 sm->state = STATE_INIT; | |
328 sm->tid = 0;// | |
329 sm->events = NULL; | |
330 pthread_mutex_t p_sm_mtx; | |
331 sm->req_num = 0; | |
332 sm->sess = NULL; | |
333 | |
334 return 0; | |
335 } | |
336 int free_gx_sm(struct gx_sm_t *sm) | |
337 { | |
338 | |
339 free(sm); | |
340 } | |
341 struct gx_sm_t *gl_gx_sm = NULL; | |
342 | |
343 void sig_hdlr() | |
344 { | |
345 struct gx_sm_t *gx_sm = gl_gx_sm; | |
346 | |
347 if( gx_sm) { | |
348 | |
349 fd_sess_dump( 0 , g_gx_sm.sess); | |
350 | |
351 } else { | |
352 | |
353 if(gx_sm= (struct gx_sm_t *)malloc(sizeof(struct gx_sm_t))) { | |
354 init_gx_sm(gx_sm); | |
355 } | |
356 gl_gx_sm = gx_sm; | |
357 } | |
358 | |
359 snd_ccr_msg( &gx_sm, ccr_cmd); | |
360 return; | |
361 } | |
362 | |
363 static void cr_cb_ans(void *data, struct msg **msg) | |
364 { | |
365 printf("call back \n"); | |
366 return; | |
367 } | |
368 | |
369 /* < Session-Id > | |
370 { Origin-Host } | |
371 { Origin-Realm } | |
372 { Destination-Realm } | |
373 { Auth-Application-Id } | |
374 { Service-Context-Id } | |
375 { CC-Request-Type } | |
376 { CC-Request-Number } | |
377 */ | |
378 | |
379 int snd_ccr_msg(struct gx_sm_t **sm , struct dict_object *cmd_r ) | |
380 { | |
381 struct msg * req = NULL; | |
382 struct avp * avp = NULL; | |
383 union avp_value val; | |
384 struct ta_mess_info * mi = NULL, *svg; | |
385 struct session *sess = NULL; | |
386 struct gx_sm_t *gx_sm = NULL; | |
387 struct gx_sm_t *ptr = NULL; | |
388 | |
389 TRACE_DEBUG(FULL, "Creating a new CCR message for sending. %p", gx_sm); | |
390 | |
391 /* Create the request from template */ | |
392 CHECK_FCT_DO( fd_msg_new( cmd_r, MSGFL_ALLOC_ETEID, &req ), goto out ); | |
393 | |
394 gx_sm = *sm; | |
395 /* Create a new session */ | |
396 if(!gx_sm->sess) { | |
397 | |
398 CHECK_FCT_DO( fd_sess_new( &sess, | |
399 fd_g_config->cnf_diamid, | |
400 fd_g_config->cnf_diamid_len, | |
401 "CCR_SESSION", strlen("CCR_SESSION") ), goto out ); | |
402 | |
403 printf("statemachine: %p %p %p\n", *(&gx_sm), gx_sm , *sm); | |
404 gx_sm->sess = sess; | |
405 printf("new session %p \n", sess); | |
406 //Hold the session till terminate happens | |
407 CHECK_FCT( fd_sess_ref_msg(sess) ); | |
408 | |
409 } else { | |
410 | |
411 sess = gx_sm->sess; | |
412 printf("use previous session %p \n", sess); | |
413 | |
414 } | |
415 | |
416 fd_sess_dump( 0 , sess); | |
417 | |
418 | |
419 // dump_sess_eyec( sess, __FUNCTION__); | |
420 /* Now set all AVPs values */ | |
421 | |
422 /* Session-Id */ | |
423 { | |
424 os0_t sid; | |
425 size_t sidlen; | |
426 struct dict_object *sess_id = NULL; | |
427 | |
428 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict | |
429 , DICT_AVP, AVP_BY_NAME | |
430 , "Session-Id" | |
431 , &sess_id, ENOENT) ); | |
432 | |
433 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out ); | |
434 CHECK_FCT_DO( fd_msg_avp_new ( sess_id, 0, &avp ), goto out ); | |
435 val.os.data = sid; | |
436 val.os.len = sidlen; | |
437 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
438 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out ); | |
439 } | |
440 | |
441 /* Set the Destination-Realm AVP */ | |
442 { | |
443 CHECK_FCT_DO( fd_msg_avp_new ( dest_realm, 0, &avp ), goto out ); | |
444 val.os.data = (unsigned char *)("vm"); | |
445 val.os.len = strlen("vm"); | |
446 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
447 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
448 } | |
449 | |
450 | |
451 /* Set the Destination-Host AVP if needed*/ | |
452 { | |
453 CHECK_FCT_DO( fd_msg_avp_new ( dest_host, 0, &avp ), goto out ); | |
454 val.os.data = (unsigned char *)("192.168.101.3"); | |
455 val.os.len = strlen("192.168.101.3"); | |
456 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
457 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
458 } | |
459 | |
460 | |
461 /* Set Origin-Host & Origin-Realm */ | |
462 CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); | |
463 | |
464 | |
465 /* Set Auth-Application ID */ | |
466 { | |
467 CHECK_FCT_DO( fd_msg_avp_new ( auth_app_id, 0, &avp ), goto out ); | |
468 val.i32 = AUTH_APP_ID; // Auth-App id is 4 for CCR | |
469 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
470 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
471 } | |
472 | |
473 /* Set Service Context ID */ | |
474 { | |
475 | |
476 CHECK_FCT_DO( fd_msg_avp_new ( service_cxt_id, 0, &avp ), goto out ); | |
477 val.os.data = (unsigned char *)("test@tst"); | |
478 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
479 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
480 | |
481 } | |
482 | |
483 /* Set Request Type */ | |
484 { | |
485 #define CCR_INIT_REQUEST 1 | |
486 #define CCR_UPDATE_REQUEST 2 | |
487 #define CCR_TERMINATION_REQUEST 3 | |
488 #define CCR_EVENT_REQUEST 4 | |
489 //TODO Change this to use enum object | |
490 CHECK_FCT_DO( fd_msg_avp_new ( cc_req_type, 0, &avp ), goto out ); | |
491 if(gx_sm->state == STATE_INIT) | |
492 val.i32 = CCR_INIT_REQUEST; | |
493 else if(gx_sm->state == STATE_FINAL) | |
494 val.i32 = CCR_TERMINATION_REQUEST; | |
495 else | |
496 val.i32 = CCR_UPDATE_REQUEST; | |
497 | |
498 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
499 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
500 | |
501 } | |
502 | |
503 /* Set Request Number */ | |
504 { | |
505 CHECK_FCT_DO( fd_msg_avp_new ( cc_req_num, 0, &avp ), goto out ); | |
506 val.i32 = gx_sm->req_num; | |
507 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
508 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
509 gx_sm->req_num++; | |
510 } | |
511 | |
512 switch(gx_sm->state) { | |
513 | |
514 case STATE_INIT: | |
515 | |
516 { | |
517 //Set Bearer-Usage | |
518 //TODO Change this to use enum object | |
519 CHECK_FCT_DO( fd_msg_avp_new ( bearer_usage, 0, &avp ), goto out ); | |
520 val.i32 = 1;//IMS | |
521 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
522 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
523 } | |
524 { | |
525 //Set Packet Filter Operation | |
526 //TODO Change this to use enum object | |
527 CHECK_FCT_DO( fd_msg_avp_new ( pflt_oper, 0, &avp ), goto out ); | |
528 val.i32 = 1;//ADDITION | |
529 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
530 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
531 } | |
532 struct avp *flt_info = NULL; | |
533 { | |
534 //Set Packet Filter Information | |
535 CHECK_FCT_DO( fd_msg_avp_new ( pflt_info, 0, &flt_info ), goto out ); | |
536 | |
537 | |
538 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, flt_info ), goto out ); | |
539 } | |
540 // Set Packet Filter Identity | |
541 { | |
542 | |
543 CHECK_FCT_DO( fd_msg_avp_new ( pflt_id, 0, &avp ), goto out ); | |
544 val.os.data = (unsigned char *)("ID"); | |
545 val.os.len = strlen("ID"); | |
546 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
547 if(flt_info) { | |
548 CHECK_FCT_DO( fd_msg_avp_add( flt_info, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
549 }else { | |
550 printf("flt_info NULL\n"); | |
551 } | |
552 | |
553 } | |
554 CHECK_FCT(fd_sess_state_store(g_hdlr, sess, &gx_sm)); | |
555 | |
556 break; | |
557 case STATE_FINAL: | |
558 { | |
559 //Set Packet Filter Operation | |
560 //TODO Change this to use enum object | |
561 CHECK_FCT_DO( fd_msg_avp_new ( term_cause, 0, &avp ), goto out ); | |
562 val.i32 = 1;//Diameter logout | |
563 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
564 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
565 } | |
566 break; | |
567 default: | |
568 printf("State mismatch \n"); | |
569 } | |
570 fflush(stderr); | |
571 | |
572 /* Send the request */ | |
573 printf("CCA %p\n",req); | |
574 // Everthing Done Store the state: reply should retreive it | |
575 CHECK_FCT_DO( fd_msg_send( &req, NULL, NULL ), goto out ); | |
576 | |
577 out: | |
578 return; | |
579 } | |
580 | |
581 | |
582 static int reauth_cb( struct msg ** msg, struct avp * avp, struct session * sess, void * opaque, enum disp_action * act) | |
583 { | |
584 struct msg *ans, *qry; | |
585 struct avp * a; | |
586 | |
587 TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); | |
588 | |
589 if (msg == NULL) | |
590 return EINVAL; | |
591 | |
592 | |
593 /* Create answer header */ | |
594 qry = *msg; | |
595 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); | |
596 ans = *msg; | |
597 | |
598 /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ | |
599 CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); | |
600 | |
601 /* Send the answer */ | |
602 CHECK_FCT( fd_msg_send( msg, NULL, NULL ) ); | |
603 | |
604 | |
605 | |
606 } | |
607 static int dcca_ans_from_req( struct dict_object * obj, struct msg *qry, struct msg **msg) | |
608 { | |
609 struct avp *avp = NULL; | |
610 struct avp_hdr * avpdata; | |
611 int rc = -1; | |
612 | |
613 CHECK_FCT(fd_msg_search_avp( qry, obj, &avp)); | |
614 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata)); | |
615 avp = NULL; | |
616 | |
617 CHECK_FCT_DO( fd_msg_avp_new ( obj, 0, &avp ), goto out ); | |
618 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, avpdata->avp_value ), goto out ); | |
619 CHECK_FCT_DO( fd_msg_avp_add( *msg, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
620 | |
621 rc = 0; | |
622 out: | |
623 return rc; | |
624 | |
625 } | |
626 /* Dummy ccr which : | |
627 Read the cc-req-type && cc-req-number from the msg and stick it back | |
628 in the reply | |
629 | |
630 */ | |
631 static int ccr_cb( struct msg ** msg, struct avp * r_avp, struct session * sess, void * opaque, enum disp_action * act) | |
632 { | |
633 struct msg *ans, *qry; | |
634 struct avp *avp = NULL; | |
635 struct avp_hdr * avp_data; | |
636 int rc = - 1; | |
637 | |
638 TRACE_ENTRY("%p %p %p %p", msg, r_avp, sess, act); | |
639 | |
640 if (msg == NULL) | |
641 return EINVAL; | |
642 | |
643 | |
644 /* Create answer header */ | |
645 qry = *msg; | |
646 CHECK_FCT_DO( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) , goto out); | |
647 ans = *msg; | |
648 | |
649 /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ | |
650 CHECK_FCT_DO( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ), goto out ); | |
651 | |
652 // Get the auth_app_id and from the reply and set it in the reply | |
653 CHECK_FCT_DO(dcca_ans_from_req( auth_app_id, qry, msg), goto out); | |
654 CHECK_FCT_DO(dcca_ans_from_req( cc_req_type, qry, msg), goto out); | |
655 CHECK_FCT_DO(dcca_ans_from_req( cc_req_num, qry, msg), goto out); | |
656 | |
657 /* Send the answer */ | |
658 CHECK_FCT_DO( fd_msg_send( msg, NULL, NULL ), goto out ); | |
659 rc = 0; | |
660 out: | |
661 //Free up the memory | |
662 return rc ; | |
663 | |
664 } | |
665 int send_reauth_req() | |
666 | |
667 { | |
668 struct dict_application_data appdata; | |
669 struct avp *avp = NULL; | |
670 union avp_value val ; | |
671 struct msg *qry, *ans = NULL; | |
672 struct msg *req = NULL; | |
673 struct msg *tst = NULL; | |
674 struct dict_object * auth_app_id = NULL, *reauth_req_type = NULL; | |
675 | |
676 // qry = *msg; | |
677 | |
678 | |
679 { // Send new reauth request | |
680 | |
681 CHECK_FCT_DO( fd_msg_new( reauth_cmd, MSGFL_ALLOC_ETEID, &req ), goto out ); | |
682 CHECK_FCT( fd_dict_getval(gx_inf, &appdata) ); | |
683 | |
684 struct msg_hdr * header = NULL; | |
685 CHECK_FCT( fd_msg_hdr ( req, &header ) ); | |
686 header->msg_appl = appdata.application_id; | |
687 | |
688 } | |
689 | |
690 /* Session-Id */ | |
691 { | |
692 os0_t sid; | |
693 size_t sidlen; | |
694 struct dict_object *sess_id = NULL; | |
695 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id, ENOENT) ); | |
696 | |
697 //CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), goto out ); | |
698 CHECK_FCT_DO( fd_msg_avp_new ( sess_id, 0, &avp ), goto out ); | |
699 val.os.data = sid; | |
700 val.os.len = sidlen; | |
701 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
702 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_FIRST_CHILD, avp ), goto out ); | |
703 | |
704 } | |
705 | |
706 /* Set the Destination-Realm AVP */ | |
707 { | |
708 CHECK_FCT_DO( fd_msg_avp_new ( dest_realm, 0, &avp ), goto out ); | |
709 val.os.data = (unsigned char *)("vm"); | |
710 val.os.len = strlen("vm"); | |
711 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
712 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
713 } | |
714 | |
715 /* Set the Destination-Host AVP if needed*/ | |
716 // if (ta_conf->dest_host) { | |
717 CHECK_FCT_DO( fd_msg_avp_new ( dest_host, 0, &avp ), goto out ); | |
718 val.os.data = (unsigned char *)("cli.vm"); | |
719 val.os.len = strlen("cli.vm"); | |
720 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
721 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
722 // } | |
723 | |
724 /* Set Origin-Host & Origin-Realm */ | |
725 CHECK_FCT_DO( fd_msg_add_origin ( req, 0 ), goto out ); | |
726 | |
727 /* AUTH_Application-ID */ | |
728 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &auth_app_id, ENOENT) ); | |
729 CHECK_FCT_DO( fd_msg_avp_new ( auth_app_id, 0, &avp ), goto out ); | |
730 val.i32 = appdata.application_id; | |
731 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
732 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
733 | |
734 /* Re-Auth Request Type */ | |
735 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Re-Auth-Request-Type", &reauth_req_type, ENOENT) ); | |
736 CHECK_FCT_DO( fd_msg_avp_new ( reauth_req_type, 0, &avp ), goto out ); | |
737 val.i32 = 0; | |
738 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), goto out ); | |
739 CHECK_FCT_DO( fd_msg_avp_add( req, MSG_BRW_LAST_CHILD, avp ), goto out ); | |
740 | |
741 | |
742 CHECK_FCT_DO( fd_msg_send( &req, cr_cb_ans, NULL ), goto out ); | |
743 out: | |
744 return 0 ; | |
745 | |
746 | |
747 } | |
748 /* Search a given AVP model in an AVP (extracted from libfreediameter/message.c ) */ | |
749 int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp ) | |
750 { | |
751 struct avp * nextavp; | |
752 struct avp_hdr * nextavphdr; | |
753 struct dict_avp_data dictdata; | |
754 | |
755 | |
756 TRACE_ENTRY("%p %p %p", groupedavp, what, avp); | |
757 | |
758 CHECK_FCT( fd_dict_getval(what, &dictdata) ); | |
759 | |
760 // Loop only in the group AVP | |
761 CHECK_FCT( fd_msg_browse(groupedavp, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL) ); | |
762 CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); | |
763 | |
764 while (nextavphdr) { | |
765 | |
766 if ( (nextavphdr->avp_code == dictdata.avp_code) && (nextavphdr->avp_vendor == dictdata.avp_vendor) ) // always 0 if no Vendor flag | |
767 { | |
768 break; | |
769 } | |
770 | |
771 // Otherwise move to next AVP in the grouped AVP | |
772 CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); | |
773 | |
774 if(nextavp!=NULL) | |
775 { | |
776 CHECK_FCT( fd_msg_avp_hdr( nextavp, &nextavphdr ) ); | |
777 } | |
778 else | |
779 nextavphdr=NULL; | |
780 } | |
781 if (avp) | |
782 *avp = nextavp; | |
783 | |
784 if (avp && nextavp) { | |
785 struct dictionary * dict; | |
786 CHECK_FCT( fd_dict_getdict( what, &dict) ); | |
787 CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), ); | |
788 } | |
789 | |
790 if (avp || nextavp) | |
791 return 0; | |
792 else | |
793 return ENOENT; | |
794 } | |
795 | |
796 static int cca_cb( struct msg ** msg, | |
797 struct avp * t_avp , | |
798 struct session * sess, | |
799 void * opaque, | |
800 enum disp_action * act) | |
801 { | |
802 struct avp *avp = NULL, *g_avp = NULL; | |
803 struct msg *req = *msg; | |
804 struct dict_object *chrg_rule_name = NULL ; | |
805 struct dict_object *chrg_rule_grp = NULL ; | |
806 struct avp_hdr * avpdata = NULL; | |
807 struct dict_avp_request grule_req = {VENDOR_ID_3GPP, 0,"Charging-Rule-Install"}; | |
808 struct dict_avp_request rule_req = {VENDOR_ID_3GPP, 0,"Charging-Rule-Name"}; | |
809 struct timespec sess_timeout; | |
810 struct gx_sm_t *gx_sm = NULL; | |
811 // struct session *sess = NULL; | |
812 | |
813 | |
814 CHECK_FCT(fd_sess_state_retrieve( g_hdlr, sess, &gx_sm)); | |
815 fd_sess_dump( 0, sess); | |
816 if(gx_sm->state != STATE_FINAL) { | |
817 | |
818 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict | |
819 , DICT_AVP, AVP_BY_NAME_AND_VENDOR | |
820 , &grule_req | |
821 , &chrg_rule_grp | |
822 , ENOENT)); | |
823 | |
824 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict | |
825 , DICT_AVP, AVP_BY_NAME_AND_VENDOR | |
826 , &rule_req | |
827 , &chrg_rule_name | |
828 , ENOENT)); | |
829 | |
830 | |
831 CHECK_FCT(fd_msg_search_avp ( *msg, chrg_rule_grp, &g_avp )); | |
832 CHECK_FCT(fd_avp_search_avp(g_avp, chrg_rule_name, &avp)); | |
833 | |
834 if(avp) { | |
835 CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata)); | |
836 } else { | |
837 printf("NULL AVP \n"); | |
838 } | |
839 printf("charging-rule-name %s\n", avpdata->avp_value->os.data); | |
840 gx_sm->state = STATE_FINAL; | |
841 dump_sess_eyec( sess, __FUNCTION__); | |
842 printf("next dump\n"); | |
843 CHECK_FCT(fd_sess_state_store( g_hdlr, sess, &gx_sm)); | |
844 fd_msg_free(*msg); | |
845 *msg = NULL; | |
846 | |
847 } else { | |
848 printf("Session terminated\n"); | |
849 free_gx_sm(gx_sm); | |
850 fd_msg_free(*msg); | |
851 fd_sess_reclaim(&sess); | |
852 *msg = NULL; | |
853 } | |
854 fd_sess_dump( 0 , sess); | |
855 | |
856 return 0; | |
857 } | |
858 | |
859 static int gx_entry(char * conffile) | |
860 { | |
861 return 0; | |
862 } | |
863 EXTENSION_ENTRY( "app_gx", app_gx_entry, "dict_dcca"); | |
864 //EXTENSION_ENTRY( "app_gx", gx_entry); |