Cancel stream if not established at time stream is about to be removed
This commit is contained in:
parent
9d8d02961b
commit
de67c79a12
|
@ -59,8 +59,9 @@ AST_MUTEX_DEFINE_STATIC(stream_write_lock);
|
||||||
typedef enum _diva_stream_state {
|
typedef enum _diva_stream_state {
|
||||||
DivaStreamCreated = 0,
|
DivaStreamCreated = 0,
|
||||||
DivaStreamActive = 1,
|
DivaStreamActive = 1,
|
||||||
DivaStreamDisconnectSent = 2,
|
DivaStreamCancelSent = 2,
|
||||||
DivaStreamDisconnected = 3
|
DivaStreamDisconnectSent = 3,
|
||||||
|
DivaStreamDisconnected = 4
|
||||||
} diva_stream_state_t;
|
} diva_stream_state_t;
|
||||||
|
|
||||||
typedef struct _diva_stream_scheduling_entry {
|
typedef struct _diva_stream_scheduling_entry {
|
||||||
|
@ -72,6 +73,7 @@ typedef struct _diva_stream_scheduling_entry {
|
||||||
int tx_flow_control;
|
int tx_flow_control;
|
||||||
char vname[CAPI_MAX_STRING]; /* Cached from capi_pvt */
|
char vname[CAPI_MAX_STRING]; /* Cached from capi_pvt */
|
||||||
dword PLCI; /* Cached from capi_pvt */
|
dword PLCI; /* Cached from capi_pvt */
|
||||||
|
time_t cancel_start;
|
||||||
} diva_stream_scheduling_entry_t;
|
} diva_stream_scheduling_entry_t;
|
||||||
|
|
||||||
static diva_entity_queue_t diva_streaming_new; /* protected by capi_put_lock, new streams */
|
static diva_entity_queue_t diva_streaming_new; /* protected by capi_put_lock, new streams */
|
||||||
|
@ -1196,7 +1198,13 @@ static int divaStreamingMessageRx (void* user_context, dword message, dword leng
|
||||||
switch ((byte)(message >> 8)) {
|
switch ((byte)(message >> 8)) {
|
||||||
case DIVA_STREAM_MESSAGE_INIT: /* Stream active */
|
case DIVA_STREAM_MESSAGE_INIT: /* Stream active */
|
||||||
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream active (PLCI=%#x)\n", pE->vname, pE->PLCI);
|
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: stream active (PLCI=%#x)\n", pE->vname, pE->PLCI);
|
||||||
pE->diva_stream_state = DivaStreamActive;
|
if (pE->diva_stream_state == DivaStreamCreated) {
|
||||||
|
pE->diva_stream_state = DivaStreamActive;
|
||||||
|
} else if (pE->diva_stream_state == DivaStreamCancelSent) {
|
||||||
|
pE->diva_stream->release_stream(pE->diva_stream);
|
||||||
|
pE->i = 0;
|
||||||
|
pE->diva_stream_state = DivaStreamDisconnectSent;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DIVA_STREAM_MESSAGE_RX_TX_ACK: /* Resolved Tx flow control */
|
case DIVA_STREAM_MESSAGE_RX_TX_ACK: /* Resolved Tx flow control */
|
||||||
|
@ -1276,6 +1284,26 @@ void capi_DivaStreamingOn(struct capi_pvt *i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove stream info
|
||||||
|
*
|
||||||
|
* To remove stream from one active connection:
|
||||||
|
* remove stream info
|
||||||
|
* disconnect B3
|
||||||
|
* remove stream
|
||||||
|
* select_b
|
||||||
|
*/
|
||||||
|
void capi_DivaStreamingRemoveInfo(struct capi_pvt *i)
|
||||||
|
{
|
||||||
|
byte description[] = { 2, 0, 0 };
|
||||||
|
MESSAGE_EXCHANGE_ERROR error;
|
||||||
|
|
||||||
|
cc_mutex_lock(&capi_put_lock);
|
||||||
|
error = capi_sendf (NULL, 0, CAPI_MANUFACTURER_REQ, i->PLCI, get_capi_MessageNumber(),
|
||||||
|
"dws", _DI_MANU_ID, _DI_STREAM_CTRL, description);
|
||||||
|
cc_mutex_unlock(&capi_put_lock);
|
||||||
|
}
|
||||||
|
|
||||||
void capi_DivaStreamingRemove(struct capi_pvt *i)
|
void capi_DivaStreamingRemove(struct capi_pvt *i)
|
||||||
{
|
{
|
||||||
diva_stream_scheduling_entry_t* pE = i->diva_stream_entry;
|
diva_stream_scheduling_entry_t* pE = i->diva_stream_entry;
|
||||||
|
@ -1284,12 +1312,37 @@ void capi_DivaStreamingRemove(struct capi_pvt *i)
|
||||||
if (pE->diva_stream_state == DivaStreamCreated) {
|
if (pE->diva_stream_state == DivaStreamCreated) {
|
||||||
cc_mutex_lock(&capi_put_lock);
|
cc_mutex_lock(&capi_put_lock);
|
||||||
/** \todo Use Diva MANUFACTURER_REQ to cancel stream */
|
/** \todo Use Diva MANUFACTURER_REQ to cancel stream */
|
||||||
|
|
||||||
|
if (i->NCCI != 0) {
|
||||||
|
/*
|
||||||
|
If NCCI is not sen then this is no possibility to send cancel request
|
||||||
|
to queued in the IDI L2 streaming info. But in user mode this is OK,
|
||||||
|
if removing PLCI CAPI removes networking entity and this operation
|
||||||
|
causes cancellation of create streaming request.
|
||||||
|
Timeout is only for the rare case where create streaming request was newer
|
||||||
|
sent to hardware.
|
||||||
|
*/
|
||||||
|
byte data[] = { 0x8 /* CONTROL */, 0x01 /* CANCEL */};
|
||||||
|
MESSAGE_EXCHANGE_ERROR error;
|
||||||
|
|
||||||
|
error = capi_sendf(NULL, 0, CAPI_DATA_B3_REQ, i->NCCI, get_capi_MessageNumber(),
|
||||||
|
"dwww", data, sizeof(data), 0, 1U << 4);
|
||||||
|
if (likely(error == 0)) {
|
||||||
|
cc_mutex_lock(&i->lock);
|
||||||
|
i->B3count++;
|
||||||
|
cc_mutex_unlock(&i->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
pE->i = 0;
|
pE->i = 0;
|
||||||
|
pE->diva_stream_state = DivaStreamCancelSent;
|
||||||
|
pE->cancel_start = time(NULL) + 5;
|
||||||
cc_mutex_unlock(&capi_put_lock);
|
cc_mutex_unlock(&capi_put_lock);
|
||||||
|
DBG_LOG(("stream %p canceled", pE->diva_stream))
|
||||||
} else if (pE->diva_stream_state == DivaStreamActive) {
|
} else if (pE->diva_stream_state == DivaStreamActive) {
|
||||||
cc_mutex_lock(&capi_put_lock);
|
cc_mutex_lock(&capi_put_lock);
|
||||||
pE->diva_stream->release_stream(pE->diva_stream);
|
pE->diva_stream->release_stream(pE->diva_stream);
|
||||||
pE->i = 0;
|
pE->i = 0;
|
||||||
|
pE->diva_stream_state = DivaStreamDisconnectSent;
|
||||||
cc_mutex_unlock(&capi_put_lock);
|
cc_mutex_unlock(&capi_put_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1304,6 +1357,7 @@ void capi_DivaStreamingRemove(struct capi_pvt *i)
|
||||||
void divaStreamingWakeup (void) {
|
void divaStreamingWakeup (void) {
|
||||||
static diva_entity_queue_t active_streams;
|
static diva_entity_queue_t active_streams;
|
||||||
diva_entity_link_t* link;
|
diva_entity_link_t* link;
|
||||||
|
time_t current_time = time (NULL);
|
||||||
|
|
||||||
cc_mutex_lock(&capi_put_lock);
|
cc_mutex_lock(&capi_put_lock);
|
||||||
while ((link = diva_q_get_head (&diva_streaming_new)) != 0) {
|
while ((link = diva_q_get_head (&diva_streaming_new)) != 0) {
|
||||||
|
@ -1313,7 +1367,7 @@ void divaStreamingWakeup (void) {
|
||||||
}
|
}
|
||||||
cc_mutex_unlock(&capi_put_lock);
|
cc_mutex_unlock(&capi_put_lock);
|
||||||
|
|
||||||
for (link = diva_q_get_head (&active_streams); link != 0;) {
|
for (link = diva_q_get_head (&active_streams); likely(link != 0);) {
|
||||||
diva_entity_link_t* next = diva_q_get_next(link);
|
diva_entity_link_t* next = diva_q_get_next(link);
|
||||||
diva_stream_scheduling_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_stream_scheduling_entry_t, link);
|
diva_stream_scheduling_entry_t* pE = DIVAS_CONTAINING_RECORD(link, diva_stream_scheduling_entry_t, link);
|
||||||
|
|
||||||
|
@ -1321,7 +1375,14 @@ void divaStreamingWakeup (void) {
|
||||||
pE->diva_stream->wakeup (pE->diva_stream);
|
pE->diva_stream->wakeup (pE->diva_stream);
|
||||||
cc_mutex_unlock(&stream_write_lock);
|
cc_mutex_unlock(&stream_write_lock);
|
||||||
|
|
||||||
if (pE->diva_stream == 0) {
|
if (unlikely(pE->diva_stream_state == DivaStreamCancelSent && pE->cancel_start < current_time)) {
|
||||||
|
DBG_LOG(("stream %p reclaimed", pE->diva_stream))
|
||||||
|
pE->diva_stream->release (pE->diva_stream);
|
||||||
|
pE->diva_stream_state = DivaStreamDisconnected;
|
||||||
|
pE->diva_stream = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(pE->diva_stream == 0)) {
|
||||||
diva_q_remove (&active_streams, &pE->link);
|
diva_q_remove (&active_streams, &pE->link);
|
||||||
if (pE->i != 0) {
|
if (pE->i != 0) {
|
||||||
pE->i->diva_stream_entry = 0;
|
pE->i->diva_stream_entry = 0;
|
||||||
|
|
|
@ -61,6 +61,7 @@ extern int capi_write_frame(struct capi_pvt *i, struct ast_frame *f);
|
||||||
extern int capi_verify_resource_plci(const struct capi_pvt *i);
|
extern int capi_verify_resource_plci(const struct capi_pvt *i);
|
||||||
#ifdef DIVA_STREAMING
|
#ifdef DIVA_STREAMING
|
||||||
extern void capi_DivaStreamingOn(struct capi_pvt *i);
|
extern void capi_DivaStreamingOn(struct capi_pvt *i);
|
||||||
|
extern void capi_DivaStreamingRemoveInfo(struct capi_pvt *i);
|
||||||
extern void capi_DivaStreamingRemove(struct capi_pvt *i);
|
extern void capi_DivaStreamingRemove(struct capi_pvt *i);
|
||||||
extern void divaStreamingWakeup (void);
|
extern void divaStreamingWakeup (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue