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);
"Welcome to our mercurial repository"