~ubuntu-branches/debian/sid/kamailio/sid

« back to all changes in this revision

Viewing changes to modules/debugger/debugger_api.c

  • Committer: Package Import Robot
  • Author(s): Victor Seva
  • Date: 2014-01-06 11:47:13 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20140106114713-t8xidp4arzrnyeya
Tags: 4.1.1-1
* New upstream release
* debian/patches:
  - add upstream fixes
* Added tls outbound websocket autheph dnssec modules
  - openssl exception added to their license
* removing sparc and ia64 from supported archs
  for mono module (Closes: #728915)

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "../../rpc_lookup.h"
36
36
#include "../../route_struct.h"
37
37
#include "../../mem/shm_mem.h"
38
 
                       
 
38
#include "../../locking.h"
 
39
#include "../../lvalue.h"
 
40
#include "../../hashes.h"
 
41
#include "../../lib/srutils/srjson.h"
 
42
#include "../../xavp.h"
 
43
#include "../pv/pv_xavp.h"
 
44
 
39
45
#include "debugger_act.h"
40
46
#include "debugger_api.h"
 
47
#include "debugger_config.h"
41
48
 
42
49
#define DBG_CMD_SIZE 256
43
50
 
145
152
/**
146
153
 *
147
154
 */
 
155
int _dbg_cfgpkgcheck = 0;
 
156
 
 
157
/**
 
158
 *
 
159
 */
148
160
int _dbg_breakpoint = 0;
149
161
 
150
162
/**
173
185
int _dbg_step_loops = 200;
174
186
 
175
187
/**
 
188
 * disabled by default
 
189
 */
 
190
int _dbg_reset_msgid = 0;
 
191
 
 
192
/**
176
193
 *
177
194
 */
178
195
typedef struct _dbg_cmd
192
209
        unsigned int state;
193
210
        dbg_cmd_t in;
194
211
        dbg_cmd_t out;
 
212
        gen_lock_t *lock;
 
213
        unsigned int reset_msgid; /* flag to reset the id */
 
214
        unsigned int msgid_base; /* real id since the reset */
195
215
} dbg_pid_t;
196
216
 
197
217
/**
220
240
 */
221
241
static dbg_bp_t *_dbg_bp_list = NULL;
222
242
 
 
243
/* defined later */
 
244
int dbg_get_pid_index(unsigned int pid);
 
245
 
 
246
/*!
 
247
 * \brief Callback function that checks if reset_msgid is set
 
248
 *  and modifies msg->id if necessary.
 
249
 * \param msg SIP message
 
250
 * \param flags unused
 
251
 * \param bar unused
 
252
 * \return 1 on success, -1 on failure
 
253
 */
 
254
int dbg_msgid_filter(struct sip_msg *msg, unsigned int flags, void *bar)
 
255
{
 
256
        unsigned int process_no = my_pid();
 
257
        int indx = dbg_get_pid_index(process_no);
 
258
        unsigned int msgid_base = 0;
 
259
        unsigned int msgid_new = 0;
 
260
        if(indx<0) return -1;
 
261
        LM_DBG("process_no:%d indx:%d\n", process_no, indx);
 
262
        lock_get(_dbg_pid_list[indx].lock);
 
263
        if(_dbg_pid_list[indx].reset_msgid==1)
 
264
        {
 
265
                LM_DBG("reset_msgid! msgid_base:%d\n", msg->id);
 
266
                _dbg_pid_list[indx].reset_msgid = 0;
 
267
                _dbg_pid_list[indx].msgid_base = msg->id - 1;
 
268
        }
 
269
        msgid_base = _dbg_pid_list[indx].msgid_base;
 
270
        lock_release(_dbg_pid_list[indx].lock);
 
271
        msgid_new = msg->id - msgid_base;
 
272
        LM_DBG("msg->id:%d msgid_base:%d -> %d\n", msg->id, msgid_base, msgid_new);
 
273
        if(msgid_new>0)
 
274
        {
 
275
                msg->id = msgid_new;
 
276
                return 1;
 
277
        }
 
278
        else
 
279
        {
 
280
                LM_WARN("msgid_new<=0??\n");
 
281
                return -1;
 
282
        }
 
283
}
 
284
 
223
285
/**
224
286
 * callback executed for each cfg action
225
287
 */
245
307
 
246
308
        an = dbg_get_action_name(a);
247
309
 
 
310
        if(_dbg_cfgpkgcheck!=0)
 
311
        {
 
312
#ifdef q_malloc_h
 
313
                LM_DBG("checking pkg memory before action %.*s (line %d)\n",
 
314
                                an->len, an->s, a->cline);
 
315
                qm_check(mem_block);
 
316
#else
 
317
                LM_DBG("cfg pkg check is disbled due to missing qm handler\n");
 
318
#endif
 
319
        }
 
