예제 #1
0
파일: ucontact.c 프로젝트: SipSeb/kamailio
/*!
 * \brief Delete contact from the database by address
 * \param _c deleted contact
 * \return 0 on success, -1 on failure
 */
int db_delete_ucontact_addr(ucontact_t* _c)
{
	char* dom;
	db_key_t keys[4];
	db_val_t vals[4];
	int n;

	if (_c->flags & FL_MEM) {
		return 0;
	}
	struct udomain * _d;
	if(register_udomain(_c->domain->s, &_d) < 0){
		return -1;
	}

    n = 0;
	keys[n] = &user_col;
	vals[n].type = DB1_STR;
	vals[n].nul = 0;
	vals[n].val.str_val = *_c->aor;
	n++;

    keys[n] = &contact_col;
	vals[n].type = DB1_STR;
	vals[n].nul = 0;
	vals[n].val.str_val = _c->c;
	n++;
	
	keys[n] = &callid_col;
	vals[n].type = DB1_STR;
	vals[n].nul = 0;
	vals[n].val.str_val = _c->callid;
	n++;

	if (use_domain) {
	    keys[n] = &domain_col;
		vals[n].type = DB1_STR;
		vals[n].nul = 0;
		dom = memchr(_c->aor->s, '@', _c->aor->len);
		if (dom==0) {
			vals[0].val.str_val.len = 0;
			vals[n].val.str_val = *_c->aor;
		} else {
			vals[0].val.str_val.len = dom - _c->aor->s;
			vals[n].val.str_val.s = dom + 1;
			vals[n].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
		}
		n++;
	}

	if (ul_db_layer_delete(_d, &vals[0].val.str_val, &vals[3].val.str_val, keys, 0, vals, (use_domain) ? (4) : (3)) < 0) {
		LM_ERR("deleting from database failed\n");
		return -1;
	}

	return 0;
}
예제 #2
0
파일: ucontact.c 프로젝트: SipSeb/kamailio
/*!
 * \brief Delete contact from the database by ruid
 * \param _c deleted contact
 * \return 0 on success, -1 on failure
 */
int db_delete_ucontact_ruid(ucontact_t* _c)
{
   db_key_t keys[1];
   db_val_t vals[1];
   int n;
   char * dom;
   str user, domain;

   if (_c->flags & FL_MEM) {
       return 0;
   }

   if(_c->ruid.len<=0) {
       LM_ERR("deleting from database failed - empty ruid\n");
       return -1;
   }

   struct udomain * _d;
   if(register_udomain(_c->domain->s, &_d) < 0){
       return -1;
   }

   n = 0;
   keys[n] = &ruid_col;
   vals[n].type = DB1_STR;
   vals[n].nul = 0;
   vals[n].val.str_val = _c->ruid;
   n++;

   user = *_c->aor;

   if (use_domain) {
       dom = memchr(_c->aor->s, '@', _c->aor->len);
       if (dom==0) {
           user.len = 0;
           domain = *_c->aor;
        } else {
            user.len = dom - _c->aor->s;
            domain.s = dom + 1;
            domain.len = _c->aor->s + _c->aor->len - dom - 1;
        }
   }

   if (ul_db_layer_delete(_d, &user, &domain, keys, 0, vals, n) < 0) {
       LM_ERR("deleting from database failed\n");
       return -1;
    }

   return 0;
}
예제 #3
0
파일: reg_avps.c 프로젝트: 4N7HR4X/kamailio
int read_reg_avps_fixup(void** param, int param_no)
{
	udomain_t* d;

	switch (param_no) {
		case 1:
			if (register_udomain((char*)*param, &d) < 0) {
				ERR("Error while registering domain\n");
				return -1;
			}
			*param = (void*)d;
			break;
		case 2:
			return fixup_var_str_2(param, param_no);
	}
	return 0;
}
예제 #4
0
/*!
 * \brief Expires timer for NO_DB db_mode
 *
 * Expires timer for NO_DB db_mode, process all contacts from
 * the record, delete the expired ones from memory.
 * \param _r processed record
 */
