memset(&port_settings, 0, sizeof(port_settings));
SCPY(port_settings.tones_dir, options.tones_dir);
- ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
+ ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, mISDNport->ifport->interface, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
if (!ss5port)
FATAL("No memory for Pss5 class.\n");
if (!ss5port->p_m_b_channel)
return NULL;
}
+int queue_event(struct lcr_work *work, void *instance, int index);
/*
* constructor
*/
-Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, channel, exclusive, mode)
+Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, interface, channel, exclusive, mode)
{
p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
p_m_s_state = SS5_STATE_IDLE;
//p_m_s_decoder_buffer;
p_m_s_sample_nr = 0;
p_m_s_recog = 0;
- p_m_s_timer = 0.0;
- p_m_s_timer_fn = NULL;
+ memset(&p_m_s_queue, 0, sizeof(p_m_s_queue));
+ add_work(&p_m_s_queue, queue_event, this, 0);
p_m_s_answer = 0;
p_m_s_busy_flash = 0;
p_m_s_clear_back = 0;
*/
Pss5::~Pss5()
{
+ del_work(&p_m_s_queue);
}
PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 state from %s to %s\n", p_name, func, line, ss5_state_name[p_m_s_state], ss5_state_name[state]);
p_m_s_state = state;
p_m_s_signal = SS5_SIGNAL_NULL;
+
+ if (p_m_s_state == SS5_STATE_IDLE && (p_m_s_answer || p_m_s_busy_flash || p_m_s_clear_back))
+ trigger_work(&p_m_s_queue);
}
+
+int queue_event(struct lcr_work *work, void *instance, int index)
+{
+ class Pss5 *ss5port = (class Pss5 *)instance;
+
+ if (ss5port->p_m_s_state == SS5_STATE_IDLE) {
+ /* if answer signal is queued */
+ if (ss5port->p_m_s_answer) {
+ ss5port->p_m_s_answer = 0;
+ /* start answer */
+ ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_ANSWER_REQ, ss5port->p_m_b_channel);
+ end_trace();
+ ss5port->start_signal(SS5_STATE_ANSWER);
+ }
+
+ /* if busy-flash signal is queued */
+ if (ss5port->p_m_s_busy_flash) {
+ ss5port->p_m_s_busy_flash = 0;
+ /* start busy-flash */
+ ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_BUSY_FLASH_REQ, ss5port->p_m_b_channel);
+ end_trace();
+ ss5port->start_signal(SS5_STATE_BUSY_FLASH);
+ }
+
+ /* if clear-back signal is queued */
+ if (ss5port->p_m_s_clear_back) {
+ ss5port->p_m_s_clear_back = 0;
+ /* start clear-back */
+ ss5_trace_header(ss5port->p_m_mISDNport, ss5port, SS5_CLEAR_BACK_REQ, ss5port->p_m_b_channel);
+ end_trace();
+ ss5port->start_signal(SS5_STATE_CLEAR_BACK);
+ }
+ }
+
+ return 0;
+}
+
void Pss5::_new_ss5_signal(int signal, const char *func, int line)
{
if (p_m_s_signal)
if (duration > 0 && p_m_s_sample_nr >= duration) {
PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
- do_release(CAUSE_NOCHANNEL, LOCATION_BEYOND);
+ do_release(CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL);
break;
}
new_ss5_state(SS5_STATE_DELAY);
{
struct lcr_msg *message;
- p_m_s_timer = 0.0;
-
/* sending release to endpoint */
while(p_epointlist) {
message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
FATAL("Incoming call but already got an endpoint.\n");
if (!(epoint = new Endpoint(p_serial, 0)))
FATAL("No memory for Endpoint instance\n");
- if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
- FATAL("No memory for Endpoint Application instance\n");
+ epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
epointlist_new(epoint->ep_serial);
/* send setup message to endpoit */
}
-/*
- * handler
- */
-int Pss5::handler(void)
-{
- int ret;
-
- if ((ret = PmISDN::handler()))
- return(ret);
-
- /* handle timer */
- if (p_m_s_timer && p_m_s_timer < now) {
- p_m_s_timer = 0.0;
- (this->*(p_m_s_timer_fn))();
- }
-
- /* if answer signal is queued */
- if (p_m_s_answer && p_m_s_state == SS5_STATE_IDLE) {
- p_m_s_answer = 0;
- /* start answer */
- ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_REQ, p_m_b_channel);
- end_trace();
- start_signal(SS5_STATE_ANSWER);
- }
-
- /* if busy-flash signal is queued */
- if (p_m_s_busy_flash && p_m_s_state == SS5_STATE_IDLE) {
- p_m_s_busy_flash = 0;
- /* start busy-flash */
- ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_REQ, p_m_b_channel);
- end_trace();
- start_signal(SS5_STATE_BUSY_FLASH);
- }
-
- /* if clear-back signal is queued */
- if (p_m_s_clear_back && p_m_s_state == SS5_STATE_IDLE) {
- p_m_s_clear_back = 0;
- /* start clear-back */
- ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_REQ, p_m_b_channel);
- end_trace();
- start_signal(SS5_STATE_CLEAR_BACK);
- }
-
- return(0);
-}
-
/*
* handles all messages from endpoint
memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
/* screen outgoing caller id */
- do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface);
- do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface);
+ do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
+ do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
/* parse dial string */
dash = 0; /* dash must be used next time */
if (p_state != PORT_STATE_CONNECT) {
new_state(PORT_STATE_CONNECT);
p_m_s_answer = 1;
+ trigger_work(&p_m_s_queue);
}
set_tone("", NULL);
start_signal(SS5_STATE_CLEAR_BACK);
new_state(PORT_STATE_OUT_DISCONNECT);
-// p_m_s_timer_fn = &Pss5::register_timeout;
-// p_m_s_timer = now + 30.0;
}
/* MESSAGE_RELEASE */
void Pss5::register_timeout(void)
{
- do_release(CAUSE_NORMAL, LOCATION_BEYOND);
+ do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL);
}
/*