typedef enum {
BST_FREE,
BST_WAITING,
+ BST_ACK,
BST_READY,
BST_FAIL
} sangoma_boost_request_status_t;
return 0;
}
+/**
+ * \brief determines whether media is ready
+ * \param event boost event
+ * \return 1 true, 0 for false
+ */
+
+static int boost_media_ready(sangomabc_event_t *event)
+{
+ /* FORMAT is of type: SMG003-EVI-1-MEDIA-# */
+ char* p = NULL;
+ p = strstr(event->isup_in_rdnis, "MEDIA");
+ if (p) {
+ int media_ready = 0;
+ if ((sscanf(p, "MEDIA-%d", &media_ready)) == 1) {
+ if (media_ready) {
+ return 1;
+ } else {
+ }
+ } else {
+ zap_log(ZAP_LOG_ERROR, "Invalid boost isup_rdnis MEDIA format %s\n", p);
+ }
+ }
+ return 0;
+}
/**
* \brief Requests an sangoma boost channel on a span (outgoing call)
}
//printf("WTF %d\n", sanity);
}
+
+ if (OUTBOUND_REQUESTS[r].status == BST_ACK && OUTBOUND_REQUESTS[r].zchan) {
+ *zchan = OUTBOUND_REQUESTS[r].zchan;
+ status = ZAP_SUCCESS;
+ (*zchan)->init_state = ZAP_CHANNEL_STATE_PROGRESS;
+ zap_log(ZAP_LOG_DEBUG, "Channel state changed to PROGRESS [Csid:%d]\n", r);
+ }
+
+ sanity = 5000;
+ while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_ACK) {
+ zap_sleep(1);
+ if (--sanity <= 0) {
+ status = ZAP_FAIL;
+ *zchan = NULL;
+ goto done;
+ }
+ //printf("WTF %d\n", sanity);
+ }
if (OUTBOUND_REQUESTS[r].status == BST_READY && OUTBOUND_REQUESTS[r].zchan) {
*zchan = OUTBOUND_REQUESTS[r].zchan;
status = ZAP_SUCCESS;
(*zchan)->init_state = ZAP_CHANNEL_STATE_PROGRESS_MEDIA;
+ zap_log(ZAP_LOG_DEBUG, "Channel state changed to PROGRESS_MEDIA [Csid:%d]\n", r);
} else {
status = ZAP_FAIL;
*zchan = NULL;
return status;
}
+/**
+ * \brief Handler for call start ack no media event
+ * \param mcon sangoma boost connection
+ * \param event Event to handle
+ */
+static void handle_call_progress(sangomabc_connection_t *mcon, sangomabc_short_event_t *event)
+{
+ zap_channel_t *zchan;
+
+ if (nack_map[event->call_setup_id]) {
+ return;
+ }
+
+ //if we received a progress for this device already
+ if (OUTBOUND_REQUESTS[event->call_setup_id].status == BST_ACK) {
+ if (boost_media_ready((sangomabc_event_t*) event)) {
+ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY;
+ zap_log(ZAP_LOG_DEBUG, "chan media ready %d:%d CSid:%d\n", event->span+1, event->chan+1, event->call_setup_id);
+ }
+ return;
+ }
+
+ OUTBOUND_REQUESTS[event->call_setup_id].event = *event;
+ SETUP_GRID[event->span][event->chan] = event->call_setup_id;
+
+ if ((zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, (sangomabc_short_event_t*) event, 0))) {
+ if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) {
+ zap_log(ZAP_LOG_ERROR, "OPEN ERROR [%s]\n", zchan->last_error);
+ } else {
+ zap_set_flag(zchan, ZAP_CHANNEL_OUTBOUND);
+ zap_set_flag_locked(zchan, ZAP_CHANNEL_INUSE);
+ zchan->extra_id = event->call_setup_id;
+ zap_log(ZAP_LOG_DEBUG, "Assign chan %d:%d (%d:%d) CSid=%d\n", zchan->span_id, zchan->chan_id, event->span+1,event->chan+1, event->call_setup_id);
+ zchan->sflags = 0;
+ OUTBOUND_REQUESTS[event->call_setup_id].zchan = zchan;
+ if (boost_media_ready((sangomabc_event_t*)event)) {
+ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY;
+ } else {
+ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_ACK;
+ }
+ return;
+ }
+ }
+
+ //printf("WTF BAD ACK CSid=%d span=%d chan=%d\n", event->call_setup_id, event->span+1,event->chan+1);
+ if ((zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 1))) {
+ //printf("WTF BAD ACK2 %d:%d (%d:%d) CSid=%d xtra_id=%d out=%d state=%s\n", zchan->span_id, zchan->chan_id, event->span+1,event->chan+1, event->call_setup_id, zchan->extra_id, zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND), zap_channel_state2str(zchan->state));
+ }
+
+
+ zap_log(ZAP_LOG_CRIT, "START PROGRESS CANT FIND A CHAN %d:%d\n", event->span+1,event->chan+1);
+ sangomabc_exec_command(mcon,
+ event->span,
+ event->chan,
+ event->call_setup_id,
+ SIGBOOST_EVENT_CALL_STOPPED,
+ ZAP_CAUSE_DESTINATION_OUT_OF_ORDER);
+ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_FAIL;
+}
+
/**
* \brief Handler for call start ack event
* \param mcon sangoma boost connection
0,
SIGBOOST_EVENT_CALL_STOPPED_ACK,
0);
-
- release_request_id_span_chan(event->span, event->chan);
+
+ release_request_id_span_chan(event->span, event->chan);
}
/**
case SIGBOOST_EVENT_CALL_START_ACK:
handle_call_start_ack(mcon, event);
break;
+ case SIGBOOST_EVENT_CALL_PROGRESS:
+ handle_call_progress(mcon, event);
+ break;
case SIGBOOST_EVENT_CALL_START_NACK:
handle_call_start_nack(span, mcon, event);
break;
};
static struct sangomabc_map sangomabc_table[] = {
- {SIGBOOST_EVENT_CALL_START, "CALL_START"},
+ {SIGBOOST_EVENT_CALL_START, "CALL_START"},
{SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"},
- {SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
+ {SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
+ {SIGBOOST_EVENT_CALL_PROGRESS, "CALL PROGRESS"},
{SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"},
{SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"},
{SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"},
{
if (event->event_id == SIGBOOST_EVENT_HEARTBEAT)
return;
- zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s]\n",
+ zap_log(file, func, line, ZAP_LOG_LEVEL_WARNING, "%s EVENT: %s:(%X) [w%dg%d] CSid=%i Seq=%i Cn=[%s] Cd=[%s] Ci=[%s] Rdnis=[%s]\n",
dir ? "TX":"RX",
sangomabc_event_id_name(event->event_id),
event->event_id,
event->fseqno,
strlen(event->calling_name)?event->calling_name:"N/A",
(event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
- (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A")
- );
+ (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"),
+ event->isup_in_rdnis);
}
static void sangomabc_print_event_short(sangomabc_connection_t *mcon, sangomabc_short_event_t *event, int priority, int dir, const char *file, const char *func, int line)
SIGBOOST_EVENT_CALL_STOPPED_ACK = 0x86, /*134*/
SIGBOOST_EVENT_SYSTEM_RESTART = 0x87, /*135*/
SIGBOOST_EVENT_SYSTEM_RESTART_ACK = 0x88, /*136*/
+ SIGBOOST_EVENT_CALL_PROGRESS = 0x50, /*decimal 80*/
/* Following IDs are ss7boost to sangoma_mgd only. */
SIGBOOST_EVENT_HEARTBEAT = 0x89, /*137*/
SIGBOOST_EVENT_INSERT_CHECK_LOOP = 0x8a, /*138*/
SIGBOOST_HUNTGRP_RR_DESC = 0x03, /* round-robin with highest available first */
};
+enum e_sigboost_event_info_par_values
+{
+ SIGBOOST_EVI_SPARE = 0x00,
+ SIGBOOST_EVI_ALERTING = 0x01,
+ SIGBOOST_EVI_PROGRESS = 0x02,
+};
+
+
#define MAX_DIALED_DIGITS 31
/* Next two defines are used to create the range of values for call_setup_id
* in the t_sigboost structure.
* 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */
#define CORE_MAX_SPANS 200
-#define CORE_MAX_CHAN_PER_SPAN 30
+#define CORE_MAX_CHAN_PER_SPAN 32
#define MAX_PENDING_CALLS CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
#define SIZE_RDNIS 900
uint32_t trunk_group;
uint8_t span;
uint8_t chan;
+ /* struct timeval tv; */
uint8_t called_number_digits_count;
char called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
uint8_t calling_number_digits_count; /* it's an array */
uint32_t trunk_group;
uint8_t span;
uint8_t chan;
+ /* struct timeval tv; */
uint8_t release_cause;
} t_sigboost_short;
#pragma pack()
+
static inline int boost_full_event(int event_id)
{
switch (event_id) {
case SIGBOOST_EVENT_CALL_START:
case SIGBOOST_EVENT_DIGIT_IN:
+ case SIGBOOST_EVENT_CALL_PROGRESS:
return 1;
default:
return 0;
return 0;
}
-
#endif