1019
typedef struct _dbg_mod_level {
1021
unsigned int hashid;
1023
struct _dbg_mod_level *next;
1026
typedef struct _dbg_mod_slot
1028
dbg_mod_level_t *first;
1032
static dbg_mod_slot_t *_dbg_mod_table = NULL;
1033
static unsigned int _dbg_mod_table_size = 0;
1038
int dbg_init_mod_levels(int dbg_mod_hash_size)
1041
if(dbg_mod_hash_size<=0)
1043
if(_dbg_mod_table!=NULL)
1045
_dbg_mod_table_size = 1 << dbg_mod_hash_size;
1046
_dbg_mod_table = (dbg_mod_slot_t*)shm_malloc(_dbg_mod_table_size*sizeof(dbg_mod_slot_t));
1047
if(_dbg_mod_table==NULL)
1049
LM_ERR("no more shm.\n");
1052
memset(_dbg_mod_table, 0, _dbg_mod_table_size*sizeof(dbg_mod_slot_t));
1054
for(i=0; i<_dbg_mod_table_size; i++)
1056
if(lock_init(&_dbg_mod_table[i].lock)==0)
1058
LM_ERR("cannot initalize lock[%d]\n", i);
1062
lock_destroy(&_dbg_mod_table[i].lock);
1065
shm_free(_dbg_mod_table);
1066
_dbg_mod_table = NULL;
1074
* case insensitive hashing - clone here to avoid usage of LOG*()
1075
* - s1 - str to hash
1076
* - s1len - len of s1
1077
* return computed hash id
1079
#define dbg_ch_h_inc h+=v^(v>>3)
1080
#define dbg_ch_icase(_c) (((_c)>='A'&&(_c)<='Z')?((_c)|0x20):(_c))
1081
static inline unsigned int dbg_compute_hash(char *s1, int s1len)
1084
register unsigned v;
1085
register unsigned h;
1090
for ( p=s1 ; p<=(end-4) ; p+=4 ){
1091
v=(dbg_ch_icase(*p)<<24)+(dbg_ch_icase(p[1])<<16)+(dbg_ch_icase(p[2])<<8)
1092
+ dbg_ch_icase(p[3]);
1096
for (; p<end ; p++){ v<<=8; v+=dbg_ch_icase(*p);}
1099
h=((h)+(h>>11))+((h>>13)+(h>>23));
1103
int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel)
1107
dbg_mod_level_t *it;
1108
dbg_mod_level_t *itp;
1109
dbg_mod_level_t *itn;
1111
if(_dbg_mod_table==NULL)
1114
hid = dbg_compute_hash(mname, mnlen);
1115
idx = hid&(_dbg_mod_table_size-1);
1117
lock_get(&_dbg_mod_table[idx].lock);
1118
it = _dbg_mod_table[idx].first;
1120
while(it!=NULL && it->hashid < hid) {
1124
while(it!=NULL && it->hashid==hid)
1126
if(mnlen==it->name.len
1127
&& strncmp(mname, it->name.s, mnlen)==0)
1133
itp->next = it->next;
1135
_dbg_mod_table[idx].first = it->next;
1140
it->level = *mlevel;
1142
lock_release(&_dbg_mod_table[idx].lock);
1148
/* not found - add */
1150
lock_release(&_dbg_mod_table[idx].lock);
1153
itn = (dbg_mod_level_t*)shm_malloc(sizeof(dbg_mod_level_t) + (mnlen+1)*sizeof(char));
1155
LM_ERR("no more shm\n");
1156
lock_release(&_dbg_mod_table[idx].lock);
1159
memset(itn, 0, sizeof(dbg_mod_level_t) + (mnlen+1)*sizeof(char));
1160
itn->level = *mlevel;
1162
itn->name.s = (char*)(itn) + sizeof(dbg_mod_level_t);
1163
itn->name.len = mnlen;
1164
strncpy(itn->name.s, mname, mnlen);
1165
itn->name.s[itn->name.len] = '\0';
1168
itn->next = _dbg_mod_table[idx].first;
1169
_dbg_mod_table[idx].first = itn;
1171
itn->next = itp->next;
1174
lock_release(&_dbg_mod_table[idx].lock);
1179
static int _dbg_get_mod_debug_level = 0;
1180
int dbg_get_mod_debug_level(char *mname, int mnlen, int *mlevel)
1184
dbg_mod_level_t *it;
1185
/* no LOG*() usage in this function and those executed insite it
1186
* - use fprintf(stderr, ...) if need for troubleshooting
1187
* - it will loop otherwise */
1188
if(_dbg_mod_table==NULL)
1191
if(cfg_get(dbg, dbg_cfg, mod_level_mode)==0)
1194
if(_dbg_get_mod_debug_level!=0)
1196
_dbg_get_mod_debug_level = 1;
1198
hid = dbg_compute_hash(mname, mnlen);
1199
idx = hid&(_dbg_mod_table_size-1);
1200
lock_get(&_dbg_mod_table[idx].lock);
1201
it = _dbg_mod_table[idx].first;
1202
while(it!=NULL && it->hashid < hid)
1204
while(it!=NULL && it->hashid == hid)
1206
if(mnlen==it->name.len
1207
&& strncmp(mname, it->name.s, mnlen)==0)
1210
*mlevel = it->level;
1211
lock_release(&_dbg_mod_table[idx].lock);
1212
_dbg_get_mod_debug_level = 0;
1217
lock_release(&_dbg_mod_table[idx].lock);
1218
_dbg_get_mod_debug_level = 0;
1225
void dbg_enable_mod_levels(void)
1227
if(_dbg_mod_table==NULL)
1229
set_module_debug_level_cb(dbg_get_mod_debug_level);
1232
#define DBG_PVCACHE_SIZE 32
1234
typedef struct _dbg_pvcache {
1237
struct _dbg_pvcache *next;
1240
static dbg_pvcache_t **_dbg_pvcache = NULL;
1242
int dbg_init_pvcache()
1244
_dbg_pvcache = (dbg_pvcache_t**)pkg_malloc(sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
1245
if(_dbg_pvcache==NULL)
1247
LM_ERR("no more memory.\n");
1250
memset(_dbg_pvcache, 0, sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
1254
int dbg_assign_add(str *name, pv_spec_t *spec)
1256
dbg_pvcache_t *pvn, *last, *next;
1259
if(name==NULL||spec==NULL)
1262
if(_dbg_pvcache==NULL)
1265
pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
1266
pvn = (dbg_pvcache_t*)pkg_malloc(sizeof(dbg_pvcache_t));
1269
LM_ERR("no more memory\n");
1272
memset(pvn, 0, sizeof(dbg_pvcache_t));
1275
next = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
1278
_dbg_pvcache[pvid%DBG_PVCACHE_SIZE] = pvn;
1292
str *_dbg_pvcache_lookup(pv_spec_t *spec)
1301
if(_dbg_pvcache==NULL)
1304
pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
1305
pvi = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
1308
if(pvi->spec==spec) {
1313
name = pv_cache_get_name(spec);
1316
/*LM_DBG("Add name[%.*s] to pvcache\n", name->len, name->s);*/
1317
dbg_assign_add(name, spec);
1322
int _dbg_log_assign_action_avp(struct sip_msg* msg, struct lvalue* lv)
1326
avp_spec_t* avp_s = &lv->lv.avps;
1327
avp = search_avp_by_index(avp_s->type, avp_s->name,
1328
&avp_val, avp_s->index);
1330
if (avp->flags&(AVP_VAL_STR)){
1331
LM_DBG("%.*s:\"%.*s\"\n", avp_s->name.s.len, avp_s->name.s.s,
1332
avp_val.s.len, avp_val.s.s);
1334
LM_DBG("%.*s:%d\n", avp_s->name.s.len, avp_s->name.s.s,
1341
int _dbg_log_assign_action_pvar(struct sip_msg* msg, struct lvalue* lv)
1344
pv_spec_t* pvar = lv->lv.pvs;
1345
str def_name = {"unknown", 7};
1346
str *name = _dbg_pvcache_lookup(pvar);
1350
if(pv_get_spec_value(msg, pvar, &value)!=0)
1352
LM_ERR("can't get value\n");
1356
if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE)){
1357
LM_DBG("%.*s: $null\n", name->len, name->s);
1358
}else if(value.flags&(PV_VAL_INT)){
1359
LM_DBG("%.*s:%d\n", name->len, name->s, value.ri);
1360
}else if(value.flags&(PV_VAL_STR)){
1361
LM_DBG("%.*s:\"%.*s\"\n", name->len, name->s, value.rs.len, value.rs.s);
1366
int dbg_log_assign(struct sip_msg* msg, struct lvalue *lv)
1370
LM_ERR("left value is NULL\n");
1375
return _dbg_log_assign_action_avp(msg, lv);
1378
return _dbg_log_assign_action_pvar(msg, lv);
1386
void dbg_enable_log_assign(void)
1388
if(_dbg_pvcache==NULL)
1390
set_log_assign_action_cb(dbg_log_assign);
1393
int dbg_level_mode_fixup(void *temp_handle,
1394
str *group_name, str *var_name, void **value){
1395
if(_dbg_mod_table==NULL)
1397
LM_ERR("mod_hash_size must be set on start\n");
1403
int _dbg_get_array_avp_vals(struct sip_msg *msg,
1404
pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobj,
1407
struct usr_avp *avp;
1408
unsigned short name_type;
1411
struct search_state state;
1413
memset(&state, 0, sizeof(struct search_state));
1415
if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0)
1417
LM_ERR("invalid name\n");
1420
*jobj = srjson_CreateArray(jdoc);
1423
LM_ERR("cannot create json object\n");
1426
if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0)
1432
if(avp->flags & AVP_VAL_STR)
1434
jobjt = srjson_CreateStr(jdoc, avp_value.s.s, avp_value.s.len);
1437
LM_ERR("cannot create json object\n");
1441
jobjt = srjson_CreateNumber(jdoc, avp_value.n);
1444
LM_ERR("cannot create json object\n");
1448
srjson_AddItemToArray(jdoc, *jobj, jobjt);
1449
} while ((avp=search_next_avp(&state, &avp_value))!=0);
1451
item_name->s = avp_name.s.s;
1452
item_name->len = avp_name.s.len;
1455
#define DBG_XAVP_DUMP_SIZE 32
1456
static str* _dbg_xavp_dump[DBG_XAVP_DUMP_SIZE];
1457
int _dbg_xavp_dump_lookup(pv_param_t *param)
1460
pv_xavp_name_t *xname;
1465
xname = (pv_xavp_name_t*)param->pvn.u.dname;
1467
while(_dbg_xavp_dump[i]!=NULL&&i<DBG_XAVP_DUMP_SIZE)
1469
if(_dbg_xavp_dump[i]->len==xname->name.len)
1471
if(strncmp(_dbg_xavp_dump[i]->s, xname->name.s, xname->name.len)==0)
1472
return 1; /* already dump before */
1476
if(i==DBG_XAVP_DUMP_SIZE)
1478
LM_WARN("full _dbg_xavp_dump cache array\n");
1479
return 0; /* end cache names */
1481
_dbg_xavp_dump[i] = &xname->name;
1485
void _dbg_get_obj_xavp_val(sr_xavp_t *avp, srjson_doc_t *jdoc, srjson_t **jobj)
1487
static char _pv_xavp_buf[128];
1490
switch(avp->val.type) {
1492
*jobj = srjson_CreateNull(jdoc);
1495
*jobj = srjson_CreateNumber(jdoc, avp->val.v.i);
1498
*jobj = srjson_CreateStr(jdoc, avp->val.v.s.s, avp->val.v.s.len);
1501
result = snprintf(_pv_xavp_buf, 128, "%lu", (long unsigned)avp->val.v.t);
1504
result = snprintf(_pv_xavp_buf, 128, "%ld", (long unsigned)avp->val.v.l);
1506
case SR_XTYPE_LLONG:
1507
result = snprintf(_pv_xavp_buf, 128, "%lld", avp->val.v.ll);
1510
result = snprintf(_pv_xavp_buf, 128, "<<xavp:%p>>", avp->val.v.xavp);
1513
result = snprintf(_pv_xavp_buf, 128, "<<data:%p>>", avp->val.v.data);
1516
LM_WARN("unknown data type\n");
1517
*jobj = srjson_CreateNull(jdoc);
1521
LM_ERR("cannot convert to str\n");
1522
*jobj = srjson_CreateNull(jdoc);
1524
else if(*jobj==NULL)
1526
*jobj = srjson_CreateStr(jdoc, _pv_xavp_buf, 128);
1530
int _dbg_get_obj_avp_vals(str name, sr_xavp_t *xavp, srjson_doc_t *jdoc, srjson_t **jobj)
1532
sr_xavp_t *avp = NULL;
1533
srjson_t *jobjt = NULL;
1535
*jobj = srjson_CreateArray(jdoc);
1538
LM_ERR("cannot create json object\n");
1542
while(avp!=NULL&&!STR_EQ(avp->name,name))
1548
_dbg_get_obj_xavp_val(avp, jdoc, &jobjt);
1549
srjson_AddItemToArray(jdoc, *jobj, jobjt);
1551
avp = xavp_get_next(avp);
1557
int _dbg_get_obj_xavp_vals(struct sip_msg *msg,
1558
pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobjr,
1561
pv_xavp_name_t *xname = (pv_xavp_name_t*)param->pvn.u.dname;
1562
sr_xavp_t *xavp = NULL;
1563
sr_xavp_t *avp = NULL;
1564
srjson_t *jobj = NULL;
1565
srjson_t *jobjt = NULL;
1566
struct str_list *keys;
1569
*jobjr = srjson_CreateArray(jdoc);
1572
LM_ERR("cannot create json object\n");
1576
item_name->s = xname->name.s;
1577
item_name->len = xname->name.len;
1578
xavp = xavp_get_by_index(&xname->name, 0, NULL);
1581
return 0; /* empty */
1586
if(xavp->val.type==SR_XTYPE_XAVP)
1588
avp = xavp->val.v.xavp;
1589
jobj = srjson_CreateObject(jdoc);
1592
LM_ERR("cannot create json object\n");
1595
keys = xavp_get_list_key_names(xavp);
1600
_dbg_get_obj_avp_vals(keys->s, avp, jdoc, &jobjt);
1601
srjson_AddStrItemToObject(jdoc, jobj, keys->s.s,
1602
keys->s.len, jobjt);
1612
srjson_AddItemToArray(jdoc, *jobjr, jobj);
1615
}while((xavp = xavp_get_next(xavp))!=0);
1620
int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level)
1624
pv_cache_t **_pv_cache = pv_cache_get_table();
1625
pv_cache_t *el = NULL;
1627
srjson_t *jobj = NULL;
1628
char *output = NULL;
1629
str item_name = STR_NULL;
1630
static char iname[128];
1635
LM_ERR("cannot access pv_cache\n");
1639
memset(_dbg_xavp_dump, 0, sizeof(str*)*DBG_XAVP_DUMP_SIZE);
1640
srjson_InitDoc(&jdoc, NULL);
1643
jdoc.root = srjson_CreateObject(&jdoc);
1646
LM_ERR("cannot create json root\n");
1650
for(i=0;i<PV_CACHE_SIZE;i++)
1655
if(!(el->spec.type==PVT_AVP||
1656
el->spec.type==PVT_SCRIPTVAR||
1657
el->spec.type==PVT_XAVP||
1658
el->spec.type==PVT_OTHER)||
1659
!((el->spec.type==PVT_AVP&&mask&DBG_DP_AVP)||
1660
(el->spec.type==PVT_XAVP&&mask&DBG_DP_XAVP)||
1661
(el->spec.type==PVT_SCRIPTVAR&&mask&DBG_DP_SCRIPTVAR)||
1662
(el->spec.type==PVT_OTHER&&mask&DBG_DP_OTHER))||
1663
(el->spec.trans!=NULL))
1672
if(el->spec.type==PVT_AVP)
1674
if(el->spec.pvp.pvi.type==PV_IDX_ALL||
1675
(el->spec.pvp.pvi.type==PV_IDX_INT&&el->spec.pvp.pvi.u.ival!=0))
1682
if(_dbg_get_array_avp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
1684
LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
1688
if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
1693
snprintf(iname, 128, "$avp(%.*s)", item_name.len, item_name.s);
1696
else if(el->spec.type==PVT_XAVP)
1698
if(_dbg_xavp_dump_lookup(&el->spec.pvp)!=0)
1703
if(_dbg_get_obj_xavp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
1705
LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
1709
if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
1714
snprintf(iname, 128, "$xavp(%.*s)", item_name.len, item_name.s);
1718
if(pv_get_spec_value(msg, &el->spec, &value)!=0)
1720
LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
1724
if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE))
1726
if(mask&DBG_DP_NULL)
1728
jobj = srjson_CreateNull(&jdoc);
1735
}else if(value.flags&(PV_VAL_INT)){
1736
jobj = srjson_CreateNumber(&jdoc, value.ri);
1737
}else if(value.flags&(PV_VAL_STR)){
1738
jobj = srjson_CreateStr(&jdoc, value.rs.s, value.rs.len);
1740
LM_WARN("el->pvname[%.*s] value[%d] unhandled\n", el->pvname.len, el->pvname.s,
1747
LM_ERR("el->pvname[%.*s] empty json object\n", el->pvname.len,
1751
snprintf(iname, 128, "%.*s", el->pvname.len, el->pvname.s);
1755
srjson_AddItemToObject(&jdoc, jdoc.root, iname, jobj);
1760
output = srjson_PrintUnformatted(&jdoc, jdoc.root);
1763
LM_ERR("cannot print json doc\n");
1766
LOG(level, "%s\n", output);
1770
if(output!=NULL) jdoc.free_fn(output);
1771
srjson_DestroyDoc(&jdoc);