00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00035 #include "../../mem/shm_mem.h"
00036 #include "../../hashes.h"
00037 #include "../../trim.h"
00038 #include "../../dprint.h"
00039 #include "../../ut.h"
00040 #include "../../route.h"
00041 #include "../../modules/tm/tm_load.h"
00042 #include "dlg_hash.h"
00043 #include "dlg_var.h"
00044 #include "dlg_handlers.h"
00045 #include "dlg_profile.h"
00046
00047
00049 #define PROFILE_HASH_SIZE 16
00050
00052 extern struct tm_binds d_tmb;
00053
00055 static unsigned int current_dlg_msg_id = 0 ;
00056 static unsigned int current_dlg_msg_pid = 0 ;
00057
00059 static dlg_profile_link_t *current_pending_linkers = NULL;
00060
00062 static dlg_profile_table_t *profiles = NULL;
00063
00064
00065 static dlg_profile_table_t* new_dlg_profile( str *name,
00066 unsigned int size, unsigned int has_value);
00067
00068
00069
00077 int add_profile_definitions( char* profiles, unsigned int has_value)
00078 {
00079 char *p;
00080 char *d;
00081 str name;
00082 unsigned int i;
00083
00084 if (profiles==NULL || strlen(profiles)==0 )
00085 return 0;
00086
00087 p = profiles;
00088 do {
00089
00090 name.s = p;
00091 d = strchr( p, ';');
00092 if (d) {
00093 name.len = d-p;
00094 d++;
00095 } else {
00096 name.len = strlen(p);
00097 }
00098
00099
00100 trim_spaces_lr( name );
00101
00102
00103 if (name.len==0)
00104
00105 continue;
00106
00107
00108 for(i=0;i<name.len;i++) {
00109 if ( !isalnum(name.s[i]) ) {
00110 LM_ERR("bad profile name <%.*s>, char %c - use only "
00111 "alphanumerical characters\n", name.len,name.s,name.s[i]);
00112 return -1;
00113 }
00114 }
00115
00116
00117 LM_DBG("creating profile <%.*s>\n",name.len,name.s);
00118
00119 if (new_dlg_profile( &name, PROFILE_HASH_SIZE, has_value)==NULL) {
00120 LM_ERR("failed to create new profile <%.*s>\n",name.len,name.s);
00121 return -1;
00122 }
00123
00124 }while( (p=d)!=NULL );
00125
00126 return 0;
00127 }
00128
00129
00136 struct dlg_profile_table* search_dlg_profile(str *name)
00137 {
00138 struct dlg_profile_table *profile;
00139
00140 for( profile=profiles ; profile ; profile=profile->next ) {
00141 if (name->len==profile->name.len &&
00142 memcmp(name->s,profile->name.s,name->len)==0 )
00143 return profile;
00144 }
00145 return NULL;
00146 }
00147
00148
00157 static struct dlg_profile_table* new_dlg_profile( str *name, unsigned int size,
00158 unsigned int has_value)
00159 {
00160 struct dlg_profile_table *profile;
00161 struct dlg_profile_table *ptmp;
00162 unsigned int len;
00163 unsigned int i;
00164
00165 if ( name->s==NULL || name->len==0 || size==0 ) {
00166 LM_ERR("invalid parameters\n");
00167 return NULL;
00168 }
00169
00170 for( len=0,i=0 ; i<8*sizeof(size) ; i++ ) {
00171 if ( size & (1<<i) ) len++;
00172 }
00173 if (len!=1) {
00174 LM_ERR(" size %u is not power of 2!\n", size);
00175 return NULL;
00176 }
00177
00178 profile = search_dlg_profile(name);
00179 if (profile!=NULL) {
00180 LM_ERR("duplicate dialog profile registered <%.*s>\n",
00181 name->len, name->s);
00182 return NULL;
00183 }
00184
00185 len = sizeof(struct dlg_profile_table) +
00186 size*sizeof(struct dlg_profile_entry) +
00187 name->len + 1;
00188 profile = (struct dlg_profile_table *)shm_malloc(len);
00189 if (profile==NULL) {
00190 LM_ERR("no more shm mem\n");
00191 return NULL;
00192 }
00193
00194 memset( profile , 0 , len);
00195 profile->size = size;
00196 profile->has_value = (has_value==0)?0:1;
00197
00198
00199 if (lock_init( &profile->lock )==NULL) {
00200 LM_ERR("failed to init lock\n");
00201 shm_free(profile);
00202 return NULL;
00203 }
00204
00205
00206 profile->entries = (struct dlg_profile_entry*)(profile + 1);
00207 profile->name.s = ((char*)profile->entries) +
00208 size*sizeof(struct dlg_profile_entry);
00209
00210
00211 memcpy( profile->name.s, name->s, name->len );
00212 profile->name.len = name->len;
00213 profile->name.s[profile->name.len] = 0;
00214
00215
00216 for( ptmp=profiles ; ptmp && ptmp->next; ptmp=ptmp->next );
00217 if (ptmp==NULL)
00218 profiles = profile;
00219 else
00220 ptmp->next = profile;
00221
00222 return profile;
00223 }
00224
00225
00230 static void destroy_dlg_profile(struct dlg_profile_table *profile)
00231 {
00232 if (profile==NULL)
00233 return;
00234
00235 lock_destroy( &profile->lock );
00236 shm_free( profile );
00237 return;
00238 }
00239
00240
00244 void destroy_dlg_profiles(void)
00245 {
00246 struct dlg_profile_table *profile;
00247
00248 while(profiles) {
00249 profile = profiles;
00250 profiles = profiles->next;
00251 destroy_dlg_profile( profile );
00252 }
00253 return;
00254 }
00255
00256
00261 void destroy_linkers(struct dlg_profile_link *linker)
00262 {
00263 struct dlg_profile_entry *p_entry;
00264 struct dlg_profile_link *l;
00265 struct dlg_profile_hash *lh;
00266
00267 while(linker) {
00268 l = linker;
00269 linker = linker->next;
00270
00271 if (l->hash_linker.next) {
00272 p_entry = &l->profile->entries[l->hash_linker.hash];
00273 lock_get( &l->profile->lock );
00274 lh = &l->hash_linker;
00275
00276 if (lh==lh->next) {
00277 p_entry->first = NULL;
00278 } else {
00279 if (p_entry->first==lh)
00280 p_entry->first = lh->next;
00281 lh->next->prev = lh->prev;
00282 lh->prev->next = lh->next;
00283 }
00284 lh->next = lh->prev = NULL;
00285 p_entry->content --;
00286 lock_release( &l->profile->lock );
00287 }
00288
00289 shm_free(l);
00290 }
00291 }
00292
00293
00301 int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param )
00302 {
00303 dlg_cell_t *dlg;
00304
00305 current_dlg_msg_id = 0;
00306 current_dlg_msg_pid = 0;
00307 dlg = dlg_get_ctx_dialog();
00308 if (dlg!=NULL) {
00309 if(dlg->dflags & DLG_FLAG_TM) {
00310 dlg_unref(dlg, 1);
00311 } else {
00312
00313 dlg_unref(dlg, 2);
00314 }
00315 }
00316 if (current_pending_linkers) {
00317 destroy_linkers(current_pending_linkers);
00318 current_pending_linkers = NULL;
00319 }
00320
00321
00322 return 1;
00323 }
00324
00325
00326
00335 inline static unsigned int calc_hash_profile(str *value, dlg_cell_t *dlg,
00336 dlg_profile_table_t *profile)
00337 {
00338 if (profile->has_value) {
00339
00340 return core_hash( value, NULL, profile->size);
00341 } else {
00342
00343 return ((unsigned long)dlg) % profile->size ;
00344 }
00345 }
00346
00347
00353 static void link_dlg_profile(struct dlg_profile_link *linker, struct dlg_cell *dlg)
00354 {
00355 unsigned int hash;
00356 struct dlg_profile_entry *p_entry;
00357 struct dlg_entry *d_entry;
00358
00359
00360
00361
00362 if (dlg->h_id) {
00363 d_entry = &d_table->entries[dlg->h_entry];
00364 dlg_lock( d_table, d_entry);
00365 linker->next = dlg->profile_links;
00366 dlg->profile_links =linker;
00367 linker->hash_linker.dlg = dlg;
00368 dlg_unlock( d_table, d_entry);
00369 } else {
00370 linker->next = dlg->profile_links;
00371 dlg->profile_links =linker;
00372 linker->hash_linker.dlg = dlg;
00373 }
00374
00375
00376 hash = calc_hash_profile(&linker->hash_linker.value, dlg, linker->profile);
00377 linker->hash_linker.hash = hash;
00378
00379
00380 p_entry = &linker->profile->entries[hash];
00381 lock_get( &linker->profile->lock );
00382 if (p_entry->first) {
00383 linker->hash_linker.prev = p_entry->first->prev;
00384 linker->hash_linker.next = p_entry->first;
00385 p_entry->first->prev->next = &linker->hash_linker;
00386 p_entry->first->prev = &linker->hash_linker;
00387 } else {
00388 p_entry->first = linker->hash_linker.next
00389 = linker->hash_linker.prev = &linker->hash_linker;
00390 }
00391 p_entry->content ++;
00392 lock_release( &linker->profile->lock );
00393 }
00394
00395
00401 void set_current_dialog(sip_msg_t *msg, dlg_cell_t *dlg)
00402 {
00403 struct dlg_profile_link *linker;
00404 struct dlg_profile_link *tlinker;
00405
00406 LM_DBG("setting current dialog [%u:%u]\n", dlg->h_entry, dlg->h_id);
00407
00408 if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) {
00409 current_dlg_msg_id = msg->id;
00410 current_dlg_msg_pid = msg->pid;
00411 destroy_linkers(current_pending_linkers);
00412 } else {
00413
00414 linker = current_pending_linkers;
00415 while (linker) {
00416 tlinker = linker;
00417 linker = linker->next;
00418
00419 tlinker->next = NULL;
00420 link_dlg_profile( tlinker, dlg);
00421 }
00422 }
00423 current_pending_linkers = NULL;
00424 }
00425
00426
00434 int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *profile)
00435 {
00436 dlg_cell_t *dlg = NULL;
00437 dlg_profile_link_t *linker;
00438
00439
00440 dlg = dlg_get_msg_dialog(msg);
00441
00442 if (dlg==NULL && !is_route_type(REQUEST_ROUTE)) {
00443 LM_CRIT("BUG - dialog not found in a non REQUEST route (%d)\n",
00444 REQUEST_ROUTE);
00445 return -1;
00446 }
00447
00448
00449 linker = (struct dlg_profile_link*)shm_malloc(
00450 sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) );
00451 if (linker==NULL) {
00452 LM_ERR("no more shm memory\n");
00453 goto error;
00454 }
00455 memset(linker, 0, sizeof(struct dlg_profile_link));
00456
00457
00458 linker->profile = profile;
00459
00460
00461 if (profile->has_value) {
00462 linker->hash_linker.value.s = (char*)(linker+1);
00463 memcpy( linker->hash_linker.value.s, value->s, value->len);
00464 linker->hash_linker.value.len = value->len;
00465 }
00466
00467 if (dlg!=NULL) {
00468
00469 link_dlg_profile( linker, dlg);
00470 } else {
00471
00472 if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) {
00473 current_dlg_msg_id = msg->id;
00474 current_dlg_msg_pid = msg->pid;
00475 destroy_linkers(current_pending_linkers);
00476 }
00477
00478 linker->next = current_pending_linkers;
00479 current_pending_linkers = linker;
00480 }
00481
00482 dlg_release(dlg);
00483 return 0;
00484 error:
00485 dlg_release(dlg);
00486 return -1;
00487 }
00488
00496 int dlg_add_profile(dlg_cell_t *dlg, str *value, struct dlg_profile_table *profile)
00497 {
00498 dlg_profile_link_t *linker;
00499
00500 if (dlg==NULL)
00501 return -1;
00502
00503
00504 linker = (struct dlg_profile_link*)shm_malloc(
00505 sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) );
00506 if (linker==NULL) {
00507 LM_ERR("no more shm memory\n");
00508 goto error;
00509 }
00510 memset(linker, 0, sizeof(struct dlg_profile_link));
00511
00512
00513 linker->profile = profile;
00514
00515
00516 if (profile->has_value) {
00517 linker->hash_linker.value.s = (char*)(linker+1);
00518 memcpy( linker->hash_linker.value.s, value->s, value->len);
00519 linker->hash_linker.value.len = value->len;
00520 }
00521
00522
00523 link_dlg_profile( linker, dlg);
00524 return 0;
00525 error:
00526 return -1;
00527 }
00528
00536 int unset_dlg_profile(sip_msg_t *msg, str *value,
00537 dlg_profile_table_t *profile)
00538 {
00539 dlg_cell_t *dlg;
00540 dlg_profile_link_t *linker;
00541 dlg_profile_link_t *linker_prev;
00542 dlg_entry_t *d_entry;
00543
00544 if (is_route_type(REQUEST_ROUTE)) {
00545 LM_ERR("dialog delete profile cannot be used in request route\n");
00546 return -1;
00547 }
00548
00549
00550 dlg = dlg_get_msg_dialog(msg);
00551
00552 if (dlg==NULL) {
00553 LM_WARN("dialog is NULL for delete profile\n");
00554 return -1;
00555 }
00556
00557
00558 d_entry = &d_table->entries[dlg->h_entry];
00559 dlg_lock( d_table, d_entry);
00560 linker = dlg->profile_links;
00561 linker_prev = NULL;
00562 for( ; linker ; linker_prev=linker,linker=linker->next) {
00563 if (linker->profile==profile) {
00564 if (profile->has_value==0) {
00565 goto found;
00566 } else if (value && value->len==linker->hash_linker.value.len &&
00567 memcmp(value->s,linker->hash_linker.value.s,value->len)==0){
00568 goto found;
00569 }
00570
00571
00572
00573 }
00574 }
00575 dlg_unlock( d_table, d_entry);
00576 dlg_release(dlg);
00577 return -1;
00578
00579 found:
00580
00581
00582 if (linker_prev==NULL) {
00583 dlg->profile_links = linker->next;
00584 } else {
00585 linker_prev->next = linker->next;
00586 }
00587 linker->next = NULL;
00588 dlg_unlock( d_table, d_entry);
00589
00590 destroy_linkers(linker);
00591 dlg_release(dlg);
00592 return 1;
00593 }
00594
00595
00603 int is_dlg_in_profile(struct sip_msg *msg, struct dlg_profile_table *profile,
00604 str *value)
00605 {
00606 struct dlg_cell *dlg;
00607 struct dlg_profile_link *linker;
00608 struct dlg_entry *d_entry;
00609
00610
00611 dlg = dlg_get_msg_dialog(msg);
00612
00613 if (dlg==NULL)
00614 return -1;
00615
00616
00617 d_entry = &d_table->entries[dlg->h_entry];
00618 dlg_lock( d_table, d_entry);
00619 for( linker=dlg->profile_links ; linker ; linker=linker->next) {
00620 if (linker->profile==profile) {
00621 if (profile->has_value==0) {
00622 dlg_unlock( d_table, d_entry);
00623 goto done;
00624 } else if (value && value->len==linker->hash_linker.value.len &&
00625 memcmp(value->s,linker->hash_linker.value.s,value->len)==0){
00626 dlg_unlock( d_table, d_entry);
00627 goto done;
00628 }
00629
00630
00631
00632 }
00633 }
00634 dlg_unlock( d_table, d_entry);
00635
00636 done:
00637 dlg_release(dlg);
00638 return -1;
00639 }
00640
00641
00648 unsigned int get_profile_size(struct dlg_profile_table *profile, str *value)
00649 {
00650 unsigned int n,i;
00651 struct dlg_profile_hash *ph;
00652
00653 if (profile->has_value==0 || value==NULL) {
00654
00655 lock_get( &profile->lock );
00656 for( i=0,n=0 ; i<profile->size ; i++ )
00657 n += profile->entries[i].content;
00658 lock_release( &profile->lock );
00659 return n;
00660 } else {
00661
00662
00663 i = calc_hash_profile( value, NULL, profile);
00664 n = 0;
00665 lock_get( &profile->lock );
00666 ph = profile->entries[i].first;
00667 if(ph) {
00668 do {
00669
00670 if ( value->len==ph->value.len &&
00671 memcmp(value->s,ph->value.s,value->len)==0 ) {
00672
00673 n++;
00674 }
00675
00676 ph=ph->next;
00677 }while( ph!=profile->entries[i].first );
00678 }
00679 lock_release( &profile->lock );
00680 return n;
00681 }
00682 }
00683
00684
00685
00686
00687 int is_known_dlg(struct sip_msg *msg) {
00688 dlg_cell_t *dlg;
00689
00690 dlg = dlg_get_msg_dialog(msg);
00691
00692 if(dlg == NULL)
00693 return -1;
00694
00695 dlg_release(dlg);
00696
00697 return 1;
00698 }
00699
00700
00701
00708 struct mi_root * mi_get_profile(struct mi_root *cmd_tree, void *param)
00709 {
00710 struct mi_node* node;
00711 struct mi_root* rpl_tree= NULL;
00712 struct mi_node* rpl = NULL;
00713 struct mi_attr* attr;
00714 struct dlg_profile_table *profile;
00715 str *value;
00716 str *profile_name;
00717 unsigned int size;
00718 int len;
00719 char *p;
00720
00721 node = cmd_tree->node.kids;
00722 if (node==NULL || !node->value.s || !node->value.len)
00723 return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
00724 profile_name = &node->value;
00725
00726 if (node->next) {
00727 node = node->next;
00728 if (!node->value.s || !node->value.len)
00729 return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
00730 if (node->next)
00731 return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
00732 value = &node->value;
00733 } else {
00734 value = NULL;
00735 }
00736
00737
00738 profile = search_dlg_profile( profile_name );
00739 if (profile==NULL)
00740 return init_mi_tree( 404, MI_SSTR("Profile not found"));
00741
00742 size = get_profile_size( profile , value );
00743
00744 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00745 if (rpl_tree==0)
00746 return 0;
00747 rpl = &rpl_tree->node;
00748
00749 node = add_mi_node_child(rpl, MI_DUP_VALUE, "profile", 7, NULL, 0);
00750 if (node==0) {
00751 free_mi_tree(rpl_tree);
00752 return NULL;
00753 }
00754
00755 attr = add_mi_attr(node, MI_DUP_VALUE, "name", 4,
00756 profile->name.s, profile->name.len);
00757 if(attr == NULL) {
00758 goto error;
00759 }
00760
00761 if (value) {
00762 attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, value->s, value->len);
00763 } else {
00764 attr = add_mi_attr(node, MI_DUP_VALUE, "value", 5, NULL, 0);
00765 }
00766 if(attr == NULL) {
00767 goto error;
00768 }
00769
00770 p= int2str((unsigned long)size, &len);
00771 attr = add_mi_attr(node, MI_DUP_VALUE, "count", 5, p, len);
00772 if(attr == NULL) {
00773 goto error;
00774 }
00775
00776 return rpl_tree;
00777 error:
00778 free_mi_tree(rpl_tree);
00779 return NULL;
00780 }
00781
00782
00789 struct mi_root * mi_profile_list(struct mi_root *cmd_tree, void *param )
00790 {
00791 struct mi_node* node;
00792 struct mi_root* rpl_tree= NULL;
00793 struct mi_node* rpl = NULL;
00794 struct dlg_profile_table *profile;
00795 struct dlg_profile_hash *ph;
00796 str *profile_name;
00797 str *value;
00798 unsigned int i;
00799
00800 node = cmd_tree->node.kids;
00801 if (node==NULL || !node->value.s || !node->value.len)
00802 return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
00803 profile_name = &node->value;
00804
00805 if (node->next) {
00806 node = node->next;
00807 if (!node->value.s || !node->value.len)
00808 return init_mi_tree( 400, MI_SSTR(MI_BAD_PARM));
00809 if (node->next)
00810 return init_mi_tree( 400, MI_SSTR(MI_MISSING_PARM));
00811 value = &node->value;
00812 } else {
00813 value = NULL;
00814 }
00815
00816
00817 profile = search_dlg_profile( profile_name );
00818 if (profile==NULL)
00819 return init_mi_tree( 404, MI_SSTR("Profile not found"));
00820
00821 rpl_tree = init_mi_tree( 200, MI_SSTR(MI_OK));
00822 if (rpl_tree==0)
00823 return 0;
00824 rpl = &rpl_tree->node;
00825
00826
00827 if (profile->has_value==0 || value==NULL) {
00828
00829 lock_get( &profile->lock );
00830 for ( i=0 ; i< profile->size ; i++ ) {
00831 ph = profile->entries[i].first;
00832 if(ph) {
00833 do {
00834
00835 if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 )
00836 goto error;
00837
00838 ph=ph->next;
00839 }while( ph!=profile->entries[i].first );
00840 }
00841 lock_release( &profile->lock );
00842 }
00843 } else {
00844
00845 lock_get( &profile->lock );
00846 for ( i=0 ; i< profile->size ; i++ ) {
00847 ph = profile->entries[i].first;
00848 if(ph) {
00849 do {
00850 if ( value->len==ph->value.len &&
00851 memcmp(value->s,ph->value.s,value->len)==0 ) {
00852
00853 if ( mi_print_dlg( rpl, ph->dlg, 0)!=0 )
00854 goto error;
00855 }
00856
00857 ph=ph->next;
00858 }while( ph!=profile->entries[i].first );
00859 }
00860 lock_release( &profile->lock );
00861 }
00862 }
00863
00864 return rpl_tree;
00865 error:
00866 free_mi_tree(rpl_tree);
00867 return NULL;
00868 }
00869
00870
00874 int dlg_profiles_to_json(dlg_cell_t *dlg, srjson_doc_t *jdoc)
00875 {
00876 dlg_profile_link_t *l;
00877 srjson_t *sj = NULL;
00878 srjson_t *dj = NULL;
00879
00880 LM_DBG("serializing profiles for dlg[%u:%u]\n",
00881 dlg->h_entry, dlg->h_id);
00882 if(dlg==NULL || dlg->profile_links==NULL)
00883 return -1;
00884 LM_DBG("start of serializing profiles for dlg[%u:%u]\n",
00885 dlg->h_entry, dlg->h_id);
00886
00887 for (l = dlg->profile_links ; l ; l=l->next) {
00888 if(l->profile->has_value)
00889 {
00890 if(dj==NULL)
00891 {
00892 dj = srjson_CreateObject(jdoc);
00893 if(dj==NULL)
00894 {
00895 LM_ERR("cannot create json dynamic profiles obj\n");
00896 goto error;
00897 }
00898 }
00899 srjson_AddStrStrToObject(jdoc, dj,
00900 l->profile->name.s, l->profile->name.len,
00901 l->hash_linker.value.s, l->hash_linker.value.len);
00902 } else {
00903 if(sj==NULL)
00904 {
00905 sj = srjson_CreateArray(jdoc);
00906 if(sj==NULL)
00907 {
00908 LM_ERR("cannot create json static profiles obj\n");
00909 goto error;
00910 }
00911 }
00912 srjson_AddItemToArray(jdoc, sj,
00913 srjson_CreateStr(jdoc, l->profile->name.s, l->profile->name.len));
00914 }
00915 }
00916
00917 if(jdoc->root==NULL)
00918 {
00919 jdoc->root = srjson_CreateObject(jdoc);
00920 if(jdoc->root==NULL)
00921 {
00922 LM_ERR("cannot create json root\n");
00923 goto error;
00924 }
00925 }
00926 if(dj!=NULL)
00927 srjson_AddItemToObject(jdoc, jdoc->root, "dprofiles", dj);
00928 if(sj!=NULL)
00929 srjson_AddItemToObject(jdoc, jdoc->root, "sprofiles", sj);
00930 if(jdoc->buf.s != NULL)
00931 {
00932 jdoc->free_fn(jdoc->buf.s);
00933 jdoc->buf.s = NULL;
00934 jdoc->buf.len = 0;
00935 }
00936 jdoc->buf.s = srjson_PrintUnformatted(jdoc, jdoc->root);
00937 if(jdoc->buf.s!=NULL)
00938 {
00939 jdoc->buf.len = strlen(jdoc->buf.s);
00940 LM_DBG("serialized profiles for dlg[%u:%u] = [[%.*s]]\n",
00941 dlg->h_entry, dlg->h_id, jdoc->buf.len, jdoc->buf.s);
00942 return 0;
00943 }
00944 return -1;
00945
00946 error:
00947 srjson_Delete(jdoc, dj);
00948 srjson_Delete(jdoc, sj);
00949 return -1;
00950 }
00951
00952
00956 int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc)
00957 {
00958 srjson_t *sj = NULL;
00959 srjson_t *dj = NULL;
00960 srjson_t *it = NULL;
00961 dlg_profile_table_t *profile;
00962 str name;
00963 str val;
00964
00965 if(dlg==NULL || jdoc==NULL || jdoc->buf.s==NULL)
00966 return -1;
00967
00968 if(jdoc->root == NULL)
00969 {
00970 jdoc->root = srjson_Parse(jdoc, jdoc->buf.s);
00971 if(jdoc->root == NULL)
00972 {
00973 LM_ERR("invalid json doc [[%s]]\n", jdoc->buf.s);
00974 return -1;
00975 }
00976 }
00977 dj = srjson_GetObjectItem(jdoc, jdoc->root, "dprofiles");
00978 sj = srjson_GetObjectItem(jdoc, jdoc->root, "sprofiles");
00979 if(dj!=NULL)
00980 {
00981 for(it=dj->child; it; it = it->next)
00982 {
00983 name.s = it->string;
00984 name.len = strlen(name.s);
00985 val.s = it->valuestring;
00986 val.len = strlen(val.s);
00987 profile = search_dlg_profile(&name);
00988 if(profile==NULL)
00989 {
00990 LM_ERR("profile [%.*s] not found\n", name.len, name.s);
00991 continue;
00992 }
00993 if(profile->has_value)
00994 {
00995 if(dlg_add_profile(dlg, &val, profile) < 0)
00996 LM_ERR("dynamic profile cannot be added, ignore!\n");
00997 else
00998 LM_DBG("dynamic profile added [%s : %s]\n", name.s, val.s);
00999 }
01000 }
01001 }
01002 if(sj!=NULL)
01003 {
01004 for(it=sj->child; it; it = it->next)
01005 {
01006 name.s = it->valuestring;
01007 name.len = strlen(name.s);
01008 profile = search_dlg_profile(&name);
01009 if(profile==NULL)
01010 {
01011 LM_ERR("profile [%.*s] not found\n", name.len, name.s);
01012 continue;
01013 }
01014 if(!profile->has_value)
01015 {
01016 if(dlg_add_profile(dlg, NULL, profile) < 0)
01017 LM_ERR("static profile cannot be added, ignore!\n");
01018 else
01019 LM_DBG("static profile added [%s]\n", name.s);
01020 }
01021 }
01022 }
01023 return 0;
01024 }