Mercurial > hg > freeDiameter
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 ) ); |