提交 c07a6b6b authored 作者: Anthony Minessale's avatar Anthony Minessale

add polycom support to multicast paging, broadcast all formats at once to…

add polycom support to multicast paging, broadcast all formats at once to support most every popular phone at once
上级 3fe701d2
...@@ -1304,6 +1304,7 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_join(switch_socket_t *sock, switch_ ...@@ -1304,6 +1304,7 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_join(switch_socket_t *sock, switch_
SWITCH_DECLARE(switch_status_t) switch_mcast_hops(switch_socket_t *sock, uint8_t ttl); SWITCH_DECLARE(switch_status_t) switch_mcast_hops(switch_socket_t *sock, uint8_t ttl);
SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uint8_t opt); SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uint8_t opt);
SWITCH_DECLARE(switch_status_t) switch_mcast_interface(switch_socket_t *sock, switch_sockaddr_t *iface);
/** @} */ /** @} */
......
...@@ -35,6 +35,45 @@ ...@@ -35,6 +35,45 @@
SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load); SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load);
SWITCH_MODULE_DEFINITION(mod_esf, mod_esf_load, NULL, NULL); SWITCH_MODULE_DEFINITION(mod_esf, mod_esf_load, NULL, NULL);
#ifdef _MSC_VER
#pragma pack(push, r1, 1)
#else
#pragma pack(1)
#endif
struct polycom_packet {
switch_byte_t op;
switch_byte_t channel;
uint32_t serno;
uint8_t cid_len;
unsigned char cid[13];
};
typedef struct polycom_packet polycom_packet_t;
typedef struct {
switch_byte_t codec;
switch_byte_t flags;
uint32_t seq;
} polycom_audio_header_t;
typedef struct polycom_alert_packet {
polycom_packet_t header;
polycom_audio_header_t audio_header;
uint8_t data[];
} polycom_alert_packet_t;
#ifdef _MSC_VER
#pragma pack(pop, r1)
#else
#pragma pack()
#endif
struct ls_control_packet { struct ls_control_packet {
uint32_t unique_id; uint32_t unique_id;
uint32_t command; uint32_t command;
...@@ -52,35 +91,82 @@ typedef enum { ...@@ -52,35 +91,82 @@ typedef enum {
typedef enum { typedef enum {
SEND_TYPE_UNKNOWN = 0, SEND_TYPE_UNKNOWN = 0,
SEND_TYPE_RTP = 1, SEND_TYPE_RTP = 1,
SEND_TYPE_RAW = 2, SEND_TYPE_NOMEDIA = 2
SEND_TYPE_NOMEDIA = 3
} ls_how_t; } ls_how_t;
static uint32_t SERNO = 0;
switch_mutex_t *MUTEX = NULL;
uint32_t get_serno(void)
{
uint32_t r = 0;
switch_mutex_lock(MUTEX);
r = SERNO;
switch_mutex_unlock(MUTEX);
return r;
}
void inc_serno(void)
{
switch_mutex_lock(MUTEX);
SERNO++;
switch_mutex_unlock(MUTEX);
}
void dec_serno(void)
{
switch_mutex_lock(MUTEX);
SERNO--;
switch_mutex_unlock(MUTEX);
}
SWITCH_STANDARD_APP(bcast_function) SWITCH_STANDARD_APP(bcast_function)
{ {
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
switch_socket_t *socket; switch_socket_t *socket, *polycom_socket = NULL;
switch_sockaddr_t *audio_addr = NULL, *control_packet_addr; switch_sockaddr_t *audio_addr = NULL, *control_packet_addr = NULL, *polycom_addr = NULL, *local_addr = NULL;
switch_frame_t *read_frame = NULL; switch_frame_t *read_frame = NULL;
switch_status_t status; switch_status_t status;
switch_size_t bytes; switch_size_t bytes;
ls_control_packet_t control_packet; ls_control_packet_t control_packet;
unsigned char polycom_buf[1024] = { 0 };
unsigned char last_polycom_buf[1024] = { 0 };
uint32_t last_polycom_len = 0;
polycom_packet_t *polycom_packet = (polycom_packet_t *) polycom_buf;
polycom_alert_packet_t *alert_packet = (polycom_alert_packet_t *) polycom_buf;
switch_codec_t codec = { 0 }; switch_codec_t codec = { 0 };
switch_codec_t write_codec = { 0 };
switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0};
const char *err; const char *err;
switch_rtp_t *rtp_session = NULL; switch_rtp_t *rtp_session = NULL;
switch_port_t rtp_port; switch_port_t rtp_port = 0;
char guess_ip[25];
ls_how_t ready = SEND_TYPE_UNKNOWN; ls_how_t ready = SEND_TYPE_UNKNOWN;
//int argc;
char *mydata, *argv[5]; char *mydata, *argv[5];
char *mcast_ip = "224.168.168.168"; char *mcast_ip = "224.168.168.168";
switch_port_t mcast_port = 34567; switch_port_t mcast_port = 34567;
switch_port_t mcast_control_port = 6061; switch_port_t mcast_control_port = 6061;
char *mcast_port_str = "34567"; char *mcast_port_str = "34567";
const char *esf_broadcast_ip = NULL, *var; char *polycom_ip = "224.0.1.116";
const char *source_ip = NULL;
switch_port_t polycom_port = 5001;
const char *var;
switch_codec_implementation_t read_impl = { 0 }; switch_codec_implementation_t read_impl = { 0 };
int mcast_ttl = 1; int mcast_ttl = 1;
const char *caller_id_name = NULL;
int x = 0;
uint32_t seq = 0;
const char *codec_name = "PCMU";
int read_rate = 8000;
int need_transcode = 0;
inc_serno();
switch_core_session_get_read_impl(session, &read_impl); switch_core_session_get_read_impl(session, &read_impl);
...@@ -115,6 +201,9 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -115,6 +201,9 @@ SWITCH_STANDARD_APP(bcast_function)
} }
} }
switch_channel_set_variable_printf(channel, "multicast_ttl", "%d", mcast_ttl);
if (switch_true(switch_channel_get_variable(channel, SWITCH_BYPASS_MEDIA_VARIABLE))) { if (switch_true(switch_channel_get_variable(channel, SWITCH_BYPASS_MEDIA_VARIABLE))) {
switch_core_session_message_t msg = { 0 }; switch_core_session_message_t msg = { 0 };
...@@ -132,13 +221,27 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -132,13 +221,27 @@ SWITCH_STANDARD_APP(bcast_function)
switch_channel_answer(channel); switch_channel_answer(channel);
} }
if (!(source_ip = switch_channel_get_variable(channel, "esf_multicast_bind_ip"))) {
if (!(source_ip = switch_channel_get_variable(channel, "local_ip_v4"))) {
source_ip = "127.0.0.1";
}
}
/* everyone */
if (switch_sockaddr_info_get(&local_addr, source_ip, SWITCH_UNSPEC,
0, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "address Error\n");
goto fail;
}
if (switch_socket_create(&socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { if (switch_socket_create(&socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n");
goto fail; goto fail;
} }
if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) { if (switch_socket_opt_set(socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n");
goto fail; goto fail;
} }
...@@ -148,30 +251,108 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -148,30 +251,108 @@ SWITCH_STANDARD_APP(bcast_function)
goto fail; goto fail;
} }
if (switch_socket_bind(socket, local_addr) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n");
goto fail;
}
if (switch_mcast_interface(socket, local_addr) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n");
goto fail;
}
if (switch_mcast_join(socket, control_packet_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n");
goto fail;
}
if (switch_mcast_hops(socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
goto fail;
}
/* polycom */
if (switch_sockaddr_info_get(&polycom_addr, polycom_ip, SWITCH_UNSPEC,
polycom_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 3\n");
goto fail;
}
if (switch_socket_create(&polycom_socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 1\n");
goto fail;
}
if (switch_socket_opt_set(polycom_socket, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Option Error\n");
goto fail;
}
if (switch_socket_bind(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket bind Error\n");
goto fail;
}
if (switch_mcast_interface(polycom_socket, local_addr) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket interface Error\n");
goto fail;
}
if (switch_mcast_join(polycom_socket, polycom_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Multicast Error\n");
goto fail;
}
if (switch_mcast_hops(polycom_socket, (uint8_t) mcast_ttl) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Mutlicast TTL set failed\n");
goto fail;
}
while (!ready) { while (!ready) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (read_frame && switch_test_flag(read_frame, SFF_CNG)) {
continue;
}
if (!SWITCH_READ_ACCEPTABLE(status) || !read_frame) { if (!SWITCH_READ_ACCEPTABLE(status) || !read_frame) {
goto fail; goto fail;
} }
if (read_frame->packet && read_frame->packetlen && read_impl.ianacode == 0) {
ready = SEND_TYPE_RAW; if (switch_test_flag(read_frame, SFF_CNG)) {
} else { continue;
}
ready = SEND_TYPE_RTP; ready = SEND_TYPE_RTP;
} }
alert_packet->audio_header.codec = 0x00;
alert_packet->audio_header.flags = 0;
if ((var = switch_channel_get_variable(channel, "esf_multicast_write_codec"))) {
if (!strcasecmp(var, "PCMU")) {
codec_name = var;
} else if (!strcasecmp(var, "G722")) {
codec_name = var;
read_rate = 16000;
alert_packet->audio_header.codec = 0x09;
} }
}
if (ready == SEND_TYPE_RTP) { if (ready == SEND_TYPE_RTP) {
if (read_impl.ianacode != 0) { if (strcasecmp(read_impl.iananame, codec_name)) {
need_transcode = 1;
if (switch_core_codec_init(&codec, if (switch_core_codec_init(&codec,
"L16", "L16",
NULL, NULL,
8000, read_rate,
20, 20,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
...@@ -181,26 +362,33 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -181,26 +362,33 @@ SWITCH_STANDARD_APP(bcast_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n");
goto fail; goto fail;
} }
}
if ((var = switch_channel_get_variable(channel, "esf_broadcast_ip"))) { if (switch_core_codec_init(&write_codec,
esf_broadcast_ip = switch_core_session_strdup(session, var); codec_name,
NULL,
8000,
20,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
switch_core_session_set_read_codec(session, &codec);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activation Success\n");
} else { } else {
switch_find_local_ip(guess_ip, sizeof(guess_ip), NULL, AF_INET); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Activation Fail\n");
esf_broadcast_ip = guess_ip; goto fail;
}
} }
if (!(rtp_port = switch_rtp_request_port(esf_broadcast_ip))) { if (!(rtp_port = switch_rtp_request_port(source_ip))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Port Error\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Port Error\n");
goto fail; goto fail;
} }
rtp_session = switch_rtp_new(esf_broadcast_ip, rtp_session = switch_rtp_new(source_ip,
rtp_port, rtp_port,
mcast_ip, mcast_ip,
mcast_port, mcast_port,
0, alert_packet->audio_header.codec,
160, 160,
20000, flags, "soft", &err, switch_core_session_get_pool(session)); 20000, flags, "soft", &err, switch_core_session_get_pool(session));
...@@ -208,13 +396,9 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -208,13 +396,9 @@ SWITCH_STANDARD_APP(bcast_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "RTP Error\n");
goto fail; goto fail;
} }
} else if (ready == SEND_TYPE_NOMEDIA) { } else if (ready == SEND_TYPE_NOMEDIA) {
switch_yield(10000); switch_yield(10000);
} else if (ready == SEND_TYPE_RAW) {
if (switch_sockaddr_info_get(&audio_addr, mcast_ip, SWITCH_UNSPEC, mcast_port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Socket Error 2\n");
goto fail;
}
} }
control_packet.unique_id = htonl((u_long) switch_epoch_time_now(NULL)); control_packet.unique_id = htonl((u_long) switch_epoch_time_now(NULL));
...@@ -227,6 +411,38 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -227,6 +411,38 @@ SWITCH_STANDARD_APP(bcast_function)
bytes = 16; bytes = 16;
switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes); switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
if (!(caller_id_name = switch_channel_get_variable(channel, "caller_id_name"))) {
caller_id_name = "FreeSWITCH";
}
strncpy((char *)polycom_packet->cid, caller_id_name, sizeof(polycom_packet->cid));
polycom_packet->cid_len = 13;
polycom_packet->op = 0x0F;
polycom_packet->channel = 0x1a;
polycom_packet->serno = htonl(get_serno());
if ((var = switch_channel_get_variable(channel, "esf_multicast_channel"))) {
int channel_no = atoi(var);
if (channel_no > 0 && channel_no < 255) {
polycom_packet->channel = (uint8_t) channel_no;
}
}
for (x = 0; x < 32; x++) {
bytes = sizeof(polycom_packet_t);
switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes);
//switch_yield(30000);
}
polycom_packet->op = 0x10;
if ((var = switch_channel_get_variable(channel, "esf_multicast_alert_sound"))) {
switch_ivr_displace_session(session, var, 0, "mr");
}
while (switch_channel_ready(channel)) { while (switch_channel_ready(channel)) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
...@@ -234,26 +450,57 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -234,26 +450,57 @@ SWITCH_STANDARD_APP(bcast_function)
if (!SWITCH_READ_ACCEPTABLE(status)) { if (!SWITCH_READ_ACCEPTABLE(status)) {
break; break;
} }
if (switch_test_flag(read_frame, SFF_CNG)) { if (switch_test_flag(read_frame, SFF_CNG)) {
continue; continue;
} }
if (ready == SEND_TYPE_RTP) { if (ready == SEND_TYPE_RTP) {
short *dbuf;
unsigned char *ebuf; unsigned char *ebuf;
uint32_t i;
unsigned char encoded_data[4192]; unsigned char encoded_data[4192];
uint32_t encoded_datalen = sizeof(encoded_data);
if (need_transcode) {
uint32_t rate = codec.implementation->actual_samples_per_second;
uint32_t flag = 0;
dbuf = read_frame->data;
ebuf = encoded_data; ebuf = encoded_data;
for (i = 0; i < read_frame->datalen / sizeof(short); i++) { switch_core_codec_encode(&write_codec,
ebuf[i] = linear_to_ulaw(dbuf[i]); &codec,
} read_frame->data,
read_frame->datalen,
read_impl.actual_samples_per_second,
ebuf, &encoded_datalen, &rate, &flag);
read_frame->data = encoded_data; read_frame->data = encoded_data;
read_frame->datalen = read_frame->datalen / 2; read_frame->datalen = encoded_datalen;
} else {
ebuf = read_frame->data;
encoded_datalen = read_frame->datalen;
}
switch_rtp_write_frame(rtp_session, read_frame); switch_rtp_write_frame(rtp_session, read_frame);
read_frame->data = dbuf;
read_frame->datalen = read_frame->datalen * 2; seq += 160;
alert_packet->audio_header.seq = htonl(seq);
if (last_polycom_len) {
memcpy(alert_packet->data, last_polycom_buf, last_polycom_len);
memcpy(alert_packet->data + last_polycom_len, ebuf, encoded_datalen);
} else {
memcpy(alert_packet->data, ebuf, encoded_datalen);
}
bytes = sizeof(*alert_packet) + encoded_datalen + last_polycom_len;
switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_buf, &bytes);
last_polycom_len = encoded_datalen;
memcpy((void *)last_polycom_buf, (void *)ebuf, last_polycom_len);
} else { } else {
bytes = read_frame->packetlen; bytes = read_frame->packetlen;
switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes); switch_socket_sendto(socket, audio_addr, 0, read_frame->packet, &bytes);
...@@ -267,6 +514,16 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -267,6 +514,16 @@ SWITCH_STANDARD_APP(bcast_function)
bytes = 8; bytes = 8;
switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes); switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
polycom_packet->op = 0xFF;
//switch_yield(50000);
for (x = 0; x < 12; x++) {
bytes = sizeof(*polycom_packet);
switch_socket_sendto(socket, polycom_addr, 0, (void *) polycom_packet, &bytes);
//switch_yield(30000);
}
fail: fail:
switch_core_session_set_read_codec(session, NULL); switch_core_session_set_read_codec(session, NULL);
...@@ -282,6 +539,16 @@ SWITCH_STANDARD_APP(bcast_function) ...@@ -282,6 +539,16 @@ SWITCH_STANDARD_APP(bcast_function)
switch_socket_close(socket); switch_socket_close(socket);
} }
if (polycom_socket) {
switch_socket_close(polycom_socket);
}
if (rtp_port) {
switch_rtp_release_port(source_ip, rtp_port);
}
dec_serno();
return; return;
} }
...@@ -289,6 +556,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load) ...@@ -289,6 +556,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_esf_load)
{ {
switch_application_interface_t *app_interface; switch_application_interface_t *app_interface;
switch_mutex_init(&MUTEX, SWITCH_MUTEX_NESTED, pool);
/* connect my internal structure to the blank pointer passed to me */ /* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname); *module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_APP(app_interface, "esf_page_group", NULL, NULL, bcast_function, NULL, SAF_NONE); SWITCH_ADD_APP(app_interface, "esf_page_group", NULL, NULL, bcast_function, NULL, SAF_NONE);
......
...@@ -834,6 +834,12 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uin ...@@ -834,6 +834,12 @@ SWITCH_DECLARE(switch_status_t) switch_mcast_loopback(switch_socket_t *sock, uin
return apr_mcast_loopback(sock, opt); return apr_mcast_loopback(sock, opt);
} }
SWITCH_DECLARE(switch_status_t) switch_mcast_interface(switch_socket_t *sock, switch_sockaddr_t *iface)
{
return apr_mcast_interface(sock, iface);
}
/* socket functions */ /* socket functions */
SWITCH_DECLARE(const char *) switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in) SWITCH_DECLARE(const char *) switch_get_addr(char *buf, switch_size_t len, switch_sockaddr_t *in)
......
...@@ -1999,6 +1999,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s ...@@ -1999,6 +1999,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
{ {
switch_socket_t *new_sock = NULL, *old_sock = NULL; switch_socket_t *new_sock = NULL, *old_sock = NULL;
switch_status_t status = SWITCH_STATUS_FALSE; switch_status_t status = SWITCH_STATUS_FALSE;
int j = 0;
#ifndef WIN32 #ifndef WIN32
char o[5] = "TEST", i[5] = ""; char o[5] = "TEST", i[5] = "";
switch_size_t len, ilen = 0; switch_size_t len, ilen = 0;
...@@ -2057,6 +2058,40 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s ...@@ -2057,6 +2058,40 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
goto done; goto done;
} }
if ((j = atoi(host)) && j > 223 && j < 240) { /* mcast */
if (switch_mcast_interface(new_sock, rtp_session->local_addr) != SWITCH_STATUS_SUCCESS) {
*err = "Multicast Socket interface Error";
goto done;
}
if (switch_mcast_join(new_sock, rtp_session->local_addr, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
*err = "Multicast Error";
goto done;
}
if (rtp_session->session) {
switch_channel_t *channel = switch_core_session_get_channel(rtp_session->session);
const char *var;
if ((var = switch_channel_get_variable(channel, "multicast_ttl"))) {
int ttl = atoi(var);
if (ttl > 0 && ttl < 256) {
if (switch_mcast_hops(new_sock, (uint8_t) ttl) != SWITCH_STATUS_SUCCESS) {
*err = "Mutlicast TTL set failed";
goto done;
}
}
}
}
}
#ifndef WIN32 #ifndef WIN32
len = sizeof(i); len = sizeof(i);
switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, TRUE); switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, TRUE);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论