/*! * \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; }
/*! * \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; }
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; }
/*! * \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; } } }
/*! \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; }
/*! * \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] = ®_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; }
/*! * \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] = ®_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; }
/*! * \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] = ®_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; }
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; } }