320
 
248
321
        if(_dbg_pid_list[process_no].set&DBG_CFGTRACE_ON)
249
322
        {
250
323
                if(is_printable(_dbg_cfgtrace_level))
490
563
                _dbg_pid_list[process_no].set |= DBG_ABKPOINT_ON;
491
564
        if(_dbg_cfgtrace==1)
492
565
                _dbg_pid_list[process_no].set |= DBG_CFGTRACE_ON;
 
566
        if(_dbg_reset_msgid==1)
 
567
        {
 
568
                LM_DBG("[%d] create locks\n", process_no);
 
569
                _dbg_pid_list[process_no].lock = lock_alloc();
 
570
                if(_dbg_pid_list[process_no].lock==NULL)
 
571
                {
 
572
                        LM_ERR("cannot allocate the lock\n");
 
573
                        return -1;
 
574
                }
 
575
                if(lock_init(_dbg_pid_list[process_no].lock)==NULL)
 
576
                {
 
577
                        LM_ERR("cannot init the lock\n");
 
578
                        lock_dealloc(_dbg_pid_list[process_no].lock);
 
579
                        return -1;
 
580
                }
 
581
        }
493
582
        return 0;
494
583
}
495
584
 
843
932
        rpc->add(ctx, "s", "200 ok");
844
933
}
845
934
 
 
935
/**
 
936
 *
 
937
 */
 
938
static const char* dbg_rpc_mod_level_doc[2] = {
 
939
        "Specify module log level",
 
940
        0
 
941
};
 
942
 
 
943
static void dbg_rpc_mod_level(rpc_t* rpc, void* ctx){
 
944
        int l;
 
945
        str value = {0,0};
 
946
 
 
947
        if (rpc->scan(ctx, "Sd", &value, &l) < 1)
 
948
        {
 
949
                rpc->fault(ctx, 500, "invalid parameters");
 
950
                return;
 
951
        }
 
952
 
 
953
        if(dbg_set_mod_debug_level(value.s, value.len, &l)<0)
 
954
        {
 
955
                rpc->fault(ctx, 500, "cannot store parameter\n");
 
956
                return;
 
957
        }
 
958
        rpc->add(ctx, "s", "200 ok");
 
959
}
 
960
 
 
961
/**
 
962
 *
 
963
 */
 
964
static const char* dbg_rpc_reset_msgid_doc[2] = {
 
965
        "Reset msgid on all process",
 
966
        0
 
967
};
 
968
 
 
969
static void dbg_rpc_reset_msgid(rpc_t* rpc, void* ctx){
 
970
        int i;
 
971
        if (_dbg_reset_msgid==0)
 
972
        {
 
973
                rpc->fault(ctx, 500, "reset_msgid is 0. Set it to 1 to enable.");
 
974
                return;
 
975
        }
 
976
        if(_dbg_pid_list==NULL)
 
977
        {
 
978
                rpc->fault(ctx, 500, "_dbg_pid_list is NULL");
 
979
                return;
 
980
        }
 
981
        LM_DBG("set reset_msgid\n");
 
982
        for(i=0; i<_dbg_pid_no; i++)
 
983
        {
 
984
                if (_dbg_pid_list[i].lock!=NULL)
 
985
                {
 
986
                        lock_get(_dbg_pid_list[i].lock);
 
987
                        _dbg_pid_list[i].reset_msgid = 1;
 
988
                        lock_release(_dbg_pid_list[i].lock);
 
989
                }
 
990
        }
 
991
        rpc->add(ctx, "s", "200 ok");
 
992
}
846
993
 
847
994
/**
848
995
 *
849
996
 */
850
997
rpc_export_t dbg_rpc[] = {
851
 
        {"dbg.bp",    dbg_rpc_bp,        dbg_rpc_bp_doc,       0},
852
 
        {"dbg.ls",    dbg_rpc_list,      dbg_rpc_list_doc,     0},
853
 
        {"dbg.trace", dbg_rpc_trace,     dbg_rpc_trace_doc,    0},
 
998
        {"dbg.bp",        dbg_rpc_bp,        dbg_rpc_bp_doc,        0},
 
999
        {"dbg.ls",        dbg_rpc_list,      dbg_rpc_list_doc,      0},
 
1000
        {"dbg.trace",     dbg_rpc_trace,     dbg_rpc_trace_doc,     0},
 
1001
        {"dbg.mod_level", dbg_rpc_mod_level, dbg_rpc_mod_level_doc, 0},
 
1002
        {"dbg.reset_msgid", dbg_rpc_reset_msgid, dbg_rpc_reset_msgid_doc, 0},
854
1003
        {0, 0, 0, 0}
855
1004
};
856
1005
 
867
1016
        return 0;
