comparison extensions/app_acct/app_acct.c @ 285:0daf6fc2b751

Added a test case for the app_acct extension
author Sebastien Decugis <sdecugis@nict.go.jp>
date Fri, 30 Apr 2010 17:55:16 +0900
parents 397cdcd41f53
children 43cdf237bb8c
comparison
equal deleted inserted replaced
284:397cdcd41f53 285:0daf6fc2b751
35 35
36 /* The simple Accounting server for freeDiameter */ 36 /* The simple Accounting server for freeDiameter */
37 37
38 #include "app_acct.h" 38 #include "app_acct.h"
39 39
40 /* Default callback for the Accounting application. */ 40 /* Mandatory AVPs for the Accounting-Answer */
41 static int acct_fallback( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act) 41 static struct {
42 { 42 struct dict_object * Accounting_Record_Number;
43 /* This CB should never be called */ 43 struct dict_object * Accounting_Record_Type;
44 TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); 44 } acct_dict;
45
46 fd_log_debug("Unexpected message received!\n");
47
48 return ENOTSUP;
49 }
50 45
51 46
52 /* Callback for incoming Base Accounting Accounting-Request messages */ 47 /* Callback for incoming Base Accounting Accounting-Request messages */
53 static int acct_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act) 48 static int acct_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act)
54 { 49 {
55 struct msg_hdr *hdr = NULL; 50 struct msg_hdr *hdr = NULL;
56 struct msg *ans, *qry; 51 struct msg * m;
57 struct avp * a = NULL; 52 struct avp * a = NULL;
58 struct avp_hdr * h = NULL; 53 struct avp_hdr * art=NULL, *arn=NULL; /* We keep a pointer on the Accounting-Record-{Type, Number} AVPs from the query */
59 char * s; 54 char * s;
55 struct acct_record_list rl;
60 56
61 TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); 57 TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
62 if (msg == NULL) 58 if (msg == NULL)
63 return EINVAL; 59 return EINVAL;
64 60
65 qry = *msg; 61 m = *msg;
66 /* Create the answer message, including the Session-Id AVP */ 62
63 /* Prepare a new record list */
64 CHECK_FCT( acct_rec_prepare( &rl ) );
65
66 /* Maps the AVPs from the query with this record list */
67 CHECK_FCT( acct_rec_map( &rl, m ) );
68
69 /* Check that at least one AVP was mapped */
70 CHECK_FCT( acct_rec_validate( &rl ) );
71
72 /* Now, save these mapped AVPs in the database */
73 CHECK_FCT( acct_db_insert( &rl ) );
74
75 acct_rec_empty( &rl );
76
77 /* OK, we can send a positive reply now */
78
79 /* Get Accounting-Record-{Number,Type} values */
80 CHECK_FCT( fd_msg_search_avp ( m, acct_dict.Accounting_Record_Type, &a) );
81 if (a) {
82 CHECK_FCT( fd_msg_avp_hdr( a, &art ) );
83 }
84 CHECK_FCT( fd_msg_search_avp ( m, acct_dict.Accounting_Record_Number, &a) );
85 if (a) {
86 CHECK_FCT( fd_msg_avp_hdr( a, &arn ) );
87 }
88
89 /* Create the answer message */
67 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) ); 90 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
68 ans = *msg; 91 m = *msg;
69 92
70 /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */ 93 /* Set the Origin-Host, Origin-Realm, Result-Code AVPs */
71 CHECK_FCT( fd_msg_rescode_set( ans, "DIAMETER_SUCCESS", NULL, NULL, 1 ) ); 94 CHECK_FCT( fd_msg_rescode_set( m, "DIAMETER_SUCCESS", NULL, NULL, 1 ) );
72 95
73 fd_log_debug("--------------Received the following Accounting message:--------------\n"); 96 /* Add the mandatory AVPs in the ACA */
74 97 if (art) {
75 CHECK_FCT( fd_sess_getsid ( sess, &s ) ); 98 CHECK_FCT( fd_msg_avp_new ( acct_dict.Accounting_Record_Type, 0, &a ) );
76 fd_log_debug("Session: %s\n", s); 99 CHECK_FCT( fd_msg_avp_setvalue( a, art->avp_value ) );
77 100 CHECK_FCT( fd_msg_avp_add( m, MSG_BRW_LAST_CHILD, a ) );
78 /* We may also dump other data from the message, such as Accounting session Id, number of packets, ... */ 101 }
79 102 if (arn) {
80 fd_log_debug("----------------------------------------------------------------------\n"); 103 CHECK_FCT( fd_msg_avp_new ( acct_dict.Accounting_Record_Number, 0, &a ) );
81 104 CHECK_FCT( fd_msg_avp_setvalue( a, arn->avp_value ) );
105 CHECK_FCT( fd_msg_avp_add( m, MSG_BRW_LAST_CHILD, a ) );
106 }
107
82 /* Send the answer */ 108 /* Send the answer */
83 CHECK_FCT( fd_msg_send( msg, NULL, NULL ) ); 109 *act = DISP_ACT_SEND;
84
85 return 0; 110 return 0;
86 } 111 }
87 112
88 113
89 /* entry point */ 114 /* entry point */
91 { 116 {
92 struct disp_when data; 117 struct disp_when data;
93 118
94 TRACE_ENTRY("%p", conffile); 119 TRACE_ENTRY("%p", conffile);
95 120
121 #ifndef TEST_DEBUG /* We do this differently in the test scenario */
96 /* Initialize the configuration and parse the file */ 122 /* Initialize the configuration and parse the file */
97 CHECK_FCT( acct_conf_init() ); 123 CHECK_FCT( acct_conf_init() );
98 CHECK_FCT( acct_conf_parse(conffile) ); 124 CHECK_FCT( acct_conf_parse(conffile) );
99 CHECK_FCT( acct_conf_check(conffile) ); 125 CHECK_FCT( acct_conf_check(conffile) );
126 #endif /* TEST_DEBUG */
100 127
101 /* Now initialize the database module */ 128 /* Now initialize the database module */
102 CHECK_FCT( acct_db_init() ); 129 CHECK_FCT( acct_db_init() );
103 130
131 /* Search the AVPs we will need in this file */
132 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Number", &acct_dict.Accounting_Record_Number, ENOENT) );
133 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Type", &acct_dict.Accounting_Record_Type, ENOENT) );
134
104 /* Register the dispatch callbacks */ 135 /* Register the dispatch callbacks */
105 memset(&data, 0, sizeof(data)); 136 memset(&data, 0, sizeof(data));
106 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &data.app, ENOENT) ); 137 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &data.app, ENOENT) );
107 CHECK_FCT( fd_disp_register( acct_fallback, DISP_HOW_APPID, &data, NULL ) );
108 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &data.command, ENOENT) ); 138 CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &data.command, ENOENT) );
109 CHECK_FCT( fd_disp_register( acct_cb, DISP_HOW_CC, &data, NULL ) ); 139 CHECK_FCT( fd_disp_register( acct_cb, DISP_HOW_CC, &data, NULL ) );
110 140
111 /* Advertise the support for the Diameter Base Accounting application in the peer */ 141 /* Advertise the support for the Diameter Base Accounting application in the peer */
112 CHECK_FCT( fd_disp_app_support ( data.app, NULL, 0, 1 ) ); 142 CHECK_FCT( fd_disp_app_support ( data.app, NULL, 0, 1 ) );
"Welcome to our mercurial repository"