Commit 18fa4716 authored by Jeff Peeler's avatar Jeff Peeler

Add service maintenance message support

This adds support for two new message types: Service and Service Acknowledge.
When a channel receives a service message it will either take the channel in
or out of service and then send a service acknowledgment. Although not
enforced here (enforced in chan_dahdi), the service messages are only supported
with switch types 4ess/5ess. The required Asterisk changes will be coming next.

(issue #3450)
Reported by: cmaj


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@732 2fbb986a-6c06-0410-b554-c9c1f0a7f128
parent f9d5aa3c
......@@ -81,6 +81,8 @@
#define PRI_EVENT_NOTIFY 16 /* Notification received (NOTIFY) */
#define PRI_EVENT_PROGRESS 17 /* When we get PROGRESS */
#define PRI_EVENT_KEYPAD_DIGIT 18 /* When we receive during ACTIVE state (INFORMATION) */
#define PRI_EVENT_SERVICE 19 /* SERVICE maintenance message */
#define PRI_EVENT_SERVICE_ACK 20 /* SERVICE maintenance acknowledgement message */
/* Simple states */
#define PRI_STATE_DOWN 0
......@@ -430,6 +432,18 @@ typedef struct pri_event_keypad_digit {
char digits[64];
} pri_event_keypad_digit;
typedef struct pri_event_service {
int e;
int channel;
int changestatus;
} pri_event_service;
typedef struct pri_event_service_ack {
int e;
int channel;
int changestatus;
} pri_event_service_ack;
typedef union {
int e;
pri_event_generic gen; /* Generic view */
......@@ -445,6 +459,8 @@ typedef union {
pri_event_setup_ack setup_ack; /* SETUP_ACKNOWLEDGE structure */
pri_event_notify notify; /* Notification */
pri_event_keypad_digit digit; /* Digits that come during a call */
pri_event_service service; /* service message */
pri_event_service_ack service_ack; /* service acknowledgement message */
} pri_event;
struct pri;
......@@ -556,6 +572,9 @@ int pri_restart(struct pri *pri);
int pri_reset(struct pri *pri, int channel);
/* handle b-channel maintenance messages */
extern int pri_maintenance_service(struct pri *pri, int span, int channel, int changestatus);
/* Create a new call */
q931_call *pri_new_call(struct pri *pri);
......@@ -601,6 +620,9 @@ int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan
/* Send an MWI deactivate request to a remote location */
int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerplan, char *callername, int callerpres, char *called, int calledplan);
/* Set service message support flag */
int pri_set_service_message_support(struct pri *pri, int supportflag);
#define PRI_2BCT
/* Attempt to pass the channels back to the NET side if compatable and
* suscribed. Sometimes called 2 bchannel transfer (2BCT) */
......
......@@ -110,6 +110,15 @@ int pri_get_timer(struct pri *pri, int timer)
return pri->timers[timer];
}
int pri_set_service_message_support(struct pri *pri, int supportflag)
{
if (!pri) {
return -1;
}
pri->service_message_support = supportflag;
return 0;
}
int pri_timer2idx(char *timer)
{
if (!strcasecmp(timer, "N200"))
......@@ -630,6 +639,14 @@ int pri_reset(struct pri *pri, int channel)
return q931_restart(pri, channel);
}
int pri_maintenance_service(struct pri *pri, int span, int channel, int changestatus)
{
if (!pri) {
return -1;
}
return maintenance_service(pri, span, channel, changestatus);
}
q931_call *pri_new_call(struct pri *pri)
{
if (!pri)
......
......@@ -114,6 +114,9 @@ struct pri {
/* do we do overlap dialing */
int overlapdial;
/* do we support SERVICE messages */
int service_message_support;
/* do not skip channel 16 */
int chan_mapping_logical;
......@@ -264,6 +267,8 @@ struct q931_call {
/* Bridged call info */
q931_call *bridged_call; /* Pointer to other leg of bridged call */
int changestatus; /* SERVICE message changestatus */
};
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
......
......@@ -192,4 +192,8 @@ extern pri_event *q921_receive(struct pri *pri, q921_h *h, int len);
extern int q921_transmit_iframe(struct pri *pri, void *buf, int len, int cr);
extern pri_event *q921_dchannel_up(struct pri *pri);
extern pri_event *q921_dchannel_down(struct pri *pri);
#endif
......@@ -113,6 +113,8 @@ typedef struct q931_ie {
#define Q931_PROTOCOL_DISCRIMINATOR 0x08
#define GR303_PROTOCOL_DISCRIMINATOR 0x4f
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_1 0x03
#define MAINTENANCE_PROTOCOL_DISCRIMINATOR_2 0x43
/* Q.931 / National ISDN Message Types */
......@@ -160,6 +162,12 @@ typedef struct q931_ie {
#define NATIONAL_SERVICE 0x0f
#define NATIONAL_SERVICE_ACKNOWLEDGE 0x07
#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
......@@ -248,6 +256,10 @@ typedef struct q931_ie {
/* 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
......
......@@ -248,7 +248,6 @@ static int q921_ack_packet(struct pri *pri, int num)
static void t203_expire(void *);
static void t200_expire(void *);
static pri_event *q921_dchannel_down(struct pri *pri);
static void reschedule_t200(struct pri *pri)
{
......@@ -785,7 +784,7 @@ void q921_dump(struct pri *pri, q921_h *h, int len, int showraw, int txrx)
}
}
static pri_event *q921_dchannel_up(struct pri *pri)
pri_event *q921_dchannel_up(struct pri *pri)
{
/* Stop any SABME retransmissions */
if (pri->sabme_timer) {
......@@ -814,7 +813,7 @@ static pri_event *q921_dchannel_up(struct pri *pri)
return &pri->ev;
}
static pri_event *q921_dchannel_down(struct pri *pri)
pri_event *q921_dchannel_down(struct pri *pri)
{
/* Reset counters, reset sabme timer etc */
q921_reset(pri);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment