Add COLP support to libpri for ETSI PTP, ETSI PTMP, and Q.SIG.

Add Connected Line Presentation (COLP) support to chan_dahdi/libpri as an
addition to issue 8824.  This is the libpri portion.  COLP support is now
available for ETSI PTP, ETSI PTMP, and Q.SIG with this patch.

(closes issue #14068)
Tested by: rmudgett

Review: https://reviewboard.asterisk.org/r/339/


git-svn-id: https://origsvn.digium.com/svn/libpri/branches/1.4@982 2fbb986a-6c06-0410-b554-c9c1f0a7f128
This commit is contained in:
Richard Mudgett
2009-08-18 23:53:32 +00:00
parent 926cc924d2
commit dcd62e467f
13 changed files with 6448 additions and 445 deletions

View File

@@ -52,6 +52,8 @@ STATIC_OBJS= \
rose.o \
rose_address.o \
rose_etsi_aoc.o \
rose_etsi_diversion.o \
rose_etsi_ect.o \
rose_other.o \
rose_q931.o \
rose_qsig_aoc.o \
@@ -71,6 +73,8 @@ DYNAMIC_OBJS= \
rose.lo \
rose_address.lo \
rose_etsi_aoc.lo \
rose_etsi_diversion.lo \
rose_etsi_ect.lo \
rose_other.lo \
rose_q931.lo \
rose_qsig_aoc.lo \

219
libpri.h
View File

@@ -80,7 +80,8 @@
#define PRI_EVENT_ANSWER 8 /* Call has been answered (CONNECT) */
#define PRI_EVENT_HANGUP_ACK 9 /* Call hangup has been acknowledged */
#define PRI_EVENT_RESTART_ACK 10 /* Restart complete on a given channel (RESTART_ACKNOWLEDGE) */
#define PRI_EVENT_FACNAME 11 /* Caller*ID Name received on Facility */
#define PRI_EVENT_FACNAME 11 /* Caller*ID Name received on Facility (DEPRECATED) */
#define PRI_EVENT_FACILITY 11 /* Facility received (FACILITY) */
#define PRI_EVENT_INFO_RECEIVED 12 /* Additional info (digits) received (INFORMATION) */
#define PRI_EVENT_PROCEEDING 13 /* When we get CALL_PROCEEDING */
#define PRI_EVENT_SETUP_ACK 14 /* When we get SETUP_ACKNOWLEDGE */
@@ -301,8 +302,8 @@
#define PRI_RATE_ADAPT_ASYNC 0x40
/* Notifications */
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended */
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed */
#define PRI_NOTIFY_USER_SUSPENDED 0x00 /* User suspended (Q.931) (Call is placed on hold) */
#define PRI_NOTIFY_USER_RESUMED 0x01 /* User resumed (Q.931) (Call is taken off hold) */
#define PRI_NOTIFY_BEARER_CHANGE 0x02 /* Bearer service change (DSS1) */
#define PRI_NOTIFY_ASN1_COMPONENT 0x03 /* ASN.1 encoded component (DSS1) */
#define PRI_NOTIFY_COMPLETION_DELAY 0x04 /* Call completion delay */
@@ -317,12 +318,12 @@
#define PRI_NOTIFY_CONF_OTHER_DISCONNECTED 0x4a /* Other party disconnected */
#define PRI_NOTIFY_CONF_FLOATING 0x4b /* Conference floating */
#define PRI_NOTIFY_WAITING_CALL 0x60 /* Call is waiting call */
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) */
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting */
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active */
#define PRI_NOTIFY_DIVERSION_ACTIVATED 0x68 /* Diversion activated (DSS1) (cfu, cfb, cfnr) (EN 300 207-1 Section 7.2.1) */
#define PRI_NOTIFY_TRANSFER_ALERTING 0x69 /* Call transfer, alerting (EN 300 369-1 Section 7.2) */
#define PRI_NOTIFY_TRANSFER_ACTIVE 0x6a /* Call transfer, active(answered) (EN 300 369-1 Section 7.2) */
#define PRI_NOTIFY_REMOTE_HOLD 0x79 /* Remote hold */
#define PRI_NOTIFY_REMOTE_RETRIEVAL 0x7a /* Remote retrieval */
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting */
#define PRI_NOTIFY_CALL_DIVERTING 0x7b /* Call is diverting (EN 300 207-1 Section 7.2.1) */
#define PRI_COPY_DIGITS_CALLED_NUMBER
@@ -347,6 +348,151 @@
typedef struct q931_call q931_call;
/* Name character set enumeration values */
#define PRI_CHAR_SET_UNKNOWN 0
#define PRI_CHAR_SET_ISO8859_1 1
#define PRI_CHAR_SET_WITHDRAWN 2
#define PRI_CHAR_SET_ISO8859_2 3
#define PRI_CHAR_SET_ISO8859_3 4
#define PRI_CHAR_SET_ISO8859_4 5
#define PRI_CHAR_SET_ISO8859_5 6
#define PRI_CHAR_SET_ISO8859_7 7
#define PRI_CHAR_SET_ISO10646_BMPSTRING 8
#define PRI_CHAR_SET_ISO10646_UTF_8STRING 9
/*! \brief Q.SIG name information. */
struct pri_party_name {
/*! \brief TRUE if the name information is valid/present */
int valid;
/*!
* \brief Q.931 presentation-indicator encoded field
* \note Must tollerate the Q.931 screening-indicator field values being present.
*/
int presentation;
/*!
* \brief Character set the name is using.
* \details
* unknown(0),
* iso8859-1(1),
* enum-value-withdrawn-by-ITU-T(2)
* iso8859-2(3),
* iso8859-3(4),
* iso8859-4(5),
* iso8859-5(6),
* iso8859-7(7),
* iso10646-BmpString(8),
* iso10646-utf-8String(9)
* \details
* Set to iso8859-1(1) if unsure what to use.
*/
int char_set;
/*! \brief Name data with null terminator. */
char str[64];
};
struct pri_party_number {
/*! \brief TRUE if the number information is valid/present */
int valid;
/*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
int presentation;
/*! \brief Q.931 Type-Of-Number and numbering-plan encoded fields */
int plan;
/*! \brief Number data with null terminator. */
char str[64];
};
/*!
* \note This structure is a place holder for possible future subaddress support
* to maintain ABI compatibility.
*/
struct pri_party_subaddress {
/*! \brief TRUE if the subaddress information is valid/present */
int valid;
/*!
* \brief Subaddress type.
* \details
* nsap(0),
* user_specified(2)
*/
int type;
/*!
* \brief TRUE if odd number of address signals
* \note The odd/even indicator is used when the type of subaddress is
* user_specified and the coding is BCD.
*/
int odd_even_indicator;
/*! \brief Length of the subaddress data */
int length;
/*!
* \brief Subaddress data with null terminator.
* \note The null terminator is a convenience only since the data could be
* BCD/binary and thus have a null byte as part of the contents.
*/
char data[32];
};
/*! \brief Information needed to identify an endpoint in a call. */
struct pri_party_id {
/*! \brief Subscriber name */
struct pri_party_name name;
/*! \brief Subscriber phone number */
struct pri_party_number number;
/*! \brief Subscriber subaddress */
struct pri_party_subaddress subaddress;
};
/*! \brief Connected Line/Party information */
struct pri_party_connected_line {
/*! Connected party ID */
struct pri_party_id id;
};
/*!
* \brief Redirecting Line information.
* \details
* RDNIS (Redirecting Directory Number Information Service)
* Where a call diversion or transfer was invoked.
*/
struct pri_party_redirecting {
/*! Who is redirecting the call (Sent to the party the call is redirected toward) */
struct pri_party_id from;
/*! Call is redirecting to a new party (Sent to the caller) */
struct pri_party_id to;
/*! Originally called party (in cases of multiple redirects) */
struct pri_party_id orig_called;
/*! Number of times the call was redirected */
int count;
/*! Original reason for redirect (in cases of multiple redirects) */
int orig_reason;
/*! Redirection reason */
int reason;
};
/* Subcommands derived from supplementary services. */
#define PRI_SUBCMD_REDIRECTING 1
#define PRI_SUBCMD_CONNECTED_LINE 2
struct pri_subcommand {
/*! PRI_SUBCMD_xxx defined values */
int cmd;
union {
/*! Reserve room for possible expansion to maintain ABI compatibility. */
char reserve_space[512];
struct pri_party_connected_line connected_line;
struct pri_party_redirecting redirecting;
} u;
};
/* Max number of subcommands per event message */
#define PRI_MAX_SUBCOMMANDS 8
struct pri_subcommands {
int counter_subcmd;
struct pri_subcommand subcmd[PRI_MAX_SUBCOMMANDS];
};
typedef struct pri_event_generic {
/* Events with no additional information fall in this category */
int e;
@@ -370,6 +516,7 @@ typedef struct pri_event_ringing {
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
struct pri_subcommands *subcmds;
} pri_event_ringing;
typedef struct pri_event_answer {
@@ -380,8 +527,10 @@ typedef struct pri_event_answer {
int progressmask;
q931_call *call;
char useruserinfo[260]; /* User->User info */
struct pri_subcommands *subcmds;
} pri_event_answer;
/*! Deprecated replaced by struct pri_event_facility. */
typedef struct pri_event_facname {
int e;
char callingname[256];
@@ -393,6 +542,18 @@ typedef struct pri_event_facname {
int callingplan; /* Dialing plan of Calling entity */
} pri_event_facname;
struct pri_event_facility {
int e;
char callingname[256]; /*!< Deprecated, preserved for struct pri_event_facname compatibility */
char callingnum[256]; /*!< Deprecated, preserved for struct pri_event_facname compatibility */
int channel;
int cref;
q931_call *call;
int callingpres; /*!< Presentation of Calling CallerID (Deprecated, preserved for struct pri_event_facname compatibility) */
int callingplan; /*!< Dialing plan of Calling entity (Deprecated, preserved for struct pri_event_facname compatibility) */
struct pri_subcommands *subcmds;
};
#define PRI_CALLINGPLANANI
#define PRI_CALLINGPLANRDNIS
typedef struct pri_event_ring {
@@ -426,6 +587,7 @@ typedef struct pri_event_ring {
int callingplanorigcalled; /* Dialing plan of Originally Called Number */
int origredirectingreason;
int reversecharge;
struct pri_subcommands *subcmds;
} pri_event_ring;
typedef struct pri_event_hangup {
@@ -436,6 +598,7 @@ typedef struct pri_event_hangup {
q931_call *call; /* Opaque call pointer */
long aoc_units; /* Advise of Charge number of charged units */
char useruserinfo[260]; /* User->User info */
struct pri_subcommands *subcmds;
} pri_event_hangup;
typedef struct pri_event_restart_ack {
@@ -452,18 +615,21 @@ typedef struct pri_event_proceeding {
int progressmask;
int cause;
q931_call *call;
struct pri_subcommands *subcmds;
} pri_event_proceeding;
typedef struct pri_event_setup_ack {
int e;
int channel;
q931_call *call;
struct pri_subcommands *subcmds;
} pri_event_setup_ack;
typedef struct pri_event_notify {
int e;
int channel;
int info;
struct pri_subcommands *subcmds;
} pri_event_notify;
typedef struct pri_event_keypad_digit {
@@ -471,6 +637,7 @@ typedef struct pri_event_keypad_digit {
int channel;
q931_call *call;
char digits[64];
struct pri_subcommands *subcmds;
} pri_event_keypad_digit;
typedef struct pri_event_service {
@@ -490,7 +657,7 @@ typedef union {
pri_event_generic gen; /* Generic view */
pri_event_restart restart; /* Restart view */
pri_event_error err; /* Error view */
pri_event_facname facname; /* Caller*ID Name on Facility */
pri_event_facname facname; /* Caller*ID Name on Facility (Deprecated, use pri_event.facility) */
pri_event_ring ring; /* Ring */
pri_event_hangup hangup; /* Hang up */
pri_event_ringing ringing; /* Ringing */
@@ -502,6 +669,7 @@ typedef union {
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 */
struct pri_event_facility facility;
} pri_event;
struct pri;
@@ -588,6 +756,18 @@ int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisd
Set non-isdn to non-zero if you are not connecting to ISDN equipment */
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn);
/*!
* \brief Give connected line information to a call
* \note Could be used instead of pri_sr_set_caller_party() before calling pri_setup().
*/
int pri_connected_line_update(struct pri *pri, q931_call *call, const struct pri_party_connected_line *connected);
/*!
* \brief Give redirection information to a call
* \note Could be used instead of pri_sr_set_redirecting_parties() before calling pri_setup().
*/
int pri_redirecting_update(struct pri *pri, q931_call *call, const struct pri_party_redirecting *redirecting);
/* Set CRV reference for GR-303 calls */
@@ -642,8 +822,31 @@ void pri_sr_free(struct pri_sr *sr);
int pri_sr_set_channel(struct pri_sr *sr, int channel, int exclusive, int nonisdn);
int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1);
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int complete);
/*!
* \brief Set the caller party ID information in the call SETUP record.
*
* \param sr New call SETUP record.
* \param caller Caller party ID information to set.
*
* \return Nothing
*/
void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller);
/*! \note Use pri_sr_set_caller_party() instead to pass more precise caller information. */
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres);
/*!
* \brief Set the redirecting information in the call SETUP record.
*
* \param sr New call SETUP record.
* \param caller Redirecting information to set.
*
* \return Nothing
*/
void pri_sr_set_redirecting_parties(struct pri_sr *sr, const struct pri_party_redirecting *redirecting);
/*! \note Use pri_sr_set_redirecting_parties() instead to pass more precise redirecting information. */
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason);
#define PRI_USER_USER_TX
/* Set the user user field. Warning! don't send binary data accross this field */
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars);

301
pri.c
View File

@@ -374,8 +374,8 @@ char *pri_event2str(int id)
return "Hangup ACK";
case PRI_EVENT_RESTART_ACK:
return "Restart ACK";
case PRI_EVENT_FACNAME:
return "FacName";
case PRI_EVENT_FACILITY:
return "Facility";
case PRI_EVENT_INFO_RECEIVED:
return "Info Received";
case PRI_EVENT_PROCEEDING:
@@ -579,6 +579,203 @@ int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
return q931_connect(pri, call, channel, nonisdn);
}
/*!
* \internal
* \brief Copy the PRI party name to the Q.931 party name structure.
*
* \param q931_name Q.931 party name structure
* \param pri_name PRI party name structure
*
* \return Nothing
*/
static void pri_copy_party_name_to_q931(struct q931_party_name *q931_name, const struct pri_party_name *pri_name)
{
q931_party_name_init(q931_name);
if (pri_name->valid) {
q931_name->valid = 1;
q931_name->presentation = pri_name->presentation;
q931_name->char_set = pri_name->char_set;
libpri_copy_string(q931_name->str, pri_name->str, sizeof(q931_name->str));
}
}
/*!
* \internal
* \brief Copy the PRI party number to the Q.931 party number structure.
*
* \param q931_number Q.931 party number structure
* \param pri_number PRI party number structure
*
* \return Nothing
*/
static void pri_copy_party_number_to_q931(struct q931_party_number *q931_number, const struct pri_party_number *pri_number)
{
q931_party_number_init(q931_number);
if (pri_number->valid) {
q931_number->valid = 1;
q931_number->presentation = pri_number->presentation;
q931_number->plan = pri_number->plan;
libpri_copy_string(q931_number->str, pri_number->str, sizeof(q931_number->str));
}
}
/*!
* \internal
* \brief Copy the PRI party id to the Q.931 party id structure.
*
* \param q931_id Q.931 party id structure
* \param pri_id PRI party id structure
*
* \return Nothing
*/
static void pri_copy_party_id_to_q931(struct q931_party_id *q931_id, const struct pri_party_id *pri_id)
{
pri_copy_party_name_to_q931(&q931_id->name, &pri_id->name);
pri_copy_party_number_to_q931(&q931_id->number, &pri_id->number);
}
int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pri_party_connected_line *connected)
{
struct q931_party_id party_id;
if (!ctrl || !call) {
return -1;
}
pri_copy_party_id_to_q931(&party_id, &connected->id);
q931_party_id_fixup(ctrl, &party_id);
if (!q931_party_id_cmp(&party_id, &call->local_id)) {
/* The local party information did not change so do nothing. */
return 0;
}
call->local_id = party_id;
switch (call->ourcallstate) {
case Q931_CALL_STATE_CALL_INITIATED:
case Q931_CALL_STATE_OVERLAP_SENDING:
case Q931_CALL_STATE_OUTGOING_CALL_PROCEEDING:
case Q931_CALL_STATE_CALL_DELIVERED:
/*
* The local party transferred to someone else before
* the remote end answered.
*/
case Q931_CALL_STATE_ACTIVE:
switch (ctrl->switchtype) {
case PRI_SWITCH_EUROISDN_E1:
case PRI_SWITCH_EUROISDN_T1:
if (q931_is_ptmp(ctrl)) {
/* PTMP mode */
q931_notify_redirection(ctrl, call, PRI_NOTIFY_TRANSFER_ACTIVE,
&call->local_id.number);
} else {
/* PTP mode */
/* Immediately send EctInform APDU, callStatus=answered(0) */
send_call_transfer_complete(ctrl, call, 0);
}
break;
case PRI_SWITCH_QSIG:
/* Immediately send CallTransferComplete APDU, callStatus=answered(0) */
send_call_transfer_complete(ctrl, call, 0);
break;
default:
break;
}
break;
default:
/* Just save the data for further developments. */
break;
}
return 0;
}
int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_party_redirecting *redirecting)
{
if (!ctrl || !call) {
return -1;
}
/* Save redirecting.to information and reason. */
pri_copy_party_id_to_q931(&call->redirecting.to, &redirecting->to);
q931_party_id_fixup(ctrl, &call->redirecting.to);
call->redirecting.reason = redirecting->reason;
switch (call->ourcallstate) {
case Q931_CALL_STATE_NULL:
/* Save the remaining redirecting information before we place a call. */
pri_copy_party_id_to_q931(&call->redirecting.from, &redirecting->from);
q931_party_id_fixup(ctrl, &call->redirecting.from);
pri_copy_party_id_to_q931(&call->redirecting.orig_called, &redirecting->orig_called);
q931_party_id_fixup(ctrl, &call->redirecting.orig_called);
call->redirecting.orig_reason = redirecting->orig_reason;
if (redirecting->count <= 0) {
if (call->redirecting.from.number.valid) {
/*
* We are redirecting with an unknown count
* so assume the count is one.
*/
call->redirecting.count = 1;
} else {
call->redirecting.count = 0;
}
} else if (redirecting->count < PRI_MAX_REDIRECTS) {
call->redirecting.count = redirecting->count;
} else {
call->redirecting.count = PRI_MAX_REDIRECTS;
}
break;
case Q931_CALL_STATE_OVERLAP_RECEIVING:
case Q931_CALL_STATE_INCOMING_CALL_PROCEEDING:
case Q931_CALL_STATE_CALL_RECEIVED:
/* This is an incoming call that has not connected yet. */
if (!call->redirecting.to.number.valid) {
/* Not being redirected toward valid number data. Ignore. */
break;
}
switch (ctrl->switchtype) {
case PRI_SWITCH_EUROISDN_E1:
case PRI_SWITCH_EUROISDN_T1:
if (q931_is_ptmp(ctrl)) {
/* PTMP mode */
q931_notify_redirection(ctrl, call, PRI_NOTIFY_CALL_DIVERTING,
&call->redirecting.to.number);
break;
}
/* PTP mode - same behaviour as Q.SIG */
/* fall through */
case PRI_SWITCH_QSIG:
if (call->redirecting.state != Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3
|| strcmp(call->redirecting.to.number.str, call->called.number.str) != 0) {
/* immediately send divertingLegInformation1 APDU */
if (rose_diverting_leg_information1_encode(ctrl, call)
|| q931_facility(ctrl, call)) {
pri_message(ctrl,
"Could not schedule facility message for divertingLegInfo1\n");
}
}
call->redirecting.state = Q931_REDIRECTING_STATE_IDLE;
/* immediately send divertingLegInformation3 APDU */
if (rose_diverting_leg_information3_encode(ctrl, call, Q931_FACILITY)
|| q931_facility(ctrl, call)) {
pri_message(ctrl,
"Could not schedule facility message for divertingLegInfo3\n");
}
break;
default:
break;
}
break;
default:
pri_message(ctrl, "Ignored redirecting update because call in state %s(%d).\n",
q931_call_state_str(call->ourcallstate), call->ourcallstate);
break;
}
return 0;
}
#if 0
/* deprecated routines, use pri_hangup */
int pri_release(struct pri *pri, q931_call *call, int cause)
@@ -703,6 +900,9 @@ void pri_dump_event(struct pri *pri, pri_event *e)
static void pri_sr_init(struct pri_sr *req)
{
memset(req, 0, sizeof(struct pri_sr));
q931_party_redirecting_init(&req->redirecting);
q931_party_id_init(&req->caller);
q931_party_address_init(&req->called);
req->reversecharge = PRI_REVERSECHARGE_NONE;
}
@@ -725,13 +925,8 @@ int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan
pri_sr_init(&req);
pri_sr_set_connection_call_independent(&req);
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
pri_sr_set_caller(&req, caller, callername, callerplan, callerpres);
pri_sr_set_called(&req, called, calledplan, 0);
if (mwi_message_send(pri, c, &req, 1) < 0) {
pri_message(pri, "Unable to send MWI activate message\n");
@@ -750,13 +945,8 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
pri_sr_init(&req);
pri_sr_set_connection_call_independent(&req);
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
pri_sr_set_caller(&req, caller, callername, callerplan, callerpres);
pri_sr_set_called(&req, called, calledplan, 0);
if(mwi_message_send(pri, c, &req, 0) < 0) {
pri_message(pri, "Unable to send MWI deactivate message\n");
@@ -782,16 +972,12 @@ int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int excl
if (!pri || !c)
return -1;
pri_sr_init(&req);
pri_sr_set_caller(&req, caller, callername, callerplan, callerpres);
pri_sr_set_called(&req, called, calledplan, 0);
req.transmode = transmode;
req.channel = channel;
req.exclusive = exclusive;
req.nonisdn = nonisdn;
req.caller = caller;
req.callerplan = callerplan;
req.callername = callername;
req.callerpres = callerpres;
req.called = called;
req.calledplan = calledplan;
req.userl1 = ulayer1;
return q931_setup(pri, c, &req);
}
@@ -1002,30 +1188,81 @@ int pri_sr_set_bearer(struct pri_sr *sr, int transmode, int userl1)
int pri_sr_set_called(struct pri_sr *sr, char *called, int calledplan, int numcomplete)
{
sr->called = called;
sr->calledplan = calledplan;
q931_party_address_init(&sr->called);
if (called) {
sr->called.number.valid = 1;
sr->called.number.plan = calledplan;
libpri_copy_string(sr->called.number.str, called, sizeof(sr->called.number.str));
}
sr->numcomplete = numcomplete;
return 0;
}
int pri_sr_set_caller(struct pri_sr *sr, char *caller, char *callername, int callerplan, int callerpres)
{
sr->caller = caller;
sr->callername = callername;
sr->callerplan = callerplan;
sr->callerpres = callerpres;
q931_party_id_init(&sr->caller);
if (caller) {
sr->caller.number.valid = 1;
sr->caller.number.presentation = callerpres;
sr->caller.number.plan = callerplan;
libpri_copy_string(sr->caller.number.str, caller, sizeof(sr->caller.number.str));
if (callername) {
sr->caller.name.valid = 1;
sr->caller.name.presentation = callerpres;
sr->caller.name.char_set = PRI_CHAR_SET_ISO8859_1;
libpri_copy_string(sr->caller.name.str, callername,
sizeof(sr->caller.name.str));
}
}
return 0;
}
void pri_sr_set_caller_party(struct pri_sr *sr, const struct pri_party_id *caller)
{
pri_copy_party_id_to_q931(&sr->caller, caller);
}
int pri_sr_set_redirecting(struct pri_sr *sr, char *num, int plan, int pres, int reason)
{
sr->redirectingnum = num;
sr->redirectingplan = plan;
sr->redirectingpres = pres;
sr->redirectingreason = reason;
q931_party_redirecting_init(&sr->redirecting);
if (num && num[0]) {
sr->redirecting.from.number.valid = 1;
sr->redirecting.from.number.presentation = pres;
sr->redirecting.from.number.plan = plan;
libpri_copy_string(sr->redirecting.from.number.str, num,
sizeof(sr->redirecting.from.number.str));
sr->redirecting.count = 1;
sr->redirecting.reason = reason;
}
return 0;
}
void pri_sr_set_redirecting_parties(struct pri_sr *sr, const struct pri_party_redirecting *redirecting)
{
pri_copy_party_id_to_q931(&sr->redirecting.from, &redirecting->from);
pri_copy_party_id_to_q931(&sr->redirecting.to, &redirecting->to);
pri_copy_party_id_to_q931(&sr->redirecting.orig_called, &redirecting->orig_called);
sr->redirecting.orig_reason = redirecting->orig_reason;
sr->redirecting.reason = redirecting->reason;
if (redirecting->count <= 0) {
if (sr->redirecting.from.number.valid) {
/*
* We are redirecting with an unknown count
* so assume the count is one.
*/
sr->redirecting.count = 1;
} else {
sr->redirecting.count = 0;
}
} else if (redirecting->count < PRI_MAX_REDIRECTS) {
sr->redirecting.count = redirecting->count;
} else {
sr->redirecting.count = PRI_MAX_REDIRECTS;
}
}
void pri_sr_set_reversecharge(struct pri_sr *sr, int requested)
{
sr->reversecharge = requested;

File diff suppressed because it is too large Load Diff

View File

@@ -60,6 +60,11 @@
#define Q932_TON_SUBSCRIBER 0x04
#define Q932_TON_ABBREVIATED 0x06
/* Q.SIG Subscription Option. Listed in ECMA-174 */
#define QSIG_NO_NOTIFICATION 0x00
#define QSIG_NOTIFICATION_WITHOUT_DIVERTED_TO_NR 0x01
#define QSIG_NOTIFICATION_WITH_DIVERTED_TO_NR 0x02
/* Queues an MWI apdu on a the given call */
int mwi_message_send(struct pri *pri, q931_call *call, struct pri_sr *req, int activate);
@@ -73,6 +78,14 @@ int qsig_cf_callrerouting(struct pri *pri, q931_call *c, const char* dest, const
/* starts a QSIG Path Replacement */
int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
int send_call_transfer_complete(struct pri *pri, q931_call *call, int call_status);
int rose_diverting_leg_information1_encode(struct pri *pri, q931_call *call);
int rose_diverting_leg_information3_encode(struct pri *pri, q931_call *call, int messagetype);
int rose_connected_name_encode(struct pri *pri, q931_call *call, int messagetype);
int rose_called_name_encode(struct pri *pri, q931_call *call, int messagetype);
/* Use this function to queue a facility-IE born APDU onto a call
* call is the call to use, messagetype is any one of the Q931 messages,
* apdu is the apdu data, apdu_len is the length of the apdu data */

View File

@@ -104,6 +104,8 @@ struct pri {
struct timeval tv;
int schedev;
pri_event ev; /* Static event thingy */
/*! Subcommands for static event thingy. */
struct pri_subcommands subcmds;
/* Q.921 Re-transmission queue */
struct q921_frame *txqueue;
@@ -133,24 +135,163 @@ struct pri {
unsigned char sendfacility;
};
/*! \brief Maximum name length plus null terminator (From ECMA-164) */
#define PRI_MAX_NAME_LEN (50 + 1)
/*! \brief Q.SIG name information. */
struct q931_party_name {
/*! \brief TRUE if name data is valid */
unsigned char valid;
/*!
* \brief Q.931 presentation-indicator encoded field
* \note Must tollerate the Q.931 screening-indicator field values being present.
*/
unsigned char presentation;
/*!
* \brief Character set the name is using.
* \details
* unknown(0),
* iso8859-1(1),
* enum-value-withdrawn-by-ITU-T(2)
* iso8859-2(3),
* iso8859-3(4),
* iso8859-4(5),
* iso8859-5(6),
* iso8859-7(7),
* iso10646-BmpString(8),
* iso10646-utf-8String(9)
*/
unsigned char char_set;
/*! \brief Name data with null terminator. */
char str[PRI_MAX_NAME_LEN];
};
/*! \brief Maximum phone number (address) length plus null terminator */
#define PRI_MAX_NUMBER_LEN (31 + 1)
struct q931_party_number {
/*! \brief TRUE if number data is valid */
unsigned char valid;
/*! \brief Q.931 presentation-indicator and screening-indicator encoded fields */
unsigned char presentation;
/*! \brief Q.931 Type-Of-Number and numbering-plan encoded fields */
unsigned char plan;
/*! \brief Number data with terminator. */
char str[PRI_MAX_NUMBER_LEN];
};
/*! \brief Maximum subaddress length plus null terminator */
#define PRI_MAX_SUBADDRESS_LEN (20 + 1)
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
struct q931_party_subaddress {
/*! \brief TRUE if the subaddress information is valid/present */
unsigned char valid;
/*!
* \brief Subaddress type.
* \details
* nsap(0),
* user_specified(2)
*/
unsigned char type;
/*!
* \brief TRUE if odd number of address signals
* \note The odd/even indicator is used when the type of subaddress is
* user_specified and the coding is BCD.
*/
unsigned char odd_even_indicator;
/*! \brief Length of the subaddress data */
unsigned char length;
/*!
* \brief Subaddress data with null terminator.
* \note The null terminator is a convenience only since the data could be
* BCD/binary and thus have a null byte as part of the contents.
*/
char data[PRI_MAX_SUBADDRESS_LEN];
};
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
struct q931_party_address {
/*! \brief Subscriber phone number */
struct q931_party_number number;
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
/*! \brief Subscriber subaddress */
struct q931_party_subaddress subaddress;
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
};
/*! \brief Information needed to identify an endpoint in a call. */
struct q931_party_id {
/*! \brief Subscriber name */
struct q931_party_name name;
/*! \brief Subscriber phone number */
struct q931_party_number number;
#if defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT)
/*! \brief Subscriber subaddress */
struct q931_party_subaddress subaddress;
#endif /* defined(POSSIBLE_FUTURE_SUBADDRESS_SUPPORT) */
};
enum Q931_REDIRECTING_STATE {
/*!
* \details
* CDO-Idle/CDF-Inv-Idle
*/
Q931_REDIRECTING_STATE_IDLE,
/*!
* \details
* CDF-Inv-Wait - A DivLeg2 has been received and
* we are waiting for valid presentation restriction information to send.
*/
Q931_REDIRECTING_STATE_PENDING_TX_DIV_LEG_3,
/*!
* \details
* CDO-Divert - A DivLeg1 has been received and
* we are waiting for the presentation restriction information to come in.
*/
Q931_REDIRECTING_STATE_EXPECTING_RX_DIV_LEG_3,
};
/*!
* \brief Do not increment above this count.
* \details
* It is not our responsibility to enforce the maximum number of redirects.
* However, we cannot allow an increment past this number without breaking things.
* Besides, more than 255 redirects is probably not a good thing.
*/
#define PRI_MAX_REDIRECTS 0xFF
/*! \brief Redirecting information struct */
struct q931_party_redirecting {
enum Q931_REDIRECTING_STATE state;
/*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */
struct q931_party_id from;
/*! \brief Call is redirecting to a new party (Sent to the caller) */
struct q931_party_id to;
/*! Originally called party (in cases of multiple redirects) */
struct q931_party_id orig_called;
/*!
* \brief Number of times the call was redirected
* \note The call is being redirected if the count is non-zero.
*/
unsigned char count;
/*! Original reason for redirect (in cases of multiple redirects) */
unsigned char orig_reason;
/*! \brief Redirection reasons */
unsigned char reason;
};
/*! \brief New call setup parameter structure */
struct pri_sr {
int transmode;
int channel;
int exclusive;
int nonisdn;
char *caller;
int callerplan;
char *callername;
int callerpres;
char *called;
int calledplan;
struct q931_party_redirecting redirecting;
struct q931_party_id caller;
struct q931_party_address called;
int userl1;
int numcomplete;
char *redirectingnum;
int redirectingplan;
int redirectingpres;
int redirectingreason;
int justsignalling;
const char *useruserinfo;
int transferable;
@@ -171,8 +312,29 @@ struct apdu_event {
struct apdu_event *next; /* Linked list pointer */
};
/* q931_call datastructure */
/*! \brief Incoming call transfer states. */
enum INCOMING_CT_STATE {
/*!
* \details
* Incoming call transfer is not active.
*/
INCOMING_CT_STATE_IDLE,
/*!
* \details
* We have seen an incoming CallTransferComplete(alerting)
* so we are waiting for the expected CallTransferActive
* before updating the connected line about the remote party id.
*/
INCOMING_CT_STATE_EXPECT_CT_ACTIVE,
/*!
* \details
* A call transfer message came in that updated the remote party id
* that we need to post a connected line update.
*/
INCOMING_CT_STATE_POST_CONNECTED_LINE
};
/* q931_call datastructure */
struct q931_call {
struct pri *pri; /* PRI */
int cr; /* Call Reference */
@@ -204,8 +366,7 @@ struct q931_call {
int userl2;
int userl3;
int rateadaption;
int sentchannel;
int justsignalling; /* for a signalling-only connection */
int progcode; /* Progress coding */
@@ -213,7 +374,7 @@ struct q931_call {
int progress; /* Progress indicator */
int progressmask; /* Progress Indicator bitmask */
int notify; /* Notification */
int notify; /* Notification indicator. */
int causecode; /* Cause Coding */
int causeloc; /* Cause Location */
@@ -222,49 +383,76 @@ struct q931_call {
int peercallstate; /* Call state of peer as reported */
int ourcallstate; /* Our call state */
int sugcallstate; /* Status call state */
int callerplan;
int callerplanani;
int callerpres; /* Caller presentation */
char callerani[256]; /* Caller */
char callernum[256];
char callername[256];
char keypad_digits[64]; /* Buffer for digits that come in KEYPAD_FACILITY */
int ani2; /* ANI II */
int calledplan;
/*! Buffer for digits that come in KEYPAD_FACILITY */
char keypad_digits[32 + 1];
/*! Current dialed digits to be sent or just received. */
char overlap_digits[PRI_MAX_NUMBER_LEN];
/*!
* \brief Local party ID
* \details
* The Caller-ID and connected-line ID are just roles the local and remote party
* play while a call is being established. Which roll depends upon the direction
* of the call.
* Outgoing party info is to identify the local party to the other end.
* (Caller-ID for originated or connected-line for answered calls.)
* Incoming party info is to identify the remote party to us.
* (Caller-ID for answered or connected-line for originated calls.)
*/
struct q931_party_id local_id;
/*!
* \brief Remote party ID
* \details
* The Caller-ID and connected-line ID are just roles the local and remote party
* play while a call is being established. Which roll depends upon the direction
* of the call.
* Outgoing party info is to identify the local party to the other end.
* (Caller-ID for originated or connected-line for answered calls.)
* Incoming party info is to identify the remote party to us.
* (Caller-ID for answered or connected-line for originated calls.)
*/
struct q931_party_id remote_id;
/*!
* \brief Staging place for the Q.931 redirection number ie.
* \note
* The number could be the remote_id.number or redirecting.to.number
* depending upon the notification indicator.
*/
struct q931_party_number redirection_number;
/*!
* \brief Called party address.
* \note The called.number.str is the accumulated overlap dial digits
* and enbloc digits.
* \note The called.number.presentation value is not used.
*/
struct q931_party_address called;
int nonisdn;
char callednum[256]; /* Called Number */
int complete; /* no more digits coming */
int newcall; /* if the received message has a new call reference value */
int retranstimer; /* Timer for retransmitting DISC */
int t308_timedout; /* Whether t308 timed out once */
int redirectingplan;
int redirectingpres;
int redirectingreason;
char redirectingnum[256]; /* Number of redirecting party */
char redirectingname[256]; /* Name of redirecting party */
struct q931_party_redirecting redirecting;
/* Filled in cases of multiple diversions */
int origcalledplan;
int origcalledpres;
int origredirectingreason; /* Original reason for redirect (in cases of multiple redirects) */
char origcalledname[256]; /* Original name of person being called */
char origcallednum[256]; /* Orignal number of person being called */
/*! \brief Incoming call transfer state. */
enum INCOMING_CT_STATE incoming_ct_state;
int useruserprotocoldisc;
char useruserinfo[256];
char callingsubaddr[256]; /* Calling parties sub address */
char callingsubaddr[PRI_MAX_SUBADDRESS_LEN]; /* Calling party subaddress */
long aoc_units; /* Advice of Charge Units */
struct apdu_event *apdus; /* APDU queue for call */
int transferable;
int transferable; /* RLT call is transferable */
unsigned int rlt_call_id; /* RLT call id */
/* Bridged call info */
@@ -294,4 +482,29 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
void __pri_free_tei(struct pri *p);
void q931_party_name_init(struct q931_party_name *name);
void q931_party_number_init(struct q931_party_number *number);
void q931_party_address_init(struct q931_party_address *address);
void q931_party_id_init(struct q931_party_id *id);
void q931_party_redirecting_init(struct q931_party_redirecting *redirecting);
int q931_party_name_cmp(const struct q931_party_name *left, const struct q931_party_name *right);
int q931_party_number_cmp(const struct q931_party_number *left, const struct q931_party_number *right);
int q931_party_id_cmp(const struct q931_party_id *left, const struct q931_party_id *right);
void q931_party_name_copy_to_pri(struct pri_party_name *pri_name, const struct q931_party_name *q931_name);
void q931_party_number_copy_to_pri(struct pri_party_number *pri_number, const struct q931_party_number *q931_number);
void q931_party_id_copy_to_pri(struct pri_party_id *pri_id, const struct q931_party_id *q931_id);
void q931_party_redirecting_copy_to_pri(struct pri_party_redirecting *pri_redirecting, const struct q931_party_redirecting *q931_redirecting);
void q931_party_id_fixup(const struct pri *ctrl, struct q931_party_id *id);
int q931_party_id_presentation(const struct q931_party_id *id);
const char *q931_call_state_str(int callstate);
int q931_is_ptmp(struct pri *ctrl);
struct pri_subcommand *q931_alloc_subcommand(struct pri *ctrl);
int q931_notify_redirection(struct pri *ctrl, q931_call *call, int notify, const struct q931_party_number *number);
#endif

1159
q931.c

File diff suppressed because it is too large Load Diff

186
rose.c
View File

@@ -192,6 +192,14 @@ struct rose_convert_error {
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
*/
/*! \brief ETSI Explicit Call Transfer OID prefix. */
static const struct asn1_oid rose_etsi_ect = {
/* *INDENT-OFF* */
/* {ccitt(0) identified-organization(4) etsi(0) 369 operations-and-errors(1)} */
4, { 4, 0, 369, 1 }
/* *INDENT-ON* */
};
/*! \brief ETSI specific invoke/result encode/decode message table */
static const struct rose_convert_msg rose_etsi_msgs[] = {
/* *INDENT-OFF* */
@@ -200,6 +208,71 @@ static const struct rose_convert_msg rose_etsi_msgs[] = {
* encode_invoke_args, encode_result_args,
* decode_invoke_args, decode_result_args
*/
/*
* localValue's from Diversion-Operations
* {ccitt identified-organization etsi(0) 207 operations-and-errors(1)}
*/
{
ROSE_ETSI_ActivationDiversion, NULL, 7,
rose_enc_etsi_ActivationDiversion_ARG, NULL,
rose_dec_etsi_ActivationDiversion_ARG, NULL
},
{
ROSE_ETSI_DeactivationDiversion, NULL, 8,
rose_enc_etsi_DeactivationDiversion_ARG,NULL,
rose_dec_etsi_DeactivationDiversion_ARG,NULL
},
{
ROSE_ETSI_ActivationStatusNotificationDiv, NULL, 9,
rose_enc_etsi_ActivationStatusNotificationDiv_ARG,NULL,
rose_dec_etsi_ActivationStatusNotificationDiv_ARG,NULL
},
{
ROSE_ETSI_DeactivationStatusNotificationDiv,NULL, 10,
rose_enc_etsi_DeactivationStatusNotificationDiv_ARG,NULL,
rose_dec_etsi_DeactivationStatusNotificationDiv_ARG,NULL
},
{
ROSE_ETSI_InterrogationDiversion, NULL, 11,
rose_enc_etsi_InterrogationDiversion_ARG,rose_enc_etsi_InterrogationDiversion_RES,
rose_dec_etsi_InterrogationDiversion_ARG,rose_dec_etsi_InterrogationDiversion_RES
},
{
ROSE_ETSI_DiversionInformation, NULL, 12,
rose_enc_etsi_DiversionInformation_ARG, NULL,
rose_dec_etsi_DiversionInformation_ARG, NULL
},
{
ROSE_ETSI_CallDeflection, NULL, 13,
rose_enc_etsi_CallDeflection_ARG, NULL,
rose_dec_etsi_CallDeflection_ARG, NULL
},
{
ROSE_ETSI_CallRerouting, NULL, 14,
rose_enc_etsi_CallRerouting_ARG, NULL,
rose_dec_etsi_CallRerouting_ARG, NULL
},
{
ROSE_ETSI_DivertingLegInformation2, NULL, 15,
rose_enc_etsi_DivertingLegInformation2_ARG,NULL,
rose_dec_etsi_DivertingLegInformation2_ARG,NULL
},
{
ROSE_ETSI_InterrogateServedUserNumbers, NULL, 17,
NULL, rose_enc_etsi_InterrogateServedUserNumbers_RES,
NULL, rose_dec_etsi_InterrogateServedUserNumbers_RES
},
{
ROSE_ETSI_DivertingLegInformation1, NULL, 18,
rose_enc_etsi_DivertingLegInformation1_ARG,NULL,
rose_dec_etsi_DivertingLegInformation1_ARG,NULL
},
{
ROSE_ETSI_DivertingLegInformation3, NULL, 19,
rose_enc_etsi_DivertingLegInformation3_ARG,NULL,
rose_dec_etsi_DivertingLegInformation3_ARG,NULL
},
/*
* localValue's from Advice-of-Charge-Operations
* {ccitt identified-organization etsi (0) 182 operations-and-errors (1)}
@@ -243,6 +316,51 @@ static const struct rose_convert_msg rose_etsi_msgs[] = {
rose_enc_etsi_AOCEChargingUnit_ARG, NULL,
rose_dec_etsi_AOCEChargingUnit_ARG, NULL
},
/*
* localValue's from Explicit-Call-Transfer-Operations-and-Errors
* {ccitt identified-organization etsi(0) 369 operations-and-errors(1)}
*/
{
ROSE_ETSI_EctExecute, NULL, 6,
NULL, NULL,
NULL, NULL
},
/*
* globalValue's (OIDs) from Explicit-Call-Transfer-Operations-and-Errors
* {ccitt identified-organization etsi(0) 369 operations-and-errors(1)}
*/
{
ROSE_ETSI_ExplicitEctExecute, &rose_etsi_ect, 1,
rose_enc_etsi_ExplicitEctExecute_ARG, NULL,
rose_dec_etsi_ExplicitEctExecute_ARG, NULL
},
{
ROSE_ETSI_RequestSubaddress, &rose_etsi_ect, 2,
NULL, NULL,
NULL, NULL
},
{
ROSE_ETSI_SubaddressTransfer, &rose_etsi_ect, 3,
rose_enc_etsi_SubaddressTransfer_ARG, NULL,
rose_dec_etsi_SubaddressTransfer_ARG, NULL
},
{
ROSE_ETSI_EctLinkIdRequest, &rose_etsi_ect, 4,
NULL, rose_enc_etsi_EctLinkIdRequest_RES,
NULL, rose_dec_etsi_EctLinkIdRequest_RES
},
{
ROSE_ETSI_EctInform, &rose_etsi_ect, 5,
rose_enc_etsi_EctInform_ARG, NULL,
rose_dec_etsi_EctInform_ARG, NULL
},
{
ROSE_ETSI_EctLoopTest, &rose_etsi_ect, 6,
rose_enc_etsi_EctLoopTest_ARG, rose_enc_etsi_EctLoopTest_RES,
rose_dec_etsi_EctLoopTest_ARG, rose_dec_etsi_EctLoopTest_RES
},
/* *INDENT-ON* */
};
@@ -295,6 +413,39 @@ static const struct rose_convert_error rose_etsi_errors[] = {
NULL, NULL
},
/*
* localValue Errors from Diversion-Operations
* {ccitt identified-organization etsi(0) 207 operations-and-errors(1)}
*/
{
ROSE_ERROR_Div_InvalidDivertedToNr, NULL, 12,
NULL, NULL
},
{
ROSE_ERROR_Div_SpecialServiceNr, NULL, 14,
NULL, NULL
},
{
ROSE_ERROR_Div_DiversionToServedUserNr, NULL, 15,
NULL, NULL
},
{
ROSE_ERROR_Div_IncomingCallAccepted, NULL, 23,
NULL, NULL
},
{
ROSE_ERROR_Div_NumberOfDiversionsExceeded, NULL, 24,
NULL, NULL
},
{
ROSE_ERROR_Div_NotActivated, NULL, 46,
NULL, NULL
},
{
ROSE_ERROR_Div_RequestAlreadyAccepted, NULL, 48,
NULL, NULL
},
/*
* localValue Errors from Advice-of-Charge-Operations
* {ccitt identified-organization etsi (0) 182 operations-and-errors (1)}
@@ -303,6 +454,15 @@ static const struct rose_convert_error rose_etsi_errors[] = {
ROSE_ERROR_AOC_NoChargingInfoAvailable, NULL, 26,
NULL, NULL
},
/*
* globalValue Errors (OIDs) from Explicit-Call-Transfer-Operations-and-Errors
* {ccitt identified-organization etsi(0) 369 operations-and-errors(1)}
*/
{
ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork, &rose_etsi_ect, 21,
NULL, NULL
},
/* *INDENT-ON* */
};
@@ -880,6 +1040,27 @@ const char *rose_operation2str(enum rose_operation operation)
{ ROSE_None, "ROSE_None" },
{ ROSE_Unknown, "ROSE_Unknown" },
{ ROSE_ETSI_ActivationDiversion, "ROSE_ETSI_ActivationDiversion" },
{ ROSE_ETSI_DeactivationDiversion, "ROSE_ETSI_DeactivationDiversion" },
{ ROSE_ETSI_ActivationStatusNotificationDiv,"ROSE_ETSI_ActivationStatusNotificationDiv" },
{ ROSE_ETSI_DeactivationStatusNotificationDiv,"ROSE_ETSI_DeactivationStatusNotificationDiv" },
{ ROSE_ETSI_InterrogationDiversion, "ROSE_ETSI_InterrogationDiversion" },
{ ROSE_ETSI_DiversionInformation, "ROSE_ETSI_DiversionInformation" },
{ ROSE_ETSI_CallDeflection, "ROSE_ETSI_CallDeflection" },
{ ROSE_ETSI_CallRerouting, "ROSE_ETSI_CallRerouting" },
{ ROSE_ETSI_DivertingLegInformation2, "ROSE_ETSI_DivertingLegInformation2" },
{ ROSE_ETSI_InterrogateServedUserNumbers, "ROSE_ETSI_InterrogateServedUserNumbers" },
{ ROSE_ETSI_DivertingLegInformation1, "ROSE_ETSI_DivertingLegInformation1" },
{ ROSE_ETSI_DivertingLegInformation3, "ROSE_ETSI_DivertingLegInformation3" },
{ ROSE_ETSI_EctExecute, "ROSE_ETSI_EctExecute" },
{ ROSE_ETSI_ExplicitEctExecute, "ROSE_ETSI_ExplicitEctExecute" },
{ ROSE_ETSI_RequestSubaddress, "ROSE_ETSI_RequestSubaddress" },
{ ROSE_ETSI_SubaddressTransfer, "ROSE_ETSI_SubaddressTransfer" },
{ ROSE_ETSI_EctLinkIdRequest, "ROSE_ETSI_EctLinkIdRequest" },
{ ROSE_ETSI_EctInform, "ROSE_ETSI_EctInform" },
{ ROSE_ETSI_EctLoopTest, "ROSE_ETSI_EctLoopTest" },
{ ROSE_ETSI_ChargingRequest, "ROSE_ETSI_ChargingRequest" },
{ ROSE_ETSI_AOCSCurrency, "ROSE_ETSI_AOCSCurrency" },
{ ROSE_ETSI_AOCSSpecialArr, "ROSE_ETSI_AOCSSpecialArr" },
@@ -971,10 +1152,15 @@ const char *rose_error2str(enum rose_error_code code)
{ ROSE_ERROR_Div_InvalidDivertedToNr, "Diversion: Invalid Diverted To Number" },
{ ROSE_ERROR_Div_SpecialServiceNr, "Diversion: Special Service Number" },
{ ROSE_ERROR_Div_DiversionToServedUserNr, "Diversion: Diversion To Served User Number" },
{ ROSE_ERROR_Div_IncomingCallAccepted, "Diversion: Incoming Call Accepted" },
{ ROSE_ERROR_Div_NumberOfDiversionsExceeded, "Diversion: Number Of Diversions Exceeded" },
{ ROSE_ERROR_Div_NotActivated, "Diversion: Not Activated" },
{ ROSE_ERROR_Div_RequestAlreadyAccepted, "Diversion: Request Already Accepted" },
{ ROSE_ERROR_AOC_NoChargingInfoAvailable, "AOC: No Charging Info Available" },
{ ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork, "ECT: Link ID Not Assigned By Network" },
/* Q.SIG specific errors */
{ ROSE_ERROR_QSIG_Unspecified, "Unspecified" },

653
rose.h
View File

@@ -65,6 +65,20 @@ enum rose_operation {
ROSE_Unknown,
/* *INDENT-OFF* */
/* ETSI Diversion-Operations */
ROSE_ETSI_ActivationDiversion, /*!< Invoke/Result */
ROSE_ETSI_DeactivationDiversion, /*!< Invoke/Result */
ROSE_ETSI_ActivationStatusNotificationDiv,/*!< Invoke only */
ROSE_ETSI_DeactivationStatusNotificationDiv,/*!< Invoke only */
ROSE_ETSI_InterrogationDiversion, /*!< Invoke/Result */
ROSE_ETSI_DiversionInformation, /*!< Invoke only */
ROSE_ETSI_CallDeflection, /*!< Invoke/Result */
ROSE_ETSI_CallRerouting, /*!< Invoke/Result */
ROSE_ETSI_InterrogateServedUserNumbers, /*!< Invoke/Result */
ROSE_ETSI_DivertingLegInformation1, /*!< Invoke only */
ROSE_ETSI_DivertingLegInformation2, /*!< Invoke only */
ROSE_ETSI_DivertingLegInformation3, /*!< Invoke only */
/*
* ETSI Advice-of-Charge-Operations
*
@@ -80,6 +94,15 @@ enum rose_operation {
ROSE_ETSI_AOCECurrency, /*!< Invoke only */
ROSE_ETSI_AOCEChargingUnit, /*!< Invoke only */
/* ETSI Explicit-Call-Transfer-Operations-and-Errors */
ROSE_ETSI_EctExecute, /*!< Invoke/Result */
ROSE_ETSI_ExplicitEctExecute, /*!< Invoke/Result */
ROSE_ETSI_RequestSubaddress, /*!< Invoke only */
ROSE_ETSI_SubaddressTransfer, /*!< Invoke only */
ROSE_ETSI_EctLinkIdRequest, /*!< Invoke/Result */
ROSE_ETSI_EctInform, /*!< Invoke only */
ROSE_ETSI_EctLoopTest, /*!< Invoke/Result */
/* Q.SIG Name-Operations */
ROSE_QSIG_CallingName, /*!< Invoke only */
ROSE_QSIG_CalledName, /*!< Invoke only */
@@ -164,11 +187,17 @@ enum rose_error_code {
ROSE_ERROR_Div_InvalidDivertedToNr,
ROSE_ERROR_Div_SpecialServiceNr,
ROSE_ERROR_Div_DiversionToServedUserNr,
ROSE_ERROR_Div_IncomingCallAccepted,
ROSE_ERROR_Div_NumberOfDiversionsExceeded,
ROSE_ERROR_Div_NotActivated,
ROSE_ERROR_Div_RequestAlreadyAccepted,
/* ETSI Advice-of-Charge-Operations */
ROSE_ERROR_AOC_NoChargingInfoAvailable,
/* ETSI Explicit-Call-Transfer-Operations-and-Errors */
ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork,
/* Q.SIG from various specifications */
ROSE_ERROR_QSIG_Unspecified,
@@ -1046,6 +1075,602 @@ struct roseEtsiAOCEChargingUnit_ARG {
/* ------------------------------------------------------------------- */
/*
* ARGUMENT SEQUENCE {
* procedure Procedure,
* basicService BasicService,
* forwardedToAddress Address,
* servedUserNr ServedUserNr
* }
*/
struct roseEtsiActivationDiversion_ARG {
/*! \brief Forwarded to address */
struct roseAddress forwarded_to;
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* ARGUMENT SEQUENCE {
* procedure Procedure,
* basicService BasicService,
* servedUserNr ServedUserNr
* }
*/
struct roseEtsiDeactivationDiversion_ARG {
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* ARGUMENT SEQUENCE {
* procedure Procedure,
* basicService BasicService,
* forwardedToAddresss Address,
* servedUserNr ServedUserNr
* }
*/
struct roseEtsiActivationStatusNotificationDiv_ARG {
/*! \brief Forwarded to address */
struct roseAddress forwarded_to;
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* ARGUMENT SEQUENCE {
* procedure Procedure,
* basicService BasicService,
* servedUserNr ServedUserNr
* }
*/
struct roseEtsiDeactivationStatusNotificationDiv_ARG {
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* ARGUMENT SEQUENCE {
* procedure Procedure,
* basicService BasicService DEFAULT allServices,
* servedUserNr ServedUserNr
* }
*/
struct roseEtsiInterrogationDiversion_ARG {
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* DEFAULT allServices
*
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* IntResult ::= SEQUENCE {
* servedUserNr ServedUserNr,
* basicService BasicService,
* procedure Procedure,
* forwardedToAddress Address
* }
*/
struct roseEtsiForwardingRecord {
/*! \brief Forwarded to address */
struct roseAddress forwarded_to;
/*! \brief Forward all numbers if not present (Number length is zero). */
struct rosePartyNumber served_user_number;
/*! \details cfu(0), cfb(1), cfnr(2) */
u_int8_t procedure;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* roseInterrogationDiversion_RES
* IntResultList ::= SET SIZE (0..29) OF IntResult
*/
struct roseEtsiForwardingList {
/*!
* \brief SET SIZE (0..29) OF Forwarding Records
* \note Reduced the size of the array to conserve
* potential stack usage.
*/
struct roseEtsiForwardingRecord list[10];
/*! \brief Number of Forwarding records present */
u_int8_t num_records;
};
/*
* ARGUMENT SEQUENCE {
* diversionReason DiversionReason,
* basicService BasicService,
* servedUserSubaddress PartySubaddress OPTIONAL,
* callingAddress [0] EXPLICIT PresentedAddressScreened OPTIONAL,
* originalCalledNr [1] EXPLICIT PresentedNumberUnscreened OPTIONAL,
* lastDivertingNr [2] EXPLICIT PresentedNumberUnscreened OPTIONAL,
* lastDivertingReason [3] EXPLICIT DiversionReason OPTIONAL,
*
* -- The User-user information element, as specified
* -- in ETS 300 102-1 [11], subclause 4.5.29, shall
* -- be embedded in the userInfo parameter.
* userInfo Q931InformationElement OPTIONAL
* }
*/
struct roseEtsiDiversionInformation_ARG {
/*! \brief Served user subaddress (Optional) */
struct rosePartySubaddress served_user_subaddress;
/*! \brief Calling address (Optional) */
struct rosePresentedAddressScreened calling;
/*! \brief Original called number (Optional) */
struct rosePresentedNumberUnscreened original_called;
/*! \brief Last diverting number (Optional) */
struct rosePresentedNumberUnscreened last_diverting;
/*! \brief User-User information embedded in Q.931 IE (Optional) */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_USER + 1];
/*!
* \brief Last diverting reason (Optional)
*
* \details
* unknown(0),
* cfu(1),
* cfb(2),
* cfnr(3),
* cdAlerting(4),
* cdImmediate(5)
*/
u_int8_t last_diverting_reason;
/*! \brief TRUE if CallingAddress is present */
u_int8_t calling_present;
/*! \brief TRUE if OriginalCalled is present */
u_int8_t original_called_present;
/*! \brief TRUE if LastDiverting is present */
u_int8_t last_diverting_present;
/*! \brief TRUE if LastDivertingReason is present */
u_int8_t last_diverting_reason_present;
/*!
* \details
* unknown(0),
* cfu(1),
* cfb(2),
* cfnr(3),
* cdAlerting(4),
* cdImmediate(5)
*/
u_int8_t diversion_reason;
/*!
* \details
* allServices(0),
* speech(1),
* unrestrictedDigitalInformation(2),
* audio3k1Hz(3),
* unrestrictedDigitalInformationWithTonesAndAnnouncements(4),
* multirate(5),
* telephony3k1Hz(32),
* teletex(33),
* telefaxGroup4Class1(34),
* videotexSyntaxBased(35),
* videotelephony(36),
* telefaxGroup2-3(37),
* telephony7kHz(38),
* euroFileTransfer(39),
* fileTransferAndAccessManagement(40),
* videoconference(41),
* audioGraphicConference(42)
*/
u_int8_t basic_service;
};
/*
* ARGUMENT SEQUENCE {
* deflectionAddress Address,
* presentationAllowedDivertedToUser PresentationAllowedIndicator OPTIONAL
* }
*/
struct roseEtsiCallDeflection_ARG {
/*! \brief Deflection address (Deflected-To address) */
struct roseAddress deflection;
/*! \brief TRUE if PresentationAllowedToDivertedToUser is present */
u_int8_t presentation_allowed_to_diverted_to_user_present;
/*! \brief TRUE if presentation is allowed (Optional) */
u_int8_t presentation_allowed_to_diverted_to_user;
};
/*
* ARGUMENT SEQUENCE {
* reroutingReason DiversionReason,
* calledAddress Address,
* reroutingCounter DiversionCounter,
*
* -- The User-user information element (optional),
* -- High layer compatibility information element (optional),
* -- Bearer capability information element
* -- and Low layer compatibility information element (optional)
* -- as specified in ETS 300 102-1 [11] subclause 4.5 shall be
* -- embedded in the q931InfoElement.
* q931InfoElement Q931InformationElement,
* lastReroutingNr [1] EXPLICIT PresentedNumberUnscreened,
* subscriptionOption [2] EXPLICIT SubscriptionOption DEFAULT noNotification,
* callingPartySubaddress [3] EXPLICIT PartySubaddress OPTIONAL
* }
*/
struct roseEtsiCallRerouting_ARG {
struct roseAddress called_address;
/*! \brief The BC, HLC (optional), LLC (optional), and User-user (optional) information */
struct roseQ931ie q931ie;
/*! \brief q931ie.contents "allocated" after the stucture. */
unsigned char q931ie_contents[ROSE_Q931_MAX_BC + ROSE_Q931_MAX_HLC +
ROSE_Q931_MAX_LLC + ROSE_Q931_MAX_USER + 1];
/*! \brief Last rerouting number */
struct rosePresentedNumberUnscreened last_rerouting;
/*! \brief Calling party subaddress (Optional) */
struct rosePartySubaddress calling_subaddress;
/*!
* \details
* unknown(0),
* cfu(1),
* cfb(2),
* cfnr(3),
* cdAlerting(4),
* cdImmediate(5)
*/
u_int8_t rerouting_reason;
/*! \brief Range 1-5 */
u_int8_t rerouting_counter;
/*!
* \details
* DEFAULT noNotification
*
* \details
* noNotification(0),
* notificationWithoutDivertedToNr(1),
* notificationWithDivertedToNr(2)
*/
u_int8_t subscription_option;
};
/*
* roseInterrogateServedUserNumbers_RES
* ServedUserNumberList ::= SET SIZE (0..99) OF PartyNumber
*/
struct roseEtsiServedUserNumberList {
/*!
* \brief SET SIZE (0..99) OF Served user numbers
* \note Reduced the size of the array to conserve
* potential stack usage.
*/
struct rosePartyNumber number[20];
/*! \brief Number of Served user numbers present */
u_int8_t num_records;
};
/*
* ARGUMENT SEQUENCE {
* diversionReason DiversionReason,
* subscriptionOption SubscriptionOption,
* divertedToNumber PresentedNumberUnscreened OPTIONAL
* }
*/
struct roseEtsiDivertingLegInformation1_ARG {
/*! \brief Diverted to number (Optional) */
struct rosePresentedNumberUnscreened diverted_to;
/*! \brief TRUE if DivertedTo is present */
u_int8_t diverted_to_present;
/*!
* \details
* unknown(0),
* cfu(1),
* cfb(2),
* cfnr(3),
* cdAlerting(4),
* cdImmediate(5)
*/
u_int8_t diversion_reason;
/*!
* \details
* noNotification(0),
* notificationWithoutDivertedToNr(1),
* notificationWithDivertedToNr(2)
*/
u_int8_t subscription_option;
};
/*
* ARGUMENT SEQUENCE {
* diversionCounter DiversionCounter,
* diversionReason DiversionReason,
* divertingNr [1] EXPLICIT PresentedNumberUnscreened OPTIONAL,
* originalCalledNr [2] EXPLICIT PresentedNumberUnscreened OPTIONAL
* }
*/
struct roseEtsiDivertingLegInformation2_ARG {
/*! \brief Diverting number (Optional) */
struct rosePresentedNumberUnscreened diverting;
/*! \brief Original called number (Optional) */
struct rosePresentedNumberUnscreened original_called;
/*! \brief TRUE if Diverting number is present */
u_int8_t diverting_present;
/*! \brief TRUE if OriginalCalled is present */
u_int8_t original_called_present;
/*!
* \details
* unknown(0),
* cfu(1),
* cfb(2),
* cfnr(3),
* cdAlerting(4),
* cdImmediate(5)
*/
u_int8_t diversion_reason;
/*! \brief Range 1-5 */
u_int8_t diversion_counter;
};
/*
* ARGUMENT presentationAllowedIndicator PresentationAllowedIndicator
*/
struct roseEtsiDivertingLegInformation3_ARG {
/*! \brief TRUE if presentation is allowed */
u_int8_t presentation_allowed_indicator;
};
/* ------------------------------------------------------------------- */
/*
* ARGUMENT LinkId
*/
struct roseEtsiExplicitEctExecute_ARG {
int16_t link_id;
};
/*
* ARGUMENT transferredToSubaddress PartySubaddress
*/
struct roseEtsiSubaddressTransfer_ARG {
/*! \brief Transferred to subaddress */
struct rosePartySubaddress subaddress;
};
/*
* RESULT LinkId
*/
struct roseEtsiEctLinkIdRequest_RES {
int16_t link_id;
};
/*
* ARGUMENT SEQUENCE {
* ENUMERATED {
* alerting (0),
* active (1)
* },
* redirectionNumber PresentedNumberUnscreened OPTIONAL
* }
*/
struct roseEtsiEctInform_ARG {
/*! \brief Redirection Number (Optional) */
struct rosePresentedNumberUnscreened redirection;
/*! \brief TRUE if the Redirection Number is present */
u_int8_t redirection_present;
/*! \details alerting(0), active(1) */
u_int8_t status;
};
/*
* ARGUMENT CallTransferIdentity
*/
struct roseEtsiEctLoopTest_ARG {
int8_t call_transfer_id;
};
/*
* RESULT LoopResult
*/
struct roseEtsiEctLoopTest_RES {
/*!
* \details
* insufficientInformation(0),
* noLoopExists(1),
* simultaneousTransfer(2)
*/
u_int8_t loop_result;
};
/* ------------------------------------------------------------------- */
/*
* Name ::= CHOICE {
* -- iso8859-1 is implied in namePresentationAllowedSimple.
@@ -2638,12 +3263,40 @@ union rose_msg_invoke_etsi_args {
struct roseEtsiAOCDChargingUnit_ARG AOCDChargingUnit;
struct roseEtsiAOCECurrency_ARG AOCECurrency;
struct roseEtsiAOCEChargingUnit_ARG AOCEChargingUnit;
/* ETSI Call Diversion */
struct roseEtsiActivationDiversion_ARG ActivationDiversion;
struct roseEtsiDeactivationDiversion_ARG DeactivationDiversion;
struct roseEtsiActivationStatusNotificationDiv_ARG ActivationStatusNotificationDiv;
struct roseEtsiDeactivationStatusNotificationDiv_ARG
DeactivationStatusNotificationDiv;
struct roseEtsiInterrogationDiversion_ARG InterrogationDiversion;
struct roseEtsiDiversionInformation_ARG DiversionInformation;
struct roseEtsiCallDeflection_ARG CallDeflection;
struct roseEtsiCallRerouting_ARG CallRerouting;
struct roseEtsiDivertingLegInformation1_ARG DivertingLegInformation1;
struct roseEtsiDivertingLegInformation2_ARG DivertingLegInformation2;
struct roseEtsiDivertingLegInformation3_ARG DivertingLegInformation3;
/* ETSI Explicit Call Transfer (ECT) */
struct roseEtsiExplicitEctExecute_ARG ExplicitEctExecute;
struct roseEtsiSubaddressTransfer_ARG SubaddressTransfer;
struct roseEtsiEctInform_ARG EctInform;
struct roseEtsiEctLoopTest_ARG EctLoopTest;
};
/*! \brief Facility ie result etsi messages with arguments. */
union rose_msg_result_etsi_args {
/* ETSI Advice Of Charge (AOC) */
struct roseEtsiChargingRequest_RES ChargingRequest;
/* ETSI Call Diversion */
struct roseEtsiForwardingList InterrogationDiversion;
struct roseEtsiServedUserNumberList InterrogateServedUserNumbers;
/* ETSI Explicit Call Transfer (ECT) */
struct roseEtsiEctLinkIdRequest_RES EctLinkIdRequest;
struct roseEtsiEctLoopTest_RES EctLoopTest;
};
/*! \brief Facility ie invoke qsig messages with arguments. */

1623
rose_etsi_diversion.c Normal file

File diff suppressed because it is too large Load Diff

332
rose_etsi_ect.c Normal file
View File

@@ -0,0 +1,332 @@
/*
* libpri: An implementation of Primary Rate ISDN
*
* Copyright (C) 2009 Digium, Inc.
*
* Richard Mudgett <rmudgett@digium.com>
*
* 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.
*/
/*!
* \file
* \brief ROSE Explicit Call Transfer operations.
*
* Explicit Call Transfer (ECT) Supplementary Services ETS 300 369-1
*
* \author Richard Mudgett <rmudgett@digium.com>
*/
#include "compat.h"
#include "libpri.h"
#include "pri_internal.h"
#include "rose.h"
#include "rose_internal.h"
#include "asn1.h"
/* ------------------------------------------------------------------- */
/*!
* \brief Encode the ExplicitEctExecute invoke facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
args->etsi.ExplicitEctExecute.link_id);
}
/*!
* \brief Encode the SubaddressTransfer invoke facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return rose_enc_PartySubaddress(ctrl, pos, end,
&args->etsi.SubaddressTransfer.subaddress);
}
/*!
* \brief Encode the EctLinkIdRequest result facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args)
{
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
args->etsi.EctLinkIdRequest.link_id);
}
/*!
* \brief Encode the EctInform invoke facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_EctInform_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
const struct roseEtsiEctInform_ARG *ect_inform;
unsigned char *seq_len;
ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
ect_inform = &args->etsi.EctInform;
ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED, ect_inform->status));
if (ect_inform->redirection_present) {
ASN1_CALL(pos, rose_enc_PresentedNumberUnscreened(ctrl, pos, end,
&ect_inform->redirection));
}
ASN1_CONSTRUCTED_END(seq_len, pos, end);
return pos;
}
/*!
* \brief Encode the EctLoopTest invoke facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args)
{
return asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
args->etsi.EctLoopTest.call_transfer_id);
}
/*!
* \brief Encode the EctLoopTest result facility ie arguments.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param pos Starting position to encode ASN.1 component.
* \param end End of ASN.1 encoding data buffer.
* \param args Arguments to encode in the buffer.
*
* \retval Start of the next ASN.1 component to encode on success.
* \retval NULL on error.
*/
unsigned char *rose_enc_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args)
{
return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
args->etsi.EctLoopTest.loop_result);
}
/*!
* \brief Decode the ExplicitEctExecute invoke argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
int32_t value;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
args->etsi.ExplicitEctExecute.link_id = value;
return pos;
}
/*!
* \brief Decode the SubaddressTransfer invoke argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
return rose_dec_PartySubaddress(ctrl, "transferredToSubaddress", tag, pos, end,
&args->etsi.SubaddressTransfer.subaddress);
}
/*!
* \brief Decode the EctLinkIdRequest result argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
{
int32_t value;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "linkId", tag, pos, end, &value));
args->etsi.EctLinkIdRequest.link_id = value;
return pos;
}
/*!
* \brief Decode the EctInform invoke argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_EctInform_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
struct roseEtsiEctInform_ARG *ect_inform;
int length;
int seq_offset;
const unsigned char *seq_end;
int32_t value;
if (ctrl->debug & PRI_DEBUG_APDU) {
pri_message(ctrl, " EctInform %s\n", asn1_tag2str(tag));
}
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
ect_inform = &args->etsi.EctInform;
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
ASN1_CALL(pos, asn1_dec_int(ctrl, "callStatus", tag, pos, seq_end, &value));
ect_inform->status = value;
if (pos < seq_end && *pos != ASN1_INDEF_TERM) {
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
ASN1_CALL(pos, rose_dec_PresentedNumberUnscreened(ctrl, "redirectionNumber", tag,
pos, seq_end, &ect_inform->redirection));
ect_inform->redirection_present = 1;
} else {
ect_inform->redirection_present = 0;
}
ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
return pos;
}
/*!
* \brief Decode the EctLoopTest invoke argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
{
int32_t value;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
ASN1_CALL(pos, asn1_dec_int(ctrl, "callTransferId", tag, pos, end, &value));
args->etsi.EctLoopTest.call_transfer_id = value;
return pos;
}
/*!
* \brief Decode the EctLoopTest result argument parameters.
*
* \param ctrl D channel controller for diagnostic messages or global options.
* \param tag Component tag that identified this structure.
* \param pos Starting position of the ASN.1 component length.
* \param end End of ASN.1 decoding data buffer.
* \param args Arguments to fill in from the decoded buffer.
*
* \retval Start of the next ASN.1 component on success.
* \retval NULL on error.
*/
const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
{
int32_t value;
ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
ASN1_CALL(pos, asn1_dec_int(ctrl, "loopResult", tag, pos, end, &value));
args->etsi.EctLoopTest.loop_result = value;
return pos;
}
/* ------------------------------------------------------------------- */
/* end rose_etsi_ect.c */

View File

@@ -137,6 +137,107 @@ const unsigned char *rose_dec_etsi_AOCEChargingUnit_ARG(struct pri *ctrl, unsign
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
/* ETSI Call Diversion */
unsigned char *rose_enc_etsi_ActivationDiversion_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_DeactivationDiversion_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_ActivationStatusNotificationDiv_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_DeactivationStatusNotificationDiv_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_InterrogationDiversion_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_InterrogationDiversion_RES(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_DiversionInformation_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CallDeflection_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_CallRerouting_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_InterrogateServedUserNumbers_RES(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_DivertingLegInformation1_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_DivertingLegInformation2_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_DivertingLegInformation3_ARG(struct pri *ctrl,
unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_ActivationDiversion_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_DeactivationDiversion_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_ActivationStatusNotificationDiv_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_DeactivationStatusNotificationDiv_ARG(struct pri
*ctrl, unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_InterrogationDiversion_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_InterrogationDiversion_RES(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_DiversionInformation_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_CallDeflection_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_CallRerouting_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_InterrogateServedUserNumbers_RES(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_DivertingLegInformation1_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_DivertingLegInformation2_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_DivertingLegInformation3_ARG(struct pri *ctrl,
unsigned tag, const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
/* ETSI Explicit Call Transfer (ECT) */
unsigned char *rose_enc_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
unsigned char *rose_enc_etsi_EctInform_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_invoke_args *args);
unsigned char *rose_enc_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_ExplicitEctExecute_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_SubaddressTransfer_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_EctLinkIdRequest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
const unsigned char *rose_dec_etsi_EctInform_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_EctLoopTest_ARG(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_invoke_args *args);
const unsigned char *rose_dec_etsi_EctLoopTest_RES(struct pri *ctrl, unsigned tag,
const unsigned char *pos, const unsigned char *end,
union rose_msg_result_args *args);
/* Q.SIG Name-Operations */
unsigned char *rose_enc_qsig_Name(struct pri *ctrl, unsigned char *pos,
unsigned char *end, const struct roseQsigName *name);

View File

@@ -80,6 +80,18 @@ static const struct fac_extension_header fac_headers[] = {
static const struct rose_message rose_etsi_msgs[] = {
/* *INDENT-OFF* */
/* Error messages */
{
.type = ROSE_COMP_TYPE_ERROR,
.component.error.invoke_id = 82,
.component.error.code = ROSE_ERROR_Div_SpecialServiceNr,
},
{
.type = ROSE_COMP_TYPE_ERROR,
.component.error.invoke_id = 8,
.component.error.code = ROSE_ERROR_ECT_LinkIdNotAssignedByNetwork,
},
/* Reject messages */
{
.type = ROSE_COMP_TYPE_REJECT,
@@ -513,6 +525,432 @@ static const struct rose_message rose_etsi_msgs[] = {
.component.invoke.args.etsi.AOCEChargingUnit.charging_unit.charging_association.type = 0,
.component.invoke.args.etsi.AOCEChargingUnit.charging_unit.charging_association.id = -37,
},
/* Call diversion */
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_ActivationDiversion,
.component.invoke.invoke_id = 67,
.component.invoke.linked_id_present = 1,
.component.invoke.linked_id = 27,
.component.invoke.args.etsi.ActivationDiversion.procedure = 2,
.component.invoke.args.etsi.ActivationDiversion.basic_service = 3,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.plan = 4,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.length = 4,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.str = "1803",
.component.invoke.args.etsi.ActivationDiversion.served_user_number.plan = 4,
.component.invoke.args.etsi.ActivationDiversion.served_user_number.length = 4,
.component.invoke.args.etsi.ActivationDiversion.served_user_number.str = "5398",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_ActivationDiversion,
.component.invoke.invoke_id = 68,
.component.invoke.args.etsi.ActivationDiversion.procedure = 1,
.component.invoke.args.etsi.ActivationDiversion.basic_service = 5,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.plan = 4,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.length = 4,
.component.invoke.args.etsi.ActivationDiversion.forwarded_to.number.str = "1803",
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_ActivationDiversion,
.component.result.invoke_id = 69,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DeactivationDiversion,
.component.invoke.invoke_id = 70,
.component.invoke.args.etsi.DeactivationDiversion.procedure = 1,
.component.invoke.args.etsi.DeactivationDiversion.basic_service = 5,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_DeactivationDiversion,
.component.result.invoke_id = 71,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_ActivationStatusNotificationDiv,
.component.invoke.invoke_id = 72,
.component.invoke.args.etsi.ActivationStatusNotificationDiv.procedure = 1,
.component.invoke.args.etsi.ActivationStatusNotificationDiv.basic_service = 5,
.component.invoke.args.etsi.ActivationStatusNotificationDiv.forwarded_to.number.plan = 4,
.component.invoke.args.etsi.ActivationStatusNotificationDiv.forwarded_to.number.length = 4,
.component.invoke.args.etsi.ActivationStatusNotificationDiv.forwarded_to.number.str = "1803",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DeactivationStatusNotificationDiv,
.component.invoke.invoke_id = 73,
.component.invoke.args.etsi.DeactivationStatusNotificationDiv.procedure = 1,
.component.invoke.args.etsi.DeactivationStatusNotificationDiv.basic_service = 5,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_InterrogationDiversion,
.component.invoke.invoke_id = 74,
.component.invoke.args.etsi.InterrogationDiversion.procedure = 1,
.component.invoke.args.etsi.InterrogationDiversion.basic_service = 5,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_InterrogationDiversion,
.component.invoke.invoke_id = 75,
.component.invoke.args.etsi.InterrogationDiversion.procedure = 1,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_InterrogationDiversion,
.component.result.invoke_id = 76,
.component.result.args.etsi.InterrogationDiversion.num_records = 2,
.component.result.args.etsi.InterrogationDiversion.list[0].procedure = 2,
.component.result.args.etsi.InterrogationDiversion.list[0].basic_service = 5,
.component.result.args.etsi.InterrogationDiversion.list[0].forwarded_to.number.plan = 4,
.component.result.args.etsi.InterrogationDiversion.list[0].forwarded_to.number.length = 4,
.component.result.args.etsi.InterrogationDiversion.list[0].forwarded_to.number.str = "1803",
.component.result.args.etsi.InterrogationDiversion.list[1].procedure = 1,
.component.result.args.etsi.InterrogationDiversion.list[1].basic_service = 3,
.component.result.args.etsi.InterrogationDiversion.list[1].forwarded_to.number.plan = 4,
.component.result.args.etsi.InterrogationDiversion.list[1].forwarded_to.number.length = 4,
.component.result.args.etsi.InterrogationDiversion.list[1].forwarded_to.number.str = "1903",
.component.result.args.etsi.InterrogationDiversion.list[1].served_user_number.plan = 4,
.component.result.args.etsi.InterrogationDiversion.list[1].served_user_number.length = 4,
.component.result.args.etsi.InterrogationDiversion.list[1].served_user_number.str = "5398",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 77,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 3,
.component.invoke.args.etsi.DiversionInformation.basic_service = 5,
.component.invoke.args.etsi.DiversionInformation.served_user_subaddress.type = 1,
.component.invoke.args.etsi.DiversionInformation.served_user_subaddress.length = 4,
.component.invoke.args.etsi.DiversionInformation.served_user_subaddress.u.nsap = "6492",
.component.invoke.args.etsi.DiversionInformation.calling_present = 1,
.component.invoke.args.etsi.DiversionInformation.calling.presentation = 0,
.component.invoke.args.etsi.DiversionInformation.calling.screened.screening_indicator = 3,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.plan = 4,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.length = 4,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.str = "1803",
.component.invoke.args.etsi.DiversionInformation.original_called_present = 1,
.component.invoke.args.etsi.DiversionInformation.original_called.presentation = 1,
.component.invoke.args.etsi.DiversionInformation.last_diverting_present = 1,
.component.invoke.args.etsi.DiversionInformation.last_diverting.presentation = 2,
.component.invoke.args.etsi.DiversionInformation.last_diverting_reason_present = 1,
.component.invoke.args.etsi.DiversionInformation.last_diverting_reason = 3,
.component.invoke.args.etsi.DiversionInformation.q931ie.length = 5,
.component.invoke.args.etsi.DiversionInformation.q931ie_contents = "79828",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 78,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 3,
.component.invoke.args.etsi.DiversionInformation.basic_service = 5,
.component.invoke.args.etsi.DiversionInformation.calling_present = 1,
.component.invoke.args.etsi.DiversionInformation.calling.presentation = 1,
.component.invoke.args.etsi.DiversionInformation.original_called_present = 1,
.component.invoke.args.etsi.DiversionInformation.original_called.presentation = 2,
.component.invoke.args.etsi.DiversionInformation.last_diverting_present = 1,
.component.invoke.args.etsi.DiversionInformation.last_diverting.presentation = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 79,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 2,
.component.invoke.args.etsi.DiversionInformation.basic_service = 3,
.component.invoke.args.etsi.DiversionInformation.calling_present = 1,
.component.invoke.args.etsi.DiversionInformation.calling.presentation = 2,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 80,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 3,
.component.invoke.args.etsi.DiversionInformation.basic_service = 5,
.component.invoke.args.etsi.DiversionInformation.calling_present = 1,
.component.invoke.args.etsi.DiversionInformation.calling.presentation = 3,
.component.invoke.args.etsi.DiversionInformation.calling.screened.screening_indicator = 2,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.plan = 4,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.length = 4,
.component.invoke.args.etsi.DiversionInformation.calling.screened.number.str = "1803",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 81,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 2,
.component.invoke.args.etsi.DiversionInformation.basic_service = 4,
.component.invoke.args.etsi.DiversionInformation.q931ie.length = 5,
.component.invoke.args.etsi.DiversionInformation.q931ie_contents = "79828",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DiversionInformation,
.component.invoke.invoke_id = 82,
.component.invoke.args.etsi.DiversionInformation.diversion_reason = 2,
.component.invoke.args.etsi.DiversionInformation.basic_service = 4,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallDeflection,
.component.invoke.invoke_id = 83,
.component.invoke.args.etsi.CallDeflection.deflection.number.plan = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.length = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.str = "1803",
.component.invoke.args.etsi.CallDeflection.presentation_allowed_to_diverted_to_user_present = 1,
.component.invoke.args.etsi.CallDeflection.presentation_allowed_to_diverted_to_user = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallDeflection,
.component.invoke.invoke_id = 84,
.component.invoke.args.etsi.CallDeflection.deflection.number.plan = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.length = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.str = "1803",
.component.invoke.args.etsi.CallDeflection.presentation_allowed_to_diverted_to_user_present = 1,
.component.invoke.args.etsi.CallDeflection.presentation_allowed_to_diverted_to_user = 0,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallDeflection,
.component.invoke.invoke_id = 85,
.component.invoke.args.etsi.CallDeflection.deflection.number.plan = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.length = 4,
.component.invoke.args.etsi.CallDeflection.deflection.number.str = "1803",
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_CallDeflection,
.component.result.invoke_id = 86,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallRerouting,
.component.invoke.invoke_id = 87,
.component.invoke.args.etsi.CallRerouting.rerouting_reason = 3,
.component.invoke.args.etsi.CallRerouting.rerouting_counter = 2,
.component.invoke.args.etsi.CallRerouting.called_address.number.plan = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.length = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.str = "1803",
.component.invoke.args.etsi.CallRerouting.q931ie.length = 129,
.component.invoke.args.etsi.CallRerouting.q931ie_contents =
"YEHAW."
" The quick brown fox jumped over the lazy dog test."
" Now is the time for all good men to come to the aid of their country.",
.component.invoke.args.etsi.CallRerouting.last_rerouting.presentation = 1,
.component.invoke.args.etsi.CallRerouting.subscription_option = 2,
.component.invoke.args.etsi.CallRerouting.calling_subaddress.type = 1,
.component.invoke.args.etsi.CallRerouting.calling_subaddress.length = 4,
.component.invoke.args.etsi.CallRerouting.calling_subaddress.u.nsap = "6492",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallRerouting,
.component.invoke.invoke_id = 88,
.component.invoke.args.etsi.CallRerouting.rerouting_reason = 3,
.component.invoke.args.etsi.CallRerouting.rerouting_counter = 2,
.component.invoke.args.etsi.CallRerouting.called_address.number.plan = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.length = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.str = "1803",
.component.invoke.args.etsi.CallRerouting.q931ie.length = 2,
.component.invoke.args.etsi.CallRerouting.q931ie_contents = "RT",
.component.invoke.args.etsi.CallRerouting.last_rerouting.presentation = 1,
.component.invoke.args.etsi.CallRerouting.subscription_option = 2,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_CallRerouting,
.component.invoke.invoke_id = 89,
.component.invoke.args.etsi.CallRerouting.rerouting_reason = 3,
.component.invoke.args.etsi.CallRerouting.rerouting_counter = 2,
.component.invoke.args.etsi.CallRerouting.called_address.number.plan = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.length = 4,
.component.invoke.args.etsi.CallRerouting.called_address.number.str = "1803",
.component.invoke.args.etsi.CallRerouting.q931ie.length = 2,
.component.invoke.args.etsi.CallRerouting.q931ie_contents = "RT",
.component.invoke.args.etsi.CallRerouting.last_rerouting.presentation = 2,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_CallRerouting,
.component.result.invoke_id = 90,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_InterrogateServedUserNumbers,
.component.invoke.invoke_id = 91,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_InterrogateServedUserNumbers,
.component.result.invoke_id = 92,
.component.result.args.etsi.InterrogateServedUserNumbers.num_records = 2,
.component.result.args.etsi.InterrogateServedUserNumbers.number[0].plan = 4,
.component.result.args.etsi.InterrogateServedUserNumbers.number[0].length = 4,
.component.result.args.etsi.InterrogateServedUserNumbers.number[0].str = "1803",
.component.result.args.etsi.InterrogateServedUserNumbers.number[1].plan = 4,
.component.result.args.etsi.InterrogateServedUserNumbers.number[1].length = 4,
.component.result.args.etsi.InterrogateServedUserNumbers.number[1].str = "5786",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation1,
.component.invoke.invoke_id = 93,
.component.invoke.args.etsi.DivertingLegInformation1.diversion_reason = 4,
.component.invoke.args.etsi.DivertingLegInformation1.subscription_option = 1,
.component.invoke.args.etsi.DivertingLegInformation1.diverted_to_present = 1,
.component.invoke.args.etsi.DivertingLegInformation1.diverted_to.presentation = 2,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation1,
.component.invoke.invoke_id = 94,
.component.invoke.args.etsi.DivertingLegInformation1.diversion_reason = 4,
.component.invoke.args.etsi.DivertingLegInformation1.subscription_option = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation2,
.component.invoke.invoke_id = 95,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_counter = 3,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_reason = 2,
.component.invoke.args.etsi.DivertingLegInformation2.diverting_present = 1,
.component.invoke.args.etsi.DivertingLegInformation2.diverting.presentation = 2,
.component.invoke.args.etsi.DivertingLegInformation2.original_called_present = 1,
.component.invoke.args.etsi.DivertingLegInformation2.original_called.presentation = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation2,
.component.invoke.invoke_id = 96,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_counter = 3,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_reason = 2,
.component.invoke.args.etsi.DivertingLegInformation2.original_called_present = 1,
.component.invoke.args.etsi.DivertingLegInformation2.original_called.presentation = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation2,
.component.invoke.invoke_id = 97,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_counter = 1,
.component.invoke.args.etsi.DivertingLegInformation2.diversion_reason = 2,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_DivertingLegInformation3,
.component.invoke.invoke_id = 98,
.component.invoke.args.etsi.DivertingLegInformation3.presentation_allowed_indicator = 1,
},
/* Explicit Call Transfer (ECT) */
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctExecute,
.component.invoke.invoke_id = 54,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_ExplicitEctExecute,
.component.invoke.invoke_id = 55,
.component.invoke.args.etsi.ExplicitEctExecute.link_id = 23,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_RequestSubaddress,
.component.invoke.invoke_id = 56,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_SubaddressTransfer,
.component.invoke.invoke_id = 57,
.component.invoke.args.etsi.SubaddressTransfer.subaddress.type = 1,
.component.invoke.args.etsi.SubaddressTransfer.subaddress.length = 4,
.component.invoke.args.etsi.SubaddressTransfer.subaddress.u.nsap = "6492",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctLinkIdRequest,
.component.invoke.invoke_id = 58,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_EctLinkIdRequest,
.component.result.invoke_id = 59,
.component.result.args.etsi.EctLinkIdRequest.link_id = 76,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctInform,
.component.invoke.invoke_id = 60,
.component.invoke.args.etsi.EctInform.status = 1,
.component.invoke.args.etsi.EctInform.redirection_present = 1,
.component.invoke.args.etsi.EctInform.redirection.presentation = 0,
.component.invoke.args.etsi.EctInform.redirection.number.plan = 8,
.component.invoke.args.etsi.EctInform.redirection.number.length = 4,
.component.invoke.args.etsi.EctInform.redirection.number.str = "6229",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctInform,
.component.invoke.invoke_id = 61,
.component.invoke.args.etsi.EctInform.status = 1,
.component.invoke.args.etsi.EctInform.redirection_present = 1,
.component.invoke.args.etsi.EctInform.redirection.presentation = 1,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctInform,
.component.invoke.invoke_id = 62,
.component.invoke.args.etsi.EctInform.status = 1,
.component.invoke.args.etsi.EctInform.redirection_present = 1,
.component.invoke.args.etsi.EctInform.redirection.presentation = 2,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctInform,
.component.invoke.invoke_id = 63,
.component.invoke.args.etsi.EctInform.status = 1,
.component.invoke.args.etsi.EctInform.redirection_present = 1,
.component.invoke.args.etsi.EctInform.redirection.presentation = 3,
.component.invoke.args.etsi.EctInform.redirection.number.plan = 8,
.component.invoke.args.etsi.EctInform.redirection.number.length = 4,
.component.invoke.args.etsi.EctInform.redirection.number.str = "3340",
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctInform,
.component.invoke.invoke_id = 64,
.component.invoke.args.etsi.EctInform.status = 1,
.component.invoke.args.etsi.EctInform.redirection_present = 0,
},
{
.type = ROSE_COMP_TYPE_INVOKE,
.component.invoke.operation = ROSE_ETSI_EctLoopTest,
.component.invoke.invoke_id = 65,
.component.invoke.args.etsi.EctLoopTest.call_transfer_id = 7,
},
{
.type = ROSE_COMP_TYPE_RESULT,
.component.result.operation = ROSE_ETSI_EctLoopTest,
.component.result.invoke_id = 66,
.component.result.args.etsi.EctLoopTest.loop_result = 2,
},
/* *INDENT-ON* */
};
@@ -2013,6 +2451,16 @@ int main(int argc, char *argv[])
(unsigned) sizeof(struct roseQsigMWIInterrogateRes));
pri_message(&dummy_ctrl, "\n");
pri_message(&dummy_ctrl, "sizeof(struct roseEtsiForwardingList) = %u\n",
(unsigned) sizeof(struct roseEtsiForwardingList));
pri_message(&dummy_ctrl, "sizeof(struct roseEtsiServedUserNumberList) = %u\n",
(unsigned) sizeof(struct roseEtsiServedUserNumberList));
pri_message(&dummy_ctrl, "\n");
pri_message(&dummy_ctrl, "sizeof(struct roseEtsiCallRerouting_ARG) = %u\n",
(unsigned) sizeof(struct roseEtsiCallRerouting_ARG));
pri_message(&dummy_ctrl, "sizeof(struct roseEtsiDiversionInformation_ARG) = %u\n",
(unsigned) sizeof(struct roseEtsiDiversionInformation_ARG));
pri_message(&dummy_ctrl, "sizeof(struct roseEtsiAOCSCurrencyInfoList) = %u\n",
(unsigned) sizeof(struct roseEtsiAOCSCurrencyInfoList));