Beispiel #1
0
void external_delete_subscriber(reg_subscriber *s, udomain_t* _t, int lock_domain) {
    LM_DBG("Deleting subscriber");
    impurecord_t* urec;
   
    LM_DBG("Updating reg subscription in IMPU record");

    if(lock_domain) lock_udomain(_t, &s->presentity_uri);
    int res = get_impurecord(_t, &s->presentity_uri, &urec);
    if (res != 0) {
        if(lock_domain) unlock_udomain(_t, &s->presentity_uri);
        return;
    }

    delete_subscriber(urec, s);

    if(lock_domain) unlock_udomain(_t, &s->presentity_uri);

}
Beispiel #2
0
void external_delete_subscriber(reg_subscriber *s, udomain_t* _t, int lock_domain) {
    LM_DBG("Deleting subscriber");
    impurecord_t* urec;
   
    LM_DBG("Updating reg subscription in IMPU record");

    if(lock_domain) lock_udomain(_t, &s->presentity_uri);
    int res = get_impurecord(_t, &s->presentity_uri, &urec);
    if (res != 0) {
        if(lock_domain) unlock_udomain(_t, &s->presentity_uri);
        return;
    }

    if (urec->shead == s) urec->shead = s->next;
    else s->prev->next = s->next;
    if (urec->stail == s) urec->stail = s->prev;
    else s->next->prev = s->prev;
    LM_DBG("About to free subscriber memory");
    free_subscriber(s);

    if(lock_domain) unlock_udomain(_t, &s->presentity_uri);

}
Beispiel #3
0
/*!
 * \brief Delete a impurecord from domain
 * \param _d domain where the record should be deleted
 * \param _aor address of record
 * \param _r deleted record
 * \return 0 on success, -1 if the record could not be deleted
 */
int delete_impurecord(udomain_t* _d, str* _aor, struct impurecord* _r) {
    //    struct ucontact* c;//, *t;

    LM_DBG("Deleting IMPURECORD [%.*s]\n", _r->public_identity.len, _r->public_identity.s);

    if (_r == 0) {
	if (get_impurecord(_d, _aor, &_r) > 0) {
	    return 0;
	}
    }

    //TODO: need to unref the contacts in the contact list (not delete them), the timer should delete all contacts that are unreffed
    //    c = _r->contacts;
    //    while (c) {
    //	t = c;
    //	c = c->next;
    //	if (delete_ucontact(_r, t) < 0) {
    //	    LM_ERR("deleting contact failed [%.*s]\n", c->aor.len, c->aor.s);
    //	    return -1;
    //	}
    //    }

    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE)) {
	run_ul_callbacks(_r->cbs, UL_IMPU_DELETE, _r, 0);
    }

    /*DB?*/
    if (db_mode == WRITE_THROUGH
	    && db_delete_impurecord(_d, _r) != 0) {
	LM_ERR("error deleting IMPU record from db");
	return 0;
    }

    mem_delete_impurecord(_d, _r);
    return 0;
}
Beispiel #4
0
/*!
 * \brief Delete a impurecord from domain
 * \param _d domain where the record should be deleted
 * \param _aor address of record - used only if _r in next param is null
 * \param _r deleted record to delete - if null will use the aor to search (assumed that domain is locked).
 * \return 0 on success, -1 if the record could not be deleted
 */