868
1017
}
869
1018
 
 
1019
typedef struct _dbg_mod_level {
 
1020
        str name;
 
1021
        unsigned int hashid;
 
1022
        int level;
 
1023
        struct _dbg_mod_level *next;
 
1024
} dbg_mod_level_t;
 
1025
 
 
1026
typedef struct _dbg_mod_slot
 
1027
{
 
1028
        dbg_mod_level_t *first;
 
1029
        gen_lock_t lock;
 
1030
} dbg_mod_slot_t;
 
1031
 
 
1032
static dbg_mod_slot_t *_dbg_mod_table = NULL;
 
1033
static unsigned int _dbg_mod_table_size = 0;
 
1034
 
 
1035
/**
 
1036
 *
 
1037
 */
 
1038
int dbg_init_mod_levels(int dbg_mod_hash_size)
 
1039
{
 
1040
        int i;
 
1041
        if(dbg_mod_hash_size<=0)
 
1042
                return 0;
 
1043
        if(_dbg_mod_table!=NULL)
 
1044
                return 0;
 
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)
 
1048
        {
 
1049
                LM_ERR("no more shm.\n");
 
1050
                return -1;
 
1051
        }
 
1052
        memset(_dbg_mod_table, 0, _dbg_mod_table_size*sizeof(dbg_mod_slot_t));
 
1053
 
 
1054
        for(i=0; i<_dbg_mod_table_size; i++)
 
1055
        {
 
1056
                if(lock_init(&_dbg_mod_table[i].lock)==0)
 
1057
                {
 
1058
                        LM_ERR("cannot initalize lock[%d]\n", i);
 
1059
                        i--;
 
1060
                        while(i>=0)
 
1061
                        {
 
1062
                                lock_destroy(&_dbg_mod_table[i].lock);
 
1063
                                i--;
 
1064
                        }
 
1065
                        shm_free(_dbg_mod_table);
 
1066
                        _dbg_mod_table = NULL;
 
1067
                        return -1;
 
1068
                }
 
1069
        }
 
1070
        return 0;
 
1071
}
 
1072
 
 
1073
/*
 
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
 
1078
 */
 
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)
 
1082
{
 
1083
        char *p, *end;
 
1084
        register unsigned v;
 
1085
        register unsigned h;
 
1086
 
 
1087
        h=0;
 
1088
 
 
1089
        end=s1+s1len;
 
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]);
 
1093
                dbg_ch_h_inc;
 
1094
        }
 
1095
        v=0;
 
1096
        for (; p<end ; p++){ v<<=8; v+=dbg_ch_icase(*p);}
 
1097
        dbg_ch_h_inc;
 
1098
 
 
1099
        h=((h)+(h>>11))+((h>>13)+(h>>23));
 
1100
        return h;
 
1101
}
 
1102
 
 
1103
int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel)
 
1104
{
 
1105
        unsigned int idx;
 
1106
        unsigned int hid;
 
1107
        dbg_mod_level_t *it;
 
1108
        dbg_mod_level_t *itp;
 
1109
        dbg_mod_level_t *itn;
 
1110
 
 
1111
        if(_dbg_mod_table==NULL)
 
1112
                return -1;
 
1113
 
 
1114
        hid = dbg_compute_hash(mname, mnlen);
 
1115
        idx = hid&(_dbg_mod_table_size-1);
 
1116
 
 
1117
        lock_get(&_dbg_mod_table[idx].lock);
 
1118
        it = _dbg_mod_table[idx].first;
 
1119
        itp = NULL;
 
1120
        while(it!=NULL && it->hashid < hid) {
 
1121
                itp = it;
 
1122
                it = it->next;
 
1123
        }
 
1124
        while(it!=NULL && it->hashid==hid)
 
1125
        {
 
1126
                if(mnlen==it->name.len
 
1127
                                && strncmp(mname, it->name.s, mnlen)==0)
 
1128
                {
 
1129
                        /* found */
 
1130
                        if(mlevel==NULL) {
 
1131
                                /* remove */
 
1132
                                if(itp!=NULL) {
 
1133
                                        itp->next = it->next;
 
1134
                                } else {
 
1135
                                        _dbg_mod_table[idx].first = it->next;
 
1136
                                }
 
1137
                                shm_free(it);
 
1138
                        } else {
 
1139
                                /* set */
 
1140
                                it->level = *mlevel;
 
1141
                        }
 
1142
                        lock_release(&_dbg_mod_table[idx].lock);
 
1143
                        return 0;
 
1144
                }
 
1145
                itp = it;
 
1146
                it = it->next;
 
1147
        }
 
1148
        /* not found - add */
 
1149
        if(mlevel==NULL) {
 
1150
                lock_release(&_dbg_mod_table[idx].lock);
 
1151
                return 0;
 
1152
        }
 
1153
        itn = (dbg_mod_level_t*)shm_malloc(sizeof(dbg_mod_level_t) + (mnlen+1)*sizeof(char));
 
1154
        if(itn==NULL) {
 
1155
                LM_ERR("no more shm\n");
 
1156
                lock_release(&_dbg_mod_table[idx].lock);
 
1157
                return -1;
 
1158
        }
 
1159
        memset(itn, 0, sizeof(dbg_mod_level_t) + (mnlen+1)*sizeof(char));
 
1160
        itn->level    = *mlevel;
 
1161
        itn->hashid   = hid;
 
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';
 
1166
 
 
1167
        if(itp==NULL) {
 
1168
                itn->next = _dbg_mod_table[idx].first;
 
1169
                _dbg_mod_table[idx].first = itn;
 
1170
        } else {
 
1171
                itn->next = itp->next;
 
1172
                itp->next = itn;
 
1173
        }
 
1174
        lock_release(&_dbg_mod_table[idx].lock);
 
1175
        return 0;
 
1176
 
 
1177
}
 