static inline void process_impurecord(impurecord_t* _r) {
    int flag, mustdeleteimpu = 1, n, k;
    unsigned int sl;
    ucontact_t* ptr;
    int hascontacts;
    udomain_t* _d;
    reg_subscriber *s;
    subs_t* sub_dialog;

    get_act_time();

    s = _r->shead;
    LM_DBG("Checking validity of IMPU: <%.*s> registration subscriptions\n", _r->public_identity.len, _r->public_identity.s);
    while (s) {
        if (!valid_subscriber(s, act_time)) {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> expired and removed.\n",
                   s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s);
            delete_subscriber(_r, s);
        } else {
            LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> is valid and expires in %d seconds.\n",
                   s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s,
                   (unsigned int) (s->expires - time(NULL)));
            sl = core_hash(&s->call_id, &s->to_tag, sub_dialog_hash_size);
            LM_DBG("Hash size: <%i>", sub_dialog_hash_size);
            LM_DBG("Searching sub dialog hash info with call_id: <%.*s> and ttag <%.*s> ftag <%.*s> and hash code <%i>", s->call_id.len, s->call_id.s, s->to_tag.len, s->to_tag.s, s->from_tag.len, s->from_tag.s, sl);
            /* search the record in hash table */
            lock_get(&sub_dialog_table[sl].lock);
            sub_dialog = pres_search_shtable(sub_dialog_table, s->call_id, s->to_tag, s->from_tag, sl);
            if (sub_dialog == NULL) {
                LM_ERR("DBG:registrar_timer: Subscription has no dialog record in hash table\n");
            } else {
                LM_DBG("DBG:registrar_timer: Subscription has dialog record in hash table with presentity uri <%.*s>\n", sub_dialog->pres_uri.len, sub_dialog->pres_uri.s);
            }
            lock_release(&sub_dialog_table[sl].lock);
            mustdeleteimpu = 0;
        }
        s = s->next;
    }

    LM_DBG("\tPublic Identity %.*s, Barred: [%d], State: [%s]\n",
           _r->public_identity.len, _r->public_identity.s,
           _r->barring,
           get_impu_regstate_as_string(_r->reg_state));
    flag = 0;
    hascontacts = 0;
    num_contacts_to_expire = 0;
    for (k = 0; (k < _r->num_contacts) && (k < MAX_CONTACTS_PER_IMPU); k++) {
        if ((ptr = _r->newcontacts[k])) {
            flag = 1;
            if (!VALID_CONTACT(ptr, act_time)) {
                if (ptr->state == CONTACT_DELETED) {
                    LM_DBG("Contact: <%.*s> has been deleted - unlinking from IMPU\n", ptr->c.len, ptr->c.s);
                    contacts_to_expire[num_contacts_to_expire] = ptr;
                    num_contacts_to_expire++;
                } else if (ptr->state == CONTACT_EXPIRE_PENDING_NOTIFY) {
                    LM_DBG("Contact: <%.*s> is in state CONTACT_EXPIRE_PENDING_NOTIFY....running callback\n", ptr->c.len, ptr->c.s);
                    if (exists_ulcb_type(_r->cbs, UL_IMPU_DELETE_CONTACT)) {
                        LM_DBG("Running callback UL_IMPU_DELETE_CONTACT for contact [%.*s] and impu [%.*s]\n", ptr->c.len, ptr->c.s, _r->public_identity.len, _r->public_identity.s);
                        run_ul_callbacks(_r->cbs, UL_IMPU_DELETE_CONTACT, _r, ptr);
                    }
                    hascontacts = 1;    // we do this because the impu must only be deleted if in state deleted....
                    mustdeleteimpu = 0;
                } else if (ptr->state == CONTACT_VALID) {
                    LM_DBG("Contact: <%.*s> is in state valid but it has expired.... ignoring as the contact check will set the appropriate action/state\n", ptr->c.len, ptr->c.s);
                    mustdeleteimpu = 0;
                    hascontacts = 1;
                } else {
                    LM_WARN("Bogus state for contact [%.*s] - state: %d... ignoring", ptr->c.len, ptr->c.s, ptr->state);
                    mustdeleteimpu = 0;
                    hascontacts = 1;
                }
            } else {
                LM_DBG("\t\tContact #%i - %.*s, Ref [%d] (expires in %ld seconds) (State: %d)\n",
                       k, ptr->c.len, ptr->c.s, ptr->ref_count, ptr->expires - act_time, ptr->state);
                mustdeleteimpu = 0;
                hascontacts = 1;
            }
        } else {
            LM_WARN("num_contacts and actual data not consistent... .aborting\n");
            break;
        }
    }

    if (num_contacts_to_expire > 0) {
        LM_DBG("\tThere are %d contacts to expire/unlink\n", num_contacts_to_expire);
        for (n = 0; n < num_contacts_to_expire; n++) {
            ptr = contacts_to_expire[n];
            LM_DBG("\t\texpiring contact %i: [%.*s] in slot [%d]\n", n, contacts_to_expire[n]->c.len, contacts_to_expire[n]->c.s, contacts_to_expire[n]->sl);
            sl = ptr->sl;
            lock_contact_slot_i(sl);
            unlink_contact_from_impu(_r, ptr, 1, 0 /*implicit dereg of contact from IMPU*/);
            unlock_contact_slot_i(sl);
        }
    }

    if (!flag)
        LM_DBG("no contacts\n");

    if (mustdeleteimpu) {
        register_udomain("location", &_d);
        delete_impurecord(_d, &_r->public_identity, _r);
    } else {
        if (!hascontacts) {
            LM_DBG("This impu is not to be deleted but has no contacts - changing state to IMPU_UNREGISTERED\n");
            _r->reg_state = IMPU_UNREGISTERED;
        }
    }
}
예제 #5
0
파일: ul_mod.c 프로젝트: gbour/kamailio
/*! \brief
 * Module initialization function
 */
