//#include <sys/socket.h>
extern "C" {
}
-#include <q931.h>
+#include <mISDN/q931.h>
+#include <mISDN/suppserv.h>
+#ifdef OLD_MT_ASSIGN
extern unsigned int mt_assign_pid;
+#endif
#include "ie.cpp"
+static int delete_event(struct lcr_work *work, void *instance, int index);
+
/*
* constructor
*/
-Pdss1::Pdss1(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)
+Pdss1::Pdss1(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_d_ntmode = mISDNport->ntmode;
p_m_d_tespecial = mISDNport->tespecial;
p_m_d_l3id = 0;
+ memset(&p_m_d_delete, 0, sizeof(p_m_d_delete));
+ add_work(&p_m_d_delete, delete_event, this, 0);
p_m_d_ces = -1;
p_m_d_queue[0] = '\0';
p_m_d_notify_pending = NULL;
*/
Pdss1::~Pdss1()
{
+ del_work(&p_m_d_delete);
+
/* remove queued message */
if (p_m_d_notify_pending)
message_free(p_m_d_notify_pending);
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return(-34); /* to epoint: no channel available */
}
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, pid, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
p_m_d_l3id = pid;
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
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 */
dec_ie_progress(l3m, &coding, &location, &progress);
end_trace();
+ if (progress >= 0) {
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
+ message->param.progressinfo.progress = progress;
+ message->param.progressinfo.location = location;
+ message_put(message);
+ }
+
/* process channel */
ret = received_first_reply_to_setup(cmd, channel, exclusive);
if (ret < 0) {
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
dec_ie_redir_dn(l3m, &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
end_trace();
+ if (progress >= 0) {
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
+ message->param.progressinfo.progress = progress;
+ message->param.progressinfo.location = location;
+ message_put(message);
+ }
+
ret = received_first_reply_to_setup(cmd, channel, exclusive);
if (ret < 0) {
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
dec_ie_redir_dn(l3m, &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
end_trace();
+ if (progress >= 0) {
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
+ message->param.progressinfo.progress = progress;
+ message->param.progressinfo.location = location;
+ message_put(message);
+ }
+
/* process channel */
ret = received_first_reply_to_setup(cmd, channel, exclusive);
if (ret < 0) {
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
location = LOCATION_PRIVATE_LOCAL;
}
+ if (progress >= 0) {
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
+ message->param.progressinfo.progress = progress;
+ message->param.progressinfo.location = proglocation;
+ message_put(message);
+ }
+
/* release if remote sends us no tones */
if (!p_m_mISDNport->earlyb) {
l3_msg *l3m;
free_epointlist(p_epointlist);
}
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
}
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
}
/* CC_RESTART INDICATION */
}
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
}
/* T312 timeout */
#if 0
epoint = find_epoint_id(ACTIVE_EPOINT(p_epointlist));
if (epoint && p_m_d_ntmode) {
- p_m_timeout = p_settings.tout_hold;
- time(&p_m_timer);
+ if (p_settings.tout_hold)
+ schedule_timer(&p_m_timeout, p_settings.tout_hold, 0);
}
#endif
/* set hold state */
p_m_hold = 0;
- p_m_timeout = 0;
+ unsched_timer(&p_m_timeout);
/* acknowledge retrieve */
l3m = create_l3msg();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_SUSPEND_ACKNOWLEDGE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
}
/* CC_RESUME INDICATION */
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RESUME_REJECT, pid, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
p_m_d_l3id = pid;
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RESUME_REJECT, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE);
/* CC_FACILITY INDICATION */
void Pdss1::facility_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
{
- unsigned char facil[256];
- int facil_len;
+ unsigned char fac_ie[256];
+ struct asn1_parm fac;
+ int fac_len;
struct lcr_msg *message;
l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_IND, DIRECTION_IN);
- dec_ie_facility(l3m, facil, &facil_len);
+ dec_ie_facility(l3m, fac_ie + 1, &fac_len);
+ fac_ie[0] = fac_len;
end_trace();
/* facility */
- if (facil_len<=0)
+ if (fac_len<=0)
return;
+ decodeFac(fac_ie, &fac);
+ switch (fac.comp) {
+ case CompInvoke:
+ switch(fac.u.inv.operationValue) {
+ case Fac_Begin3PTY:
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
+ message->param.threepty.begin = 1;
+ message->param.threepty.invoke = 1;
+ message->param.threepty.invoke_id = fac.u.inv.invokeId;
+ message_put(message);
+ return;
+
+ case Fac_End3PTY:
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
+ message->param.threepty.end = 1;
+ message->param.threepty.invoke = 1;
+ message->param.threepty.invoke_id = fac.u.inv.invokeId;
+ message_put(message);
+ return;
+ default:
+ ;
+ }
+ break;
+ default:
+ ;
+ }
+
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
- message->param.facilityinfo.len = facil_len;
- memcpy(message->param.facilityinfo.data, facil, facil_len);
+ message->param.facilityinfo.len = fac_len;
+ memcpy(message->param.facilityinfo.data, fac_ie + 1, fac_len);
message_put(message);
}
l1l2l3_trace_header(p_m_mISDNport, this, L3_PROGRESS_IND, DIRECTION_IN);
dec_ie_progress(l3m, &coding, &location, &progress);
end_trace();
+
+ if (progress >= 0) {
+ message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROGRESS);
+ message->param.progressinfo.progress = progress;
+ message->param.progressinfo.location = location;
+ message_put(message);
+ }
}
add_trace("callref", NULL, "0x%x", p_m_d_l3id);
end_trace();
p_m_d_l3id = 0;
+ trigger_work(&p_m_d_delete);
p_m_d_ces = -1;
- p_m_delete = 1;
/* sending release to endpoint in case we still have an endpoint
* this is because we don't get any response if a release_complete is received (or a release in release state)
*/
/* set timeout */
if (state == PORT_STATE_IN_OVERLAP) {
- p_m_timeout = p_m_mISDNport->ifport->tout_dialing;
- time(&p_m_timer);
+ if (p_m_mISDNport->ifport->tout_dialing)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_dialing, 0);
}
if (state != p_state) {
+ unsched_timer(&p_m_timeout);
if (state == PORT_STATE_IN_SETUP
|| state == PORT_STATE_OUT_SETUP
|| state == PORT_STATE_IN_OVERLAP
|| state == PORT_STATE_OUT_OVERLAP) {
- p_m_timeout = p_m_mISDNport->ifport->tout_setup;
- time(&p_m_timer);
+ if (p_m_mISDNport->ifport->tout_setup)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_setup, 0);
}
if (state == PORT_STATE_IN_PROCEEDING
|| state == PORT_STATE_OUT_PROCEEDING) {
- p_m_timeout = p_m_mISDNport->ifport->tout_proceeding;
- time(&p_m_timer);
+ if (p_m_mISDNport->ifport->tout_proceeding)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_proceeding, 0);
}
if (state == PORT_STATE_IN_ALERTING
|| state == PORT_STATE_OUT_ALERTING) {
- p_m_timeout = p_m_mISDNport->ifport->tout_alerting;
- time(&p_m_timer);
+ if (p_m_mISDNport->ifport->tout_alerting)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_alerting, 0);
}
+#if 0
if (state == PORT_STATE_CONNECT
|| state == PORT_STATE_CONNECT_WAITING) {
- p_m_timeout = 0;
+ if (p_m_mISDNport->ifport->tout_connect)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_connect, 0);
}
+#endif
if (state == PORT_STATE_IN_DISCONNECT
|| state == PORT_STATE_OUT_DISCONNECT) {
- p_m_timeout = p_m_mISDNport->ifport->tout_disconnect;
- time(&p_m_timer);
+ if (p_m_mISDNport->ifport->tout_disconnect)
+ schedule_timer(&p_m_timeout, p_m_mISDNport->ifport->tout_disconnect, 0);
}
}
}
-/*
- * handler
- */
-int Pdss1::handler(void)
+/* deletes only if l3id is release, otherwhise it will be triggered then */
+static int delete_event(struct lcr_work *work, void *instance, int index)
{
- int ret;
+ class Pdss1 *isdnport = (class Pdss1 *)instance;
- if ((ret = PmISDN::handler()))
- return(ret);
+ if (!isdnport->p_m_d_l3id)
+ delete isdnport;
- /* handle destruction */
- if (p_m_delete && p_m_d_l3id==0) {
- delete this;
- return(-1);
- }
-
- return(0);
+ return 0;
}
void Pdss1::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
{
l3_msg *l3m;
+#ifdef OLD_MT_ASSIGN
int ret;
+#endif
int plan, type, screen, present, reason;
int plan2, type2, screen2, present2;
int capability, mode, rate, coding, user, presentation, interpretation, hlc, exthlc;
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
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);
+ do_screen(1, p_redirinfo.id, sizeof(p_redirinfo.id), &p_redirinfo.ntype, &p_redirinfo.present, p_m_mISDNport->ifport->interface->name);
/* only display at connect state: this case happens if endpoint is in connected mode */
if (p_state==PORT_STATE_CONNECT) {
/* creating l3id */
l1l2l3_trace_header(p_m_mISDNport, this, L3_NEW_L3ID_REQ, DIRECTION_OUT);
+#ifdef OLD_MT_ASSIGN
/* see MT_ASSIGN notes at do_layer3() */
mt_assign_pid = 0;
ret = p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_ASSIGN, 0, NULL);
- if (mt_assign_pid == 0 || ret < 0) {
+ if (mt_assign_pid == 0 || ret < 0)
+ p_m_d_l3id = mt_assign_pid;
+ mt_assign_pid = ~0;
+#else
+ p_m_d_l3id = request_new_pid(p_m_mISDNport->ml3);
+ if (p_m_d_l3id == MISDN_PID_NONE)
+#endif
+ {
struct lcr_msg *message;
add_trace("callref", NULL, "no free id");
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
+#ifdef OLD_MT_ASSIGN
p_m_d_l3id = mt_assign_pid;
mt_assign_pid = ~0;
+#endif
add_trace("callref", "new", "0x%x", p_m_d_l3id);
end_trace();
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_SETUP_REQ, DIRECTION_OUT);
/* channel information */
- if (channel >= 0) /* it should */
+ if (p_m_d_ntmode || channel != CHANNEL_ANY) /* only omit channel id in te-mode/any channel */
enc_ie_channel_id(l3m, exclusive, channel);
/* caller information */
plan = 1;
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
}
+/* MESSAGE_3PTY */
+void Pdss1::message_3pty(unsigned int epoint_id, int message_id, union parameter *param)
+{
+ l3_msg *l3m;
+ unsigned char fac_ie[256];
+ struct asn1_parm fac;
+
+ /* encode 3PTY facility */
+ memset(&fac, 0, sizeof(fac));
+ fac.Valid = 1;
+ if (param->threepty.result) {
+ fac.comp = CompReturnResult;
+ fac.u.retResult.invokeId = param->threepty.invoke_id;
+ fac.u.retResult.operationValuePresent = 1;
+ if (param->threepty.begin)
+ fac.u.retResult.operationValue = Fac_Begin3PTY;
+ if (param->threepty.end)
+ fac.u.retResult.operationValue = Fac_End3PTY;
+ }
+ if (param->threepty.error) {
+ fac.comp = CompReturnError;
+ fac.u.retError.invokeId = param->threepty.invoke_id;
+ fac.u.retError.errorValue = FacError_Gen_InvalidCallState;
+ }
+ encodeFac(fac_ie, &fac);
+
+ /* sending facility */
+ l3m = create_l3msg();
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_FACILITY_REQ, DIRECTION_OUT);
+ enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]);
+ end_trace();
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_FACILITY, p_m_d_l3id, l3m);
+}
+
/* MESSAGE_NOTIFY */
void Pdss1::message_notify(unsigned int epoint_id, int message_id, union parameter *param)
{
int notify;
int plan = 0, type = -1, present = 0;
+ if (p_m_mISDNport->ifport->nonotify) {
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_NOTIFY_REQ, DIRECTION_OUT);
+ add_trace("info", NULL, "blocked by config");
+ end_trace();
+ return;
+ }
+
// printf("if = %d\n", param->notifyinfo.notify);
if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
notify = param->notifyinfo.notify & 0x7f;
{
l3_msg *l3m;
int type, plan, present, screen;
- class Endpoint *epoint;
+ time_t current_time;
/* NT-MODE in setup state we must send PROCEEDING first */
if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP) {
/* copy connected information */
memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
/* screen outgoing caller id */
- do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface);
+ do_screen(1, p_connectinfo.id, sizeof(p_connectinfo.id), &p_connectinfo.ntype, &p_connectinfo.present, p_m_mISDNport->ifport->interface->name);
- /* only display at connect state */
- if (p_state == PORT_STATE_CONNECT)
- if (p_connectinfo.display[0]) {
- /* sending information */
- l3m = create_l3msg();
- l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
- if (p_m_d_ntmode || p_m_d_tespecial)
- enc_ie_display(l3m, (unsigned char *)p_connectinfo.display);
- end_trace();
- p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
- return;
- }
+ set_display(p_connectinfo.display);
if (p_state!=PORT_STATE_IN_SETUP && p_state!=PORT_STATE_IN_OVERLAP && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING) {
/* connect command only possible in setup, proceeding or alerting state */
// enc_facility_centrex(&connect->FACILITY, dmsg, (unsigned char *)p_connectinfo.name, 0);
/* date & time */
if (p_m_d_ntmode || p_m_d_tespecial) {
- epoint = find_epoint_id(epoint_id);
- enc_ie_date(l3m, now, p_settings.no_seconds);
+ time(¤t_time);
+ enc_ie_date(l3m, current_time, p_settings.no_seconds);
}
end_trace();
/* finally send message */
end_trace();
p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
- p_m_delete = 1;
+ trigger_work(&p_m_d_delete);
return;
}
void Pdss1::message_release(unsigned int epoint_id, int message_id, union parameter *param)
{
l3_msg *l3m;
- class Endpoint *epoint;
char *p = NULL;
/*
- * we may only release during incoming disconnect state.
- * this means that the endpoint doesnt require audio anymore
+ * if we are on incoming call setup, we may reject by sending a release_complete
+ * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
*/
- if (p_state == PORT_STATE_IN_DISCONNECT
- || p_state == PORT_STATE_OUT_DISCONNECT) {
- /* sending release */
+ if (p_state==PORT_STATE_IN_SETUP
+ || p_state==PORT_STATE_OUT_SETUP) {
+//#warning remove me
+//PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
+ /* sending release complete */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
/* send cause */
enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
end_trace();
- p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
/* remove epoint */
free_epointid(epoint_id);
// wait for callref to be released
return;
-
}
/*
- * if we are on incoming call setup, we may reject by sending a release_complete
- * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
+ * we may only release during incoming disconnect state.
+ * this means that the endpoint doesnt require audio anymore
*/
- if (p_state==PORT_STATE_IN_SETUP
- || p_state==PORT_STATE_OUT_SETUP) {
-//#warning remove me
-//PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
- /* sending release complete */
+ if (p_state == PORT_STATE_IN_DISCONNECT
+ || p_state == PORT_STATE_OUT_DISCONNECT
+ || param->disconnectinfo.force) {
+ /* sending release */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
/* send cause */
enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
end_trace();
- p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
/* remove epoint */
free_epointid(epoint_id);
// wait for callref to be released
return;
+
}
#if 0
/* send cause */
enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
/* send display */
- epoint = find_epoint_id(epoint_id);
if (param->disconnectinfo.display[0])
p = param->disconnectinfo.display;
if (p) if (*p && (p_m_d_ntmode || p_m_d_tespecial))
message_facility(epoint_id, message_id, param);
break;
+ case MESSAGE_3PTY: /* begin result message */
+ message_3pty(epoint_id, message_id, param);
+ break;
+
case MESSAGE_OVERLAP: /* more information is needed */
if (p_state!=PORT_STATE_IN_SETUP) {
break;
port = port_first;
while(port) {
/* are we ISDN ? */
- if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_mISDN_DSS1) {
+ if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
pdss1 = (class Pdss1 *)port;
/* check out correct stack and id */
if (pdss1->p_m_mISDNport == mISDNport) {
case MT_SETUP:
/* creating port object, transparent until setup with hdlc */
SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
- if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
+ if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, mISDNport->ifport->interface, 0, 0, B_MODE_TRANSPARENT)))
FATAL("Cannot create Port instance.\n");
pdss1->message_isdn(cmd, pid, l3m);
case MT_RESUME:
/* creating port object, transparent until setup with hdlc */
SPRINT(name, "%s-%d-in", mISDNport->ifport->interface->name, mISDNport->portnum);
- if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT)))
+ if (!(pdss1 = new Pdss1(PORT_TYPE_DSS1_NT_IN, mISDNport, name, NULL, mISDNport->ifport->interface, 0, 0, B_MODE_TRANSPARENT)))
FATAL("Cannot create Port instance.\n");
pdss1->message_isdn(cmd, pid, l3m);
break;
// facility als broadcast
break;
+ case MT_L2IDLE:
+ // L2 became idle - we could sent a MT_L2RELEASE if we are the L2 master
+ PDEBUG(DEBUG_ISDN, "Got L2 idle\n");
+ break;
+
default:
PERROR("unhandled message: cmd(0x%x) pid(0x%x)\n", cmd, pid);
port = port_first;
return(0);
}
+void Pdss1::set_display(const char *text)
+{
+ l3_msg *l3m;
+
+ /* only display at connect state */
+ if (p_state == PORT_STATE_CONNECT)
+ if (text[0]) {
+ /* sending information */
+ l3m = create_l3msg();
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_INFORMATION_REQ, DIRECTION_OUT);
+ if (p_m_d_ntmode || p_m_d_tespecial)
+ enc_ie_display(l3m, (unsigned char *)text);
+ end_trace();
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_INFORMATION, p_m_d_l3id, l3m);
+ return;
+ }
+}