1178
 
 
1179
static int _dbg_get_mod_debug_level = 0;
 
1180
int dbg_get_mod_debug_level(char *mname, int mnlen, int *mlevel)
 
1181
{
 
1182
        unsigned int idx;
 
1183
        unsigned int hid;
 
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)
 
1189
                return -1;
 
1190
 
 
1191
        if(cfg_get(dbg, dbg_cfg, mod_level_mode)==0)
 
1192
                return -1;
 
1193
 
 
1194
        if(_dbg_get_mod_debug_level!=0)
 
1195
                return -1;
 
1196
        _dbg_get_mod_debug_level = 1;
 
1197
 
 
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)
 
1203
                it = it->next;
 
1204
        while(it!=NULL && it->hashid == hid)
 
1205
        {
 
1206
                if(mnlen==it->name.len
 
1207
                                && strncmp(mname, it->name.s, mnlen)==0)
 
1208
                {
 
1209
                        /* found */
 
1210
                        *mlevel = it->level;
 
1211
                        lock_release(&_dbg_mod_table[idx].lock);
 
1212
                        _dbg_get_mod_debug_level = 0;
 
1213
                        return 0;
 
1214
                }
 
1215
                it = it->next;
 
1216
        }
 
1217
        lock_release(&_dbg_mod_table[idx].lock);
 
1218
        _dbg_get_mod_debug_level = 0;
 
1219
        return -1;
 
1220
}
 
1221
 
 
1222
/**
 
1223
 *
 
1224
 */
 
1225
void dbg_enable_mod_levels(void)
 
1226
{
 
1227
        if(_dbg_mod_table==NULL)
 
1228
                return;
 
1229
        set_module_debug_level_cb(dbg_get_mod_debug_level);
 
1230
}
 
1231
 
 
1232
#define DBG_PVCACHE_SIZE 32
 
1233
 
 
1234
typedef struct _dbg_pvcache {
 
1235
        pv_spec_t *spec;
 
1236
        str *pvname;
 
1237
        struct _dbg_pvcache *next;
 
1238
} dbg_pvcache_t;
 
1239
 
 
1240
static dbg_pvcache_t **_dbg_pvcache = NULL;
 
1241
 
 
1242
int dbg_init_pvcache()
 