static int mod_init(void)
{
	int i;
	udomain_t* d;

	if(sruid_init(&_ul_sruid, '-', "ulcx", SRUID_INC)<0)
		return -1;

#ifdef STATISTICS
	/* register statistics */
	if (register_module_stats( exports.name, mod_stats)!=0 ) {
		LM_ERR("failed to register core statistics\n");
		return -1;
	}
#endif
	
	if(register_mi_mod(exports.name, mi_cmds)!=0)
	{
		LM_ERR("failed to register MI commands\n");
		return -1;
	}

	if (rpc_register_array(ul_rpc)!=0)
	{
		LM_ERR("failed to register RPC commands\n");
		return -1;
	}

	/* Compute the lengths of string parameters */
	ruid_col.len = strlen(ruid_col.s);
	user_col.len = strlen(user_col.s);
	domain_col.len = strlen(domain_col.s);
	contact_col.len = strlen(contact_col.s);
	expires_col.len = strlen(expires_col.s);
	q_col.len = strlen(q_col.s);
	callid_col.len = strlen(callid_col.s);
	cseq_col.len = strlen(cseq_col.s);
	flags_col.len = strlen(flags_col.s);
	cflags_col.len = strlen(cflags_col.s);
	user_agent_col.len = strlen(user_agent_col.s);
	received_col.len = strlen(received_col.s);
	path_col.len = strlen(path_col.s);
	sock_col.len = strlen(sock_col.s);
	methods_col.len = strlen(methods_col.s);
	instance_col.len = strlen(instance_col.s);
	reg_id_col.len = strlen(reg_id_col.s);
	last_mod_col.len = strlen(last_mod_col.s);
	db_url.len = strlen(db_url.s);

	if(ul_xavp_contact_name.s!=NULL)
		ul_xavp_contact_name.len = strlen(ul_xavp_contact_name.s);

	if(ul_hash_size<=1)
		ul_hash_size = 512;
	else
		ul_hash_size = 1<<ul_hash_size;
	ul_locks_no = ul_hash_size;

	/* check matching mode */
	switch (matching_mode) {
		case CONTACT_ONLY:
		case CONTACT_CALLID:
		case CONTACT_PATH:
			break;
		default:
			LM_ERR("invalid matching mode %d\n", matching_mode);
	}

	if(ul_init_locks()!=0)
	{
		LM_ERR("locks array initialization failed\n");
		return -1;
	}

	/* Register cache timer */
	if(ul_timer_procs<=0)
	{
		if (timer_interval > 0)
			register_timer(ul_core_timer, 0, timer_interval);
	}
	else
		register_sync_timers(ul_timer_procs);

	/* init the callbacks list */
	if ( init_ulcb_list() < 0) {
		LM_ERR("usrloc/callbacks initialization failed\n");
		return -1;
	}

	/* Shall we use database ? */
	if (db_mode != NO_DB) { /* Yes */
		if (db_bind_mod(&db_url, &ul_dbf) < 0) { /* Find database module */
			LM_ERR("failed to bind database module\n");
			return -1;
		}
		if (!DB_CAPABILITY(ul_dbf, DB_CAP_ALL)) {
			LM_ERR("database module does not implement all functions"
					" needed by the module\n");
			return -1;
		}
		if(ul_fetch_rows<=0) {
			LM_ERR("invalid fetch_rows number '%d'\n", ul_fetch_rows);
			return -1;
		}
	}

	if (nat_bflag==(unsigned int)-1) {
		nat_bflag = 0;
	} else if ( nat_bflag>=8*sizeof(nat_bflag) ) {
		LM_ERR("bflag index (%d) too big!\n", nat_bflag);
		return -1;
	} else {
		nat_bflag = 1<<nat_bflag;
	}

	for(i=0; i<ul_preload_index; i++) {
		if(register_udomain((const char*)ul_preload_list[i], &d)<0) {
			LM_ERR("cannot register preloaded table %s\n", ul_preload_list[i]);
			return -1;
		}
	}

	if (handle_lost_tcp && db_mode == DB_ONLY)
		LM_WARN("handle_lost_tcp option makes nothing in DB_ONLY mode\n");

	init_flag = 1;

	return 0;
}
예제 #6
0
파일: ucontact.c 프로젝트: SipSeb/kamailio
 /*!
 * \brief Update contact in the database by ruid
 * \param _c updated contact
 * \return 0 on success, -1 on failure
 */
