e4b8bed7e9
Add the ability to announce a call to an endpoint when there are no B channels available. A call waiting call is a SETUP message with no B channel selected. Relevant specification: EN 300 056, EN 300 057, EN 300 058 Review: https://reviewboard.asterisk.org/r/569/ git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@1746 2fbb986a-6c06-0410-b554-c9c1f0a7f128
516 lines
18 KiB
C
516 lines
18 KiB
C
/*
|
|
* libpri: An implementation of Primary Rate ISDN
|
|
*
|
|
* Written by Mark Spencer <markster@digium.com>
|
|
*
|
|
* Copyright (C) 2001, Digium, Inc.
|
|
* All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* See http://www.asterisk.org for more information about
|
|
* the Asterisk project. Please do not directly contact
|
|
* any of the maintainers of this project for assistance;
|
|
* the project provides a web site, mailing lists and IRC
|
|
* channels for your use.
|
|
*
|
|
* This program is free software, distributed under the terms of
|
|
* the GNU General Public License Version 2 as published by the
|
|
* Free Software Foundation. See the LICENSE file included with
|
|
* this program for more details.
|
|
*
|
|
* In addition, when this program is distributed with Asterisk in
|
|
* any form that would qualify as a 'combined work' or as a
|
|
* 'derivative work' (but not mere aggregation), you can redistribute
|
|
* and/or modify the combination under the terms of the license
|
|
* provided with that copy of Asterisk, instead of the license
|
|
* terms granted here.
|
|
*/
|
|
|
|
#ifndef _PRI_Q931_H
|
|
#define _PRI_Q931_H
|
|
|
|
typedef enum q931_mode {
|
|
UNKNOWN_MODE,
|
|
CIRCUIT_MODE,
|
|
PACKET_MODE
|
|
} q931_mode;
|
|
|
|
typedef struct q931_h {
|
|
unsigned char raw[0];
|
|
u_int8_t pd; /* Protocol Discriminator */
|
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
u_int8_t x0:4;
|
|
u_int8_t crlen:4;/*!< Call reference length */
|
|
#else
|
|
u_int8_t crlen:4;/*!< Call reference length */
|
|
u_int8_t x0:4;
|
|
#endif
|
|
u_int8_t contents[0];
|
|
u_int8_t crv[3];/*!< Call reference value */
|
|
} __attribute__ ((packed)) q931_h;
|
|
|
|
|
|
/* Message type header */
|
|
typedef struct q931_mh {
|
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
u_int8_t f:1;
|
|
u_int8_t msg:7;
|
|
#else
|
|
u_int8_t msg:7;
|
|
u_int8_t f:1;
|
|
#endif
|
|
u_int8_t data[0];
|
|
} __attribute__ ((packed)) q931_mh;
|
|
|
|
/* Information element format */
|
|
typedef struct q931_ie {
|
|
u_int8_t ie;
|
|
u_int8_t len;
|
|
u_int8_t data[0];
|
|
} __attribute__ ((packed)) q931_ie;
|
|
|
|
#define Q931_RES_HAVEEVENT (1 << 0)
|
|
#define Q931_RES_INERRROR (1 << 1)
|
|
|
|
#define Q931_PROTOCOL_DISCRIMINATOR 0x08
|
|
#define GR303_PROTOCOL_DISCRIMINATOR 0x4f
|
|
/* AT&T Maintenance Protocol Discriminator */
|
|
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_1 0x03
|
|
/* National Maintenance Protocol Discriminator */
|
|
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_2 0x43
|
|
|
|
/* Q.931 / National ISDN Message Types */
|
|
|
|
/*! Send this facility APDU on the next message to go out. */
|
|
#define Q931_ANY_MESSAGE -1
|
|
|
|
/* Call Establishment Messages */
|
|
#define Q931_ALERTING 0x01
|
|
#define Q931_CALL_PROCEEDING 0x02
|
|
#define Q931_CONNECT 0x07
|
|
#define Q931_CONNECT_ACKNOWLEDGE 0x0f
|
|
#define Q931_PROGRESS 0x03
|
|
#define Q931_SETUP 0x05
|
|
#define Q931_SETUP_ACKNOWLEDGE 0x0d
|
|
|
|
/* Call Disestablishment Messages */
|
|
#define Q931_DISCONNECT 0x45
|
|
#define Q931_RELEASE 0x4d
|
|
#define Q931_RELEASE_COMPLETE 0x5a
|
|
#define Q931_RESTART 0x46
|
|
#define Q931_RESTART_ACKNOWLEDGE 0x4e
|
|
|
|
/* Miscellaneous Messages */
|
|
#define Q931_STATUS 0x7d
|
|
#define Q931_STATUS_ENQUIRY 0x75
|
|
#define Q931_USER_INFORMATION 0x20
|
|
#define Q931_SEGMENT 0x60
|
|
#define Q931_CONGESTION_CONTROL 0x79
|
|
#define Q931_INFORMATION 0x7b
|
|
#define Q931_FACILITY 0x62
|
|
#define Q931_REGISTER 0x64 /* Q.932 */
|
|
#define Q931_NOTIFY 0x6e
|
|
|
|
/* Call Management Messages */
|
|
#define Q931_HOLD 0x24
|
|
#define Q931_HOLD_ACKNOWLEDGE 0x28
|
|
#define Q931_HOLD_REJECT 0x30
|
|
#define Q931_RETRIEVE 0x31
|
|
#define Q931_RETRIEVE_ACKNOWLEDGE 0x33
|
|
#define Q931_RETRIEVE_REJECT 0x37
|
|
#define Q931_RESUME 0x26
|
|
#define Q931_RESUME_ACKNOWLEDGE 0x2e
|
|
#define Q931_RESUME_REJECT 0x22
|
|
#define Q931_SUSPEND 0x25
|
|
#define Q931_SUSPEND_ACKNOWLEDGE 0x2d
|
|
#define Q931_SUSPEND_REJECT 0x21
|
|
|
|
/* Maintenance messages (codeset 0 only) */
|
|
#define ATT_SERVICE 0x0f
|
|
#define ATT_SERVICE_ACKNOWLEDGE 0x07
|
|
#define NATIONAL_SERVICE 0x07
|
|
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x0f
|
|
|
|
#define SERVICE_CHANGE_STATUS_INSERVICE 0
|
|
#define SERVICE_CHANGE_STATUS_LOOPBACK 1 /* not supported */
|
|
#define SERVICE_CHANGE_STATUS_OUTOFSERVICE 2
|
|
#define SERVICE_CHANGE_STATUS_REQCONTINUITYCHECK 3 /* not supported */
|
|
#define SERVICE_CHANGE_STATUS_SHUTDOWN 4 /* not supported */
|
|
|
|
/* Special codeset 0 IE */
|
|
#define NATIONAL_CHANGE_STATUS 0x1
|
|
|
|
/* Q.931 / National ISDN Information Elements */
|
|
#define Q931_LOCKING_SHIFT 0x90
|
|
#define Q931_NON_LOCKING_SHIFT 0x98
|
|
#define Q931_BEARER_CAPABILITY 0x04
|
|
#define Q931_CAUSE 0x08
|
|
#define Q931_IE_CALL_STATE 0x14
|
|
#define Q931_CHANNEL_IDENT 0x18
|
|
#define Q931_PROGRESS_INDICATOR 0x1e
|
|
#define Q931_NETWORK_SPEC_FAC 0x20
|
|
#define Q931_CALLING_PARTY_CATEGORY (0x32 | Q931_CODESET(5))
|
|
#define Q931_INFORMATION_RATE 0x40
|
|
#define Q931_TRANSIT_DELAY 0x42
|
|
#define Q931_TRANS_DELAY_SELECT 0x43
|
|
#define Q931_BINARY_PARAMETERS 0x44
|
|
#define Q931_WINDOW_SIZE 0x45
|
|
#define Q931_PACKET_SIZE 0x46
|
|
#define Q931_CLOSED_USER_GROUP 0x47
|
|
#define Q931_REVERSE_CHARGE_INDIC 0x4a
|
|
#define Q931_CALLING_PARTY_NUMBER 0x6c
|
|
#define Q931_CALLING_PARTY_SUBADDR 0x6d
|
|
#define Q931_CALLED_PARTY_NUMBER 0x70
|
|
#define Q931_CALLED_PARTY_SUBADDR 0x71
|
|
#define Q931_REDIRECTING_NUMBER 0x74
|
|
#define Q931_REDIRECTING_SUBADDR 0x75
|
|
#define Q931_TRANSIT_NET_SELECT 0x78
|
|
#define Q931_RESTART_INDICATOR 0x79
|
|
#define Q931_LOW_LAYER_COMPAT 0x7c
|
|
#define Q931_HIGH_LAYER_COMPAT 0x7d
|
|
|
|
#define Q931_CODESET(x) ((x) << 8)
|
|
#define Q931_IE_CODESET(x) ((x) >> 8)
|
|
#define Q931_IE_IE(x) ((x) & 0xff)
|
|
#define Q931_FULL_IE(codeset, ie) (((codeset) << 8) | ((ie) & 0xff))
|
|
|
|
#define Q931_DISPLAY 0x28
|
|
#define Q931_IE_SEGMENTED_MSG 0x00
|
|
#define Q931_IE_CHANGE_STATUS 0x01
|
|
#define Q931_IE_ORIGINATING_LINE_INFO (0x01 | Q931_CODESET(6))
|
|
#define Q931_IE_CONNECTED_ADDR 0x0c
|
|
#define Q931_IE_CONNECTED_NUM 0x4c
|
|
#define Q931_IE_CONNECTED_SUBADDR 0x4d
|
|
#define Q931_IE_CALL_IDENTITY 0x10
|
|
#define Q931_IE_FACILITY 0x1c
|
|
#define Q931_IE_ENDPOINT_ID 0x26
|
|
#define Q931_IE_NOTIFY_IND 0x27
|
|
#define Q931_IE_TIME_DATE 0x29
|
|
#define Q931_IE_KEYPAD_FACILITY 0x2c
|
|
#define Q931_IE_CALL_STATUS 0x2d
|
|
#define Q931_IE_UPDATE 0x31
|
|
#define Q931_IE_INFO_REQUEST 0x32
|
|
#define Q931_IE_SIGNAL 0x34
|
|
#define Q931_IE_SWITCHHOOK 0x36
|
|
#define Q931_IE_GENERIC_DIGITS (0x37 | Q931_CODESET(6))
|
|
#define Q931_IE_FEATURE_ACTIVATE 0x38
|
|
#define Q931_IE_FEATURE_IND 0x39
|
|
#define Q931_IE_ORIGINAL_CALLED_NUMBER 0x73
|
|
#define Q931_IE_REDIRECTION_NUMBER 0x76
|
|
#define Q931_IE_REDIRECTION_SUBADDR 0x77
|
|
#define Q931_IE_USER_USER_FACILITY 0x7A
|
|
#define Q931_IE_USER_USER 0x7E
|
|
#define Q931_IE_ESCAPE_FOR_EXT 0x7F
|
|
|
|
|
|
/*! Q.931 call states */
|
|
enum Q931_CALL_STATE {
|
|
/*!
|
|
* \details
|
|
* null state (U0):
|
|
* No call exists.
|
|
* \details
|
|
* null state (N0):
|
|
* No call exists.
|
|
*/
|
|
Q931_CALL_STATE_NULL = 0,
|
|
/*!
|
|
* \details
|
|
* call initiated (U1):
|
|
* This state exists for an outgoing call, when the user requests
|
|
* call establishment from the network.
|
|
* \details
|
|
* call initiated (N1):
|
|
* This state exists for an outgoing call when the network has received
|
|
* a call establishment request but has not yet responded.
|
|
*/
|
|
Q931_CALL_STATE_CALL_INITIATED = 1,
|
|
/*!
|
|
* \details
|
|
* overlap sending (U2):
|
|
* This state exists for an outgoing call when the user has
|
|
* received acknowledgement of the call establishment request which
|
|
* permits the user to send additional call information to the network
|
|
* in overlap mode.
|
|
* \details
|
|
* overlap sending (N2):
|
|
* This state exists for an outgoing call when the network has acknowledged
|
|
* the call establishment request and is prepared to receive additional
|
|
* call information (if any) in overlap mode.
|
|
*/
|
|
Q931_CALL_STATE_OVERLAP_SENDING = 2,
|
|
/*!
|
|
* \details
|
|
* outgoing call proceeding (U3):
|
|
* This state exists for an outgoing call when the user has
|
|
* received acknowledgement that the network has received all
|
|
* call information necessary to effect call establishment.
|
|
* \details
|
|
* outgoing call proceeding (N3):
|
|
* This state exists for an outgoing call when the network has sent
|
|
* acknowledgement that the network has received all call information
|
|
* necessary to effect call establishment.
|
|
*/
|
|
Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING = 3,
|
|
/*!
|
|
* \details
|
|
* call delivered (U4):
|
|
* This state exists for an outgoing call when the calling user has
|
|
* received an indication that remote user alerting has been initiated.
|
|
* \details
|
|
* call delivered (N4):
|
|
* This state exists for an outgoing call when the network has indicated
|
|
* that remote user alerting has been initiated.
|
|
*/
|
|
Q931_CALL_STATE_CALL_DELIVERED = 4,
|
|
/*!
|
|
* \details
|
|
* call present (U6):
|
|
* This state exists for an incoming call when the user has received a
|
|
* call establishment request but has not yet responded.
|
|
* \details
|
|
* call present (N6):
|
|
* This state exists for an incoming call when the network has sent a
|
|
* call establishment request but has not yet received a satisfactory
|
|
* response.
|
|
*/
|
|
Q931_CALL_STATE_CALL_PRESENT = 6,
|
|
/*!
|
|
* \details
|
|
* call received (U7):
|
|
* This state exists for an incoming call when the user has indicated
|
|
* alerting but has not yet answered.
|
|
* \details
|
|
* call received (N7):
|
|
* This state exists for an incoming call when the network has received
|
|
* an indication that the user is alerting but has not yet received an
|
|
* answer.
|
|
*/
|
|
Q931_CALL_STATE_CALL_RECEIVED = 7,
|
|
/*!
|
|
* \details
|
|
* connect request (U8):
|
|
* This state exists for an incoming call when the user has answered
|
|
* the call and is waiting to be awarded the call.
|
|
* \details
|
|
* connect request (N8):
|
|
* This state exists for an incoming call when the network has received
|
|
* an answer but the network has not yet awarded the call.
|
|
*/
|
|
Q931_CALL_STATE_CONNECT_REQUEST = 8,
|
|
/*!
|
|
* \details
|
|
* incoming call proceeding (U9):
|
|
* This state exists for an incoming call when the user has sent
|
|
* acknowledgement that the user has received all call information
|
|
* necessary to effect call establishment.
|
|
* \details
|
|
* incoming call proceeding (N9):
|
|
* This state exists for an incoming call when the network has received
|
|
* acknowledgement that the user has received all call information
|
|
* necessary to effect call establishment.
|
|
*/
|
|
Q931_CALL_STATE_INCOMING_CALL_PROCEEDING = 9,
|
|
/*!
|
|
* \details
|
|
* active (U10):
|
|
* This state exists for an incoming call when the user has received
|
|
* an acknowledgement from the network that the user has been awarded
|
|
* the call. This state exists for an outgoing call when the user has
|
|
* received an indication that the remote user has answered the call.
|
|
* \details
|
|
* active (N10):
|
|
* This state exists for an incoming call when the network has awarded
|
|
* the call to the called user. This state exists for an outgoing call
|
|
* when the network has indicated that the remote user has answered
|
|
* the call.
|
|
*/
|
|
Q931_CALL_STATE_ACTIVE = 10,
|
|
/*!
|
|
* \details
|
|
* disconnect request (U11):
|
|
* This state exists when the user has requested the network to clear
|
|
* the end-to-end connection (if any) and is waiting for a response.
|
|
* \details
|
|
* disconnect request (N11):
|
|
* This state exists when the network has received a request from the
|
|
* user to clear the end-to-end connection (if any).
|
|
*/
|
|
Q931_CALL_STATE_DISCONNECT_REQUEST = 11,
|
|
/*!
|
|
* \details
|
|
* disconnect indication (U12):
|
|
* This state exists when the user has received an invitation to
|
|
* disconnect because the network has disconnected the end-to-end
|
|
* connection (if any).
|
|
* \details
|
|
* disconnect indication (N12):
|
|
* This state exists when the network has disconnected the end-to-end
|
|
* connection (if any) and has sent an invitation to disconnect the
|
|
* user-network connection.
|
|
*/
|
|
Q931_CALL_STATE_DISCONNECT_INDICATION = 12,
|
|
/*!
|
|
* \details
|
|
* suspend request (U15):
|
|
* This state exists when the user has requested the network to suspend
|
|
* the call and is waiting for a response.
|
|
* \details
|
|
* suspend request (N15):
|
|
* This state exists when the network has received a request to suspend
|
|
* the call but has not yet responded.
|
|
*/
|
|
Q931_CALL_STATE_SUSPEND_REQUEST = 15,
|
|
/*!
|
|
* \details
|
|
* resume request (U17):
|
|
* This state exists when the user has requested the network to resume
|
|
* a previously suspended call and is waiting for a response.
|
|
* \details
|
|
* resume request (N17):
|
|
* This state exists when the network has received a request to resume
|
|
* a previously suspended call but has not yet responded.
|
|
*/
|
|
Q931_CALL_STATE_RESUME_REQUEST = 17,
|
|
/*!
|
|
* \details
|
|
* release request (U19):
|
|
* This state exists when the user has requested the network to release
|
|
* and is waiting for a response.
|
|
* \details
|
|
* release request (N19):
|
|
* This state exists when the network has requested the user to release
|
|
* and is waiting for a response.
|
|
*/
|
|
Q931_CALL_STATE_RELEASE_REQUEST = 19,
|
|
/*!
|
|
* \details
|
|
* call abort (N22):
|
|
* This state exists for an incoming call for the point-to-multipoint
|
|
* configuration when the call is being cleared before any user has been
|
|
* awarded the call.
|
|
*/
|
|
Q931_CALL_STATE_CALL_ABORT = 22,
|
|
/*!
|
|
* \details
|
|
* overlap receiving (U25):
|
|
* This state exists for an incoming call when the user has acknowledged
|
|
* the call establishment request from the network and is prepared to
|
|
* receive additional call information (if any) in overlap mode.
|
|
* \details
|
|
* overlap receiving (N25):
|
|
* This state exists for an incoming call when the network has received
|
|
* acknowledgement of the call establishment request which permits the
|
|
* network to send additional call information (if any) in the overlap
|
|
* mode.
|
|
*/
|
|
Q931_CALL_STATE_OVERLAP_RECEIVING = 25,
|
|
/*!
|
|
* \details
|
|
* call independent service (U31): (From Q.932)
|
|
* This state exists when a call independent supplementary service
|
|
* signalling connection is established.
|
|
* \details
|
|
* call independent service (N31): (From Q.932)
|
|
* This state exists when a call independent supplementary service
|
|
* signalling connection is established.
|
|
*/
|
|
Q931_CALL_STATE_CALL_INDEPENDENT_SERVICE = 31,
|
|
Q931_CALL_STATE_RESTART_REQUEST = 61,
|
|
Q931_CALL_STATE_RESTART = 62,
|
|
/*!
|
|
* \details
|
|
* Call state has not been set.
|
|
* Call state does not exist.
|
|
* Call state not initialized.
|
|
* Call state internal use only.
|
|
*/
|
|
Q931_CALL_STATE_NOT_SET = 0xFF,
|
|
};
|
|
|
|
/*! Q.931 call establishment state ranking for competing calls in PTMP NT mode. */
|
|
enum Q931_RANKED_CALL_STATE {
|
|
/*! Call is present but has no response yet. */
|
|
Q931_RANKED_CALL_STATE_PRESENT,
|
|
/*! Call is collecting digits. */
|
|
Q931_RANKED_CALL_STATE_OVERLAP,
|
|
/*! Call routing is happening. */
|
|
Q931_RANKED_CALL_STATE_PROCEEDING,
|
|
/*! Called party is being alerted of the call. */
|
|
Q931_RANKED_CALL_STATE_ALERTING,
|
|
/*! Call is connected. A winner has been declared. */
|
|
Q931_RANKED_CALL_STATE_CONNECT,
|
|
/*! Call is in some non-call establishment state (likely disconnecting). */
|
|
Q931_RANKED_CALL_STATE_OTHER,
|
|
};
|
|
|
|
/* EuroISDN */
|
|
#define Q931_SENDING_COMPLETE 0xa1
|
|
|
|
extern int maintenance_service(struct pri *pri, int span, int channel, int changestatus);
|
|
|
|
extern int maintenance_service_ack(struct pri *pri, q931_call *call);
|
|
|
|
|
|
/* Q.SIG specific */
|
|
#define QSIG_IE_TRANSIT_COUNT 0x31
|
|
|
|
extern int q931_receive(struct pri *pri, int tei, q931_h *h, int len);
|
|
|
|
extern int q931_alerting(struct pri *pri, q931_call *call, int channel, int info);
|
|
|
|
extern int q931_call_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause);
|
|
|
|
extern int q931_call_progress(struct pri *pri, q931_call *call, int channel, int info);
|
|
|
|
extern int q931_notify(struct pri *pri, q931_call *call, int channel, int info);
|
|
|
|
extern int q931_call_proceeding(struct pri *pri, q931_call *call, int channel, int info);
|
|
|
|
extern int q931_setup_ack(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
|
|
|
extern int q931_information(struct pri *pri, q931_call *call, char digit);
|
|
|
|
extern int q931_keypad_facility(struct pri *pri, q931_call *call, const char *digits);
|
|
|
|
extern int q931_connect(struct pri *pri, q931_call *call, int channel, int nonisdn);
|
|
int q931_connect_acknowledge(struct pri *ctrl, q931_call *call, int channel);
|
|
|
|
extern int q931_release(struct pri *pri, q931_call *call, int cause);
|
|
|
|
extern int q931_disconnect(struct pri *pri, q931_call *call, int cause);
|
|
|
|
extern int q931_hangup(struct pri *pri, q931_call *call, int cause);
|
|
|
|
extern int q931_restart(struct pri *pri, int channel);
|
|
|
|
extern int q931_facility(struct pri *pri, q931_call *call);
|
|
|
|
extern int q931_call_getcrv(struct pri *pri, q931_call *call, int *callmode);
|
|
|
|
extern int q931_call_setcrv(struct pri *pri, q931_call *call, int crv, int callmode);
|
|
|
|
struct q931_call *q931_find_call(struct pri *ctrl, int cr);
|
|
struct q931_call *q931_new_call(struct pri *pri);
|
|
|
|
extern int q931_setup(struct pri *pri, q931_call *c, struct pri_sr *req);
|
|
|
|
int q931_register(struct pri *ctrl, q931_call *call);
|
|
|
|
void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
|
|
|
|
void q931_destroycall(struct pri *pri, q931_call *c);
|
|
|
|
extern void q931_dl_indication(struct pri *pri, int event);
|
|
|
|
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
|
|
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);
|
|
int q931_send_hold_rej(struct pri *ctrl, struct q931_call *call, int cause);
|
|
|
|
int q931_send_retrieve(struct pri *ctrl, struct q931_call *call, int channel);
|
|
int q931_send_retrieve_ack(struct pri *ctrl, struct q931_call *call, int channel);
|
|
int q931_send_retrieve_rej(struct pri *ctrl, struct q931_call *call, int cause);
|
|
|
|
#endif
|