Modified: freeswitch/trunk/contrib/ledr/c/mod_pcli/mod_pcli.c (15435 => 15436)
--- freeswitch/trunk/contrib/ledr/c/mod_pcli/mod_pcli.c 2009-11-11 20:40:02 UTC (rev 15435)
+++ freeswitch/trunk/contrib/ledr/c/mod_pcli/mod_pcli.c 2009-11-11 22:46:53 UTC (rev 15436)
@@ -48,18 +48,22 @@
switch_memory_pool_t *pool;
int switch_id;
char *local_addr;
+ char *remote_addr;
int local_port;
- char *remote_addr;
int remote_port;
switch_socket_t *socket;
+ switch_sockaddr_t *local_sockaddr;
+ switch_sockaddr_t *remote_sockaddr;
} pcli_globals;
// temporary declaration here.. remove after testing is done !!!!
static switch_status_t gen_pcli_header(uint32_t *pcli_header, pcli_media_direction_t media_direction, uint16_t call_id, uint8_t switch_id, uint16_t ini_id);
+static switch_status_t send_packet();
typedef struct {
switch_core_session_t *session;
- char *ini_id;
+ uint16_t ini_id;
+ uint16_t instance_id;
} pcli_session_helper_t;
/* config item validations */
@@ -94,17 +98,22 @@
return SWITCH_STATUS_FALSE;
}
- /* for now, only init port on startup, fix reload later !! */
if (!reload) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Trying to create a udp socket !!\n");
-
- if (switch_sockaddr_info_get(&local_sockaddr, pcli_globals.local_addr, SWITCH_UNSPEC, pcli_globals.local_port, 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS || !local_sockaddr) {
+ if (switch_sockaddr_info_get(&local_sockaddr, pcli_globals.local_addr, SWITCH_UNSPEC,
+ pcli_globals.local_port, 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS || !local_sockaddr) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Local Address Error!\n");
return SWITCH_STATUS_FALSE;
}
- if (switch_socket_create(&socket, switch_sockaddr_get_family(local_sockaddr), SOCK_DGRAM, 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS) {
+ if (switch_sockaddr_info_get(&remote_sockaddr, pcli_globals.remote_addr, SWITCH_UNSPEC,
+ pcli_globals.remote_port, 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS || !remote_sockaddr) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Remote Address Error!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_socket_create(&socket, switch_sockaddr_get_family(local_sockaddr), SOCK_DGRAM,
+ 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Socket Error!\n");
return SWITCH_STATUS_FALSE;
}
@@ -120,54 +129,71 @@
}
pcli_globals.socket = socket;
+ pcli_globals.local_sockaddr = local_sockaddr;
+ pcli_globals.remote_sockaddr = remote_sockaddr;
- /* TEST SENDING A PACKET */
- if (switch_sockaddr_info_get(&remote_sockaddr, pcli_globals.remote_addr, SWITCH_UNSPEC, pcli_globals.remote_port, 0, pcli_globals.pool) != SWITCH_STATUS_SUCCESS || !remote_sockaddr) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Remote Address Error!\n");
- return SWITCH_STATUS_FALSE;
- }
+ }
- /* create a pcli header */
- uint32_t pcli_header;
- pcli_media_direction_t media_direction = PCLI_MEDIA_DIRECTION_FROM_TARGET;
- uint16_t call_id = 123;
- uint8_t switch_id = 12;
- uint16_t ini_id = 10741;
- gen_pcli_header(&pcli_header, media_direction, call_id, switch_id, ini_id);
+ return SWITCH_STATUS_SUCCESS;
+}
- uint32_t network_byte_order_pcli_header;
- network_byte_order_pcli_header = htonl(pcli_header);
- /* create a pcli body */
- char *pcli_body = "ABCD";
+static switch_status_t send_packet() {
+ /* create a pcli header */
+ uint32_t pcli_header;
+ pcli_media_direction_t media_direction = PCLI_MEDIA_DIRECTION_FROM_TARGET;
+ uint16_t call_id = 123;
+ uint8_t switch_id = 12;
+ uint16_t ini_id = 10741;
+ gen_pcli_header(&pcli_header, media_direction, call_id, switch_id, ini_id);
- /* create a full packet */
- char *packet;
- packet = malloc(sizeof(network_byte_order_pcli_header) + sizeof(pcli_body));
- memcpy(packet, &network_byte_order_pcli_header, sizeof(network_byte_order_pcli_header));
- memcpy(packet + sizeof(network_byte_order_pcli_header), pcli_body, sizeof(pcli_body));
+ uint32_t network_byte_order_pcli_header;
+ network_byte_order_pcli_header = htonl(pcli_header);
- size_t packetsize;
- packetsize = sizeof(packet);
+ /* create a pcli body */
+ char *pcli_body = "ABCD";
- switch_socket_sendto(pcli_globals.socket, remote_sockaddr, 0, packet, &packetsize);
+ /* create a full packet */
+ char *packet; // TODO shouldn't this be unsigned ?
+ packet = malloc(sizeof(network_byte_order_pcli_header) + sizeof(pcli_body));
+ memcpy(packet, &network_byte_order_pcli_header, sizeof(network_byte_order_pcli_header));
+ memcpy(packet + sizeof(network_byte_order_pcli_header), pcli_body, sizeof(pcli_body));
- }
+ size_t packetsize;
+ packetsize = sizeof(packet);
+ //switch_socket_sendto(pcli_globals.socket, remote_sockaddr, 0, packet, &packetsize);
+ switch_socket_sendto(pcli_globals.socket, pcli_globals.remote_sockaddr, 0, packet, &packetsize);
+
return SWITCH_STATUS_SUCCESS;
}
+
+
+
/* called when SWITCH_EVENT_RELOADXML is sent to this module */
static void reload_event_handler(switch_event_t *event)
{
do_config(SWITCH_TRUE);
}
+/*
+static switch_status_t gen_fake_ipv4_header()
+{
+}
+
+static switch_status_t gen_fake_udp_header()
+{
+}
+
+static switch_status_t gen_fake_rtp_body()
+{
+}
+*/
+
/* generate a PacketCable Lawful Intercept header, that can be prepended to an RTP packet */
-static switch_status_t gen_pcli_header(uint32_t *pcli_header, pcli_media_direction_t media_direction, uint16_t call_id, uint8_t switch_id, uint16_t ini_id)
+static switch_status_t gen_pcli_header(uint32_t *pcli_header, pcli_media_direction_t media_direction, uint16_t instance_id, uint8_t switch_id, uint16_t ini_id)
{
- *pcli_header = 0;
-
/* some sanity checks */
if (media_direction > 3) {
@@ -175,8 +201,8 @@
return SWITCH_STATUS_FALSE;
}
- if (call_id > 1023) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid call_id, may only be 0-1023\n");
+ if (instance_id > 1023) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid instance_id, may only be 0-1023\n");
return SWITCH_STATUS_FALSE;
}
@@ -187,62 +213,55 @@
/* ini_id needs no check as it may use the full uint16_t */
+ *pcli_header = 0;
*pcli_header |= (media_direction);
- *pcli_header |= (call_id << 2);
+ *pcli_header |= (instance_id << 2); // this seems to work, but:
*pcli_header |= (switch_id << 12);
- *pcli_header |= (ini_id << 16);
+ *pcli_header |= (ini_id << 16); // how can i shift left 16 on a uint16_t ???! is shifting not done inside the memory space of the ini_id ?? FIND OUT !!
return SWITCH_STATUS_SUCCESS;
}
static switch_bool_t pcli_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
-// pcli_session_helper_t *pcli_session_helper = (pcli_session_helper_t *) user_data;
+ //pcli_session_helper_t *helper = (pcli_session_helper_t *) user_data;
switch (type) {
- case SWITCH_ABC_TYPE_INIT:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> INIT\n");
- break;
+ case SWITCH_ABC_TYPE_INIT:
+ case SWITCH_ABC_TYPE_READ_PING:
+ case SWITCH_ABC_TYPE_CLOSE:
+ case SWITCH_ABC_TYPE_READ:
+ case SWITCH_ABC_TYPE_WRITE:
+ case SWITCH_ABC_TYPE_READ_REPLACE:
+ case SWITCH_ABC_TYPE_WRITE_REPLACE:
+ break;
- case SWITCH_ABC_TYPE_READ_PING:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> PING\n");
- break;
-
- case SWITCH_ABC_TYPE_CLOSE:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> CLOSE\n");
- break;
-
- case SWITCH_ABC_TYPE_READ:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> READ\n");
- break;
-
- case SWITCH_ABC_TYPE_WRITE:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> WRITE\n");
- break;
-
- case SWITCH_ABC_TYPE_READ_REPLACE:
- {
+ case SWITCH_ABC_TYPE_READ_EARLY:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> SWITCH_ABC_TYPE_READ_EARLY\n");
+
+/*
+ {
switch_frame_t *rframe = switch_core_media_bug_get_read_replace_frame(bug);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> READ_REPLACE seq[%u] ssrc[%lu] packetlen[%lu] rate [%lu] samples [%lu]\n",
(unsigned)rframe->seq, (unsigned long)rframe->ssrc, (unsigned long)rframe->packetlen, (unsigned long)rframe->rate, (unsigned long)rframe->samples);
switch_size_t packetlength = sizeof(rframe->packet);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, ">>> [%lu]\n", (unsigned long)packetlength);
- }
- break;
+ //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "HELPER.SESSION->RAW_READ_FRAME.DATALEN [%lu]\n", helper->session->raw_read_frame.datalen);
- case SWITCH_ABC_TYPE_WRITE_REPLACE:
- {
- switch_frame_t *rframe = switch_core_media_bug_get_write_replace_frame(bug);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> WRITE_REPLACE seq[%u] ssrc[%lu] packetlen[%lu] rate [%lu] samples[%lu]\n",
- (unsigned)rframe->seq, (unsigned long)rframe->ssrc, (unsigned long)rframe->packetlen, (unsigned long)rframe->rate, (unsigned long)rframe->samples);
-switch_size_t packetlength = sizeof(rframe->packet);
-switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, ">>> [%lu]\n", (unsigned long)packetlength);
- }
- break;
+ }
+*/
+ break;
+
+ case SWITCH_ABC_TYPE_WRITE_LATE:
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "--> SWITCH_ABC_TYPE_WRITE_LATE\n");
+ break;
}
+
+ send_packet();
+
return SWITCH_TRUE;
}
@@ -285,19 +304,25 @@
/* make session available from pcli_session_helper */
pcli_session_helper->session = session;
- /* get LI_ID and store in pcli_session_helper */
- if ((p = switch_channel_get_variable(channel, "LI_ID")) && switch_true(p)) {
- pcli_session_helper->ini_id = switch_core_session_strdup(session, p);
+ /* get pcli_ini_id and store in pcli_session_helper */
+ if ((p = switch_channel_get_variable(channel, "pcli_ini_id")) && switch_true(p)) {
+ pcli_session_helper->ini_id = (uint16_t)atoi(p);
} else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No LI_ID was set!\n");
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No pcli_ini_id channel variable was set!\n");
return;
}
+ /* get pcli_instance_id and store in pcli_session_helper */
+ if ((p = switch_channel_get_variable(channel, "pcli_instance_id")) && switch_true(p)) {
+ pcli_session_helper->instance_id = (uint16_t)atoi(p);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No pcli_instance_id channel variable was set!\n");
+ return;
+ }
+
/* add the bug */
- //status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_BOTH, &bug);
- //status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_READ_STREAM | SMBF_WRITE_STREAM, &bug);
- status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_READ_REPLACE | SMBF_WRITE_REPLACE, &bug);
- //status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_READ_REPLACE, &bug);
+ //status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_READ_REPLACE | SMBF_WRITE_REPLACE, &bug);
+ status = switch_core_media_bug_add(session, pcli_callback, pcli_session_helper, 0, SMBF_READ_STREAM, &bug);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failure hooking to stream\n");
Added: freeswitch/trunk/contrib/ledr/c/mod_pcli/read_early_write_late.patch (0 => 15436)
--- freeswitch/trunk/contrib/ledr/c/mod_pcli/read_early_write_late.patch (rev 0)
+++ freeswitch/trunk/contrib/ledr/c/mod_pcli/read_early_write_late.patch 2009-11-11 22:46:53 UTC (rev 15436)
@@ -0,0 +1,162 @@
+Index: src/switch_core_io.c
+===================================================================
+--- src/switch_core_io.c (revision 15426)
++++ src/switch_core_io.c (working copy)
+@@ -188,6 +188,109 @@
+
+ switch_assert(*frame != NULL);
+
++///////////////////////////////////////////////////////////////////////////
++
++/*
++ if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) {
++ switch_media_bug_t *bp, *dp, *last = NULL;
++ switch_bool_t ok = SWITCH_TRUE;
++ switch_thread_rwlock_rdlock(session->bug_rwlock);
++ for (bp = session->bugs; bp; bp = bp->next) {
++ if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
++ continue;
++ }
++
++ if (bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) {
++ switch_mutex_lock(bp->read_mutex);
++ switch_buffer_write(bp->raw_read_buffer, read_frame->data, read_frame->datalen);
++ if (bp->callback) {
++ ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ);
++ }
++ switch_mutex_unlock(bp->read_mutex);
++ }
++
++ if (ok && switch_test_flag(bp, SMBF_READ_REPLACE)) {
++ do_bugs = 0;
++ if (bp->callback) {
++ bp->read_replace_frame_in = read_frame;
++ bp->read_replace_frame_out = read_frame;
++ if ((ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_REPLACE)) == SWITCH_TRUE) {
++ read_frame = bp->read_replace_frame_out;
++ }
++ }
++ }
++
++ if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
++ ok = SWITCH_FALSE;
++ }
++
++ if (ok == SWITCH_FALSE) {
++ bp->ready = 0;
++ if (last) {
++ last->next = bp->next;
++ } else {
++ session->bugs = bp->next;
++ }
++ dp = bp;
++ bp = last;
++ switch_core_media_bug_close(&dp);
++ if (!bp) {
++ break;
++ }
++ continue;
++ }
++ last = bp;
++ }
++ switch_thread_rwlock_unlock(session->bug_rwlock);
++ }
++*/
++
++ if (session->bugs && !switch_channel_test_flag(session->channel, CF_PAUSE_BUGS)) { /* is it necessary to be able to pause this bug ? */
++ switch_media_bug_t *bp, *dp, *last = NULL;
++ switch_bool_t ok = SWITCH_TRUE;
++ switch_thread_rwlock_rdlock(session->bug_rwlock);
++ switch_frame_t *read_frame = *frame;
++
++ for (bp = session->bugs; bp; bp = bp->next) {
++// if (!switch_channel_test_flag(session->channel, CF_ANSWERED) && switch_core_media_bug_test_flag(bp, SMBF_ANSWER_REQ)) {
++// continue;
++// }
++
++ if (ok && switch_test_flag(bp, SMBF_READ_EARLY)) {
++ do_bugs = 0;
++ if (bp->callback) {
++ bp->read_replace_frame_in = read_frame;
++ bp->read_replace_frame_out = read_frame;
++ ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_EARLY);
++ }
++ }
++
++ if (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL)) {
++ ok = SWITCH_FALSE;
++ }
++
++ if (ok == SWITCH_FALSE) {
++ bp->ready = 0;
++ if (last) {
++ last->next = bp->next;
++ } else {
++ session->bugs = bp->next;
++ }
++ dp = bp;
++ bp = last;
++ switch_core_media_bug_close(&dp);
++ if (!bp) {
++ break;
++ }
++ continue;
++ }
++ last = bp;
++ }
++ switch_thread_rwlock_unlock(session->bug_rwlock);
++ }
++
++///////////////////////////////////////////////////////////////////////////
++
+ if (switch_test_flag(*frame, SFF_PROXY_PACKET)) {
+ /* Fast PASS! */
+ status = SWITCH_STATUS_SUCCESS;
+Index: src/mod/applications/mod_vmd/mod_vmd.c
+===================================================================
+--- src/mod/applications/mod_vmd/mod_vmd.c (revision 15426)
++++ src/mod/applications/mod_vmd/mod_vmd.c (working copy)
+@@ -215,6 +215,8 @@
+ return process_data(vmd_info, frame);
+
+ case SWITCH_ABC_TYPE_WRITE_REPLACE:
++ case SWITCH_ABC_TYPE_READ_EARLY:
++ case SWITCH_ABC_TYPE_WRITE_LATE:
+ break;
+ }
+
+Index: src/include/switch_types.h
+===================================================================
+--- src/include/switch_types.h (revision 15426)
++++ src/include/switch_types.h (working copy)
+@@ -341,7 +341,9 @@
+ SWITCH_ABC_TYPE_WRITE_REPLACE,
+ SWITCH_ABC_TYPE_READ_REPLACE,
+ SWITCH_ABC_TYPE_READ_PING,
+- SWITCH_ABC_TYPE_CLOSE
++ SWITCH_ABC_TYPE_CLOSE,
++ SWITCH_ABC_TYPE_READ_EARLY,
++ SWITCH_ABC_TYPE_WRITE_LATE
+ } switch_abc_type_t;
+
+ typedef struct {
+@@ -1118,6 +1120,8 @@
+ SMBF_STEREO - Record in stereo
+ SMBF_ANSWER_RECORD_REQ - Don't record until the channel is answered
+ SMBF_THREAD_LOCK - Only let the same thread who created the bug remove it.
++SMBF_READ_EARLY - Include the Read Stream right after reading (before transcoding - received packet is intact)
++SMBF_WRITE_LATE - Include the Write Stream just before writing (after transcoding - to be written packet is created)
+ </pre>
+ */
+ typedef enum {
+@@ -1129,7 +1133,9 @@
+ SMBF_READ_PING = (1 << 4),
+ SMBF_STEREO = (1 << 5),
+ SMBF_ANSWER_REQ = (1 << 6),
+- SMBF_THREAD_LOCK = (1 << 7)
++ SMBF_THREAD_LOCK = (1 << 7),
++ SMBF_READ_EARLY = (1 << 8),
++ SMBF_WRITE_LATE = (1 << 9)
+ } switch_media_bug_flag_enum_t;
+ typedef uint32_t switch_media_bug_flag_t;
+