int db_update_ucontact_ruid(ucontact_t* _c)
{
   db_key_t keys1[1];
   db_val_t vals1[1];
   int n1;

   db_key_t keys2[17];
   db_val_t vals2[17];
   int n2;

   char *dom;
   str user, domain;

   if (_c->flags & FL_MEM) {
       return 0;
   }

   if(_c->ruid.len<=0) {
       LM_ERR("updating record in database failed - empty ruid\n");
       return -1;
   }

   struct udomain * _d;
   if(register_udomain(_c->domain->s, &_d) < 0){
       return -1;
   }

   n1 = 0;
   keys1[n1] = &ruid_col;
   vals1[n1].type = DB1_STR;
   vals1[n1].nul = 0;
   vals1[n1].val.str_val = _c->ruid;
   n1++;

   n2 = 0;
   keys2[n2] = &contact_col;
   vals2[n2].type = DB1_STR;
   vals2[n2].nul = 0;
   vals2[n2].val.str_val = _c->c;
   n2++;

   keys2[n2] = &expires_col;
   vals2[n2].type = DB1_DATETIME;
   vals2[n2].nul = 0;
   vals2[n2].val.time_val = _c->expires;
   n2++;

   keys2[n2] = &q_col;
   vals2[n2].type = DB1_DOUBLE;
   vals2[n2].nul = 0;
   vals2[n2].val.double_val = q2double(_c->q);
   n2++;

   keys2[n2] = &cseq_col;
   vals2[n2].type = DB1_INT;
   vals2[n2].nul = 0;
   vals2[n2].val.int_val = _c->cseq;
   n2++;

   keys2[n2] = &flags_col;
   vals2[n2].type = DB1_INT;
   vals2[n2].nul = 0;
   vals2[n2].val.bitmap_val = _c->flags;
   n2++;

   keys2[n2] = &cflags_col;
   vals2[n2].type = DB1_INT;
   vals2[n2].nul = 0;
   vals2[n2].val.bitmap_val = _c->cflags;
   n2++;

   keys2[n2] = &user_agent_col;
   vals2[n2].type = DB1_STR;
   vals2[n2].nul = 0;
   vals2[n2].val.str_val = _c->user_agent;
   n2++;

   keys2[n2] = &received_col;
   vals2[n2].type = DB1_STR;
   if (_c->received.s == 0) {
       vals2[n2].nul = 1;
   } else {
       vals2[n2].nul = 0;
       vals2[n2].val.str_val = _c->received;
   }
   n2++;

   keys2[n2] = &path_col;
   vals2[n2].type = DB1_STR;
   if (_c->path.s == 0) {
       vals2[n2].nul = 1;
   } else {
       vals2[n2].nul = 0;
       vals2[n2].val.str_val = _c->path;
   }
   n2++;

   keys2[n2] = &sock_col;
   vals2[n2].type = DB1_STR;
   if (_c->sock) {
       vals2[n2].val.str_val = _c->sock->sock_str;
       vals2[n2].nul = 0;
   } else {
       vals2[n2].nul = 1;
   }
   n2++;

   keys2[n2] = &methods_col;
   vals2[n2].type = DB1_BITMAP;
   if (_c->methods == 0xFFFFFFFF) {
       vals2[n2].nul = 1;
   } else {
       vals2[n2].val.bitmap_val = _c->methods;
       vals2[n2].nul = 0;
   }
   n2++;

   keys2[n2] = &last_mod_col;
   vals2[n2].type = DB1_DATETIME;
   vals2[n2].nul = 0;
   vals2[n2].val.time_val = _c->last_modified;
   n2++;

   keys2[n2] = &callid_col;
   vals2[n2].type = DB1_STR;
   vals2[n2].nul = 0;
   vals2[n2].val.str_val = _c->callid;
   n2++;

   keys2[n2] = &instance_col;
   if(_c->instance.len>0)
   {
       vals2[n2].type = DB1_STR;
       vals2[n2].nul = 0;
       vals2[n2].val.str_val = _c->instance;
   } else {
       vals2[n2].nul = 1;
   }
   n2++;

   keys2[n2] = &reg_id_col;
   vals2[n2].type = DB1_INT;
   vals2[n2].nul = 0;
   vals2[n2].val.int_val = (int)_c->reg_id;
   n2++;

   user = *_c->aor;

   if (use_domain) {
       dom = memchr(_c->aor->s, '@', _c->aor->len);
       if (dom==0) {
           user.len = 0;
           domain = *_c->aor;
       } else {
           user.len = dom - _c->aor->s;
           domain.s = dom + 1;
           domain.len = _c->aor->s + _c->aor->len - dom - 1;
       }
   }


   if (ul_db_layer_update(_d, &user, &domain, keys1, 0, vals1, keys2, vals2,
   n1, n2) < 0) {
       LM_ERR("updating database failed\n");
       return -1;
   }



   return 0;
}
예제 #7
0
파일: ucontact.c 프로젝트: SipSeb/kamailio
/*!
 * \brief Update contact in the database by address
 * \param _c updated contact
 * \return 0 on success, -1 on failure
 */