1243
{
 
1244
        _dbg_pvcache = (dbg_pvcache_t**)pkg_malloc(sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
 
1245
        if(_dbg_pvcache==NULL)
 
1246
        {
 
1247
                LM_ERR("no more memory.\n");
 
1248
                return -1;
 
1249
        }
 
1250
        memset(_dbg_pvcache, 0, sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
 
1251
        return 0;
 
1252
}
 
1253
 
 
1254
int dbg_assign_add(str *name, pv_spec_t *spec)
 
1255
{
 
1256
        dbg_pvcache_t *pvn, *last, *next;
 
1257
        unsigned int pvid;
 
1258
 
 
1259
        if(name==NULL||spec==NULL)
 
1260
                return -1;
 
1261
 
 
1262
        if(_dbg_pvcache==NULL)
 
1263
                return -1;
 
1264
 
 
1265
        pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
 
1266
        pvn = (dbg_pvcache_t*)pkg_malloc(sizeof(dbg_pvcache_t));
 
1267
        if(pvn==NULL)
 
1268
        {
 
1269
                LM_ERR("no more memory\n");
 
1270
                return -1;
 
1271
        }
 
1272
        memset(pvn, 0, sizeof(dbg_pvcache_t));
 
1273
        pvn->pvname = name;
 
1274
        pvn->spec = spec;
 
1275
        next = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
 
1276
        if(next==NULL)
 
1277
        {
 
1278
                _dbg_pvcache[pvid%DBG_PVCACHE_SIZE] = pvn;
 
1279
        }
 
1280
        else
 
1281
        {
 
1282
                while(next)
 
1283
                {
 
1284
                        last = next;
 
1285
                        next = next->next;
 
1286
                }
 
1287
                last->next = pvn;
 
1288
        }
 
1289
        return 0;
 
1290
}
 
1291
 
 
1292
str *_dbg_pvcache_lookup(pv_spec_t *spec)
 
1293
{
 
1294
        dbg_pvcache_t *pvi;
 
1295
        unsigned int pvid;
 
1296
        str *name = NULL;
 
1297
 
 
1298
        if(spec==NULL)
 
1299
                return NULL;
 
1300
 
 
1301
        if(_dbg_pvcache==NULL)
 
1302
                return NULL;
 
1303
 
 
1304
        pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
 
1305
        pvi = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
 
1306
        while(pvi)
 
1307
        {
 
1308
                if(pvi->spec==spec) {
 
1309
                        return pvi->pvname;
 
1310
                }
 
1311
                pvi = pvi->next;
 
1312
        }
 
1313
        name = pv_cache_get_name(spec);
 
1314
        if(name!=NULL)
 
1315
        {
 
1316
                /*LM_DBG("Add name[%.*s] to pvcache\n", name->len, name->s);*/
 
1317
                dbg_assign_add(name, spec);
 
1318
        }
 
1319
        return name;
 
1320
}
 
1321
 
 
1322
int _dbg_log_assign_action_avp(struct sip_msg* msg, struct lvalue* lv)
 
1323
{
 
1324
        int_str avp_val;
 
1325
        avp_t* avp;
 
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);
 
1329
        if (likely(avp)){
 
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);
 
1333
                }else{
 
1334
                        LM_DBG("%.*s:%d\n", avp_s->name.s.len, avp_s->name.s.s,
 
1335
                                avp_val.n);
 
1336
                }
 
1337
        }
 
1338
        return 0;
 
1339
}
 
1340
 
 
1341
int _dbg_log_assign_action_pvar(struct sip_msg* msg, struct lvalue* lv)
 
1342
{
 
1343
        pv_value_t value;
 
1344
        pv_spec_t* pvar = lv->lv.pvs;
 
1345
        str def_name = {"unknown", 7};
 
1346
        str *name = _dbg_pvcache_lookup(pvar);
 
1347
 
 
1348
        if(name==NULL)
 
1349
                name = &def_name;
 
1350
        if(pv_get_spec_value(msg, pvar, &value)!=0)
 
1351
        {
 
1352
                LM_ERR("can't get value\n");
 
1353
                return -1;
 
1354
        }
 
1355
 
 
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);
 
1362
        }
 
1363
        return 0;
 
1364
}
 
1365
 
 
1366
int dbg_log_assign(struct sip_msg* msg, struct lvalue *lv)
 
1367
{
 
1368
        if(lv==NULL)
 
1369
        {
 
1370
                LM_ERR("left value is NULL\n");
 
1371
                return -1;
 
1372
        }
 
1373
        switch(lv->type){
 
1374
                case LV_AVP:
 
1375
                        return _dbg_log_assign_action_avp(msg, lv);
 
1376
                        break;
 
1377
                case LV_PVAR:
 
1378
                        return _dbg_log_assign_action_pvar(msg, lv);
 
1379
                        break;
 
1380
                case LV_NONE:
 
1381
                        break;
 
1382
        }
 
1383
        return 0;
 
1384
}
 
1385
 
 
1386
void dbg_enable_log_assign(void)
 
1387
{
 
1388
        if(_dbg_pvcache==NULL)
 
1389
                return;
 
1390
        set_log_assign_action_cb(dbg_log_assign);
 
1391
}
 
1392
 
 
1393
int dbg_level_mode_fixup(void *temp_handle,
 
1394
        str *group_name, str *var_name, void **value){
 
1395
        if(_dbg_mod_table==NULL)
 
1396
        {
 
1397
                LM_ERR("mod_hash_size must be set on start\n");
 
1398
                return -1;
 
1399
        }
 
1400
        return 0;
 
1401
}
 
1402
 
 
1403
int _dbg_get_array_avp_vals(struct sip_msg *msg,
 
1404
                pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobj,
 
1405
                str *item_name)
 
