26
26
#include "../../ut.h"
27
27
28
28
#include "aaa_impl.h"
29
+ #include "aaa_evi.h"
29
30
#include "peer.h"
30
31
31
32
static int mod_init (void );
@@ -40,6 +41,7 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code,
40
41
str * avp_json , pv_spec_t * rpl_avps_pv );
41
42
static int dm_send_request_async (struct sip_msg * msg , async_ctx * ctx ,
42
43
int * app_id , int * cmd_code , str * avp_json , pv_spec_t * rpl_avps_pv );
44
+ static int dm_send_reply (struct sip_msg * msg , str * avp_json );
43
45
static int dm_bind_api (aaa_prot * api );
44
46
45
47
int fd_log_level = FD_LOG_NOTICE ;
@@ -56,6 +58,10 @@ static const cmd_export_t cmds[]= {
56
58
{CMD_PARAM_VAR |CMD_PARAM_OPT ,0 ,0 }, {0 ,0 ,0 }},
57
59
ALL_ROUTES },
58
60
61
+ {"dm_send_reply" , (cmd_function )dm_send_reply , {
62
+ {CMD_PARAM_STR ,0 ,0 }, {0 ,0 ,0 }},
63
+ EVENT_ROUTE },
64
+
59
65
{"aaa_bind_api" , (cmd_function ) dm_bind_api , {{0 , 0 , 0 }}, 0 },
60
66
{0 ,0 ,{{0 ,0 ,0 }},0 }
61
67
};
@@ -143,6 +149,11 @@ int mod_init(void)
143
149
return -1 ;
144
150
}
145
151
152
+ if (dm_init_evi () != 0 ) {
153
+ LM_ERR ("failed to init the Diameter event\n" );
154
+ return -1 ;
155
+ }
156
+
146
157
if (dm_init_peer () != 0 ) {
147
158
LM_ERR ("failed to init the local Diameter peer\n" );
148
159
return -1 ;
@@ -229,11 +240,11 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code,
229
240
struct dict_object * req ;
230
241
cJSON * avps ;
231
242
int rc ;
232
- char * rpl_avps ;
243
+ char * rpl_avps = NULL ;
233
244
234
- if (fd_dict_search (fd_g_config -> cnf_dict , DICT_COMMAND , CMD_BY_CODE_R ,
235
- cmd_code , & req , ENOENT ) == ENOENT ) {
236
- LM_ERR ("unrecognized Request command code: %d\n" , * cmd_code );
245
+ if (( rc = fd_dict_search (fd_g_config -> cnf_dict , DICT_COMMAND ,CMD_BY_CODE_R ,
246
+ cmd_code , & req , ENOENT )) != 0 ) {
247
+ LM_ERR ("unrecognized Request command code: %d (errno: %d) \n" , * cmd_code , rc );
237
248
LM_ERR ("to fix this, you can define the Request/Answer format in the "
238
249
"'extra-avps-file' config file\n" );
239
250
return -1 ;
@@ -259,7 +270,7 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code,
259
270
goto error ;
260
271
}
261
272
262
- dmsg = _dm_create_message (NULL , AAA_CUSTOM , * app_id , * cmd_code );
273
+ dmsg = _dm_create_message (NULL , AAA_CUSTOM_REQ , * app_id , * cmd_code , NULL );
263
274
if (!dmsg ) {
264
275
LM_ERR ("oom\n" );
265
276
goto error ;
@@ -280,8 +291,8 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code,
280
291
LM_ERR ("failed to set output rpl_avps pv to: %s\n" , rpl_avps );
281
292
}
282
293
283
- if (rc != 0 ) {
284
- LM_ERR ("Diameter request failed\n" );
294
+ if (rc < 0 ) {
295
+ LM_ERR ("Diameter request failed (rc: %d) \n" , rc );
285
296
cJSON_Delete (avps );
286
297
return rc ;
287
298
}
@@ -301,6 +312,108 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code,
301
312
return -1 ;
302
313
}
303
314
315
+
316
+ static int dm_send_reply (struct sip_msg * msg , str * avp_json )
317
+ {
318
+ aaa_message * dmsg = NULL ;
319
+ cJSON * avps ;
320
+ pv_param_t evp ;
321
+ pv_value_t res ;
322
+ str sessid ;
323
+ int appid , cmdcode , rc ;
324
+ unsigned long fd_req ;
325
+
326
+ if (ZSTRP (avp_json )) {
327
+ LM_ERR ("unable to build reply (NULL 'avps_json' input)\n" );
328
+ return -1 ;
329
+ }
330
+
331
+ avps = cJSON_Parse (avp_json -> s );
332
+ if (!avps ) {
333
+ LM_ERR ("failed to parse input JSON ('%.*s' ..., total: %d)\n" ,
334
+ avp_json -> len > 512 ? 512 : avp_json -> len , avp_json -> s , avp_json -> len );
335
+ return -1 ;
336
+ }
337
+
338
+ if (avps -> type != cJSON_Array ) {
339
+ LM_ERR ("bad JSON type: must be Array ('%.*s' ..., total: %d)\n" ,
340
+ avp_json -> len > 512 ? 512 : avp_json -> len , avp_json -> s , avp_json -> len );
341
+ goto error ;
342
+ }
343
+
344
+ /* Here, we know 100% that we're inside an event_route, so we can pull the
345
+ * Diameter request info (Session-ID, App, Code) using the "params" API */
346
+ memset (& evp , 0 , sizeof evp );
347
+ evp .pvn .type = PV_NAME_INTSTR ;
348
+ evp .pvn .u .isname .type = AVP_NAME_STR ;
349
+
350
+ evp .pvn .u .isname .name .s = dmev_req_pname_sessid ;
351
+ route_params_run (msg , & evp , & res );
352
+ if (ZSTR (res .rs ) || !pvv_is_str (& res )) {
353
+ LM_ERR ("failed to fetch unique session ID\n" );
354
+ sessid = STR_NULL ;
355
+ } else {
356
+ sessid = res .rs ;
357
+ }
358
+
359
+ evp .pvn .u .isname .name .s = dmev_req_pname_appid ;
360
+ route_params_run (msg , & evp , & res );
361
+ if (!pvv_is_int (& res )) {
362
+ LM_ERR ("failed to fetch Application ID\n" );
363
+ appid = 0 ;
364
+ } else {
365
+ appid = res .ri ;
366
+ }
367
+
368
+ evp .pvn .u .isname .name .s = dmev_req_pname_cmdcode ;
369
+ route_params_run (msg , & evp , & res );
370
+ if (!pvv_is_int (& res )) {
371
+ LM_ERR ("failed to fetch Command Code\n" );
372
+ cmdcode = 0 ;
373
+ } else {
374
+ cmdcode = res .ri ;
375
+ }
376
+
377
+ evp .pvn .u .isname .name .s = dmev_req_pname_fdmsg ;
378
+ route_params_run (msg , & evp , & res );
379
+ if (!pvv_is_str (& res )) {
380
+ LM_ERR ("failed to fetch FD Message\n" );
381
+ goto error ;
382
+ } else {
383
+ reverse_hex2int64 (res .rs .s , res .rs .len , 1 , & fd_req );
384
+ }
385
+
386
+ dmsg = _dm_create_message (NULL , AAA_CUSTOM_RPL , appid , cmdcode , (void * )fd_req );
387
+ if (!dmsg ) {
388
+ LM_ERR ("oom\n" );
389
+ goto error ;
390
+ }
391
+
392
+ if (dm_build_avps (& ((struct dm_message * )(dmsg -> avpair ))-> avps ,
393
+ avps -> child ) != 0 ) {
394
+ LM_ERR ("failed to unpack JSON ('%.*s' ..., total: %d)\n" ,
395
+ avp_json -> len > 512 ? 512 : avp_json -> len , avp_json -> s , avp_json -> len );
396
+ goto error ;
397
+ }
398
+
399
+ rc = _dm_send_message (NULL , dmsg , NULL , NULL );
400
+ if (rc < 0 ) {
401
+ LM_ERR ("failed to send Diameter reply (sess: %.*s, app: %d, cmd: %d)\n" ,
402
+ sessid .len , sessid .s , appid , cmdcode );
403
+ cJSON_Delete (avps );
404
+ return rc ;
405
+ }
406
+
407
+ cJSON_Delete (avps );
408
+ return 0 ;
409
+
410
+ error :
411
+ _dm_destroy_message (dmsg );
412
+ cJSON_Delete (avps );
413
+ return -1 ;
414
+ }
415
+
416
+
304
417
struct dm_async_msg {
305
418
pv_spec_p ret ;
306
419
struct dm_cond * cond ;
@@ -403,7 +516,7 @@ static int dm_send_request_async(struct sip_msg *msg, async_ctx *ctx,
403
516
goto error ;
404
517
}
405
518
406
- dmsg = _dm_create_message (NULL , AAA_CUSTOM , * app_id , * cmd_code );
519
+ dmsg = _dm_create_message (NULL , AAA_CUSTOM_REQ , * app_id , * cmd_code , NULL );
407
520
if (!dmsg ) {
408
521
LM_ERR ("oom\n" );
409
522
goto error ;
0 commit comments