Diva streaming, rx

This commit is contained in:
MelwareDE 2010-05-07 22:28:56 +00:00
parent 3256ef3db9
commit 77265e267b
5 changed files with 124 additions and 37 deletions

View File

@ -39,6 +39,13 @@
#include "chan_capi_supplementary.h"
#include "chan_capi_chat.h"
#include "chan_capi_command.h"
#ifdef DIVA_STREAMING
#include "platform.h"
#include "diva_streaming_result.h"
#include "diva_streaming_messages.h"
#include "diva_streaming_vector.h"
#include "diva_streaming_manager.h"
#endif
/* #define CC_VERSION "x.y.z" */
#define CC_VERSION "$Revision$"
@ -4217,7 +4224,12 @@ static void capidev_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, u
/*
* CAPI DATA_B3_IND
*/
static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
static void capidev_handle_data_b3_indication(_cmsg *CMSG,
unsigned int PLCI,
unsigned int NCCI,
struct capi_pvt *i,
struct _diva_streaming_vector* vind,
int vind_nr)
{
struct ast_frame fr = { AST_FRAME_NULL, };
unsigned char *b3buf = NULL;
@ -4229,14 +4241,23 @@ static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
if (i != NULL) {
if ((i->isdnstate & CAPI_ISDN_STATE_RTP)) rtpoffset = RTP_HEADER_SIZE;
b3len = DATA_B3_IND_DATALENGTH(CMSG);
b3buf = &(i->rec_buffer[AST_FRIENDLY_OFFSET - rtpoffset]);
memcpy(b3buf, (char *)DATA_B3_IND_DATA(CMSG), b3len);
if (CMSG != 0) {
b3len = DATA_B3_IND_DATALENGTH(CMSG);
memcpy(b3buf, (char *)DATA_B3_IND_DATA(CMSG), b3len);
} else {
dword i = 0, k = 0;
#ifdef DIVA_STREAMING
b3len = (int)diva_streaming_read_vector_data (vind, vind_nr, &i, &k, b3buf, CAPI_MAX_B3_BLOCK_SIZE);
#endif
}
}
/* send a DATA_B3_RESP very quickly to free the buffer in capi */
capi_sendf(NULL, 0, CAPI_DATA_B3_RESP, NCCI, HEADER_MSGNUM(CMSG),
"w", DATA_B3_IND_DATAHANDLE(CMSG));
if (CMSG != 0) { /* send a DATA_B3_RESP very quickly to free the buffer in capi */
capi_sendf(NULL, 0, CAPI_DATA_B3_RESP, NCCI, HEADER_MSGNUM(CMSG),
"w", DATA_B3_IND_DATAHANDLE(CMSG));
}
return_on_no_interface("DATA_B3_IND");
@ -4331,6 +4352,15 @@ static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, un
return;
}
#ifdef DIVA_STREAMING
void capidev_handle_data_b3_indication_vector (struct capi_pvt *i,
struct _diva_streaming_vector* vind,
int vind_nr)
{
capidev_handle_data_b3_indication(0, 0, 0, i, vind, vind_nr);
}
#endif
/*
* signal 'answer' to PBX
*/
@ -5126,7 +5156,7 @@ static void capidev_handle_msg(_cmsg *CMSG)
capidev_handle_connect_indication(CMSG, PLCI, NCCI, &i);
break;
case CAPI_P_IND(DATA_B3):
capidev_handle_data_b3_indication(CMSG, PLCI, NCCI, i);
capidev_handle_data_b3_indication(CMSG, PLCI, NCCI, i, 0, 0);
break;
case CAPI_P_IND(CONNECT_B3):
capidev_handle_connect_b3_indication(CMSG, PLCI, NCCI, i);
@ -5243,7 +5273,10 @@ static void capidev_handle_msg(_cmsg *CMSG)
wInfo = (unsigned short)(CMSG->Class >> 16);
capidev_handle_connection_conf(&i, PLCI, wInfo, wMsgNum);
break;
#ifdef DIVA_STREAMING
case _DI_STREAM_CTRL:
break;
#endif
default:
cc_log(LOG_ERROR, CC_MESSAGE_BIGNAME ": unknown manufacturer command: %04x",
CMSG->Class & 0xffff);
@ -7971,7 +8004,7 @@ static int cc_init_capi(void)
}
#ifdef DIVA_STREAMING
/** \todo check CAPI profile */
cc_verbose(3, 0, VERBOSE_PREFIX_4 "Divaa streaming is supported\n");
cc_verbose(3, 0, VERBOSE_PREFIX_4 "CAPI %d Diva streaming is supported\n", cp->controller);
cp->divaStreaming = 1;
#endif
capi_controllers[controller] = cp;