1406
{
 
1407
        struct usr_avp *avp;
 
1408
        unsigned short name_type;
 
1409
        int_str avp_name;
 
1410
        int_str avp_value;
 
1411
        struct search_state state;
 
1412
        srjson_t *jobjt;
 
1413
        memset(&state, 0, sizeof(struct search_state));
 
1414
 
 
1415
        if(pv_get_avp_name(msg, param, &avp_name, &name_type)!=0)
 
1416
        {
 
1417
                LM_ERR("invalid name\n");
 
1418
                return -1;
 
1419
        }
 
1420
        *jobj = srjson_CreateArray(jdoc);
 
1421
        if(*jobj==NULL)
 
1422
        {
 
1423
                LM_ERR("cannot create json object\n");
 
1424
                return -1;
 
1425
        }
 
1426
        if ((avp=search_first_avp(name_type, avp_name, &avp_value, &state))==0)
 
1427
        {
 
1428
                goto ok;
 
1429
        }
 
1430
        do
 
1431
        {
 
1432
                if(avp->flags & AVP_VAL_STR)
 
1433
                {
 
1434
                        jobjt = srjson_CreateStr(jdoc, avp_value.s.s, avp_value.s.len);
 
1435
                        if(jobjt==NULL)
 
1436
                        {
 
1437
                                LM_ERR("cannot create json object\n");
 
1438
                                return -1;
 
1439
                        }
 
1440
                } else {
 
1441
                        jobjt = srjson_CreateNumber(jdoc, avp_value.n);
 
1442
                        if(jobjt==NULL)
 
1443
                        {
 
1444
                                LM_ERR("cannot create json object\n");
 
1445
                                return -1;
 
1446
                        }
 
1447
                }
 
1448
                srjson_AddItemToArray(jdoc, *jobj, jobjt);
 
1449
        } while ((avp=search_next_avp(&state, &avp_value))!=0);
 
1450
ok:
 
1451
        item_name->s = avp_name.s.s;
 
1452
        item_name->len = avp_name.s.len;
 
1453
        return 0;
 
1454
}
 
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)
 
1458
{
 
1459
        unsigned int i = 0;
 
1460
        pv_xavp_name_t *xname;
 
1461
 
 
1462
        if(param==NULL)
 
1463
                return -1;
 
1464
 
 
1465
        xname = (pv_xavp_name_t*)param->pvn.u.dname;
 
1466
 
 
1467
        while(_dbg_xavp_dump[i]!=NULL&&i<DBG_XAVP_DUMP_SIZE)
 
1468
        {
 
1469
                if(_dbg_xavp_dump[i]->len==xname->name.len)
 
1470
                {
 
1471
                        if(strncmp(_dbg_xavp_dump[i]->s, xname->name.s, xname->name.len)==0)
 
1472
                                return 1; /* already dump before */
 
1473
                }
 
1474
                i++;
 
1475
        }
 
1476
        if(i==DBG_XAVP_DUMP_SIZE)
 
1477
        {
 
1478
                LM_WARN("full _dbg_xavp_dump cache array\n");
 
1479
                return 0; /* end cache names */
 
1480
        }
 
1481
        _dbg_xavp_dump[i] = &xname->name;
 
1482
        return 0;
 
1483
}
 
1484
 
 
1485
void _dbg_get_obj_xavp_val(sr_xavp_t *avp, srjson_doc_t *jdoc, srjson_t **jobj)
 
1486
{
 
1487
        static char _pv_xavp_buf[128];
 
1488
        int result = 0;
 
1489
 
 
1490
        switch(avp->val.type) {
 
1491
                case SR_XTYPE_NULL:
 
1492
                        *jobj = srjson_CreateNull(jdoc);
 
1493
                break;
 
1494
                case SR_XTYPE_INT:
 
1495
                        *jobj = srjson_CreateNumber(jdoc, avp->val.v.i);
 
1496
                break;
 
1497
                case SR_XTYPE_STR:
 
1498
                        *jobj = srjson_CreateStr(jdoc, avp->val.v.s.s, avp->val.v.s.len);
 
1499
                break;
 
1500
                case SR_XTYPE_TIME:
 
1501
                        result = snprintf(_pv_xavp_buf, 128, "%lu", (long unsigned)avp->val.v.t);
 
1502
                break;
 
1503
                case SR_XTYPE_LONG:
 
1504
                        result = snprintf(_pv_xavp_buf, 128, "%ld", (long unsigned)avp->val.v.l);
 
1505
                break;
 
1506
                case SR_XTYPE_LLONG:
 
1507
                        result = snprintf(_pv_xavp_buf, 128, "%lld", avp->val.v.ll);
 
1508
                break;
 
1509
                case SR_XTYPE_XAVP:
 
1510
                        result = snprintf(_pv_xavp_buf, 128, "<<xavp:%p>>", avp->val.v.xavp);
 
1511
                break;
 
1512
                case SR_XTYPE_DATA:
 
1513
                        result = snprintf(_pv_xavp_buf, 128, "<<data:%p>>", avp->val.v.data);
 
1514
                break;
 
1515
                default:
 
1516
                        LM_WARN("unknown data type\n");
 
1517
                        *jobj = srjson_CreateNull(jdoc);
 
1518
        }
 
1519
        if(result<0)
 
1520
        {
 
1521
                LM_ERR("cannot convert to str\n");
 
1522
                *jobj = srjson_CreateNull(jdoc);
 
1523
        }
 
1524
        else if(*jobj==NULL)
 
1525
        {
 
1526
                *jobj = srjson_CreateStr(jdoc, _pv_xavp_buf, 128);
 
1527
        }
 
1528
}
 
