BFCP episode #4
This commit is contained in:
parent
50cc03eb04
commit
4ad4ed6cbe
|
@ -25,15 +25,24 @@
|
|||
|
||||
TBFCP_BEGIN_DECLS
|
||||
|
||||
struct tbfcp_session_s;
|
||||
|
||||
TINYBFCP_API int tbfcp_session_create(enum tnet_socket_type_e e_socket_type, const char* pc_local_ip, struct tbfcp_session_s** pp_self);
|
||||
TINYBFCP_API int tbfcp_session_create_2(struct tnet_ice_ctx_s* p_ice_ctx, struct tbfcp_session_s** pp_self);
|
||||
TINYBFCP_API int tbfcp_session_set_ice_ctx(struct tbfcp_session_s* p_self, struct tnet_ice_ctx_s* p_ice_ctx);
|
||||
TINYBFCP_API int tbfcp_session_prepare(struct tbfcp_session_s* p_self);
|
||||
TINYBFCP_API int tbfcp_session_start(struct tbfcp_session_s* p_self);
|
||||
TINYBFCP_API int tbfcp_session_pause(struct tbfcp_session_s* p_self);
|
||||
TINYBFCP_API int tbfcp_session_stop(struct tbfcp_session_s* p_self);
|
||||
TINYBFCP_API int tbfcp_session_set_remote(struct tbfcp_session_s* p_self, const char* pc_ip, tnet_port_t u_port);
|
||||
TINYBFCP_API int tbfcp_session_set_natt_ctx(struct tbfcp_session_s* p_self, struct tnet_nat_context_s* p_natt_ctx);
|
||||
TINYBFCP_API int tbfcp_session_set_remote_address(struct tbfcp_session_s* p_self, const char* pc_ip, tnet_port_t u_port);
|
||||
TINYBFCP_API int tbfcp_session_set_remote_role(struct tbfcp_session_s* p_self, enum tbfcp_role_e e_role_remote);
|
||||
TINYBFCP_API int tbfcp_session_set_remote_setup(struct tbfcp_session_s* p_self, enum tbfcp_setup_e e_setup_remote);
|
||||
TINYBFCP_API int tbfcp_session_set_conf_ids(struct tbfcp_session_s* p_self, uint32_t u_conf_id, uint16_t u_user_id, uint16_t u_floor_id);
|
||||
TINYBFCP_API int tbfcp_session_get_profile(const struct tbfcp_session_s* pc_self, const char** ppc_profile);
|
||||
TINYBFCP_API int tbfcp_session_get_profile_2(enum tnet_socket_type_e e_socket_type, const char** ppc_profile);
|
||||
TINYBFCP_API int tbfcp_session_get_local_role(const struct tbfcp_session_s* pc_self, enum tbfcp_role_e *pe_role_local);
|
||||
TINYBFCP_API int tbfcp_session_get_local_setup(const struct tbfcp_session_s* pc_self, enum tbfcp_setup_e *pe_setup_local);
|
||||
TINYBFCP_API int tbfcp_session_get_local_address(const struct tbfcp_session_s* pc_self, const char** ppc_ip, tnet_port_t *pu_port);
|
||||
TINYBFCP_API int tbfcp_session_send_pkt(struct tbfcp_session_s* p_self, const struct tbfcp_pkt_s* pc_pkt);
|
||||
|
||||
TBFCP_END_DECLS
|
||||
|
|
|
@ -66,7 +66,7 @@ TBFCP_BEGIN_DECLS
|
|||
#endif /* kBfcpProfileDTLS */
|
||||
|
||||
#if !defined(kBfcpTransportDefault)
|
||||
# define kBfcpTransportDefault tnet_socket_type_tcp_ipv4
|
||||
# define kBfcpTransportDefault tnet_socket_type_udp_ipv4
|
||||
#endif /* kBfcpTransportDefault */
|
||||
|
||||
#if !defined(kBfcpTransportFriendlyName)
|
||||
|
@ -78,6 +78,43 @@ TBFCP_BEGIN_DECLS
|
|||
#endif /* kBfcpBuffMinPad */
|
||||
|
||||
|
||||
// rfc4583 - 4. Floor Control Server Determination
|
||||
#if !defined(kBfcpRoleC)
|
||||
# define kBfcpRoleC "c-only"
|
||||
#endif /* kBfcpRoleC */
|
||||
#if !defined(kBfcpRoleS)
|
||||
# define kBfcpRoleS "s-only"
|
||||
#endif /* kBfcpRoleS */
|
||||
#if !defined(kBfcpRoleCS)
|
||||
# define kBfcpRoleCS "c-s"
|
||||
#endif /* kBfcpRoleCS */
|
||||
#if !defined(kBfcpRoleDefault)
|
||||
# define kBfcpRoleDefault tbfcp_role_c_only // For know the stack works in client mode only
|
||||
#endif /* kBfcpRoleDefault */
|
||||
typedef enum tbfcp_role_e {
|
||||
tbfcp_role_c_only = (1 << 0),
|
||||
tbfcp_role_s_only = (1 << 1),
|
||||
tbfcp_role_c_s = (tbfcp_role_c_only | tbfcp_role_s_only)
|
||||
} tbfcp_role_t;
|
||||
|
||||
typedef enum tbfcp_setup_e {
|
||||
tbfcp_setup_active = (1 << 0),
|
||||
tbfcp_setup_passive = (1 << 1),
|
||||
tbfcp_setup_actpass = (tbfcp_setup_active | tbfcp_setup_passive),
|
||||
} tbfcp_setup_t;
|
||||
#if !defined(kBfcpSetupDefault)
|
||||
# define kBfcpSetupDefault tbfcp_setup_actpass
|
||||
#endif /* kBfcpSetupDefault */
|
||||
#if !defined(kBfcpSetupActPass)
|
||||
# define kBfcpSetupActPass "actpass"
|
||||
#endif /* kBfcpSetupActPass */
|
||||
#if !defined(kBfcpSetupActive)
|
||||
# define kBfcpSetupActive "active"
|
||||
#endif /* kBfcpSetupActive */
|
||||
#if !defined(kBfcpSetupPassive)
|
||||
# define kBfcpSetupPassive "passive"
|
||||
#endif /* kBfcpSetupPassive */
|
||||
|
||||
// RFC4582 - 5.1. COMMON-HEADER Format
|
||||
typedef enum tbfcp_primitive_e {
|
||||
tbfcp_primitive_FloorRequest = 1, // | P -> S |
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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.
|
||||
*
|
||||
* DOUBANGO 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#ifndef TBFCP_UTILS_H
|
||||
#define TBFCP_UTILS_H
|
||||
|
||||
#include "tinybfcp_config.h"
|
||||
#include "tinybfcp/tbfcp_types.h"
|
||||
|
||||
#include "tsk_common.h"
|
||||
|
||||
TBFCP_BEGIN_DECLS
|
||||
|
||||
TINYBFCP_API int tbfcp_utils_get_profile(enum tnet_socket_type_e e_socket_type, const char** ppc_profile);
|
||||
TINYBFCP_API int tbfcp_utils_get_role(enum tbfcp_role_e e_role, const char** ppc_role);
|
||||
TINYBFCP_API int tbfcp_utils_parse_role(const char* pc_role, enum tbfcp_role_e* pe_role);
|
||||
TINYBFCP_API int tbfcp_utils_get_setup(enum tbfcp_role_e e_setup, const char** ppc_setup);
|
||||
TINYBFCP_API int tbfcp_utils_parse_setup(const char* pc_setup, enum tbfcp_setup_e* pe_setup);
|
||||
TINYBFCP_API int tbfcp_utils_is_role_acceptable(enum tbfcp_role_e e_role_local, enum tbfcp_role_e e_role_proposed, tsk_bool_t *pb_acceptable);
|
||||
TINYBFCP_API int tbfcp_utils_is_setup_acceptable(enum tbfcp_setup_e e_setup_local, enum tbfcp_setup_e e_setup_proposed, tsk_bool_t *pb_acceptable);
|
||||
TINYBFCP_API uint16_t tbfcp_utils_rand_u16();
|
||||
|
||||
TBFCP_END_DECLS
|
||||
|
||||
#endif /* TBFCP_UTILS_H */
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
#include "tinybfcp/tbfcp_session.h"
|
||||
#include "tinybfcp/tbfcp_pkt.h"
|
||||
#include "tinybfcp/tbfcp_types.h"
|
||||
#include "tinybfcp/tbfcp_utils.h"
|
||||
|
||||
#include "tsk_time.h"
|
||||
#include "tsk_timer.h"
|
||||
|
@ -34,6 +34,20 @@ typedef struct tbfcp_session_s {
|
|||
tsk_bool_t b_stopping;
|
||||
tsk_bool_t b_prepared;
|
||||
|
||||
// Values received from the server in the 200 OK. Attributes from rfc4583
|
||||
struct {
|
||||
uint32_t u_conf_id;
|
||||
uint16_t u_user_id;
|
||||
uint16_t u_floor_id;
|
||||
}
|
||||
conf_ids;
|
||||
|
||||
enum tbfcp_role_e e_role_local;
|
||||
enum tbfcp_role_e e_role_remote;
|
||||
|
||||
enum tbfcp_setup_e e_setup_local;
|
||||
enum tbfcp_setup_e e_setup_remote;
|
||||
|
||||
enum tnet_socket_type_e e_socket_type;
|
||||
char* p_local_ip;
|
||||
tnet_port_t u_local_port;
|
||||
|
@ -45,6 +59,7 @@ typedef struct tbfcp_session_s {
|
|||
tnet_port_t u_remote_port;
|
||||
struct sockaddr_storage remote_addr;
|
||||
|
||||
struct tnet_nat_context_s* p_natt_ctx;
|
||||
struct tnet_ice_ctx_s* p_ice_ctx;
|
||||
struct tnet_transport_s* p_transport;
|
||||
|
||||
|
@ -71,10 +86,15 @@ typedef enum _bfcp_timer_type_e {
|
|||
}
|
||||
_bfcp_timer_type_t;
|
||||
|
||||
static int _tbfcp_session_send_Hello(struct tbfcp_session_s* p_self);
|
||||
static int _tbfcp_session_send_HelloAck(struct tbfcp_session_s* p_self, const tbfcp_pkt_t *pc_hello);
|
||||
static int _tbfcp_session_send_FloorRequest(struct tbfcp_session_s* p_self);
|
||||
static int _tbfcp_session_process_incoming_pkt(struct tbfcp_session_s* p_self, const tbfcp_pkt_t *pc_pkt);
|
||||
static int _tbfcp_session_socket_type_make_valid(enum tnet_socket_type_e e_in_st, enum tnet_socket_type_e *pe_out_st);
|
||||
static int _tbfcp_session_timer_callback(const void* pc_arg, tsk_timer_id_t timer_id);
|
||||
static int _tbfcp_session_timer_schedule(struct tbfcp_session_s* p_self, _bfcp_timer_type_t e_timer, uint64_t u_timeout);
|
||||
static int _tbfcp_session_transport_layer_cb(const tnet_transport_event_t* e);
|
||||
static int _tbfcp_session_transport_layer_dgram_cb(const tnet_transport_event_t* e);
|
||||
static int _tbfcp_session_transport_layer_stream_cb(const tnet_transport_event_t* e);
|
||||
|
||||
int tbfcp_session_create(tnet_socket_type_t e_socket_type, const char* pc_local_ip, tbfcp_session_t** pp_self)
|
||||
{
|
||||
|
@ -178,7 +198,7 @@ int tbfcp_session_prepare(tbfcp_session_t* p_self)
|
|||
return -3;
|
||||
}
|
||||
// set transport callback
|
||||
if ((ret = tnet_transport_set_callback(p_self->p_transport, _tbfcp_session_transport_layer_cb, p_self))) {
|
||||
if ((ret = tnet_transport_set_callback(p_self->p_transport, TNET_SOCKET_TYPE_IS_DGRAM(p_self->e_socket_type) ? _tbfcp_session_transport_layer_dgram_cb : _tbfcp_session_transport_layer_stream_cb, p_self))) {
|
||||
goto bail;
|
||||
}
|
||||
bfcp_local_ip = p_self->p_transport->master->ip;
|
||||
|
@ -245,6 +265,10 @@ int tbfcp_session_start(tbfcp_session_t* p_self)
|
|||
TSK_DEBUG_ERROR("Invalid BFCP host:port [%s:%u]", p_self->p_remote_ip, p_self->u_remote_port);
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tnet_transport_set_natt_ctx(p_self->p_transport, p_self->p_natt_ctx))) {
|
||||
TSK_DEBUG_ERROR("Failed to start to set NATT ctx for the %s transport", kBfcpTransportFriendlyName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// start the transport
|
||||
if ((ret = tnet_transport_start(p_self->p_transport))) {
|
||||
|
@ -254,12 +278,38 @@ int tbfcp_session_start(tbfcp_session_t* p_self)
|
|||
|
||||
p_self->b_started = tsk_true;
|
||||
|
||||
// Send hello now if UDP/DTLS. Otherwise (TCP/TLS), wait for the connection to complete.
|
||||
if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->e_socket_type)) {
|
||||
if ((ret = _tbfcp_session_send_Hello(p_self))) {
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
// unlock()
|
||||
tsk_safeobj_unlock(p_self);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tbfcp_session_pause(tbfcp_session_t* p_self)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// lock()
|
||||
tsk_safeobj_lock(p_self);
|
||||
|
||||
goto bail;
|
||||
|
||||
bail:
|
||||
// unlock()
|
||||
tsk_safeobj_unlock(p_self);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tbfcp_session_stop(tbfcp_session_t* p_self)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -307,7 +357,18 @@ bail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int tbfcp_session_set_remote(tbfcp_session_t* p_self, const char* pc_ip, tnet_port_t u_port)
|
||||
int tbfcp_session_set_natt_ctx(tbfcp_session_t* p_self, struct tnet_nat_context_s* p_natt_ctx)
|
||||
{
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
TSK_OBJECT_SAFE_FREE(p_self->p_natt_ctx);
|
||||
p_self->p_natt_ctx = tsk_object_ref(p_natt_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_set_remote_address(tbfcp_session_t* p_self, const char* pc_ip, tnet_port_t u_port)
|
||||
{
|
||||
if (!p_self || !pc_ip /*|| u_port < 1024*/) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
|
@ -319,41 +380,94 @@ int tbfcp_session_set_remote(tbfcp_session_t* p_self, const char* pc_ip, tnet_po
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_set_remote_role(tbfcp_session_t* p_self, enum tbfcp_role_e e_role_remote)
|
||||
{
|
||||
tsk_bool_t b_is_role_acceptable;
|
||||
int ret;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tbfcp_utils_is_role_acceptable(p_self->e_role_local, e_role_remote, &b_is_role_acceptable))) {
|
||||
return ret;
|
||||
}
|
||||
if (!b_is_role_acceptable) {
|
||||
TSK_DEBUG_ERROR("%d not acceptable as remote role because local role = %d", e_role_remote, p_self->e_role_local);
|
||||
return -2;
|
||||
}
|
||||
p_self->e_role_remote = e_role_remote;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_set_remote_setup(struct tbfcp_session_s* p_self, enum tbfcp_setup_e e_setup_remote)
|
||||
{
|
||||
tsk_bool_t b_is_setup_acceptable;
|
||||
int ret;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tbfcp_utils_is_setup_acceptable(p_self->e_setup_local, e_setup_remote, &b_is_setup_acceptable))) {
|
||||
return ret;
|
||||
}
|
||||
if (!b_is_setup_acceptable) {
|
||||
TSK_DEBUG_ERROR("%d not acceptable as remote setup because local setup = %d", e_setup_remote, p_self->e_setup_local);
|
||||
return -2;
|
||||
}
|
||||
p_self->e_setup_remote = e_setup_remote;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_set_conf_ids(tbfcp_session_t* p_self, uint32_t u_conf_id, uint16_t u_user_id, uint16_t u_floor_id)
|
||||
{
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
p_self->conf_ids.u_conf_id = u_conf_id;
|
||||
p_self->conf_ids.u_user_id = u_user_id;
|
||||
p_self->conf_ids.u_floor_id = u_floor_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_get_profile(const tbfcp_session_t* pc_self, const char** ppc_profile)
|
||||
{
|
||||
if (!pc_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
return tbfcp_session_get_profile_2(pc_self->e_socket_type, ppc_profile);
|
||||
return tbfcp_utils_get_profile(pc_self->e_socket_type, ppc_profile);
|
||||
}
|
||||
|
||||
|
||||
int tbfcp_session_get_profile_2(enum tnet_socket_type_e e_socket_type, const char** ppc_profile)
|
||||
int tbfcp_session_get_local_role(const tbfcp_session_t* pc_self, enum tbfcp_role_e *pe_role_local)
|
||||
{
|
||||
if (!ppc_profile) {
|
||||
if (!pc_self || !pe_role_local) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
*pe_role_local = pc_self->e_role_local;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (TNET_SOCKET_TYPE_IS_DTLS(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileDTLS;
|
||||
return 0;
|
||||
int tbfcp_session_get_local_setup(const struct tbfcp_session_s* pc_self, enum tbfcp_setup_e *pe_setup_local)
|
||||
{
|
||||
if (!pc_self || !pe_setup_local) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_UDP(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileUDP;
|
||||
return 0;
|
||||
*pe_setup_local = pc_self->e_setup_local;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_session_get_local_address(const tbfcp_session_t* pc_self, const char** ppc_ip, tnet_port_t *pu_port)
|
||||
{
|
||||
if (!pc_self || !ppc_ip || !pu_port) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_TLS(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileTLS;
|
||||
return 0;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_TCP(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileTCP;
|
||||
return 0;
|
||||
}
|
||||
TSK_DEBUG_ERROR("%d not supported as valid socket type for BFCP sessions", e_socket_type);
|
||||
return -2;
|
||||
*ppc_ip = pc_self->p_local_public_ip;
|
||||
*pu_port = pc_self->u_local_public_port;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _tbfcp_session_send_buff(tbfcp_session_t* p_self, const void* pc_buff_ptr, tsk_size_t u_buff_size)
|
||||
|
@ -436,6 +550,97 @@ bail:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int _tbfcp_session_send_Hello(tbfcp_session_t* p_self)
|
||||
{
|
||||
tbfcp_pkt_t* p_pkt = tsk_null;
|
||||
int ret;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tbfcp_pkt_create_Hello(p_self->conf_ids.u_conf_id, tbfcp_utils_rand_u16(), p_self->conf_ids.u_user_id, &p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tbfcp_session_send_pkt(p_self, p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _tbfcp_session_send_HelloAck(tbfcp_session_t* p_self, const tbfcp_pkt_t *pc_hello)
|
||||
{
|
||||
tbfcp_pkt_t* p_pkt = tsk_null;
|
||||
int ret;
|
||||
if (!p_self || !pc_hello) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tbfcp_pkt_create_HelloAck_2(pc_hello->hdr.conf_id, pc_hello->hdr.transac_id, pc_hello->hdr.user_id, &p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tbfcp_session_send_pkt(p_self, p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _tbfcp_session_send_FloorRequest(tbfcp_session_t* p_self)
|
||||
{
|
||||
tbfcp_pkt_t* p_pkt = tsk_null;
|
||||
int ret;
|
||||
if (!p_self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if ((ret = tbfcp_pkt_create_FloorRequest_2(p_self->conf_ids.u_conf_id, tbfcp_utils_rand_u16(), p_self->conf_ids.u_user_id, p_self->conf_ids.u_floor_id, &p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = tbfcp_session_send_pkt(p_self, p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _tbfcp_session_process_incoming_pkt(tbfcp_session_t* p_self, const tbfcp_pkt_t *pc_pkt)
|
||||
{
|
||||
int ret = 0;
|
||||
if (!p_self || !pc_pkt) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// lock()
|
||||
tsk_safeobj_lock(p_self);
|
||||
|
||||
switch (pc_pkt->hdr.primitive) {
|
||||
case tbfcp_primitive_Hello:
|
||||
if ((ret = _tbfcp_session_send_HelloAck(p_self, pc_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
case tbfcp_primitive_HelloAck:
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
_tbfcp_session_send_FloorRequest(p_self);
|
||||
_tbfcp_session_send_FloorRequest(p_self);
|
||||
|
||||
bail:
|
||||
// unlock()
|
||||
tsk_safeobj_unlock(p_self);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// clear junks (e.g. IPSec)
|
||||
static int _tbfcp_session_socket_type_make_valid(enum tnet_socket_type_e e_in_st, enum tnet_socket_type_e *pe_out_st)
|
||||
{
|
||||
|
@ -514,9 +719,37 @@ static int _tbfcp_session_timer_callback(const void* pc_arg, tsk_timer_id_t time
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _tbfcp_session_transport_layer_cb(const tnet_transport_event_t* e)
|
||||
static int _tbfcp_session_transport_layer_dgram_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
tbfcp_session_t* p_session = (tbfcp_session_t*)e->callback_data;
|
||||
int ret;
|
||||
tbfcp_pkt_t* p_pkt = tsk_null;
|
||||
switch(e->type){
|
||||
case event_data: {
|
||||
break;
|
||||
}
|
||||
case event_closed:
|
||||
case event_connected:
|
||||
default:{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = tbfcp_pkt_read(e->data, e->size, &p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
if ((ret = _tbfcp_session_process_incoming_pkt(p_session, p_pkt))) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
TSK_OBJECT_SAFE_FREE(p_pkt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _tbfcp_session_transport_layer_stream_cb(const tnet_transport_event_t* e)
|
||||
{
|
||||
tbfcp_session_t* p_session = (tbfcp_session_t*)e->callback_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -533,6 +766,8 @@ static tsk_object_t* tbfcp_session_ctor(tsk_object_t * self, va_list * app)
|
|||
return tsk_null;
|
||||
}
|
||||
p_session->u_local_port = TNET_SOCKET_PORT_ANY;
|
||||
p_session->e_role_local = kBfcpRoleDefault;
|
||||
p_session->e_setup_local = kBfcpSetupDefault;
|
||||
tsk_safeobj_init(p_session);
|
||||
}
|
||||
return self;
|
||||
|
@ -552,6 +787,7 @@ static tsk_object_t* tbfcp_session_dtor(tsk_object_t * self)
|
|||
TSK_FREE(p_session->p_local_public_ip);
|
||||
TSK_FREE(p_session->p_remote_ip);
|
||||
TSK_FREE(p_session->p_buff_send_ptr);
|
||||
TSK_OBJECT_SAFE_FREE(p_session->p_natt_ctx);
|
||||
TSK_OBJECT_SAFE_FREE(p_session->p_ice_ctx);
|
||||
TSK_OBJECT_SAFE_FREE(p_session->p_transport);
|
||||
tsk_safeobj_deinit(p_session);
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
/* Copyright (C) 2014 Mamadou DIOP.
|
||||
*
|
||||
* This file is part of Open Source Doubango Framework.
|
||||
*
|
||||
* DOUBANGO 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.
|
||||
*
|
||||
* DOUBANGO 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DOUBANGO.
|
||||
*
|
||||
*/
|
||||
#include "tinybfcp/tbfcp_utils.h"
|
||||
|
||||
#include "tinynet.h"
|
||||
#include "tsk_string.h"
|
||||
#include "tsk_debug.h"
|
||||
|
||||
int tbfcp_utils_get_profile(enum tnet_socket_type_e e_socket_type, const char** ppc_profile)
|
||||
{
|
||||
if (!ppc_profile) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TNET_SOCKET_TYPE_IS_DTLS(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileDTLS;
|
||||
return 0;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_UDP(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileUDP;
|
||||
return 0;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_TLS(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileTLS;
|
||||
return 0;
|
||||
}
|
||||
if (TNET_SOCKET_TYPE_IS_TCP(e_socket_type)) {
|
||||
*ppc_profile = kBfcpProfileTCP;
|
||||
return 0;
|
||||
}
|
||||
TSK_DEBUG_ERROR("%d not supported as valid socket type for BFCP sessions", e_socket_type);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int tbfcp_utils_get_role(enum tbfcp_role_e e_role, const char** ppc_role)
|
||||
{
|
||||
if (!ppc_role) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
switch (e_role) {
|
||||
case tbfcp_role_c_only:
|
||||
*ppc_role = kBfcpRoleC;
|
||||
return 0;
|
||||
case tbfcp_role_s_only:
|
||||
*ppc_role = kBfcpRoleS;
|
||||
return 0;
|
||||
case tbfcp_role_c_s:
|
||||
*ppc_role = kBfcpRoleCS;
|
||||
return 0;
|
||||
default:
|
||||
TSK_DEBUG_ERROR("%d not valid BFCP role", e_role);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int tbfcp_utils_parse_role(const char* pc_role, enum tbfcp_role_e* pe_role)
|
||||
{
|
||||
if (!pc_role || !pe_role) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (tsk_striequals(pc_role, kBfcpRoleC)) {
|
||||
*pe_role = tbfcp_role_c_only;
|
||||
return 0;
|
||||
}
|
||||
if (tsk_striequals(pc_role, kBfcpRoleS)) {
|
||||
*pe_role = tbfcp_role_s_only;
|
||||
return 0;
|
||||
}
|
||||
if (tsk_striequals(pc_role, kBfcpRoleCS)) {
|
||||
*pe_role = tbfcp_role_c_s;
|
||||
return 0;
|
||||
}
|
||||
TSK_DEBUG_ERROR("%s not valid BFCP role", pc_role);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int tbfcp_utils_get_setup(enum tbfcp_role_e e_setup, const char** ppc_setup)
|
||||
{
|
||||
if (!ppc_setup) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
switch (e_setup) {
|
||||
case tbfcp_setup_actpass:
|
||||
*ppc_setup = kBfcpSetupActPass;
|
||||
return 0;
|
||||
case tbfcp_setup_active:
|
||||
*ppc_setup = kBfcpSetupActive;
|
||||
return 0;
|
||||
case tbfcp_setup_passive:
|
||||
*ppc_setup = kBfcpSetupPassive;
|
||||
return 0;
|
||||
default:
|
||||
TSK_DEBUG_ERROR("%d not valid BFCP setup", e_setup);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int tbfcp_utils_parse_setup(const char* pc_setup, enum tbfcp_setup_e* pe_setup)
|
||||
{
|
||||
if (!pc_setup || !pe_setup) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
if (tsk_striequals(pc_setup, kBfcpSetupActPass)) {
|
||||
*pe_setup = tbfcp_setup_actpass;
|
||||
return 0;
|
||||
}
|
||||
if (tsk_striequals(pc_setup, kBfcpSetupActive)) {
|
||||
*pe_setup = tbfcp_setup_active;
|
||||
return 0;
|
||||
}
|
||||
if (tsk_striequals(pc_setup, kBfcpSetupPassive)) {
|
||||
*pe_setup = tbfcp_setup_passive;
|
||||
return 0;
|
||||
}
|
||||
TSK_DEBUG_ERROR("%s not valid BFCP setup", pc_setup);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int tbfcp_utils_is_role_acceptable(enum tbfcp_role_e e_role_local, enum tbfcp_role_e e_role_proposed, tsk_bool_t *pb_acceptable)
|
||||
{
|
||||
if (!pb_acceptable) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
switch (e_role_local) {
|
||||
case tbfcp_role_c_only:
|
||||
*pb_acceptable = (e_role_proposed == tbfcp_role_s_only || e_role_proposed == tbfcp_role_c_s);
|
||||
break;
|
||||
case tbfcp_role_s_only:
|
||||
*pb_acceptable = (e_role_proposed == tbfcp_role_c_only || e_role_proposed == tbfcp_role_c_s);
|
||||
break;
|
||||
case tbfcp_role_c_s:
|
||||
*pb_acceptable = tsk_true;
|
||||
break;
|
||||
default:
|
||||
*pb_acceptable = tsk_false;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tbfcp_utils_is_setup_acceptable(enum tbfcp_setup_e e_setup_local, enum tbfcp_setup_e e_setup_proposed, tsk_bool_t *pb_acceptable)
|
||||
{
|
||||
if (!pb_acceptable) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
switch (e_setup_local) {
|
||||
case tbfcp_setup_active:
|
||||
*pb_acceptable = (e_setup_proposed == tbfcp_setup_passive || e_setup_proposed == tbfcp_setup_actpass);
|
||||
break;
|
||||
case tbfcp_setup_passive:
|
||||
*pb_acceptable = (e_setup_proposed == tbfcp_setup_active || e_setup_proposed == tbfcp_setup_actpass);
|
||||
break;
|
||||
case tbfcp_setup_actpass:
|
||||
*pb_acceptable = tsk_true;
|
||||
break;
|
||||
default:
|
||||
*pb_acceptable = tsk_false;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t tbfcp_utils_rand_u16()
|
||||
{
|
||||
return (rand() ^ rand()) % 0xFFFF;
|
||||
}
|
|
@ -190,6 +190,10 @@
|
|||
RelativePath=".\src\tbfcp_session.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tbfcp_utils.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="include(*.h)"
|
||||
|
@ -212,6 +216,10 @@
|
|||
RelativePath=".\include\tinybfcp\tbfcp_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\tinybfcp\tbfcp_utils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\tinybfcp.h"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue