/*! * \brief Add dialog to a profile * \param dlg dialog * \param value value * \param profile dialog profile table * \return 0 on success, -1 on failure */ int dlg_add_profile(dlg_cell_t *dlg, str *value, struct dlg_profile_table *profile) { dlg_profile_link_t *linker; if (dlg==NULL) return -1; /* build new linker */ linker = (struct dlg_profile_link*)shm_malloc( sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) ); if (linker==NULL) { LM_ERR("no more shm memory\n"); goto error; } memset(linker, 0, sizeof(struct dlg_profile_link)); /* set backpointer to profile */ linker->profile = profile; /* set the value */ if (profile->has_value) { linker->hash_linker.value.s = (char*)(linker+1); memcpy( linker->hash_linker.value.s, value->s, value->len); linker->hash_linker.value.len = value->len; } /* add linker directly to the dialog and profile */ link_dlg_profile( linker, dlg); return 0; error: return -1; }
/*! * \brief Add dialog to a profile * \param dlg dialog * \param value value * \param profile dialog profile table * \return 0 on success, -1 on failure */ int dlg_add_profile(dlg_cell_t *dlg, str *value, struct dlg_profile_table *profile, str *puid, time_t expires, int flags) { dlg_profile_link_t *linker; str vkey; /* build new linker */ linker = (struct dlg_profile_link*)shm_malloc( sizeof(struct dlg_profile_link) + (profile->has_value?(value->len+1):0) ); if (linker==NULL) { LM_ERR("no more shm memory\n"); goto error; } memset(linker, 0, sizeof(struct dlg_profile_link)); /* set backpointers to profile and linker (itself) */ linker->profile = profile; linker->hash_linker.linker = linker; /* set the value */ if (profile->has_value) { linker->hash_linker.value.s = (char*)(linker+1); memcpy( linker->hash_linker.value.s, value->s, value->len); linker->hash_linker.value.len = value->len; linker->hash_linker.value.s[value->len] = '\0'; } if(puid && puid->s && puid->len>0 && puid->len<SRUID_SIZE) { strcpy(linker->hash_linker.puid, puid->s); linker->hash_linker.puid_len = puid->len; } else { sruid_next_safe(&_dlg_profile_sruid); strcpy(linker->hash_linker.puid, _dlg_profile_sruid.uid.s); linker->hash_linker.puid_len = _dlg_profile_sruid.uid.len; } linker->hash_linker.expires = expires; linker->hash_linker.flags = flags; /* add linker directly to the dialog and profile */ if(dlg!=NULL) { link_dlg_profile(linker, dlg); } else { vkey.s = linker->hash_linker.puid; vkey.len = linker->hash_linker.puid_len; profile->flags |= FLAG_PROFILE_REMOTE; link_profile(linker, &vkey); } return 0; error: return -1; }
/*! * \brief Set the global variables to the current dialog * \param msg SIP message * \param dlg dialog cell */ void set_current_dialog(sip_msg_t *msg, dlg_cell_t *dlg) { struct dlg_profile_link *linker; struct dlg_profile_link *tlinker; LM_DBG("setting current dialog [%u:%u]\n", dlg->h_entry, dlg->h_id); /* if linkers are not from current request, just discard them */ if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { current_dlg_msg_id = msg->id; current_dlg_msg_pid = msg->pid; destroy_linkers(current_pending_linkers); } else { /* add the linker, one by one, to the dialog */ linker = current_pending_linkers; while (linker) { tlinker = linker; linker = linker->next; /* process tlinker */ tlinker->next = NULL; link_dlg_profile( tlinker, dlg); } } current_pending_linkers = NULL; }
/*! * \brief Set a dialog profile * \param msg SIP message * \param value value * \param profile dialog profile table * \return 0 on success, -1 on failure */ int set_dlg_profile(struct sip_msg *msg, str *value, struct dlg_profile_table *profile) { dlg_cell_t *dlg = NULL; dlg_profile_link_t *linker; /* get current dialog */ dlg = dlg_get_msg_dialog(msg); if (dlg==NULL && !is_route_type(REQUEST_ROUTE)) { LM_CRIT("BUG - dialog not found in a non REQUEST route (%d)\n", REQUEST_ROUTE); return -1; } /* build new linker */ linker = (struct dlg_profile_link*)shm_malloc( sizeof(struct dlg_profile_link) + (profile->has_value?value->len:0) ); if (linker==NULL) { LM_ERR("no more shm memory\n"); goto error; } memset(linker, 0, sizeof(struct dlg_profile_link)); /* set backpointers to profile and linker (itself) */ linker->profile = profile; linker->hash_linker.linker = linker; /* set the value */ if (profile->has_value) { linker->hash_linker.value.s = (char*)(linker+1); memcpy( linker->hash_linker.value.s, value->s, value->len); linker->hash_linker.value.len = value->len; } sruid_next_safe(&_dlg_profile_sruid); strcpy(linker->hash_linker.puid, _dlg_profile_sruid.uid.s); linker->hash_linker.puid_len = _dlg_profile_sruid.uid.len; if (dlg!=NULL) { /* add linker directly to the dialog and profile */ link_dlg_profile( linker, dlg); } else { /* if existing linkers are not from current request, just discard them */ if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { current_dlg_msg_id = msg->id; current_dlg_msg_pid = msg->pid; destroy_linkers(current_pending_linkers); current_pending_linkers = NULL; } /* no dialog yet -> set linker as pending */ if (msg->id!=current_dlg_msg_id || msg->pid!=current_dlg_msg_pid) { current_dlg_msg_id = msg->id; current_dlg_msg_pid = msg->pid; destroy_linkers(current_pending_linkers); } linker->next = current_pending_linkers; current_pending_linkers = linker; } dlg_release(dlg); return 0; error: dlg_release(dlg); return -1; }