int db_update_ucontact_addr(ucontact_t* _c)
{
	char* dom;
	db_key_t keys1[4];
	db_val_t vals1[4];
	int n1;

	db_key_t keys2[14];
	db_val_t vals2[14];
	int nr_cols2;

	if (_c->flags & FL_MEM) {
		return 0;
	}
	struct udomain * _d;
	if(register_udomain(_c->domain->s, &_d) < 0){
		return -1;
	}

	keys2[0] = &expires_col;
	keys2[1] = &q_col;
	keys2[2] = &cseq_col;
	keys2[3] = &flags_col;
	keys2[4] = &cflags_col;
	keys2[5] = &user_agent_col;
	keys2[6] = &received_col;
	keys2[7] = &path_col;
	keys2[8] = &sock_col;
	keys2[9] = &methods_col;
	keys2[10] = &last_mod_col;
	keys2[11] = &ruid_col;
	keys2[12] = &instance_col;
	keys2[13] = &reg_id_col;

	n1 = 0;
	keys1[n1] = &user_col;
	vals1[n1].type = DB1_STR;
	vals1[n1].nul = 0;
	vals1[n1].val.str_val = *_c->aor;

	n1++;
	keys1[n1] = &contact_col;
	vals1[n1].type = DB1_STR;
	vals1[n1].nul = 0;
	vals1[n1].val.str_val = _c->c;
    
    n1++;
    keys1[n1] = &callid_col;
	vals1[n1].type = DB1_STR;
	vals1[n1].nul = 0;
	vals1[n1].val.str_val = _c->callid;

	n1++;

	vals2[0].type = DB1_DATETIME;
	vals2[0].nul = 0;
	vals2[0].val.time_val = _c->expires;

	vals2[1].type = DB1_DOUBLE;
	vals2[1].nul = 0;
	vals2[1].val.double_val = q2double(_c->q);

	vals2[2].type = DB1_INT;
	vals2[2].nul = 0;
	vals2[2].val.int_val = _c->cseq;

	vals2[3].type = DB1_INT;
	vals2[3].nul = 0;
	vals2[3].val.bitmap_val = _c->flags;

	vals2[4].type = DB1_INT;
	vals2[4].nul = 0;
	vals2[4].val.bitmap_val = _c->cflags;

	vals2[5].type = DB1_STR;
	vals2[5].nul = 0;
	vals2[5].val.str_val = _c->user_agent;

	vals2[6].type = DB1_STR;
	if (_c->received.s == 0) {
		vals2[6].nul = 1;
	} else {
		vals2[6].nul = 0;
		vals2[6].val.str_val = _c->received;
	}
	
	vals2[7].type = DB1_STR;
	if (_c->path.s == 0) {
		vals2[7].nul = 1;
	} else {
		vals2[7].nul = 0;
		vals2[7].val.str_val = _c->path;
	}

	vals2[8].type = DB1_STR;
	if (_c->sock) {
		vals2[8].val.str_val = _c->sock->sock_str;
		vals2[8].nul = 0;
	} else {
		vals2[8].nul = 1;
	}

	vals2[9].type = DB1_BITMAP;
	if (_c->methods == 0xFFFFFFFF) {
		vals2[9].nul = 1;
	} else {
		vals2[9].val.bitmap_val = _c->methods;
		vals2[9].nul = 0;
	}

	vals2[10].type = DB1_DATETIME;
	vals2[10].nul = 0;
	vals2[10].val.time_val = _c->last_modified;

    nr_cols2 = 11;
	if(_c->ruid.len>0)
	{
		vals2[nr_cols2].type = DB1_STR;
		vals2[nr_cols2].nul = 0;
		vals2[nr_cols2].val.str_val = _c->ruid;
	} else {
		vals2[nr_cols2].nul = 1;
	}
    
    nr_cols2++;
	if(_c->instance.len>0)
	{
		vals2[nr_cols2].type = DB1_STR;
		vals2[nr_cols2].nul = 0;
		vals2[nr_cols2].val.str_val = _c->instance;
	} else {
		vals2[nr_cols2].nul = 1;
	}

    nr_cols2++;
	vals2[nr_cols2].type = DB1_INT;
	vals2[nr_cols2].nul = 0;
	vals2[nr_cols2].val.int_val = (int)_c->reg_id;

	nr_cols2++;

	if (use_domain) {
	    keys1[n1] = &domain_col;
	    vals1[n1].type = DB1_STR;
	    vals1[n1].nul = 0;
		dom = memchr(_c->aor->s, '@', _c->aor->len);
		if (dom==0) {
			vals1[0].val.str_val.len = 0;
			vals1[n1].val.str_val = *_c->aor;
		} else {
			vals1[0].val.str_val.len = dom - _c->aor->s;
			vals1[n1].val.str_val.s = dom + 1;
			vals1[n1].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
		}
		n1++;
	}

	if (ul_db_layer_update(_d, &vals1[0].val.str_val, &vals1[n1-1].val.str_val, keys1, 0, vals1, keys2, vals2,
	            n1, nr_cols2) < 0) 
	{
		LM_ERR("updating database failed\n");
		return -1;
	}

	return 0;
}
예제 #8
0
파일: ucontact.c 프로젝트: SipSeb/kamailio
/*!
 * \brief Insert contact into the database
 * \param _c inserted contact
 * \return 0 on success, -1 on failure
 */
