/*
* libpri: An implementation of Primary Rate ISDN
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2005, Digium
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
#include "pri_q921.h"
#include "pri_q931.h"
#include "pri_facility.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <limits.h>
#define MAX_MAND_IES 10
struct msgtype {
int msgnum;
char *name;
int mandies[MAX_MAND_IES];
};
static struct msgtype msgs[] = {
/* Call establishment messages */
{ Q931_ALERTING, "ALERTING" },
{ Q931_CALL_PROCEEDING, "CALL PROCEEDING" },
{ Q931_CONNECT, "CONNECT" },
{ Q931_CONNECT_ACKNOWLEDGE, "CONNECT ACKNOWLEDGE" },
{ Q931_PROGRESS, "PROGRESS", { Q931_PROGRESS_INDICATOR } },
{ Q931_SETUP, "SETUP", { Q931_BEARER_CAPABILITY, Q931_CHANNEL_IDENT } },
{ Q931_SETUP_ACKNOWLEDGE, "SETUP ACKNOWLEDGE" },
/* Call disestablishment messages */
{ Q931_DISCONNECT, "DISCONNECT", { Q931_CAUSE } },
{ Q931_RELEASE, "RELEASE" },
{ Q931_RELEASE_COMPLETE, "RELEASE COMPLETE" },
{ Q931_RESTART, "RESTART", { Q931_RESTART_INDICATOR } },
{ Q931_RESTART_ACKNOWLEDGE, "RESTART ACKNOWLEDGE", { Q931_RESTART_INDICATOR } },
/* Miscellaneous */
{ Q931_STATUS, "STATUS", { Q931_CAUSE, Q931_CALL_STATE } },
{ Q931_STATUS_ENQUIRY, "STATUS ENQUIRY" },
{ Q931_USER_INFORMATION, "USER_INFORMATION" },
{ Q931_SEGMENT, "SEGMENT" },
{ Q931_CONGESTION_CONTROL, "CONGESTION CONTROL" },
{ Q931_INFORMATION, "INFORMATION" },
{ Q931_FACILITY, "FACILITY" },
{ Q931_NOTIFY, "NOTIFY", { Q931_IE_NOTIFY_IND } },
/* Call Management */
{ Q931_HOLD, "HOLD" },
{ Q931_HOLD_ACKNOWLEDGE, "HOLD ACKNOWLEDGE" },
{ Q931_HOLD_REJECT, "HOLD REJECT" },
{ Q931_RETRIEVE, "RETRIEVE" },
{ Q931_RETRIEVE_ACKNOWLEDGE, "RETRIEVE ACKNOWLEDGE" },
{ Q931_RETRIEVE_REJECT, "RETRIEVE REJECT" },
{ Q931_RESUME, "RESUME" },
{ Q931_RESUME_ACKNOWLEDGE, "RESUME ACKNOWLEDGE", { Q931_CHANNEL_IDENT } },
{ Q931_RESUME_REJECT, "RESUME REJECT", { Q931_CAUSE } },
{ Q931_SUSPEND, "SUSPEND" },
{ Q931_SUSPEND_ACKNOWLEDGE, "SUSPEND ACKNOWLEDGE" },
{ Q931_SUSPEND_REJECT, "SUSPEND REJECT" },
/* Maintenance */
{ NATIONAL_SERVICE, "SERVICE" },
{ NATIONAL_SERVICE_ACKNOWLEDGE, "SERVICE ACKNOWLEDGE" },
};
static struct msgtype causes[] = {
{ PRI_CAUSE_UNALLOCATED, "Unallocated (unassigned) number" },
{ PRI_CAUSE_NO_ROUTE_TRANSIT_NET, "No route to specified transmit network" },
{ PRI_CAUSE_NO_ROUTE_DESTINATION, "No route to destination" },
{ PRI_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable" },
{ PRI_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded and being delivered in an established channel" },
{ PRI_CAUSE_NORMAL_CLEARING, "Normal Clearing" },
{ PRI_CAUSE_USER_BUSY, "User busy" },
{ PRI_CAUSE_NO_USER_RESPONSE, "No user responding" },
{ PRI_CAUSE_NO_ANSWER, "User alerting, no answer" },
{ PRI_CAUSE_CALL_REJECTED, "Call Rejected" },
{ PRI_CAUSE_NUMBER_CHANGED, "Number changed" },
{ PRI_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order" },
{ PRI_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format" },
{ PRI_CAUSE_FACILITY_REJECTED, "Facility rejected" },
{ PRI_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to STATus ENQuiry" },
{ PRI_CAUSE_NORMAL_UNSPECIFIED, "Normal, unspecified" },
{ PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Circuit/channel congestion" },
{ PRI_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order" },
{ PRI_CAUSE_NORMAL_TEMPORARY_FAILURE, "Temporary failure" },
{ PRI_CAUSE_SWITCH_CONGESTION, "Switching equipment congestion" },
{ PRI_CAUSE_ACCESS_INFO_DISCARDED, "Access information discarded" },
{ PRI_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel not available" },
{ PRI_CAUSE_PRE_EMPTED, "Pre-empted" },
{ PRI_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed" },
{ PRI_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred" },
{ PRI_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred" },
{ PRI_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized" },
{ PRI_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available" },
{ PRI_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented" },
{ PRI_CAUSE_SERVICEOROPTION_NOTAVAIL, "Service or option not available, unspecified" },
{ PRI_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented" },
{ PRI_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented" },
{ PRI_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference value" },
{ PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST, "Identified channel does not exist" },
{ PRI_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination" },
{ PRI_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified" },
{ PRI_CAUSE_MANDATORY_IE_MISSING, "Mandatory information element is missing" },
{ PRI_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexist." },
{ PRI_CAUSE_WRONG_MESSAGE, "Wrong message" },
{ PRI_CAUSE_IE_NONEXIST, "Info. element nonexist or not implemented" },
{ PRI_CAUSE_INVALID_IE_CONTENTS, "Invalid information element contents" },
{ PRI_CAUSE_WRONG_CALL_STATE, "Message not compatible with call state" },
{ PRI_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recover on timer expiry" },
{ PRI_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error" },
{ PRI_CAUSE_PROTOCOL_ERROR, "Protocol error, unspecified" },
{ PRI_CAUSE_INTERWORKING, "Interworking, unspecified" },
};
static struct msgtype facilities[] = {
{ PRI_NSF_SID_PREFERRED, "CPN (SID) preferred" },
{ PRI_NSF_ANI_PREFERRED, "BN (ANI) preferred" },
{ PRI_NSF_SID_ONLY, "CPN (SID) only" },
{ PRI_NSF_ANI_ONLY, "BN (ANI) only" },
{ PRI_NSF_CALL_ASSOC_TSC, "Call Associated TSC" },
{ PRI_NSF_NOTIF_CATSC_CLEARING, "Notification of CATSC Clearing or Resource Unavailable" },
{ PRI_NSF_OPERATOR, "Operator" },
{ PRI_NSF_PCCO, "Pre-subscribed Common Carrier Operator (PCCO)" },
{ PRI_NSF_SDN, "SDN (including GSDN)" },
{ PRI_NSF_TOLL_FREE_MEGACOM, "Toll Free MEGACOM" },
{ PRI_NSF_MEGACOM, "MEGACOM" },
{ PRI_NSF_ACCUNET, "ACCUNET Switched Digital Service" },
{ PRI_NSF_LONG_DISTANCE_SERVICE, "Long Distance Service" },
{ PRI_NSF_INTERNATIONAL_TOLL_FREE, "International Toll Free Service" },
{ PRI_NSF_ATT_MULTIQUEST, "AT&T MultiQuest" },
{ PRI_NSF_CALL_REDIRECTION_SERVICE, "Call Redirection Service" }
};
#define FLAG_PREFERRED 2
#define FLAG_EXCLUSIVE 4
#define RESET_INDICATOR_CHANNEL 0
#define RESET_INDICATOR_DS1 6
#define RESET_INDICATOR_PRI 7
#define TRANS_MODE_64_CIRCUIT 0x10
#define TRANS_MODE_2x64_CIRCUIT 0x11
#define TRANS_MODE_384_CIRCUIT 0x13
#define TRANS_MODE_1536_CIRCUIT 0x15
#define TRANS_MODE_1920_CIRCUIT 0x17
#define TRANS_MODE_MULTIRATE 0x18
#define TRANS_MODE_PACKET 0x40
#define RATE_ADAPT_56K 0x0f
#define LAYER_2_LAPB 0x46
#define LAYER_3_X25 0x66
/* The 4ESS uses a different audio field */
#define PRI_TRANS_CAP_AUDIO_4ESS 0x08
/* Don't forget to update PRI_PROG_xxx at libpri.h */
#define Q931_PROG_CALL_NOT_E2E_ISDN 0x01
#define Q931_PROG_CALLED_NOT_ISDN 0x02
#define Q931_PROG_CALLER_NOT_ISDN 0x03
#define Q931_PROG_CALLER_RETURNED_TO_ISDN 0x04
#define Q931_PROG_INBAND_AVAILABLE 0x08
#define Q931_PROG_DELAY_AT_INTERF 0x0a
#define Q93