+#ifdef SOCKET_MISDN
+void Pdss1::message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
+{
+ int timer = 0;
+
+ switch (cmd)
+ {
+ case MT_TIMEOUT:
+ if (!l3m->cause)
+ {
+ PERROR("Pdss1(%s) timeout without cause.\n", p_name);
+ break;
+ }
+ if (l3m->cause[0] != 5)
+ {
+ PERROR("Pdss1(%s) expecting timeout with timer diagnostic. (got len=%d)\n", p_name, l3m->cause[0]);
+ break;
+ }
+ timer = (l3m->cause[3]-'0')*100;
+ timer += (l3m->cause[4]-'0')*10;
+ timer += (l3m->cause[5]-'0');
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_TIMEOUT_IND, DIRECTION_IN);
+ add_trace("timer", NULL, "%d", timer);
+ end_trace();
+ if (timer == 312)
+ t312_timeout_ind(cmd, pid, l3m);
+ break;
+
+ case MT_SETUP:
+ if (p_state != PORT_STATE_IDLE)
+ break;
+ setup_ind(cmd, pid, l3m);
+ break;
+
+ case MT_INFORMATION:
+ information_ind(cmd, pid, l3m);
+ break;
+
+ case MT_SETUP_ACKNOWLEDGE:
+ if (p_state != PORT_STATE_OUT_SETUP)
+ {
+ PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
+ break;
+ }
+ setup_acknowledge_ind(cmd, pid, l3m);
+ break;
+
+ case MT_CALL_PROCEEDING:
+ if (p_state != PORT_STATE_OUT_SETUP
+ && p_state != PORT_STATE_OUT_OVERLAP)
+ {
+ PDEBUG(DEBUG_ISDN, "Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
+ break;
+ }
+ proceeding_ind(cmd, pid, l3m);
+ break;
+
+ case MT_ALERTING:
+ if (p_state != PORT_STATE_OUT_SETUP
+ && p_state != PORT_STATE_OUT_OVERLAP
+ && p_state != PORT_STATE_OUT_PROCEEDING)
+ {
+ PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
+ break;
+ }
+ alerting_ind(cmd, pid, l3m);
+ break;
+
+ case MT_CONNECT:
+ if (p_state != PORT_STATE_OUT_SETUP
+ && p_state != PORT_STATE_OUT_OVERLAP
+ && p_state != PORT_STATE_OUT_PROCEEDING
+ && p_state != PORT_STATE_OUT_ALERTING)
+ {
+ PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING.\n", p_name);
+ break;
+ }
+ connect_ind(cmd, pid, l3m);
+ if (p_m_d_notify_pending)
+ {
+ /* send pending notify message during connect */
+ message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
+ message_free(p_m_d_notify_pending);
+ p_m_d_notify_pending = NULL;
+ }
+ break;
+
+ case MT_CONNECT_ACKNOWLEDGE:
+ if (p_state == PORT_STATE_CONNECT_WAITING)
+ new_state(PORT_STATE_CONNECT);
+ if (p_m_d_notify_pending)
+ {
+ /* send pending notify message during connect-ack */
+ message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
+ message_free(p_m_d_notify_pending);
+ p_m_d_notify_pending = NULL;
+ }
+ break;
+
+ case MT_DISCONNECT:
+ disconnect_ind(cmd, pid, l3m);
+ break;
+
+ case MT_RELEASE:
+ release_ind(cmd, pid, l3m);
+ break;
+
+ case MT_RELEASE_COMPLETE:
+ release_complete_ind(cmd, pid, l3m);
+ break;
+
+ case MT_NOTIFY:
+ notify_ind(cmd, pid, l3m);
+ break;
+
+ case MT_HOLD:
+ hold_ind(cmd, pid, l3m);
+ break;
+
+ case MT_RETRIEVE:
+ retrieve_ind(cmd, pid, l3m);
+ break;
+
+ case MT_SUSPEND:
+ suspend_ind(cmd, pid, l3m);
+ break;
+
+ case MT_RESUME:
+ resume_ind(cmd, pid, l3m);
+ break;
+
+ case MT_FACILITY:
+ facility_ind(cmd, pid, l3m);
+ break;
+
+ case MT_FREE:
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_L3ID_IND, DIRECTION_IN);
+ add_trace("callref", NULL, "0x%x", p_m_d_l3id);
+ end_trace();
+ p_m_d_l3id = 0;
+ 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)
+ */
+ while(p_epointlist) // only if not already released
+ {
+ struct lcr_msg *message;
+ message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
+ if (p_m_d_collect_cause)
+ {
+ message->param.disconnectinfo.cause = p_m_d_collect_cause;
+ message->param.disconnectinfo.location = p_m_d_collect_location;
+ } else
+ {
+ message->param.disconnectinfo.cause = CAUSE_NOUSER;
+ message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ }
+ message_put(message);
+ /* remove epoint */
+ free_epointlist(p_epointlist);
+
+ new_state(PORT_STATE_RELEASE);
+ }
+ break;
+
+ default:
+ l1l2l3_trace_header(p_m_mISDNport, this, L3_UNKNOWN, DIRECTION_IN);
+ add_trace("unhandled", "cmd", "0x%x", cmd);
+ end_trace();
+ }
+}
+#else