void *tunnelclient; }; static belle_sip_channel_t *tunnel_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){ belle_sip_channel_t *chan=belle_sip_channel_new_tunnel(lp->stack, ((belle_sip_tunnel_listening_point_t*)lp)->tunnelclient, belle_sip_uri_get_host(lp->listening_uri), belle_sip_uri_get_port(lp->listening_uri), hop->host, hop->port); return chan; } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_tunnel_listening_point_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_tunnel_listening_point_t) { { BELLE_SIP_VPTR_INIT(belle_sip_tunnel_listening_point_t, belle_sip_listening_point_t,TRUE), NULL, NULL, NULL }, "UDP", tunnel_create_channel } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END static void belle_sip_tunnel_listening_point_init(belle_sip_tunnel_listening_point_t *lp, belle_sip_stack_t *s, void *tunnelclient) { belle_sip_listening_point_init((belle_sip_listening_point_t*)lp,s,"0.0.0.0",5060); lp->tunnelclient = tunnelclient; }
} static void transaction_destroy(belle_sip_transaction_t *t){ if (t->request) belle_sip_object_unref(t->request); if (t->last_response) belle_sip_object_unref(t->last_response); if (t->channel) belle_sip_object_unref(t->channel); if (t->branch_id) belle_sip_free(t->branch_id); belle_sip_transaction_set_dialog(t,NULL); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_transaction_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_transaction_t) { BELLE_SIP_VPTR_INIT(belle_sip_transaction_t,belle_sip_object_t,FALSE), (belle_sip_object_destroy_t) transaction_destroy, NULL,/*no clone*/ NULL,/*no marshal*/ }, NULL /*on_terminate*/ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END void *belle_sip_transaction_get_application_data(const belle_sip_transaction_t *t){ return t->appdata; } void belle_sip_transaction_set_application_data(belle_sip_transaction_t *t, void *data){ t->appdata=data; }
belle_sip_object_unref(obj->inactivity_timer); } if (obj->public_ip) belle_sip_free(obj->public_ip); if (obj->outgoing_messages) belle_sip_list_free_with_data(obj->outgoing_messages,belle_sip_object_unref); channel_end_send_background_task(obj); channel_end_recv_background_task(obj); /*normally this should do nothing because it sould have been terminated already, however leaving a background task open is so dangerous that we have to be paranoid*/ belle_sip_message("Channel [%p] destroyed",obj); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_channel_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_channel_t) { BELLE_SIP_VPTR_INIT(belle_sip_channel_t,belle_sip_source_t,FALSE), (belle_sip_object_destroy_t)belle_sip_channel_destroy, NULL, /*clone*/ NULL, /*marshal*/ } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END static void fix_incoming_via(belle_sip_request_t *msg, const struct addrinfo* origin){ char received[NI_MAXHOST]; char rport[NI_MAXSERV]; belle_sip_header_via_t *via; int err; struct sockaddr_storage saddr; socklen_t slen=sizeof(saddr); if (!origin) {
belle_sip_transaction_start_timer(base,obj->timer_A); } obj->timer_B=belle_sip_timeout_source_new((belle_sip_source_func_t)ict_on_timer_B,obj,cfg->T1*64); belle_sip_transaction_start_timer(base,obj->timer_B); belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->request); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_ict_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_ict_t) { { { BELLE_SIP_VPTR_INIT(belle_sip_ict_t,belle_sip_client_transaction_t,TRUE), (belle_sip_object_destroy_t)ict_destroy, NULL, NULL }, (void (*)(belle_sip_transaction_t*))on_ict_terminate }, (void (*)(belle_sip_client_transaction_t*))ict_send_request, (void (*)(belle_sip_client_transaction_t*,belle_sip_response_t*))ict_on_response } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END belle_sip_ict_t *belle_sip_ict_new(belle_sip_provider_t *prov, belle_sip_request_t *req){ belle_sip_ict_t *obj=belle_sip_object_new(belle_sip_ict_t); belle_sip_client_transaction_init((belle_sip_client_transaction_t*)obj,prov,req);
obj->headers=belle_sip_list_copy_with_data(orig->headers,(void *(*)(void*))belle_sip_object_clone_and_ref); if (orig->headerStringBuffer!=NULL) { obj->headerStringBuffer = strdup(orig->headerStringBuffer); } } static void belle_sip_body_handler_destroy(belle_sip_body_handler_t *obj){ belle_sip_list_free_with_data(obj->headers,belle_sip_object_unref); belle_sip_free(obj->headerStringBuffer); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_body_handler_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_body_handler_t) { BELLE_SIP_VPTR_INIT(belle_sip_body_handler_t,belle_sip_object_t,TRUE), (belle_sip_object_destroy_t) belle_sip_body_handler_destroy, (belle_sip_object_clone_t) belle_sip_body_handler_clone, NULL,/*no marshal*/ }, NULL, /*chunk_recv*/ NULL /*chunk_send*/ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END void belle_sip_body_handler_init(belle_sip_body_handler_t *obj, belle_sip_body_handler_progress_callback_t progress_cb, void *user_data){ obj->user_data=user_data; obj->progress_cb=progress_cb; obj->headers = NULL; /* header is not used in most of the case, set it using a dedicated function if needed */ obj->headerStringBuffer = NULL; /* header string buffer is set when adding a body handler to a multipart body handler */ }
} static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){ belle_sip_channel_t *chan=belle_sip_channel_new_tls(lp->stack, ((belle_sip_tls_listening_point_t*) lp)->crypto_config ,belle_sip_uri_get_host(lp->listening_uri) ,belle_sip_uri_get_port(lp->listening_uri) ,hop->cname ,hop->host,hop->port); return chan; } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_tls_listening_point_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_tls_listening_point_t) { { BELLE_SIP_VPTR_INIT(belle_sip_tls_listening_point_t, belle_sip_stream_listening_point_t,TRUE), (belle_sip_object_destroy_t)belle_sip_tls_listening_point_uninit, NULL, NULL }, "TLS", tls_create_channel } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END #ifdef ENABLE_SERVER_SOCKETS static int on_new_connection(void *userdata, unsigned int revents){ belle_sip_socket_t child; struct sockaddr_storage addr; socklen_t slen=sizeof(addr); belle_sip_tls_listening_point_t *lp=(belle_sip_tls_listening_point_t*)userdata;
} for (iterator=lp->channels;iterator!=NULL;iterator=iterator->next) { belle_sip_channel_t *chan=(belle_sip_channel_t*)iterator->data; belle_sip_channel_force_close(chan); } lp->channels=belle_sip_list_free_with_data(lp->channels,(void (*)(void*))belle_sip_object_unref); } int belle_sip_listening_point_get_channel_count(const belle_sip_listening_point_t *lp){ return belle_sip_list_size(lp->channels); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_listening_point_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_listening_point_t) { BELLE_SIP_VPTR_INIT(belle_sip_listening_point_t, belle_sip_object_t,FALSE), (belle_sip_object_destroy_t)belle_sip_listening_point_uninit, NULL, NULL }, NULL, NULL BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END const char *belle_sip_listening_point_get_ip_address(const belle_sip_listening_point_t *lp){ return belle_sip_uri_get_host(lp->listening_uri); } int belle_sip_listening_point_get_port(const belle_sip_listening_point_t *lp){ return belle_sip_uri_get_listening_port(lp->listening_uri); }
LinphoneLDAPContactProvider* linphone_ldap_contact_provider_cast(void* obj) { return BELLE_SIP_CAST(obj, LinphoneLDAPContactProvider); } int linphone_ldap_contact_provider_available() { return 1; } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactProvider); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(LinphoneLDAPContactProvider) { { BELLE_SIP_VPTR_INIT(LinphoneLDAPContactProvider,LinphoneContactProvider,TRUE), (belle_sip_object_destroy_t)linphone_ldap_contact_provider_destroy, NULL, (belle_sip_object_marshal_t)linphone_ldap_contact_provider_marshal }, "LDAP", (LinphoneContactProviderStartSearchMethod)linphone_ldap_contact_provider_begin_search, (LinphoneContactProviderCancelSearchMethod)linphone_ldap_contact_provider_cancel_search } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END #else /* Stubbed implementation */ LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPContactProvider* ld,
int udp_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai){ struct sockaddr_storage laddr; socklen_t lslen=sizeof(laddr); if (obj->local_ip==NULL){ belle_sip_get_src_addr_for(ai->ai_addr,ai->ai_addrlen,(struct sockaddr*)&laddr,&lslen,obj->local_port); } belle_sip_channel_set_ready(obj,(struct sockaddr*)&laddr,lslen); return 0; } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_udp_channel_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_udp_channel_t) { { BELLE_SIP_VPTR_INIT(belle_sip_udp_channel_t,belle_sip_channel_t,FALSE), (belle_sip_object_destroy_t)udp_channel_uninit, NULL, NULL }, "UDP", 0, /*is_reliable*/ udp_channel_connect, udp_channel_send, udp_channel_recv /*no close method*/ } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END belle_sip_channel_t * belle_sip_channel_new_udp(belle_sip_stack_t *stack, int sock, const char *bindip, int localport, const char *dest, int port){ belle_sip_udp_channel_t *obj=belle_sip_object_new(belle_sip_udp_channel_t);
belle_sip_channel_set_socket(obj,sock,(belle_sip_source_func_t)tls_process_data); return 0; } return -1; } BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_channel_t,belle_sip_stream_channel_t) BELLE_SIP_DECLARE_CUSTOM_VPTR_END BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_tls_channel_t); BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_tls_channel_t) { { { BELLE_SIP_VPTR_INIT(belle_sip_tls_channel_t,belle_sip_stream_channel_t,FALSE), (belle_sip_object_destroy_t)tls_channel_uninit, NULL, NULL }, "TLS", 1, /*is_reliable*/ tls_channel_connect, tls_channel_send, tls_channel_recv, (void (*)(belle_sip_channel_t*))tls_channel_close } } BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END static int tls_channel_handshake(belle_sip_tls_channel_t *channel) {