View File

@ -724,6 +724,13 @@ extern char chatinfo_usage[];
typedef int (*pbx_capi_command_proc_t)(struct ast_channel *, char *);
pbx_capi_command_proc_t pbx_capi_lockup_command_by_name(const char* name);
#ifdef DIVA_STREAMING
struct _diva_streaming_vector;
void capidev_handle_data_b3_indication_vector (struct capi_pvt *i,
struct _diva_streaming_vector* vind,
int vind_nr);
#endif
/* DIVA specific MANUFACTURER definitions */
#define _DI_MANU_ID 0x44444944
#define _DI_ASSIGN_PLCI 0x0001

View File

@ -1164,38 +1164,32 @@ static int divaStreamingMessageRx (void* user_context, dword message, dword leng
dword message_type = (message & 0xff);
if (message_type == 0) { /* IDI message */
#if 0
dword offset = 0;
diva_streaming_vector_t vind[8];
byte Ind = 0;
int vind_nr = 0;
int process_indication;
dword offset = 0;
diva_streaming_vector_t vind[8];
byte Ind = 0;
int vind_nr = 0;
int process_indication;
do {
vind_nr = sizeof(vind)/sizeof(vind[0]);
offset = diva_streaming_get_indication_data (offset, message, length, v, nr_v, &Ind, vind, &vind_nr);
do {
vind_nr = sizeof(vind)/sizeof(vind[0]);
offset = diva_streaming_get_indication_data (offset, message, length, v, nr_v, &Ind, vind, &vind_nr);
process_indication = ((Ind & 0x0f) == N_UDATA || channel_suspended == 0) && (diva_streaming_idi_supported_ind (Ind, vind_nr != 0, vind_nr != 0 ? (byte*)vind->data : (byte*)"") != 0);
process_indication = (diva_streaming_idi_supported_ind (Ind, vind_nr != 0, vind_nr != 0 ? (byte*)vind->data : (byte*)"") != 0);
if (likely(process_indication != 0)) {
if (likely(process_indication != 0)) {
if (likely(Ind == 8)) {
if (likely(pE->i != 0 && pE->i->NCCI != 0))
capidev_handle_data_b3_indication_vector (pE->i, vind, vind_nr);
} else {
dword i = 0, k = 0;
byte* indication_length_data;
word data_length;
byte ind_data_buffer[2048+512];
data_length = (word)diva_streaming_read_vector_data (vind, vind_nr, &i, &k, ind_data_buffer, sizeof(ind_data_buffer));
pE->combined_ind.data[pE->combined_ind.total_length++] = Ind;
pE->combined_ind.data[pE->combined_ind.total_length++] = pE->channels[pE->diva_stream_xdi_channel].xdi_channel;
indication_length_data = &pE->combined_ind.data[pE->combined_ind.total_length];
pE->combined_ind.total_length += 2;
data_length = (word)diva_streaming_read_vector_data (vind, vind_nr, &i, &k,
&pE->combined_ind.data[pE->combined_ind.total_length],
sizeof(pE->combined_ind.data_buffer)-pE->combined_ind.total_length-1);
*indication_length_data++ = (byte)data_length;
*indication_length_data = (byte)(data_length >> 8);
pE->combined_ind.total_length += data_length;
DBG_TRC(("Ind: %02x length:%u", Ind, data_length))
}
} while (offset != 0);
#endif
}
} while (offset != 0);
} else if (message_type == 0xff) { /* System message */
switch ((byte)(message >> 8)) {
case DIVA_STREAM_MESSAGE_INIT: /* Stream active */
@ -1204,7 +1198,7 @@ static int divaStreamingMessageRx (void* user_context, dword message, dword leng
break;
case DIVA_STREAM_MESSAGE_RX_TX_ACK: /* Resolved Tx flow control */
cc_verbose(4, 1, "%s: stream tx ack (PLCI=%#x)\n", pE->vname, pE->PLCI);
/* cc_verbose(4, 1, "%s: stream tx ack (PLCI=%#x)\n", pE->vname, pE->PLCI); */
break;
case DIVA_STREAM_MESSAGE_SYNC_ACK: /* Sync ack request acknowledge */
@ -1284,10 +1278,14 @@ void capi_DivaStreamingRemove(struct capi_pvt *i)
if (pE != 0) {
if (pE->diva_stream_state == DivaStreamCreated) {
cc_mutex_lock(&capi_put_lock);
/** \todo Use Diva MANUFACTURER_REQ to cancel stream */
pE->i = 0;
cc_mutex_unlock(&capi_put_lock);
} else if (pE->diva_stream_state == DivaStreamActive) {
cc_mutex_lock(&capi_put_lock);
pE->diva_stream->release_stream(pE->diva_stream);
pE->i = 0;
cc_mutex_unlock(&capi_put_lock);
}
}
@ -1299,7 +1297,7 @@ void capi_DivaStreamingRemove(struct capi_pvt *i)
To ensure exclusive access scheduling queue is static function variable
*/
void diva_streaming_wakeup (void) {
void divaStreamingWakeup (void) {
static diva_entity_queue_t active_streams;
diva_entity_link_t* link;

View File

@ -28,7 +28,7 @@
void diva_runtime_error_message (const char* fmt, ...);
void diva_runtime_log_message (const char* fmt, ...);
void diva_runtime_trace_message (const char* fmt, ...);
void diva_runtime_binary_message (const void* data, dword length);
void diva_runtime_binary_message (const void* data, unsigned long length);
#define DBG_ERR(__x__) do { diva_runtime_error_message __x__; } while (0);
#define DBG_LOG(__x__) do { diva_runtime_log_message __x__; } while (0);

View File

@ -24,6 +24,10 @@
*/
#include "platform.h"
#include <malloc.h>
#include "chan_capi_platform.h"
#include "chan_capi20.h"
#include "chan_capi.h"
#include "chan_capi_utils.h"
void* diva_os_malloc (unsigned long flags, unsigned long size) {
void* ret = 0;
@ -42,14 +46,59 @@ void diva_os_free (unsigned long flags, void* ptr) {
}
void diva_runtime_error_message (const char* fmt, ...) {
char tmp[512];
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
tmp[sizeof(tmp)-1]=0;
cc_log(LOG_ERROR, "%s\n", tmp);
}
void diva_runtime_log_message (const char* fmt, ...) {
char tmp[512];
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
tmp[sizeof(tmp)-1]=0;
cc_verbose(4, 0, "%s\n", tmp);
}
void diva_runtime_trace_message (const char* fmt, ...) {
char tmp[512];
va_list ap;
va_start(ap, fmt);
vsnprintf(tmp, sizeof(tmp), fmt, ap);
va_end(ap);
tmp[sizeof(tmp)-1]=0;
cc_verbose(4, 1, "%s\n", tmp);
}
void diva_runtime_binary_message (const void* data, unsigned long data_length) {
static const char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
word i, j;
char *p;
char hex_line[50];
const byte *buffer = data;
word length = (word)data_length;
for (i = 0; i < length; i += 16) {
p = hex_line;
for (j = 0; (j < 16) && (i+j < length); j++) {
*(p++) = ' ';
*(p++) = hex_digit_table[buffer[i+j] >> 4];
*(p++) = hex_digit_table[buffer[i+j] & 0xf];
}
*p = '\0';
cc_verbose(4, 1, "[%02x]%s\n", (unsigned int) i, hex_line);
}
}