1529
 
 
1530
int _dbg_get_obj_avp_vals(str name, sr_xavp_t *xavp, srjson_doc_t *jdoc, srjson_t **jobj)
 
1531
{
 
1532
        sr_xavp_t *avp = NULL;
 
1533
        srjson_t *jobjt = NULL;
 
1534
 
 
1535
        *jobj = srjson_CreateArray(jdoc);
 
1536
        if(*jobj==NULL)
 
1537
        {
 
1538
                LM_ERR("cannot create json object\n");
 
1539
                return -1;
 
1540
        }
 
1541
        avp = xavp;
 
1542
        while(avp!=NULL&&!STR_EQ(avp->name,name))
 
1543
        {
 
1544
                avp = avp->next;
 
1545
        }
 
1546
        while(avp!=NULL)
 
1547
        {
 
1548
                _dbg_get_obj_xavp_val(avp, jdoc, &jobjt);
 
1549
                srjson_AddItemToArray(jdoc, *jobj, jobjt);
 
1550
                jobjt = NULL;
 
1551
                avp = xavp_get_next(avp);
 
1552
        }
 
1553
 
 
1554
        return 0;
 
1555
}
 
1556
 
 
1557
int _dbg_get_obj_xavp_vals(struct sip_msg *msg,
 
1558
                pv_param_t *param, srjson_doc_t *jdoc, srjson_t **jobjr,
 
1559
                str *item_name)
 
1560
{
 
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;
 
1567
        struct str_list *k;
 
1568
 
 
1569
        *jobjr = srjson_CreateArray(jdoc);
 
1570
        if(*jobjr==NULL)
 
1571
        {
 
1572
                LM_ERR("cannot create json object\n");
 
1573
                return -1;
 
1574
        }
 
1575
 
 
1576
        item_name->s = xname->name.s;
 
1577
        item_name->len = xname->name.len;
 
1578
        xavp = xavp_get_by_index(&xname->name, 0, NULL);
 
1579
        if(xavp==NULL)
 
1580
        {
 
1581
                return 0; /* empty */
 
1582
        }
 
1583
 
 
1584
        do
 
1585
        {
 
1586
                if(xavp->val.type==SR_XTYPE_XAVP)
 
1587
                {
 
1588
                        avp = xavp->val.v.xavp;
 
1589
                        jobj = srjson_CreateObject(jdoc);
 
1590
                        if(jobj==NULL)
 
1591
                        {
 
1592
                                LM_ERR("cannot create json object\n");
 
1593
                                return -1;
 
1594
                        }
 
1595
                        keys = xavp_get_list_key_names(xavp);
 
1596
                        if(keys!=NULL)
 
1597
                        {
 
1598
                                do
 
1599
                                {
 
1600
                                        _dbg_get_obj_avp_vals(keys->s, avp, jdoc, &jobjt);
 
1601
                                        srjson_AddStrItemToObject(jdoc, jobj, keys->s.s,
 
1602
                                                keys->s.len, jobjt);
 
1603
                                        k = keys;
 
1604
                                        keys = keys->next;
 
1605
                                        pkg_free(k);
 
1606
                                        jobjt = NULL;
 
1607
                                }while(keys!=NULL);
 
1608
                        }
 
1609
                }
 
1610
                if(jobj!=NULL)
 
1611
                {
 
1612
                        srjson_AddItemToArray(jdoc, *jobjr, jobj);
 
1613
                        jobj = NULL;
 
1614
                }
 
1615
        }while((xavp = xavp_get_next(xavp))!=0);
 
1616
 
 
1617
        return 0;
 
1618
}
 
1619
 
 
1620
int dbg_dump_json(struct sip_msg* msg, unsigned int mask, int level)
 
1621
{
 
1622
        int i;
 
1623
        pv_value_t value;
 
1624
        pv_cache_t **_pv_cache = pv_cache_get_table();
 
1625
        pv_cache_t *el = NULL;
 
1626
        srjson_doc_t jdoc;
 
1627
        srjson_t *jobj = NULL;
 
1628
        char *output = NULL;
 
1629
        str item_name = STR_NULL;
 
1630
        static char iname[128];
 
1631
        int result = -1;
 
1632
 
 
1633
        if(_pv_cache==NULL)
 
1634
        {
 
1635
                LM_ERR("cannot access pv_cache\n");
 
1636
                return -1;
 
1637
        }
 
1638
 
 
1639
        memset(_dbg_xavp_dump, 0, sizeof(str*)*DBG_XAVP_DUMP_SIZE);
 
1640
        srjson_InitDoc(&jdoc, NULL);
 
1641
        if(jdoc.root==NULL)
 
1642
        {
 
1643
                jdoc.root = srjson_CreateObject(&jdoc);
 
1644
                if(jdoc.root==NULL)
 
1645
                {
 
1646
                        LM_ERR("cannot create json root\n");
 
1647
                        goto error;
 
1648
                }
 
1649
        }
 
1650
        for(i=0;i<PV_CACHE_SIZE;i++)
 
1651
        {
 
1652
                el = _pv_cache[i];
 
1653
                while(el)
 
1654
                {
 
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))
 
1664
                        {
 
1665
                                el = el->next;
 
1666
                                continue;
 
1667
                        }
 
1668
                        jobj = NULL;
 
1669
                        item_name.len = 0;
 
1670
                        item_name.s = 0;
 
1671
                        iname[0] = '\0';
 
1672
                        if(el->spec.type==PVT_AVP)
 
1673
                        {
 
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))
 
