void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog) { /*check if dialog has changed*/ if (dialog && dialog != op->dialog) { ms_message("Dialog set from [%p] to [%p] for op [%p]",op->dialog,dialog,op); /*fixme, shouldn't we cancel previous dialog*/ if (op->dialog) { belle_sip_dialog_set_application_data(op->dialog,NULL); belle_sip_object_unref(op->dialog); sal_op_unref(op); } op->dialog=dialog; belle_sip_dialog_set_application_data(op->dialog,op); sal_op_ref(op); belle_sip_object_ref(op->dialog); } }
static void presence_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase){ SalOp* op = (SalOp*)user_pointer; switch(status_code){ case 481: { ms_message("The server or remote ua lost the SUBSCRIBE dialog context. Let's restart a new one."); belle_sip_refresher_stop(op->refresher); if (op->dialog) { /*delete previous dialog if any*/ belle_sip_dialog_set_application_data(op->dialog,NULL); belle_sip_object_unref(op->dialog); op->dialog=NULL; } if (sal_op_get_contact_address(op)) { /*contact is also probably not good*/ SalAddress* contact=sal_address_clone(sal_op_get_contact_address(op)); sal_address_set_port(contact,-1); sal_address_set_domain(contact,NULL); sal_op_set_contact_address(op,contact); sal_address_destroy(contact); } sal_subscribe_presence(op,NULL,NULL,-1); break; } } }
static void presence_process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t); belle_sip_response_t* resp; const char *method=belle_sip_request_get_method(req); belle_sip_object_ref(server_transaction); if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); op->pending_server_trans=server_transaction; if (!op->dialog) { if (strcmp(method,"SUBSCRIBE")==0){ op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); belle_sip_dialog_set_application_data(op->dialog,op); sal_op_ref(op); ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); }else{ /* this is a NOTIFY */ ms_message("Receiving out of dialog notify"); handle_notify(op,req); return; } } dialog_state=belle_sip_dialog_get_state(op->dialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op)); break; } case BELLE_SIP_DIALOG_EARLY: ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",method,op->dialog); break; case BELLE_SIP_DIALOG_CONFIRMED: if (strcmp("NOTIFY",method)==0) { handle_notify(op,req); } else if (strcmp("SUBSCRIBE",method)==0) { /*either a refresh or an unsubscribe*/ if (expires && belle_sip_header_expires_get_expires(expires)>0) { op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op)); } else if(expires) { ms_message("Unsubscribe received from [%s]",sal_op_get_from(op)); resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } } break; default: ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state)); break; } }
void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t *t, belle_sip_response_t *resp){ belle_sip_transaction_t *base=(belle_sip_transaction_t*)t; belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(t)); const char* method = belle_sip_request_get_method(req); belle_sip_response_event_t event; belle_sip_dialog_t *dialog=base->dialog; int status_code = belle_sip_response_get_status_code(resp); if (base->last_response) belle_sip_object_unref(base->last_response); base->last_response=(belle_sip_response_t*)belle_sip_object_ref(resp); if (dialog){ if (status_code>=200 && status_code<300 && strcmp(method,"INVITE")==0 && (dialog->state==BELLE_SIP_DIALOG_EARLY || dialog->state==BELLE_SIP_DIALOG_CONFIRMED)){ /*make sure this response matches the current dialog, or creates a new one*/ if (!belle_sip_dialog_match(dialog,(belle_sip_message_t*)resp,FALSE)){ dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE);/*belle_sip_dialog_new(base);*/ if (dialog){ /*copy userdata to avoid application from being lost*/ belle_sip_dialog_set_application_data(dialog,belle_sip_dialog_get_application_data(base->dialog)); belle_sip_message("Handling response creating a new dialog !"); } } } } else if (should_dialog_be_created(t,resp)) { dialog=belle_sip_provider_create_dialog_internal(t->base.provider,BELLE_SIP_TRANSACTION(t),FALSE); } if (dialog && belle_sip_dialog_update(dialog,BELLE_SIP_TRANSACTION(t),FALSE)) { /* retransmition, just return*/ belle_sip_message("[%p] is a 200 ok retransmition on dialog [%p], skiping",resp,dialog); return; } event.source=(belle_sip_object_t*)base->provider; event.client_transaction=t; event.dialog=dialog; event.response=(belle_sip_response_t*)resp; BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(((belle_sip_transaction_t*)t),process_response_event,&event); /*check that 200Ok for INVITEs have been acknowledged by listener*/ if (dialog && strcmp(method,"INVITE")==0) belle_sip_dialog_check_ack_sent(dialog); }
static belle_sip_dialog_t *link_op_with_dialog(SalOp *op, belle_sip_dialog_t* dialog){ belle_sip_dialog_set_application_data(dialog,sal_op_ref(op)); belle_sip_object_ref(dialog); return dialog; }
static void unlink_op_with_dialog(SalOp *op, belle_sip_dialog_t* dialog){ belle_sip_dialog_set_application_data(dialog,NULL); sal_op_unref(op); belle_sip_object_unref(dialog); }