Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belle-sip
Commits
f25a7246
Commit
f25a7246
authored
Jan 12, 2012
by
Simon Morlat
Browse files
refactor channels, listening points, and deprecate send_task
parent
d6d85bf7
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
476 additions
and
303 deletions
+476
-303
include/belle-sip/Makefile.am
include/belle-sip/Makefile.am
+2
-1
include/belle-sip/belle-sip.h
include/belle-sip/belle-sip.h
+0
-1
include/belle-sip/list.h
include/belle-sip/list.h
+3
-0
include/belle-sip/listeningpoint.h
include/belle-sip/listeningpoint.h
+0
-28
include/belle-sip/transport.h
include/belle-sip/transport.h
+0
-59
src/Makefile.am
src/Makefile.am
+1
-1
src/belle_sip_internal.h
src/belle_sip_internal.h
+80
-28
src/belle_sip_utils.c
src/belle_sip_utils.c
+16
-0
src/channel.c
src/channel.c
+241
-0
src/channel.h
src/channel.h
+90
-0
src/listeningpoint.c
src/listeningpoint.c
+24
-155
src/provider.c
src/provider.c
+6
-13
src/sender_task.h
src/sender_task.h
+2
-0
src/transaction.c
src/transaction.c
+10
-16
tester/cast_test.c
tester/cast_test.c
+1
-1
No files found.
include/belle-sip/Makefile.am
View file @
f25a7246
...
...
@@ -8,12 +8,13 @@ bellesip_HEADERS=\
mainloop.h
\
transaction.h
\
message.h
\
transport.h
\
listeningpoint.h
\
sipstack.h
\
provider.h
\
listener.h
\
dialog.h
\
utils.h
\
belle-sdp.h
\
belle-sip.h
EXTRA_DIST
=
$(bellesip_HEADERS)
include/belle-sip/belle-sip.h
View file @
f25a7246
...
...
@@ -63,7 +63,6 @@ typedef enum belle_sip_type_id{
BELLE_SIP_TYPE_ID
(
belle_sip_header_call_id_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_cseq_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_content_type_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_sender_task_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_route_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_record_route_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_user_agent_t
),
...
...
include/belle-sip/list.h
View file @
f25a7246
...
...
@@ -36,6 +36,9 @@ void belle_sip_list_for_each2(const belle_sip_list_t * list, void (*func)(void *
belle_sip_list_t
*
belle_sip_list_remove_link
(
belle_sip_list_t
*
list
,
belle_sip_list_t
*
elem
);
belle_sip_list_t
*
belle_sip_list_delete_link
(
belle_sip_list_t
*
list
,
belle_sip_list_t
*
elem
);
belle_sip_list_t
*
belle_sip_list_find
(
belle_sip_list_t
*
list
,
void
*
data
);
belle_sip_list_t
*
belle_sip_list_free
(
belle_sip_list_t
*
list
);
/*frees list elements and associated data, using the supplied function pointer*/
belle_sip_list_t
*
belle_sip_list_free_with_data
(
belle_sip_list_t
*
list
,
void
(
*
freefunc
)(
void
*
));
typedef
int
(
*
belle_sip_compare_func
)(
const
void
*
,
const
void
*
);
belle_sip_list_t
*
belle_sip_list_find_custom
(
belle_sip_list_t
*
list
,
belle_sip_compare_func
cmp
,
const
void
*
user_data
);
...
...
include/belle-sip/listeningpoint.h
View file @
f25a7246
...
...
@@ -20,34 +20,6 @@
#ifndef BELLE_SIP_TRANSPORT_H
#define BELLE_SIP_TRANSPORT_H
#ifndef WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#else
#endif
typedef
struct
belle_sip_channel
belle_sip_channel_t
;
BELLE_SIP_BEGIN_DECLS
/**
* belle_sip_transport_t is an object representing a single communication channel (=unix socket or file descriptor),
* unlike the belle_sip_listening_point_t that can owns several channels for TCP or TLS (incoming server child sockets or
* outgoing client sockets).
**/
int
belle_sip_channel_send
(
belle_sip_channel_t
*
t
,
const
void
*
buf
,
size_t
buflen
);
int
belle_sip_channel_recv
(
belle_sip_channel_t
*
t
,
void
*
buf
,
size_t
buflen
);
const
struct
addrinfo
*
belle_sip_channel_get_peer
(
belle_sip_channel_t
*
t
);
const
char
*
belle_sip_listening_point_get_ip_address
(
const
belle_sip_listening_point_t
*
lp
);
int
belle_sip_listening_point_get_port
(
const
belle_sip_listening_point_t
*
lp
);
const
char
*
belle_sip_listening_point_get_transport
(
const
belle_sip_listening_point_t
*
ip
);
...
...
include/belle-sip/transport.h
deleted
100644 → 0
View file @
d6d85bf7
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BELLE_SIP_TRANSPORT_H
#define BELLE_SIP_TRANSPORT_H
typedef
struct
belle_sip_transport
belle_sip_transport_t
;
struct
belle_sip_transport_class
{
char
*
name
;
/*udp,tcp*/
int
is_reliable
;
int
(
*
connect
)(
belle_sip_transport_t
*
t
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
int
(
*
recvfrom
)(
belle_sip_transport_t
*
t
,
void
*
buf
,
size_t
buflen
,
struct
sockaddr
*
addr
,
socklen_t
*
addrlen
);
int
(
*
sendto
)(
belle_sip_transport_t
*
t
,
const
void
*
buf
,
size_t
buflen
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
/**
* Method to know if this transport is suitable for supplied transport name and address.
* Should return 1 if suitable, 0 otherwise.
**/
int
(
*
matches
)(
belle_sip_transport_t
*
,
const
char
*
name
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
void
(
*
close
)(
belle_sip_transport_t
*
);
};
typedef
struct
belle_sip_transport_class
belle_sip_transport_class_t
;
struct
belle_sip_transport
{
int
magic
;
belle_sip_transport_class_t
*
klass
;
int
refcnt
;
};
const
char
*
belle_sip_transport_get_name
(
const
belle_sip_transport_t
*
t
);
int
belle_sip_transport_is_reliable
(
const
belle_sip_transport_t
*
t
);
int
belle_sip_transport_matches
(
belle_sip_transport_t
*
t
,
const
char
*
name
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
int
belle_sip_transport_sendto
(
belle_sip_transport_t
*
t
,
const
void
*
buf
,
size_t
buflen
,
const
struct
sockaddr
*
addr
,
socklen_t
addrlen
);
int
belle_sip_transport_recvfrom
(
belle_sip_transport_t
*
t
,
void
*
buf
,
size_t
buflen
,
struct
sockaddr
*
addr
,
socklen_t
*
addrlen
);
void
belle_sip_transport_ref
(
belle_sip_transport_t
*
t
);
void
belle_sip_transport_unref
(
belle_sip_transport_t
*
t
);
BELLE_SIP_DECLARE_CAST
(
belle_sip_transport_t
);
#define BELLE_SIP_TRANSPORT(obj) BELLE_SIP_CAST(obj,belle_sip_transport_t)
#endif
src/Makefile.am
View file @
f25a7246
...
...
@@ -41,7 +41,7 @@ libbellesip_la_SOURCES=clock_gettime.h \
listeningpoint.c
\
sipstack.c
\
provider.c
\
sender_task.c sender_task
.h
\
channel.c channel
.h
\
message.c
libbellesip_la_CFLAGS
=
$(STRICT_OPTIONS)
...
...
src/belle_sip_internal.h
View file @
f25a7246
...
...
@@ -40,13 +40,12 @@ typedef void (*belle_sip_object_clone_t)(belle_sip_object_t* obj, const belle_si
typedef
int
(
*
belle_sip_object_marshal_t
)(
belle_sip_object_t
*
obj
,
char
*
buff
,
unsigned
int
offset
,
size_t
buff_size
);
struct
_belle_sip_object_vptr
{
belle_sip_type_id_t
id
;
belle_sip_type_id_t
id
;
struct
_belle_sip_object_vptr
*
parent
;
void
*
interfaces
;
/*unused for the moment*/
belle_sip_object_destroy_t
destroy
;
belle_sip_object_clone_t
clone
;
belle_sip_object_marshal_t
marshal
;
};
typedef
struct
_belle_sip_object_vptr
belle_sip_object_vptr_t
;
...
...
@@ -55,24 +54,31 @@ extern belle_sip_object_vptr_t belle_sip_object_t_vptr;
#define BELLE_SIP_OBJECT_VPTR_NAME(object_type) object_type##_vptr
#define BELLE_SIP_OBJECT_VPTR_TYPE(object_type) object_type##_vptr_t
#define BELLE_SIP_DECLARE_VPTR(object_type) \
extern belle_sip_object_vptr_t BELLE_SIP_OBJECT_VPTR_NAME(object_type);
typedef belle_sip_object_vptr_t BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\
extern BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type);
#define BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(object_type, parent_type) \
typedef struct object_type##_vptr_struct BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\
struct object_type##_vptr_struct{\
BELLE_SIP_OBJECT_VPTR_TYPE(parent_type) base;
#define BELLE_SIP_DECLARE_CUSTOM_VPTR_END };
#define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(object_type) \
BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type)
#define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(vptr_type,object_type, parent_type, destroy, clone) \
vptr_type object_type##_vptr={ {\
#define BELLE_SIP_VPTR_INIT(object_type,parent_type) \
BELLE_SIP_TYPE_ID(object_type), \
(belle_sip_object_vptr_t*)&BELLE_SIP_OBJECT_VPTR_NAME(parent_type), \
NULL, \
(belle_sip_object_destroy_t)destroy, \
(belle_sip_object_clone_t)clone },
NULL
#define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END };
#define BELLE_SIP_INSTANCIATE_VPTR(object_type,parent_type,destroy,clone,marshal) \
belle_sip_object_vptr_t object_type##_vptr={ \
BELLE_SIP_TYPE_ID(object_type), \
(belle_sip_object_vptr_t*)&BELLE_SIP_OBJECT_VPTR_NAME(parent_type), \
NULL, \
BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type)={ \
BELLE_SIP_VPTR_INIT(object_type,parent_type), \
(belle_sip_object_destroy_t)destroy, \
(belle_sip_object_clone_t)clone, \
(belle_sip_object_marshal_t)marshal\
...
...
@@ -94,16 +100,69 @@ int belle_sip_object_marshal(belle_sip_object_t* obj, char* buff,unsigned int of
#define belle_sip_object_new(_type) (_type*)_belle_sip_object_new(sizeof(_type),(belle_sip_object_vptr_t*)&BELLE_SIP_OBJECT_VPTR_NAME(_type),0)
#define belle_sip_object_new_unowed(_type)(_type*)_belle_sip_object_new(sizeof(_type),(belle_sip_object_vptr_t*)&BELLE_SIP_OBJECT_VPTR_NAME(_type),1)
#define BELLE_SIP_OBJECT_VPTR(obj,
vptr
_type) ((
vptr
_type*)(((belle_sip_object_t*)obj)->vptr))
#define BELLE_SIP_OBJECT_VPTR(obj,
object
_type) ((
BELLE_SIP_OBJECT_VPTR_TYPE(object
_type
)
*)(((belle_sip_object_t*)obj)->vptr))
#define belle_sip_object_init(obj)
/*nothing*/
/*list of all vptrs (classes) used in belle-sip*/
BELLE_SIP_DECLARE_VPTR
(
belle_sip_object_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_stack_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_listening_point_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_datagram_listening_point_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_udp_listening_point_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_provider_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_main_loop_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_source_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_resolver_context_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_transaction_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_server_transaction_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_client_transaction_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_dialog_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_address_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_contact_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_from_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_to_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_via_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_uri_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_message_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_request_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_response_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_parameters_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_contact_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_call_id_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_cseq_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_content_type_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_route_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_record_route_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_user_agent_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_content_length_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_extension_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_authorization_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_www_authenticate_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_proxy_authorization_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_max_forwards_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_expires_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_header_allow_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_attribute_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_bandwidth_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_connection_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_email_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_info_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_key_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_media_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_media_description_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_origin_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_phone_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_repeate_time_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_session_description_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_session_name_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_time_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_time_description_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_uri_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_version_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sdp_base_description_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_source_t
);
...
...
@@ -131,7 +190,7 @@ void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t fun
#define belle_list_next(elem) ((elem)->next)
/* include private headers */
#include "
sender_task
.h"
#include "
channel
.h"
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -148,6 +207,7 @@ belle_sip_list_t *belle_sip_list_find_custom(belle_sip_list_t *list, belle_sip_c
belle_sip_list_t
*
belle_sip_list_remove_custom
(
belle_sip_list_t
*
list
,
belle_sip_compare_func
compare_func
,
const
void
*
user_data
);
belle_sip_list_t
*
belle_sip_list_delete_custom
(
belle_sip_list_t
*
list
,
belle_sip_compare_func
compare_func
,
const
void
*
user_data
);
belle_sip_list_t
*
belle_sip_list_free
(
belle_sip_list_t
*
list
);
#define belle_sip_list_next(elem) ((elem)->next)
extern
belle_sip_log_function_t
belle_sip_logv_out
;
...
...
@@ -407,25 +467,18 @@ struct _belle_sip_parameters {
void
belle_sip_parameters_init
(
belle_sip_parameters_t
*
obj
);
/*
* Listening points
and channels
* Listening points
*/
struct
belle_sip_channel
{
belle_sip_object_t
base
;
belle_sip_listening_point_t
*
lp
;
/* the listening point this channel belongs */
struct
addrinfo
peer
;
struct
sockaddr_storage
peer_addr
;
};
typedef
struct
belle_sip_udp_listening_point
belle_sip_udp_listening_point_t
;
#define BELLE_SIP_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_listening_point_t)
#define BELLE_SIP_UDP_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_udp_listening_point_t)
#define BELLE_SIP_CHANNEL(obj) BELLE_SIP_CAST(obj,belle_sip_channel_t)
belle_sip_listening_point_t
*
belle_sip_udp_listening_point_new
(
belle_sip_stack_t
*
s
,
const
char
*
ipaddress
,
int
port
);
belle_sip_channel_t
*
belle_sip_listening_point_find_output_channel
(
belle_sip_listening_point_t
*
ip
,
const
struct
addrinfo
*
dest
);
belle_sip_source_t
*
belle_sip_channel_create_source
(
belle_sip_channel_t
*
,
unsigned
int
events
,
int
timeout
,
belle_sip_source_func_t
callback
,
void
*
data
);
int
belle_sip_listening_point_get_well_known_port
(
const
char
*
transport
);
...
...
@@ -456,6 +509,7 @@ struct belle_sip_provider{
belle_sip_provider_t
*
belle_sip_provider_new
(
belle_sip_stack_t
*
s
,
belle_sip_listening_point_t
*
lp
);
void
belle_sip_provider_set_transaction_terminated
(
belle_sip_provider_t
*
p
,
belle_sip_transaction_t
*
t
);
belle_sip_channel_t
*
belle_sip_provider_get_channel
(
belle_sip_provider_t
*
p
,
const
char
*
name
,
int
port
,
const
char
*
transport
);
typedef
struct
listener_ctx
{
belle_sip_listener_t
*
listener
;
...
...
@@ -483,7 +537,6 @@ struct belle_sip_transaction{
belle_sip_response_t
*
final_response
;
char
*
branch_id
;
belle_sip_transaction_state_t
state
;
belle_sip_sender_task_t
*
stask
;
uint64_t
start_time
;
belle_sip_source_t
*
timer
;
int
interval
;
...
...
@@ -567,7 +620,6 @@ belle_sdp_##object_type##_t* belle_sdp_##object_type##_parse (const char* value)
/*include private headers */
#include "belle_sip_resolver.h"
#include "sender_task.h"
#define BELLE_SIP_SOCKET_TIMEOUT 30000
...
...
src/belle_sip_utils.c
View file @
f25a7246
...
...
@@ -208,6 +208,22 @@ belle_sip_list_t* belle_sip_list_free(belle_sip_list_t* list){
return
NULL
;
}
belle_sip_list_t
*
belle_sip_list_free_with_data
(
belle_sip_list_t
*
list
,
void
(
*
freefunc
)(
void
*
)){
belle_sip_list_t
*
elem
=
list
;
belle_sip_list_t
*
tmp
;
if
(
list
==
NULL
)
return
NULL
;
while
(
elem
->
next
!=
NULL
)
{
tmp
=
elem
;
elem
=
elem
->
next
;
freefunc
(
tmp
->
data
);
belle_sip_free
(
tmp
);
}
freefunc
(
elem
->
data
);
belle_sip_free
(
elem
);
return
NULL
;
}
belle_sip_list_t
*
belle_sip_list_remove
(
belle_sip_list_t
*
first
,
void
*
data
){
belle_sip_list_t
*
it
;
it
=
belle_sip_list_find
(
first
,
data
);
...
...
src/channel.c
0 → 100644
View file @
f25a7246
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "belle_sip_internal.h"
static
void
belle_sip_channel_destroy
(
belle_sip_channel_t
*
obj
){
if
(
obj
->
peer
)
freeaddrinfo
(
obj
->
peer
);
belle_sip_free
(
obj
->
peer_name
);
}
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR
(
belle_sip_channel_t
)
=
{
{
BELLE_SIP_VPTR_INIT
(
belle_sip_channel_t
,
belle_sip_source_t
),
(
belle_sip_object_destroy_t
)
belle_sip_channel_destroy
,
NULL
,
/*clone*/
NULL
,
/*marshall*/
}
};
static
void
belle_sip_channel_init
(
belle_sip_channel_t
*
obj
,
belle_sip_provider_t
*
prov
,
const
char
*
peername
,
int
peer_port
){
obj
->
peer_name
=
belle_sip_strdup
(
peername
);
obj
->
peer_port
=
peer_port
;
obj
->
peer
=
NULL
;
obj
->
prov
=
prov
;
}
int
belle_sip_channel_matches
(
const
belle_sip_channel_t
*
obj
,
const
char
*
peername
,
int
peerport
){
return
strcmp
(
peername
,
obj
->
peer_name
)
==
0
&&
peerport
==
obj
->
peer_port
;
}
int
belle_sip_channel_send
(
belle_sip_channel_t
*
obj
,
const
void
*
buf
,
size_t
buflen
){
return
BELLE_SIP_OBJECT_VPTR
(
obj
,
belle_sip_channel_t
)
->
channel_send
(
obj
,
buf
,
buflen
);
}
int
belle_sip_channel_recv
(
belle_sip_channel_t
*
obj
,
void
*
buf
,
size_t
buflen
){
return
BELLE_SIP_OBJECT_VPTR
(
obj
,
belle_sip_channel_t
)
->
channel_recv
(
obj
,
buf
,
buflen
);
}
const
struct
addrinfo
*
belle_sip_channel_get_peer
(
belle_sip_channel_t
*
obj
){
return
obj
->
peer
;
}
static
void
send_message
(
belle_sip_channel_t
*
obj
,
belle_sip_message_t
*
msg
){
char
buffer
[
belle_sip_network_buffer_size
];
int
len
=
belle_sip_object_marshal
((
belle_sip_object_t
*
)
msg
,
buffer
,
0
,
sizeof
(
buffer
));
if
(
len
>
0
){
int
ret
=
belle_sip_channel_send
(
obj
,
buffer
,
len
);
if
(
ret
==-
1
){
belle_sip_io_error_event_t
ev
;
obj
->
state
=
BELLE_SIP_CHANNEL_ERROR
;
ev
.
transport
=
BELLE_SIP_OBJECT_VPTR
(
obj
,
belle_sip_channel_t
)
->
transport
;
ev
.
source
=
obj
->
prov
;
ev
.
port
=
obj
->
peer_port
;
ev
.
host
=
obj
->
peer_name
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
obj
->
prov
,
process_io_error
,
&
ev
);
}
}
}
static
void
channel_process_queue
(
belle_sip_channel_t
*
obj
){
if
(
obj
->
msg
){
switch
(
obj
->
state
){
case
BELLE_SIP_CHANNEL_INIT
:
belle_sip_channel_resolve
(
obj
);
break
;
case
BELLE_SIP_CHANNEL_RES_DONE
:
belle_sip_channel_connect
(
obj
);
break
;
case
BELLE_SIP_CHANNEL_READY
:
send_message
(
obj
,
obj
->
msg
);
case
BELLE_SIP_CHANNEL_ERROR
:
belle_sip_object_unref
(
obj
->
msg
);
obj
->
msg
=
NULL
;
break
;
default:
break
;
}
}
}
static
void
channel_res_done
(
void
*
data
,
const
char
*
name
,
struct
addrinfo
*
res
){
belle_sip_channel_t
*
obj
=
(
belle_sip_channel_t
*
)
data
;
obj
->
resolver_id
=
0
;
if
(
res
){
obj
->
peer
=
res
;
obj
->
state
=
BELLE_SIP_CHANNEL_RES_DONE
;
}
else
{
belle_sip_io_error_event_t
ev
;
obj
->
state
=
BELLE_SIP_CHANNEL_ERROR
;
ev
.
transport
=
BELLE_SIP_OBJECT_VPTR
(
obj
,
belle_sip_channel_t
)
->
transport
;
ev
.
source
=
obj
->
prov
;
ev
.
port
=
obj
->
peer_port
;
ev
.
host
=
obj
->
peer_name
;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
obj
->
prov
,
process_io_error
,
&
ev
);
}
channel_process_queue
(
obj
);
}
int
belle_sip_channel_resolve
(
belle_sip_channel_t
*
obj
){
obj
->
state
=
BELLE_SIP_CHANNEL_RES_IN_PROGRESS
;
obj
->
resolver_id
=
belle_sip_resolve
(
obj
->
peer_name
,
obj
->
peer_port
,
0
,
channel_res_done
,
obj
,
obj
->
prov
->
stack
->
ml
);
return
0
;
}
int
belle_sip_channel_connect
(
belle_sip_channel_t
*
obj
){
return
BELLE_SIP_OBJECT_VPTR
(
obj
,
belle_sip_channel_t
)
->
connect
(
obj
,
obj
->
peer
->
ai_addr
,
obj
->
peer
->
ai_addrlen
);
}
int
belle_sip_channel_queue_message
(
belle_sip_channel_t
*
obj
,
belle_sip_message_t
*
msg
){
if
(
msg
!=
NULL
){
belle_sip_error
(
"Queue is not a queue."
);
return
-
1
;
}
obj
->
msg
=
(
belle_sip_message_t
*
)
belle_sip_object_ref
(
msg
);
channel_process_queue
(
obj
);
return
0
;
}
struct
belle_sip_udp_channel
{
belle_sip_channel_t
base
;
int
sock
;
};
typedef
struct
belle_sip_udp_channel
belle_sip_udp_channel_t
;
static
void
udp_channel_uninit
(
belle_sip_udp_channel_t
*
obj
){
if
(
obj
->
sock
!=-
1
)
close
(
obj
->
sock
);
}
static
int
udp_channel_send
(
belle_sip_channel_t
*
obj
,
const
void
*
buf
,
size_t
buflen
){
belle_sip_udp_channel_t
*
chan
=
(
belle_sip_udp_channel_t
*
)
obj
;
int
err
;
err
=
sendto
(
chan
->
sock
,
buf
,
buflen
,
0
,
obj
->
peer
->
ai_addr
,
obj
->
peer
->
ai_addrlen
);
if
(
err
==-
1
){
belle_sip_fatal
(
"Could not send UDP packet: %s"
,
strerror
(
errno
));
return
-
errno
;
}
return
err
;
}
static
int
udp_channel_recv
(
belle_sip_channel_t
*
obj
,
void
*
buf
,
size_t
buflen
){
belle_sip_udp_channel_t
*
chan
=
(
belle_sip_udp_channel_t
*
)
obj
;
int
err
;
struct
sockaddr_storage
addr
;
socklen_t
addrlen
=
sizeof
(
addr
);
err
=
recvfrom
(
chan
->
sock
,
buf
,
buflen
,
MSG_DONTWAIT
,(
struct
sockaddr
*
)
&
addr
,
&
addrlen
);
if
(
err
==-
1
&&
errno
!=
EWOULDBLOCK
){
belle_sip_error
(
"Could not receive UDP packet: %s"
,
strerror
(
errno
));
return
-
errno
;
}
return
err
;
}
int
udp_channel_connect
(
belle_sip_channel_t
*
obj
,
const
struct
sockaddr
*
addr
,
socklen_t
socklen
){
obj
->
state
=
BELLE_SIP_CHANNEL_READY
;
channel_process_queue
(
obj
);
return
0
;
}
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR
(
belle_sip_udp_channel_t
)
=
{
{
{
BELLE_SIP_VPTR_INIT
(
belle_sip_udp_channel_t
,
belle_sip_channel_t
),
(
belle_sip_object_destroy_t
)
udp_channel_uninit
,
NULL
,
NULL
},
"UDP"
,
udp_channel_connect
,
udp_channel_send
,
udp_channel_recv
}
};
static
int
create_udp_socket
(
const
char
*
addr
,
int
port
){
struct
addrinfo
hints
=
{
0
};
struct
addrinfo
*
res
=
NULL
;
int
err
;
int
sock
;
char
portnum
[
10
];
sock
=
socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
if
(
sock
==-
1
){
belle_sip_error
(
"Cannot create UDP socket: %s"
,
strerror
(
errno
));
return
-
1
;
}
snprintf
(
portnum
,
sizeof
(
portnum
),
"%i"
,
port
);
err
=
getaddrinfo
(
addr
,
portnum
,
&
hints
,
&
res
);
if
(
err
!=
0
){
belle_sip_error
(
"getaddrinfo() failed for %s port %i: %s"
,
addr
,
port
,
strerror
(
errno
));
close
(
sock
);
return
-
1
;
}
err
=
bind
(
sock
,
res
->
ai_addr
,
res
->
ai_addrlen
);
if
(
err
==-
1
){
belle_sip_error
(
"udp bind() failed for %s port %i: %s"
,
addr
,
port
,
strerror
(
errno
));
close
(
sock
);
return
-
1
;
}
return
sock
;
}
belle_sip_channel_t
*
belle_sip_channel_new_udp_master
(
belle_sip_provider_t
*
prov
,
const
char
*
localname
,
int
localport
){
belle_sip_udp_channel_t
*
obj
=
belle_sip_object_new
(
belle_sip_udp_channel_t
);
belle_sip_channel_init
((
belle_sip_channel_t
*
)
obj
,
prov
,
""
,
-
1
);
obj
->
sock
=
create_udp_socket
(
localname
,
localport
);
return
(
belle_sip_channel_t
*
)
obj
;
}
belle_sip_channel_t
*
belle_sip_channel_new_udp_slave
(
belle_sip_channel_t
*
master
,
const
char
*
peername
,
int
peerport
){
belle_sip_udp_channel_t
*
obj
=
belle_sip_object_new
(
belle_sip_udp_channel_t
);
belle_sip_channel_init
((
belle_sip_channel_t
*
)
obj
,
master
->
prov
,
peername
,
peerport
);
obj
->
sock
=
((
belle_sip_udp_channel_t
*
)
master
)
->
sock
;
return
(
belle_sip_channel_t
*
)
obj
;
}
src/channel.h
0 → 100644
View file @
f25a7246
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by