int db_insert_ucontact(ucontact_t* _c)
{
	char* dom;
	db_key_t keys[18];
	db_val_t vals[18];
	int nr_cols = 0;

	int nr_cols_key = 0;
	struct udomain * _d;
	str user={0, 0};
	str domain={0, 0};

	if (_c->flags & FL_MEM) {
		return 0;
	}

	if(register_udomain(_c->domain->s, &_d) < 0){
		return -1;
	}
	LM_INFO("Domain set for contact %.*s\n", _c->domain->len, _c->domain->s);

	keys[nr_cols] = &user_col;
	vals[nr_cols].type = DB1_STR;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.str_val = *_c->aor;
	nr_cols++;

	keys[nr_cols] = &contact_col;
	vals[nr_cols].type = DB1_STR;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.str_val = _c->c;
	nr_cols++;

	if(use_domain) {
		keys[nr_cols] = &domain_col;
		vals[nr_cols].type = DB1_STR;
		vals[nr_cols].nul = 0;

		dom = memchr(_c->aor->s, '@', _c->aor->len);
		if (dom==0) {
			LM_INFO("*** use domain and AOR does not contain @\n");
			vals[nr_cols].val.str_val.len = 0;
			vals[nr_cols].val.str_val.s = 0;
		} else {
			vals[0].val.str_val.len = dom - _c->aor->s;
			vals[nr_cols].val.str_val.s = dom + 1;
			vals[nr_cols].val.str_val.len = _c->aor->s + _c->aor->len - dom - 1;
		}
		domain = vals[nr_cols].val.str_val;
		LM_INFO("** Username=%.*s  Domain=%.*s\n", vals[0].val.str_val.len, vals[0].val.str_val.s,
				vals[nr_cols].val.str_val.len, vals[nr_cols].val.str_val.s);
		nr_cols++;
	}
	user = vals[0].val.str_val;

	keys[nr_cols] = &expires_col;
	vals[nr_cols].type = DB1_DATETIME;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.time_val = _c->expires;
	nr_cols++;

	keys[nr_cols] = &q_col;
	vals[nr_cols].type = DB1_DOUBLE;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.double_val = q2double(_c->q);
	nr_cols++;

	keys[nr_cols] = &callid_col;
	vals[nr_cols].type = DB1_STR;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.str_val = _c->callid;
	nr_cols++;

	keys[nr_cols] = &cseq_col;
	vals[nr_cols].type = DB1_INT;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.int_val = _c->cseq;
	nr_cols++;

	keys[nr_cols] = &flags_col;
	vals[nr_cols].type = DB1_INT;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.bitmap_val = _c->flags;
	nr_cols++;

	keys[nr_cols] = &cflags_col;
	vals[nr_cols].type = DB1_INT;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.bitmap_val = _c->cflags;
	nr_cols++;

	keys[nr_cols] = &user_agent_col;
	vals[nr_cols].type = DB1_STR;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.str_val = _c->user_agent;
	nr_cols++;

	keys[nr_cols] = &received_col;
	vals[nr_cols].type = DB1_STR;
	if (_c->received.s == 0) {
		vals[nr_cols].nul = 1;
	} else {
		vals[nr_cols].nul = 0;
		vals[nr_cols].val.str_val = _c->received;
	}
	nr_cols++;

	keys[nr_cols] = &path_col;
	vals[nr_cols].type = DB1_STR;
	if (_c->path.s == 0) {
		vals[nr_cols].nul = 1;
	} else {
		vals[nr_cols].nul = 0;
		vals[nr_cols].val.str_val = _c->path;
	}
	nr_cols++;

	keys[nr_cols] = &sock_col;
	vals[nr_cols].type = DB1_STR;
	if (_c->sock) {
		vals[nr_cols].val.str_val = _c->sock->sock_str;
		vals[nr_cols].nul = 0;
	} else {
		vals[nr_cols].nul = 1;
	}
	nr_cols++;

	keys[nr_cols] = &methods_col;
	vals[nr_cols].type = DB1_BITMAP;
	if (_c->methods == 0xFFFFFFFF) {
		vals[nr_cols].nul = 1;
	} else {
		vals[nr_cols].val.bitmap_val = _c->methods;
		vals[nr_cols].nul = 0;
	}
	nr_cols++;

	keys[nr_cols] = &last_mod_col;
	vals[nr_cols].type = DB1_DATETIME;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.time_val = _c->last_modified;
	nr_cols++;

	keys[nr_cols] = &ruid_col;
	if(_c->ruid.len>0)
	{
		vals[nr_cols].type = DB1_STR;
		vals[nr_cols].nul = 0;
		vals[nr_cols].val.str_val = _c->ruid;
	} else {
		vals[nr_cols].nul = 1;
	}
	nr_cols++;

	keys[nr_cols] = &instance_col;
	if(_c->instance.len>0)
	{
		vals[nr_cols].type = DB1_STR;
		vals[nr_cols].nul = 0;
		vals[nr_cols].val.str_val = _c->instance;
	} else {
		vals[nr_cols].nul = 1;
	}
	nr_cols++;

	keys[nr_cols] = &reg_id_col;
	vals[nr_cols].type = DB1_INT;
	vals[nr_cols].nul = 0;
	vals[nr_cols].val.int_val = (int)_c->reg_id;
	nr_cols++;

	nr_cols_key  = nr_cols;
	/* to prevent errors from the DB because of duplicated entries */
	
	if (ul_db_layer_replace(_d, &user, &domain, keys, vals, nr_cols, nr_cols_key) <0) {
		LM_ERR("inserting contact in db failed\n");
		return -1;
	}

	return 0;
}
예제 #9
0
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;
    }
}