int delete_impurecord(udomain_t* _d, str* _aor, struct impurecord* _r) {
    LM_DBG("Deleting IMPURECORD [%.*s]\n", _r->public_identity.len, _r->public_identity.s);

    if (_r == 0) {
        LM_DBG("no impurecord passed in - let's search\n");
        if (get_impurecord(_d, _aor, &_r) != 0) {
            return 0;
        }
    }

    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE)) {
        run_ul_callbacks(_r->cbs, UL_IMPU_DELETE, _r, 0);
    }

    /*DB?*/
    if (db_mode == WRITE_THROUGH
            && db_delete_impurecord(_d, _r) != 0) {
        LM_ERR("error deleting IMPU record from db...continuing to remove from memory\n");
    }

    mem_delete_impurecord(_d, _r);

    return 0;
}
Beispiel #5
0
/* 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;
}
Beispiel #6
0
static void ul_rpc_show_impu(rpc_t* rpc, void* ctx)
{
	int i, j;
	str impu;
	int res;
	udomain_t* domain;
	struct impurecord* impu_rec;
	ucontact_t* contact;
	void *ah, *sh, *ch, *cdh, *sdh, *sph, *spi;
	char numstr[21+16]; //enough for all numbers up to 64bits + longest length of field name (16)

	if (rpc->scan(ctx, "S", &impu) < 1) {
		rpc->fault(ctx, 400, "required IMPU argument");
		return;
	}

	LM_DBG("searching for impu <%.*s>\n", impu.len, impu.s);

	res = get_udomain("location", &domain);
	if (res != 0) {
		LM_ERR("Failed to get domain\n");
		return;
	}

	lock_udomain(domain, &impu);
	res = get_impurecord(domain, &impu, &impu_rec);
	if (res != 0) {
		unlock_udomain(domain, &impu);
		return;
	}

	//now print the data for this IMPU record
	if (rpc->add(ctx, "{", &ah) < 0) {
		rpc->fault(ctx, 500, "Internal error creating IMPU struct");
		unlock_udomain(domain, &impu);
		return;
	}

	if (rpc->struct_add(ah, "SsdSSSS",
			"impu", &impu,
			"state", get_impu_regstate_as_string(impu_rec->reg_state),
			"barring", impu_rec->barring,
			"ccf1", &impu_rec->ccf1,
			"ccf2", &impu_rec->ccf2,
			"ecf1", &impu_rec->ecf1,
			"ecf2", &impu_rec->ecf2
			) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu data");
		unlock_udomain(domain, &impu);
		return;
	}

	if (rpc->struct_add(ah, "{", "subscription", &sh) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu subscription data");
		unlock_udomain(domain, &impu);
		return;
	}

	ims_subscription* subscription = impu_rec->s;
	lock_get(subscription->lock);
	//add subscription data
	if (rpc->struct_add(sh, "S{", "impi", &subscription->private_identity, "service profiles", &sph) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu subscription data");
		lock_release(subscription->lock);
		unlock_udomain(domain, &impu);
		return;
	}

	//add subscription detail information
	for (i=0; i<subscription->service_profiles_cnt; i++) {
		sprintf(numstr, "%d", i+1);
		if (rpc->struct_add(sph, "{", numstr, &sdh) < 0) {
			rpc->fault(ctx, 500, "Internal error adding impu subscription detail data");
			lock_release(subscription->lock);
			unlock_udomain(domain, &impu);
			return;
		}
		if (rpc->struct_add(sdh, "{", "impus", &spi) < 0) {
				rpc->fault(ctx, 500, "Internal error adding impu subscription data");
				lock_release(subscription->lock);
				unlock_udomain(domain, &impu);
				return;
		}

		for (j=0; j<subscription->service_profiles[i].public_identities_cnt; j++) {
			sprintf(numstr, "%d", j+1);
			if (rpc->struct_add(spi, "S", numstr, &subscription->service_profiles[i].public_identities[j].public_identity) < 0) {
					rpc->fault(ctx, 500, "Internal error adding impu subscription detail data");
					lock_release(subscription->lock);
					unlock_udomain(domain, &impu);
					return;
			}
		}
	}

	lock_release(subscription->lock);

	//add contact data
	if (rpc->struct_add(ah, "{", "contacts", &ch) < 0) {
		rpc->fault(ctx, 500, "Internal error adding impu contact data");
		unlock_udomain(domain, &impu);
		return;
	}
	contact = impu_rec->contacts;
	while (contact) {
		//contact is not null terminated so we need to create a null terminated version
		if (!contact_buf.s || (contact_buf.len <= contact->c.len)) {
			if (contact_buf.s && contact_buf.len <= contact->c.len){
				pkg_free(contact_buf.s);
			}
			contact_buflen = contact->c.len + 1;
			contact_buf.s = (char*)pkg_malloc(contact_buflen);
			if (!contact_buf.s) {
				LM_ERR("no more pkg memory");
				rpc->fault(ctx, 500, "Internal error adding impu contact header");
				unlock_udomain(domain, &impu);
				return;
			}
		}
		memcpy(contact_buf.s, contact->c.s, contact->c.len);
		contact_buf.s[contact->c.len] = '\0';
		contact_buf.len = contact->c.len;

		LM_DBG("contact is %s\n", contact_buf.s);
		if (rpc->struct_add(ch, "{", contact_buf.s, &cdh) < 0) {
			rpc->fault(ctx, 500, "Internal error adding impu contact header");
			unlock_udomain(domain, &impu);
			return;
		}
		if (rpc->struct_add(cdh, "dS",
				"expires", contact->expires - time(NULL),
				"client", &contact->user_agent) < 0) {
			rpc->fault(ctx, 500, "Internal error adding impu contact data");
			unlock_udomain(domain, &impu);
			return;
		}
		contact = contact->next;
	}

	unlock_udomain(domain, &impu);

}
static void contact_dlg_handler(struct dlg_cell* dlg, int cb_types, struct dlg_cb_params *dlg_params) {
    struct ucontact *ucontact_caller = 0x00,
            *ucontact_callee = 0x00;
    udomain_t *_d;
    impurecord_t* from_impu, *to_impu;
    str from_uri_clean, to_uri_clean;
    char *p;
    short iFoundCaller = 0,
          iFoundCallee  = 0;
    static unsigned int i_confirmed_count  = 0,
                        i_terminated_count =0;

    if ((cb_types == DLGCB_CONFIRMED) ||
            (cb_types == DLGCB_EXPIRED) ||
            (cb_types == DLGCB_TERMINATED) ||
            (cb_types == DLGCB_DESTROY) ||
            (cb_types == DLGCB_FAILED)) {

        //for now we will abort if there is no dlg_out.... TODO maybe we can only do the caller side....
        if (dlg->dlg_entry_out.first == 0x00) {
            LM_DBG("no dlg out... ignoring!!! for type [%d] - usually happens on failure response in dialog\n",cb_types);
            return;
        }
        register_udomain("location", &_d);
        
        from_uri_clean.s = dlg->from_uri.s;
        from_uri_clean.len = dlg->from_uri.len;
        p = memchr(dlg->from_uri.s, ';', dlg->from_uri.len);
        if (p)
            from_uri_clean.len = p - from_uri_clean.s;
        
        lock_udomain(_d, &from_uri_clean);
        if (get_impurecord(_d, &from_uri_clean, &from_impu) != 0) {
            LM_DBG("Could not find caller impu for [%.*s]\n", from_uri_clean.len, from_uri_clean.s);
            unlock_udomain(_d, &from_uri_clean);
            return;
        }
        
        if (find_contact_from_impu(from_impu, &dlg->caller_contact, &ucontact_caller) !=0) {
            LM_DBG("Unable to find caller contact from dialog.... continuing\n");
            //unlock_udomain(_d, &from_uri_clean);
            //return;
        }
        else {
           iFoundCaller = 1;
        }
        unlock_udomain(_d, &from_uri_clean);
        
        to_uri_clean.s = dlg->dlg_entry_out.first->to_uri.s;
        to_uri_clean.len = dlg->dlg_entry_out.first->to_uri.len;
        p = memchr(dlg->dlg_entry_out.first->to_uri.s, ';', dlg->dlg_entry_out.first->to_uri.len);
        if (p)
            to_uri_clean.len = p - to_uri_clean.s;
        
        lock_udomain(_d, &to_uri_clean);
        if (get_impurecord(_d, &to_uri_clean, &to_impu) != 0) {
            LM_DBG("Could not find callee impu for [%.*s]\n", to_uri_clean.len, to_uri_clean.s);
            unlock_udomain(_d, &to_uri_clean);
            return;
        }
        if (find_contact_from_impu(to_impu, &dlg->dlg_entry_out.first->callee_contact, &ucontact_callee) !=0) {
            LM_DBG("Unable to find callee contact from dialog.... continuing\n");
            //unlock_udomain(_d, &to_uri_clean);
            //return;
        }
        else{            
           iFoundCallee = 1;
        }
        unlock_udomain(_d, &to_uri_clean);
        
    } else {
        LM_ERR("Unknown event type [%d] for callid [%.*s] ", cb_types, dlg->callid.len, dlg->callid.s);
        return;
    }
    if(!iFoundCaller && !iFoundCallee)
    {
        LM_ERR("No Contacts found for both caller && callee ... bailing\n");
        return;
    }
    switch (cb_types) {
        case DLGCB_CONFIRMED:
            LM_DBG("Confirmed contact of type [%d] ,caller_id [%.*s] from handler ", cb_types, dlg->callid.len, dlg->callid.s);
            if (iFoundCaller)
              add_dialog_data_to_contact(ucontact_caller, dlg->h_entry, dlg->h_id);
            if(iFoundCallee)
              add_dialog_data_to_contact(ucontact_callee, dlg->h_entry, dlg->h_id);//dlg->dlg_entry_out.first->h_entry, dlg->dlg_entry_out.first->h_id);
            i_confirmed_count++;
            break;
        case DLGCB_FAILED:
        case DLGCB_DESTROY:
        case DLGCB_EXPIRED:
        case DLGCB_TERMINATED:
            LM_DBG("Terminated contact of type [%d] , caller_id [%.*s] from handler ", cb_types, dlg->callid.len, dlg->callid.s);
            if(iFoundCaller)
               remove_dialog_data_from_contact(ucontact_caller, dlg->h_entry, dlg->h_id);
            if(iFoundCallee)
              //if (dlg->dlg_entry_out.first) {
                remove_dialog_data_from_contact(ucontact_callee, dlg->h_entry, dlg->h_id);//dlg->dlg_entry_out.first->h_entry, dlg->dlg_entry_out.first->h_id);
            //}
            i_terminated_count++;
            break;
    }
}