/*======================================================================*/ msg_t *put_bloccante(buffer_t *buffer, msg_t *msg){ sem_wait((&buffer->VUOTE)); pthread_mutex_lock(&(buffer->USO_D)); buffer->buffer_circolare[buffer->D] = msg_copy(msg); buffer->D = (buffer->D+1)%buffer->N; pthread_mutex_unlock(&(buffer->USO_D)); sem_post(&(buffer->PIENE)); return msg; }
/*======================================================================*/ msg_t *get_bloccante(buffer_t *buffer){ sem_wait(&(buffer->PIENE)); pthread_mutex_lock(&(buffer->USO_T)); msg_t * result = (msg_t*)(malloc(sizeof(msg_t))); result = msg_copy(buffer->buffer_circolare[buffer->T]); buffer->buffer_circolare[buffer->T] = NULL; buffer->T = (buffer->T+1)%buffer->N; pthread_mutex_unlock(&(buffer->USO_T)); sem_post(&(buffer->VUOTE)); return result; }
msg_t* put_bloccante(buffer_t* buffer, msg_t* msg){ msg_t* temp = msg_copy(msg); pthread_mutex_lock(&(buffer->uso_d)); while(buffer->k==buffer->size){ pthread_cond_wait(&(buffer->non_pieno),&(buffer->uso_d)); } buffer->queue[buffer->D]=*temp; buffer->D=(buffer->D+1)%(buffer->size); buffer->k++; pthread_cond_signal(&(buffer->non_vuoto)); pthread_mutex_unlock(&(buffer->uso_d)); return temp; }
/*======================================================================*/ msg_t *put_non_bloccante(buffer_t *buffer, msg_t *msg){ if(sem_trywait(&(buffer->VUOTE)) == -1){ msg_t* msg_error = msg_init("BUFFER_ERROR\0"); return msg_error; } else{ pthread_mutex_lock(&(buffer->USO_D)); buffer->buffer_circolare[buffer->D] = msg_copy(msg); buffer->D = ((buffer->D)+1)%buffer->N; pthread_mutex_unlock(&(buffer->USO_D)); sem_post(&(buffer->PIENE)); return msg; } }
msg_t* put_non_bloccante(buffer_t* buffer, msg_t* msg){ msg_t* temp= msg_copy(msg); pthread_mutex_lock(&(buffer->uso_d)); if(buffer->k==buffer->size){ pthread_mutex_unlock(&(buffer->uso_d)); return BUFFER_ERROR; } buffer->queue[buffer->D]=*temp; buffer->D=(buffer->D+1)%(buffer->size); buffer->k++; pthread_cond_signal(&(buffer->non_vuoto)); pthread_mutex_unlock(&(buffer->uso_d)); return temp; }
msg_t* get_non_bloccante(buffer_t* buffer){ msg_t* msg= NULL; pthread_mutex_lock(&(buffer->uso_t)); if(buffer->k==0){ pthread_mutex_unlock(&(buffer->uso_t)); return BUFFER_ERROR; } msg=msg_copy(&(buffer->queue[buffer->T])); buffer->queue[buffer->T].content=NULL; buffer->T=(buffer->T+1)%(buffer->size); buffer->k--; pthread_cond_signal(&(buffer->non_pieno)); pthread_mutex_unlock(&(buffer->uso_t)); return msg; }
msg_t* get_bloccante(buffer_t* buffer){ msg_t* msg= NULL; pthread_mutex_lock(&(buffer->uso_t)); while(buffer->k==0){ pthread_cond_wait(&(buffer->non_vuoto),&(buffer->uso_t)); } msg=msg_copy(&(buffer->queue[buffer->T])); buffer->queue[buffer->T].content=NULL; //Cancello il contenuto, lasciando attivo il puntatore per poi sovrascriverlo buffer->T=(buffer->T+1)%(buffer->size); buffer->k--; pthread_cond_signal(&(buffer->non_pieno)); pthread_mutex_unlock(&(buffer->uso_t)); return msg; }
/*======================================================================*/ msg_t *get_non_bloccante(buffer_t *buffer){ if(sem_trywait(&(buffer->PIENE)) == -1){ msg_t *msg_error = msg_init("BUFFER_ERROR\0"); return msg_error; } else{ pthread_mutex_lock(&(buffer->USO_T)); msg_t * result = (msg_t*)(malloc(sizeof(msg_t))); result = msg_copy(buffer->buffer_circolare[buffer->T]); buffer->buffer_circolare[buffer->T] = NULL; buffer->T = (buffer->T+1)%buffer->N; pthread_mutex_unlock(&(buffer->USO_T)); sem_post(&(buffer->VUOTE)); return result; } }
/** @internal Send a keepalive OPTIONS that probes the registration */ static int keepalive_options_with_registration_probe(outbound_t *ob) { msg_t *req; sip_t *sip; void *request_uri; if (ob->ob_keepalive.orq) return 0; req = msg_copy(ob->ob_keepalive.msg); if (!req) return -1; sip = sip_object(req); assert(sip); request_uri = sip->sip_to->a_url; if (nta_msg_request_complete(req, nta_default_leg(ob->ob_nta), SIP_METHOD_OPTIONS, request_uri) < 0) return msg_destroy(req), -1; if (ob->ob_keepalive.auc[0]) auc_authorization(ob->ob_keepalive.auc, req, (void *)sip, "OPTIONS", request_uri, sip->sip_payload); ob->ob_keepalive.orq = nta_outgoing_mcreate(ob->ob_nta, response_to_keepalive_options, ob, NULL, req, TAG_IF(ob->ob_proxy_override, NTATAG_DEFAULT_PROXY(ob->ob_proxy)), SIPTAG_SUBJECT_STR("REGISTRATION PROBE"), /* NONE is used to remove Max-Forwards: 0 found in ordinary keepalives */ SIPTAG_MAX_FORWARDS(SIP_NONE), TAG_END()); if (!ob->ob_keepalive.orq) return msg_destroy(req), -1; ob->ob_keepalive.validating = 1; ob->ob_keepalive.validated = 0; return 0; }
static int nua_publish_client_template(nua_client_request_t *cr, msg_t **return_msg, tagi_t const *tags) { nua_dialog_usage_t *du; if (cr->cr_event == nua_r_publish) return 0; du = nua_dialog_usage_get(cr->cr_owner->nh_ds, nua_publish_usage, NULL); if (du && du->du_cr) { if (nua_client_set_target(cr, du->du_cr->cr_target) < 0) return -1; *return_msg = msg_copy(du->du_cr->cr_msg); return 1; } return 0; }
static int keepalive_options(outbound_t *ob) { msg_t *req; sip_t *sip; if (ob->ob_keepalive.orq) return 0; if (ob->ob_prefs.validate && ob->ob_registered && !ob->ob_validated) return keepalive_options_with_registration_probe(ob); req = msg_copy(ob->ob_keepalive.msg); if (!req) return -1; sip = sip_object(req); assert(sip); assert(sip->sip_request); if (nta_msg_request_complete(req, nta_default_leg(ob->ob_nta), SIP_METHOD_UNKNOWN, NULL) < 0) return msg_destroy(req), -1; if (ob->ob_keepalive.auc[0]) auc_authorization(ob->ob_keepalive.auc, req, (void *)sip, "OPTIONS", sip->sip_request->rq_url, sip->sip_payload); ob->ob_keepalive.orq = nta_outgoing_mcreate(ob->ob_nta, response_to_keepalive_options, ob, NULL, req, TAG_IF(ob->ob_proxy_override, NTATAG_DEFAULT_PROXY(ob->ob_proxy)), TAG_END()); if (!ob->ob_keepalive.orq) return msg_destroy(req), -1; return 0; }
/**Send a request message. * * @retval 0 if request is pending * @retval >=1 if error event has been sent * @retval < 0 if no error event has been sent */ static int nua_client_request_sendmsg(nua_client_request_t *cr) { nua_handle_t *nh = cr->cr_owner; nua_dialog_state_t *ds = nh->nh_ds; sip_method_t method = cr->cr_method; char const *name = cr->cr_method_name; url_string_t const *url = (url_string_t *)cr->cr_target; nta_leg_t *leg; msg_t *msg; sip_t *sip; int error; assert(cr->cr_orq == NULL); cr->cr_offer_sent = cr->cr_answer_recv = 0; cr->cr_offer_recv = cr->cr_answer_sent = 0; if (!ds->ds_leg && cr->cr_dialog) { ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta, nua_stack_process_request, nh, SIPTAG_CALL_ID(cr->cr_sip->sip_call_id), SIPTAG_FROM(cr->cr_sip->sip_from), SIPTAG_TO(cr->cr_sip->sip_to), SIPTAG_CSEQ(cr->cr_sip->sip_cseq), TAG_END()); if (!ds->ds_leg) return -1; } if (cr->cr_sip->sip_from && ds->ds_leg) { if (cr->cr_sip->sip_from->a_tag == NULL) { if (sip_from_tag(msg_home(cr->cr_msg), cr->cr_sip->sip_from, nta_leg_tag(ds->ds_leg, NULL)) < 0) { return -1; } } } cr->cr_retry_count++; if (ds->ds_leg) leg = ds->ds_leg; else leg = nh->nh_nua->nua_dhandle->nh_ds->ds_leg; /* Default leg */ msg = msg_copy(cr->cr_msg), sip = sip_object(msg); if (msg == NULL) return -1; if (nua_dialog_is_established(ds)) { while (sip->sip_route) sip_route_remove(msg, sip); } else if (!ds->ds_route) { sip_route_t *initial_route = NH_PGET(nh, initial_route); if (initial_route) { initial_route = sip_route_dup(msg_home(msg), initial_route); if (!initial_route) return -1; msg_header_prepend(msg, (msg_pub_t*)sip, /* This should be (msg_header_t **)&sip->sip_route * but directly casting pointer &sip->sip_route gives * spurious type-punning warning */ (msg_header_t **)((char *)sip + offsetof(sip_t, sip_route)), (msg_header_t *)initial_route); } } /** * For in-dialog requests, the request URI is taken from the @Contact * header received from the remote party during dialog establishment, * and the NUTAG_URL() is ignored. * * Also, the @CallID and @CSeq headers and @From and @To tags are * generated based on the dialog information and added to the request. * If the dialog has a route, it is added to the request, too. */ if (nta_msg_request_complete(msg, leg, method, name, url) < 0) { msg_destroy(msg); return -1; } /**@MaxForwards header (with default value set by NTATAG_MAX_FORWARDS()) is * also added now, if it does not exist. */ if (!ds->ds_remote) ds->ds_remote = sip_to_dup(nh->nh_home, sip->sip_to); if (!ds->ds_local) ds->ds_local = sip_from_dup(nh->nh_home, sip->sip_from); /** * Next, values previously set with nua_set_params() or nua_set_hparams() * are used: @Allow, @Supported, @Organization, @UserAgent and * @AllowEvents headers are added to the request if they are not already * set. */ if (!sip->sip_allow) sip_add_dup(msg, sip, (sip_header_t*)NH_PGET(nh, allow)); if (!sip->sip_supported && NH_PGET(nh, supported)) sip_add_dup(msg, sip, (sip_header_t *)NH_PGET(nh, supported)); if (method == sip_method_register && NH_PGET(nh, path_enable) && !sip_has_feature(sip->sip_supported, "path") && !sip_has_feature(sip->sip_require, "path")) sip_add_make(msg, sip, sip_supported_class, "path"); if (!sip->sip_organization && NH_PGET(nh, organization)) sip_add_make(msg, sip, sip_organization_class, NH_PGET(nh, organization)); if (!sip->sip_user_agent && NH_PGET(nh, user_agent)) sip_add_make(msg, sip, sip_user_agent_class, NH_PGET(nh, user_agent)); /** Any node implementing one or more event packages SHOULD include an * appropriate @AllowEvents header indicating all supported events in * all methods which initiate dialogs and their responses (such as * INVITE) and OPTIONS responses. */ if (!sip->sip_allow_events && NH_PGET(nh, allow_events) && (method == sip_method_notify || /* Always in NOTIFY */ (!ds->ds_remote_tag && /* And in initial requests */ (method == sip_method_subscribe || method == sip_method_refer || method == sip_method_options || method == sip_method_invite)))) sip_add_dup(msg, sip, (void *)NH_PGET(nh, allow_events)); /** * Next, the stack generates a @Contact header for the request (unless * the application already gave a @Contact header or it does not want to * use @Contact and indicates that by including SIPTAG_CONTACT(NULL) or * SIPTAG_CONTACT(SIP_NONE) in the tagged parameters.) If the * application has registered the URI in @From header, the @Contact * header used with registration is used. Otherwise, the @Contact header * is generated from the local IP address and port number. */ /**For the initial requests, @ServiceRoute set that was received from the * registrar is also added to the request message. */ if (cr->cr_method != sip_method_register) { if (cr->cr_contactize && cr->cr_has_contact) { sip_contact_t *ltarget = sip_contact_dup(nh->nh_home, sip->sip_contact); if (ds->ds_ltarget) msg_header_free(nh->nh_home, (msg_header_t *)ds->ds_ltarget); ds->ds_ltarget = ltarget; } if (ds->ds_ltarget && !cr->cr_has_contact) sip_add_dup(msg, sip, (sip_header_t *)ds->ds_ltarget); if (nua_registration_add_contact_to_request(nh, msg, sip, cr->cr_contactize && !cr->cr_has_contact && !ds->ds_ltarget, !ds->ds_route) < 0) { msg_destroy(msg); return -1; } } cr->cr_wait_for_cred = 0; if (cr->cr_methods->crm_send) error = cr->cr_methods->crm_send(cr, msg, sip, NULL); else error = nua_base_client_request(cr, msg, sip, NULL); if (error == -1) msg_destroy(msg); return error; }
HvMessage *hv_msg_copy(HvMessage *m) { return msg_copy(m); }