1676
                                {
 
1677
                                        el = el->next;
 
1678
                                        continue;
 
1679
                                }
 
1680
                                else
 
1681
                                {
 
1682
                                        if(_dbg_get_array_avp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
 
1683
                                        {
 
1684
                                                LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
 
1685
                                                el = el->next;
 
1686
                                                continue;
 
1687
                                        }
 
1688
                                        if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
 
1689
                                        {
 
1690
                                                el = el->next;
 
1691
                                                continue;
 
1692
                                        }
 
1693
                                        snprintf(iname, 128, "$avp(%.*s)", item_name.len, item_name.s);
 
1694
                                }
 
1695
                        }
 
1696
                        else if(el->spec.type==PVT_XAVP)
 
1697
                        {
 
1698
                                if(_dbg_xavp_dump_lookup(&el->spec.pvp)!=0)
 
1699
                                {
 
1700
                                        el = el->next;
 
1701
                                        continue;
 
1702
                                }
 
1703
                                if(_dbg_get_obj_xavp_vals(msg, &el->spec.pvp, &jdoc, &jobj, &item_name)!=0)
 
1704
                                {
 
1705
                                        LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
 
1706
                                        el = el->next;
 
1707
                                        continue;
 
1708
                                }
 
1709
                                if(srjson_GetArraySize(&jdoc, jobj)==0 && !(mask&DBG_DP_NULL))
 
1710
                                {
 
1711
                                        el = el->next;
 
1712
                                        continue;
 
1713
                                }
 
1714
                                snprintf(iname, 128, "$xavp(%.*s)", item_name.len, item_name.s);
 
1715
                        }
 
1716
                        else
 
1717
                        {
 
1718
                                if(pv_get_spec_value(msg, &el->spec, &value)!=0)
 
1719
                                {
 
1720
                                        LM_WARN("can't get value[%.*s]\n", el->pvname.len, el->pvname.s);
 
1721
                                        el = el->next;
 
1722
                                        continue;
 
1723
                                }
 
1724
                                if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE))
 
1725
                                {
 
1726
                                        if(mask&DBG_DP_NULL)
 
1727
                                        {
 
1728
                                                jobj = srjson_CreateNull(&jdoc);
 
1729
                                        }
 
1730
                                        else
 
1731
                                        {
 
1732
                                                el = el->next;
 
1733
                                                continue;
 
1734
                                        }
 
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);
 
1739
                                }else {
 
1740
                                        LM_WARN("el->pvname[%.*s] value[%d] unhandled\n", el->pvname.len, el->pvname.s,
 
1741
                                                value.flags);
 
1742
                                        el = el->next;
 
1743
                                        continue;
 
1744
                                }
 
1745
                                if(jobj==NULL)
 
1746
                                {
 
1747
                                        LM_ERR("el->pvname[%.*s] empty json object\n", el->pvname.len,
 
1748
                                                el->pvname.s);
 
1749
                                        goto error;
 
1750
                                }
 
1751
                                snprintf(iname, 128, "%.*s", el->pvname.len, el->pvname.s);
 
1752
                        }
 
1753
                        if(jobj!=NULL)
 
1754
                        {
 
1755
                                srjson_AddItemToObject(&jdoc, jdoc.root, iname, jobj);
 
1756
                        }
 
1757
                        el = el->next;
 
1758
                }
 
1759
        }
 
1760
        output = srjson_PrintUnformatted(&jdoc, jdoc.root);
 
1761
        if(output==NULL)
 
1762
        {
 
1763
                LM_ERR("cannot print json doc\n");
 
1764
                goto error;
 
1765
        }
 
1766
        LOG(level, "%s\n", output);
 
1767
        result = 0;
 
1768
 
 
1769
error:
 
1770
        if(output!=NULL) jdoc.free_fn(output);
 
1771
        srjson_DestroyDoc(&jdoc);
 
1772
 
 
1773
        return result;
 
1774
}