/*! * \brief Free all memory used by the given structure * * Free all memory used by the given structure. * The structure must be removed from all linked * lists first * \param _r freed record list */ void free_impurecord(impurecord_t* _r) { ucontact_t* ptr; struct ul_callback *cbp, *cbp_tmp; struct _reg_subscriber* subscriber, *s_tmp; while (_r->contacts) { ptr = _r->contacts; _r->contacts = _r->contacts->next; free_ucontact(ptr); } //free IMS specific extensions if (_r->ccf1.s) shm_free(_r->ccf1.s); if (_r->ccf2.s) shm_free(_r->ccf2.s); if (_r->ecf1.s) shm_free(_r->ecf1.s); if (_r->ecf2.s) shm_free(_r->ecf2.s); if (_r->s) { LM_DBG("ref count on this IMS data is %d\n", _r->s->ref_count); lock_get(_r->s->lock); if (_r->s->ref_count == 1) { LM_DBG("freeing IMS subscription data\n"); free_ims_subscription_data(_r->s); } else { LM_DBG("decrementing IMS subscription data ref count\n"); _r->s->ref_count--; lock_release(_r->s->lock); } } /*remove REG subscriptions to this IMPU*/ subscriber = _r->shead; while (subscriber) { s_tmp = subscriber->next; free_subscriber(subscriber); subscriber = s_tmp; } if (_r->public_identity.s) shm_free(_r->public_identity.s); //free callback list for (cbp = _r->cbs->first; cbp;) { cbp_tmp = cbp; cbp = cbp->next; if (cbp_tmp->param) shm_free(cbp_tmp->param); shm_free(cbp_tmp); } shm_free(_r->cbs); shm_free(_r); }
/* update an existing impurecord. if one doesnt exist it will be created. * make sure yuo lock the domain before calling this and unlock it afterwards * return: 0 on success, -1 on failure */ int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r) { int res; res = get_impurecord(_d, public_identity, _r); if (res != 0) { if (reg_state != IMPU_NOT_REGISTERED && s) { LM_DBG("No existing impu record for <%.*s>.... creating new one\n", public_identity->len, public_identity->s); res = insert_impurecord(_d, public_identity, reg_state, barring, s, ccf1, ccf2, ecf1, ecf2, _r); //for the first time we create an IMPU we must set the primary record (we don't worry about it on updates - ignored) (*_r)->is_primary = is_primary; //TODO = this should prob move to insert_impurecord fn if (reg_state == IMPU_UNREGISTERED) { //update unreg expiry so the unreg record is not stored 'forever' (*_r)->expires = time(NULL) + unreg_validity; } if (res != 0) { LM_ERR("Unable to insert new IMPU for <%.*s>\n", public_identity->len, public_identity->s); return -1; } else { run_ul_callbacks(NULL, UL_IMPU_INSERT, *_r, NULL); return 0; } } else { LM_DBG("no IMPU found to update and data not valid to create new one - not a problem record was probably removed as it has no contacts\n"); return 0; } } //if we get here, we have a record to update LM_DBG("updating IMPU record with public identity for <%.*s>\n", public_identity->len, public_identity->s); (*_r)->reg_state = reg_state; if (reg_state == IMPU_UNREGISTERED) { //update unreg expiry so the unreg record is not stored 'forever' (*_r)->expires = time(NULL) + unreg_validity; } if (barring >= 0) (*_r)->barring = barring; if (send_sar_on_delete >= 0) (*_r)->send_sar_on_delete = send_sar_on_delete; if (ccf1) { if ((*_r)->ccf1.s) shm_free((*_r)->ccf1.s); STR_SHM_DUP((*_r)->ccf1, *ccf1, "SHM CCF1"); } if (ccf2) { if ((*_r)->ccf2.s) shm_free((*_r)->ccf2.s); STR_SHM_DUP((*_r)->ccf2, *ccf2, "SHM CCF2"); } if (ecf1) { if ((*_r)->ecf1.s) shm_free((*_r)->ecf1.s); STR_SHM_DUP((*_r)->ecf1, *ecf1, "SHM ECF1"); } if (ecf2) { if ((*_r)->ecf2.s) shm_free((*_r)->ecf2.s); STR_SHM_DUP((*_r)->ecf2, *ecf2, "SHM ECF2"); } if (s) { LM_DBG("we have a new ims_subscription\n"); if ((*_r)->s) { lock_get((*_r)->s->lock); if ((*_r)->s->ref_count == 1) { LM_DBG("freeing user data as no longer referenced\n"); free_ims_subscription_data((*_r)->s); //no need to release lock after this. its gone ;) (*_r)->s = 0; } else { (*_r)->s->ref_count--; LM_DBG("new ref count for ims sub is %d\n", (*_r)->s->ref_count); lock_release((*_r)->s->lock); } } (*_r)->s = *s; lock_get((*_r)->s->lock); (*_r)->s->ref_count++; lock_release((*_r)->s->lock); } run_ul_callbacks((*_r)->cbs, UL_IMPU_UPDATE, *_r, NULL); return 0; out_of_memory: unlock_udomain(_d, public_identity); return -1; }
void delete_subscription(ims_subscription* s) { LM_DBG("Deleting subscription %p [%.*s]\n", s, s->private_identity.len, s->private_identity.s); free_ims_subscription_data(s); }