int _eXosip_build_response_default(osip_message_t **dest, osip_dialog_t *dialog, int status, osip_message_t *request) { osip_generic_param_t *tag; osip_message_t *response; int pos; int i; if (request==NULL) return -1; i = osip_message_init(&response); if (i!=0) return -1; /* initialise osip_message_t structure */ /* yet done... */ response->sip_version = (char *)osip_malloc(8*sizeof(char)); sprintf(response->sip_version,"SIP/2.0"); osip_message_set_status_code(response, status); /* handle some internal reason definitions. */ if (MSG_IS_NOTIFY(request) && status==481) { response->reason_phrase = osip_strdup("Subcription Does Not Exist"); } else if (MSG_IS_SUBSCRIBE(request) && status==202) { response->reason_phrase = osip_strdup("Accepted subscription"); } else { response->reason_phrase = osip_strdup(osip_message_get_reason(status)); if (response->reason_phrase==NULL) { if (response->status_code == 101) response->reason_phrase = osip_strdup("Dialog Establishement"); else response->reason_phrase = osip_strdup("Unknown code"); } response->req_uri = NULL; response->sip_method = NULL; } i = osip_to_clone(request->to, &(response->to)); if (i!=0) goto grd_error_1; i = osip_to_get_tag(response->to,&tag); if (i!=0) { /* we only add a tag if it does not already contains one! */ if ((dialog!=NULL) && (dialog->local_tag!=NULL)) /* it should contain the local TAG we created */ { osip_to_set_tag(response->to, osip_strdup(dialog->local_tag)); } else { if (status!=100) osip_to_set_tag(response->to, osip_to_tag_new_random()); } } i = osip_from_clone(request->from, &(response->from)); if (i!=0) goto grd_error_1; pos = 0; while (!osip_list_eol(&request->vias,pos)) { osip_via_t *via; osip_via_t *via2; via = (osip_via_t *)osip_list_get(&request->vias,pos); i = osip_via_clone(via, &via2); if (i!=-0) goto grd_error_1; osip_list_add(&response->vias, via2, -1); pos++; } i = osip_call_id_clone(request->call_id, &(response->call_id)); if (i!=0) goto grd_error_1; i = osip_cseq_clone(request->cseq, &(response->cseq)); if (i!=0) goto grd_error_1; if (MSG_IS_SUBSCRIBE(request)) { osip_header_t *exp; owsip_message_set_header(response, "Event", "presence"); i = osip_message_get_expires(request, 0, &exp); if (exp==NULL) { osip_header_t *cp; i = osip_header_clone(exp, &cp); if (cp!=NULL) osip_list_add(&response->headers, cp, 0); } } osip_message_set_allow(response, "INVITE"); osip_message_set_allow(response, "ACK"); osip_message_set_allow(response, "OPTIONS"); osip_message_set_allow(response, "CANCEL"); osip_message_set_allow(response, "BYE"); osip_message_set_allow(response, "SUBSCRIBE"); osip_message_set_allow(response, "NOTIFY"); osip_message_set_allow(response, "MESSAGE"); osip_message_set_allow(response, "INFO"); osip_message_set_allow(response, "REFER"); *dest = response; return 0; grd_error_1: osip_message_free(response); return -1; }
int eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body) { osip_event_t *evt_answer; osip_message_t *response; int i; char *size; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL || tr->orig_request==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd!=NULL && jd->d_dialog==NULL) { /* element previously removed */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd==NULL) i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); code = 500; /* ? which code to use? */ return -1; } if (code==488) { osip_message_set_content_length(response, "0"); /* TODO: send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; } if ( ! body ) { fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { goto g2atii_error_1; } size = (char *) osip_malloc(6*sizeof(char)); sprintf(size,"%i",strlen(body)); i = osip_message_set_content_length(response, size); osip_free(size); if (i!=0) goto g2atii_error_1; i = owsip_message_set_header(response, "content-type", bodytype); if (i!=0) goto g2atii_error_1; /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog(response, tr->orig_request); if (i!=0) goto g2atii_error_1; /* ?? */ /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed*/ /* right after being sent! */ if (jd==NULL) { i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response); if (i!=0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT(jc->c_dialogs, jd); } eXosip_dialog_set_200ok(jd, response); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); __eXosip_wakeup(); return 0; g2atii_error_1: osip_message_free(response); return -1; }
int eXosip_subscribe_send_subscribe(eXosip_subscribe_t *js, eXosip_dialog_t *jd, const char *expires) { osip_transaction_t *transaction; osip_message_t *subscribe; osip_event_t *sipevent; int i; if (!jd || !jd->d_dialog) { // JULIEN : Maybe the first SUBSCRIBE didn't work // that's why there's no more dialog return -1; } transaction = eXosip_find_last_out_subscribe(js, jd); if (transaction!=NULL) { if (transaction->state!=NICT_TERMINATED && transaction->state!=NIST_TERMINATED) return -1; //<MINHPQ> // Remove the transaction from dialog structure if (jd) owsip_list_remove_element (jd->d_out_trs, transaction); // Remove the transaction from jd->d_out_trs list if (js && (js->s_out_tr == transaction)) { js->s_out_tr = NULL; // Remove the transaction from js->s_out_tr } eXosip_transaction_free(transaction); transaction = NULL; //</MINHPQ> } i = _eXosip_build_request_within_dialog(&subscribe, "SUBSCRIBE", jd->d_dialog); if (i!=0) return -2; //<MINHPQ> if (js->winfo) { owsip_message_set_header(subscribe, "Event", "presence.winfo"); owsip_message_set_header(subscribe, "Accept", "application/watcherinfo+xml"); } //</MINHPQ> owsip_message_set_expires(subscribe, expires); i = osip_transaction_init(&transaction, NICT, eXosip.j_osip, subscribe); if (i!=0) { /* TODO: release the j_call.. */ osip_message_free(subscribe); return -1; } _eXosip_subscribe_set_refresh_interval(js, subscribe); osip_list_add(jd->d_out_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage(subscribe); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event(transaction, sipevent); osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(owsip_dialog_account_get (jd), NULL, jd, js, NULL)); __eXosip_wakeup(); return 0; }