/** * Creates a new p_dialog structure. * Does not add the structure to the list. * @param call_id - call-id of the dialog * @param host - host that originates/terminates this dialog * @param port - port that originates/terminates this dialog * @param transport - transport that originates/terminates this dialog * @returns the new p_dialog* on success, or NULL on error; */ p_dialog* new_p_dialog(str call_id,str host,int port, int transport) { p_dialog *d; if (!p_dialog_count_increment()) return 0; d = shm_malloc(sizeof(p_dialog)); if (!d) { LOG(L_ERR,"ERR:"M_NAME":new_p_dialog(): Unable to alloc %d bytes\n", sizeof(p_dialog)); goto error; } memset(d,0,sizeof(p_dialog)); d->hash = get_p_dialog_hash(call_id); STR_SHM_DUP(d->call_id,call_id,"shm"); STR_SHM_DUP(d->host,host,"shm"); d->port = port; d->transport = transport; return d; error: out_of_memory: if (d){ if (d->call_id.s) shm_free(d->call_id.s); if (d->host.s) shm_free(d->host.s); shm_free(d); } p_dialog_count_decrement(); return 0; }
/** * Finds and returns a dialog from the hash table. * \note the table should be locked already for the call_id in the parameter * @param call_id - call_id of the dialog * @param dir - the direction * @returns the p_dialog* or NULL if not found */ p_dialog* get_p_dialog_dir_nolock(str call_id,enum p_dialog_direction dir) { p_dialog *d=0; unsigned int hash = get_p_dialog_hash(call_id); d = p_dialogs[hash].head; while(d){ if (d->direction == dir && d->call_id.len == call_id.len && strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) { return d; } d = d->next; } return 0; }
/** * Finds and returns a dialog from the hash table. * \note Locks the hash slot if ok! Call d_unlock(p_dialog->hash) when you are finished) * @param call_id - dialog's call_id * @param host - host that originates/terminates this dialog * @param port - port that originates/terminates this dialog * @param transport - transport that originates/terminates this dialog * @param dir - the direction of the dialog. if NULL, it doesn't matter * \note transport is ignored. */ p_dialog* get_p_dialog(str call_id,str host,int port, int transport,enum p_dialog_direction *dir) { p_dialog *d=0; unsigned int hash = get_p_dialog_hash(call_id); d_lock(hash); d = p_dialogs[hash].head; while(d){ if ((!dir || d->direction == *dir) && d->port == port && /* d->transport == transport &&*/ /* commented because of strange behaviour */ d->host.len == host.len && d->call_id.len == call_id.len && strncasecmp(d->host.s,host.s,host.len)==0 && strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) { return d; } d = d->next; } d_unlock(hash); return 0; }
/** * Decode a dialog from a binary data structure * @param x - binary data to decode from * @returns the p_dialog* where the data has been decoded */ p_dialog* bin_decode_p_dialog(bin_data *x) { p_dialog *d=0; int len,i; str s; char c; unsigned char uc; len = sizeof(p_dialog); d = (p_dialog*) shm_malloc(len); if (!d) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len); goto error; } memset(d,0,len); if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->call_id),&s)) goto error; if (!bin_decode_uchar(x, &uc)) goto error; d->direction = uc; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->host),&s)) goto error; if (!bin_decode_ushort(x, &d->port)) goto error; if (!bin_decode_uchar(x, &uc)) goto error; d->transport = uc; if (!bin_decode_ushort(x, &d->routes_cnt)) goto error; len = sizeof(str)*d->routes_cnt; d->routes = (str*) shm_malloc(len); if (!d) { LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error allocating %d bytes.\n",len); goto error; } memset(d->routes,0,len); for(i=0;i<d->routes_cnt;i++) if (!bin_decode_str(x,&s)||!str_shm_dup(d->routes+i,&s)) goto error; if (!bin_decode_char(x, &c)) goto error; d->method = c; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->method_str),&s)) goto error; if (!bin_decode_int(x, &d->first_cseq)) goto error; if (!bin_decode_int(x, &d->last_cseq)) goto error; if (!bin_decode_char(x, &c)) goto error; d->state = c; if (!bin_decode_time_t(x, &d->expires)) goto error; if (!bin_decode_time_t(x, &d->lr_session_expires)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->refresher),&s)) goto error; if (!bin_decode_uchar(x,&d->uac_supp_timer)) goto error; if (!bin_decode_uchar(x, &d->is_releasing)) goto error; if (!bin_decode_str(x,&s)||!str_shm_dup(&(d->pcc_session_id),&s)) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_c))) goto error; if (!bin_decode_dlg_t(x,&(d->dialog_s))) goto error; d->hash = get_p_dialog_hash(d->call_id); return d; error: LOG(L_ERR,"ERR:"M_NAME":bin_decode_p_dialog: Error while decoding (at %d (%04x)).\n",x->max,x->max); if (d) { if (d->call_id.s) shm_free(d->call_id.s); if (d->host.s) shm_free(d->host.s); if (d->routes_cnt){ for(i=0;i<d->routes_cnt;i++) if (d->routes[i].s) shm_free(d->routes[i].s); shm_free(d->routes); } if (d->method_str.s) shm_free(d->method_str.s); if (d->refresher.s) shm_free(d->refresher.s); shm_free(d); } return 0; }