Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
271a4f3067 | ||
|
|
64ae283190 | ||
|
|
692697d39b | ||
|
|
9a7715a09d | ||
|
|
a9696d095c | ||
|
|
ea9b8059de | ||
|
|
ee25bdfb5e | ||
|
|
2fd3fff781 | ||
|
|
1b11116f18 | ||
|
|
52c6b7289d | ||
|
|
3cb1f6fbce | ||
|
|
2ab04a7663 | ||
|
|
915d423ffc | ||
|
|
a3a73a30c9 | ||
|
|
c286f741be | ||
|
|
183cd86a8d | ||
|
|
c955ba2510 | ||
|
|
a0c05f9908 | ||
|
|
9b5066cc78 | ||
|
|
9648194287 | ||
|
|
ff36053fdd | ||
|
|
d9276a9c5e | ||
|
|
c3cc1ed5b0 | ||
|
|
cd8d727df8 | ||
|
|
4e591eb689 | ||
|
|
eb0586daa1 | ||
|
|
7dca4921d2 | ||
|
|
b14525f475 | ||
|
|
5feca71b83 | ||
|
|
8d5be5281a | ||
|
|
ef3a4f1b5a | ||
|
|
969b121c9b | ||
|
|
b32ccb3fdd | ||
|
|
9b04f86bf6 | ||
|
|
2d986a8567 | ||
|
|
399513b13b | ||
|
|
ea17cdae4f | ||
|
|
d878403e92 | ||
|
|
12c20f0f91 | ||
|
|
fb53af3a71 | ||
|
|
585c016da8 | ||
|
|
f86ab05045 |
186
pri.c
186
pri.c
@@ -300,6 +300,7 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
pri_default_timers(p, switchtype);
|
||||
if (master) {
|
||||
pri_set_debug(p, master->debug);
|
||||
pri_set_inbanddisconnect(p, master->acceptinbanddisconnect);
|
||||
if (master->sendfacility)
|
||||
pri_facility_enable(p);
|
||||
}
|
||||
@@ -323,7 +324,7 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_EOC_PATH, p, NULL, NULL, NULL, Q921_TEI_GR303_EOC_PATH, 0);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case PRI_SWITCH_GR303_TMC:
|
||||
@@ -333,7 +334,7 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
p->subchannel = __pri_new_tei(-1, node, PRI_SWITCH_GR303_TMC_SWITCHING, p, NULL, NULL, NULL, Q921_TEI_GR303_TMC_SWITCHING, 0);
|
||||
if (!p->subchannel) {
|
||||
free(p);
|
||||
p = NULL;
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case PRI_SWITCH_GR303_TMC_SWITCHING:
|
||||
@@ -364,8 +365,15 @@ struct pri *__pri_new_tei(int fd, int node, int switchtype, struct pri *master,
|
||||
|
||||
void pri_call_set_useruser(q931_call *c, const char *userchars)
|
||||
{
|
||||
if (userchars)
|
||||
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
|
||||
/*
|
||||
* There is a slight risk here if c is actually stale. However,
|
||||
* if it is stale then it is better to catch it here than to
|
||||
* write with it.
|
||||
*/
|
||||
if (!userchars || !pri_is_call_valid(NULL, c)) {
|
||||
return;
|
||||
}
|
||||
libpri_copy_string(c->useruserinfo, userchars, sizeof(c->useruserinfo));
|
||||
}
|
||||
|
||||
void pri_sr_set_useruser(struct pri_sr *sr, const char *userchars)
|
||||
@@ -433,32 +441,32 @@ char *pri_event2str(int id)
|
||||
char *name;
|
||||
} events[] = {
|
||||
/* *INDENT-OFF* */
|
||||
{ PRI_EVENT_DCHAN_UP, "D-Channel Up" },
|
||||
{ PRI_EVENT_DCHAN_DOWN, "D-channel Down" },
|
||||
{ PRI_EVENT_RESTART, "Restart channel" },
|
||||
{ PRI_EVENT_CONFIG_ERR, "Configuration Error" },
|
||||
{ PRI_EVENT_RING, "Ring" },
|
||||
{ PRI_EVENT_HANGUP, "Hangup" },
|
||||
{ PRI_EVENT_RINGING, "Ringing" },
|
||||
{ PRI_EVENT_ANSWER, "Answer" },
|
||||
{ PRI_EVENT_HANGUP_ACK, "Hangup ACK" },
|
||||
{ PRI_EVENT_RESTART_ACK, "Restart ACK" },
|
||||
{ PRI_EVENT_FACILITY, "Facility" },
|
||||
{ PRI_EVENT_INFO_RECEIVED, "Info Received" },
|
||||
{ PRI_EVENT_PROCEEDING, "Proceeding" },
|
||||
{ PRI_EVENT_SETUP_ACK, "Setup ACK" },
|
||||
{ PRI_EVENT_HANGUP_REQ, "Hangup Req" },
|
||||
{ PRI_EVENT_NOTIFY, "Notify" },
|
||||
{ PRI_EVENT_PROGRESS, "Progress" },
|
||||
{ PRI_EVENT_KEYPAD_DIGIT, "Keypad Digit" },
|
||||
{ PRI_EVENT_SERVICE, "Service" },
|
||||
{ PRI_EVENT_SERVICE_ACK, "Service ACK" },
|
||||
{ PRI_EVENT_HOLD, "Hold" },
|
||||
{ PRI_EVENT_HOLD_ACK, "Hold Ack" },
|
||||
{ PRI_EVENT_HOLD_REJ, "Hold Rej" },
|
||||
{ PRI_EVENT_RETRIEVE, "Retrieve" },
|
||||
{ PRI_EVENT_RETRIEVE_ACK, "Retrieve ACK" },
|
||||
{ PRI_EVENT_RETRIEVE_REJ, "Retrieve Rej" },
|
||||
{ PRI_EVENT_DCHAN_UP, "PRI_EVENT_DCHAN_UP" },
|
||||
{ PRI_EVENT_DCHAN_DOWN, "PRI_EVENT_DCHAN_DOWN" },
|
||||
{ PRI_EVENT_RESTART, "PRI_EVENT_RESTART" },
|
||||
{ PRI_EVENT_CONFIG_ERR, "PRI_EVENT_CONFIG_ERR" },
|
||||
{ PRI_EVENT_RING, "PRI_EVENT_RING" },
|
||||
{ PRI_EVENT_HANGUP, "PRI_EVENT_HANGUP" },
|
||||
{ PRI_EVENT_RINGING, "PRI_EVENT_RINGING" },
|
||||
{ PRI_EVENT_ANSWER, "PRI_EVENT_ANSWER" },
|
||||
{ PRI_EVENT_HANGUP_ACK, "PRI_EVENT_HANGUP_ACK" },
|
||||
{ PRI_EVENT_RESTART_ACK, "PRI_EVENT_RESTART_ACK" },
|
||||
{ PRI_EVENT_FACILITY, "PRI_EVENT_FACILITY" },
|
||||
{ PRI_EVENT_INFO_RECEIVED, "PRI_EVENT_INFO_RECEIVED" },
|
||||
{ PRI_EVENT_PROCEEDING, "PRI_EVENT_PROCEEDING" },
|
||||
{ PRI_EVENT_SETUP_ACK, "PRI_EVENT_SETUP_ACK" },
|
||||
{ PRI_EVENT_HANGUP_REQ, "PRI_EVENT_HANGUP_REQ" },
|
||||
{ PRI_EVENT_NOTIFY, "PRI_EVENT_NOTIFY" },
|
||||
{ PRI_EVENT_PROGRESS, "PRI_EVENT_PROGRESS" },
|
||||
{ PRI_EVENT_KEYPAD_DIGIT, "PRI_EVENT_KEYPAD_DIGIT" },
|
||||
{ PRI_EVENT_SERVICE, "PRI_EVENT_SERVICE" },
|
||||
{ PRI_EVENT_SERVICE_ACK, "PRI_EVENT_SERVICE_ACK" },
|
||||
{ PRI_EVENT_HOLD, "PRI_EVENT_HOLD" },
|
||||
{ PRI_EVENT_HOLD_ACK, "PRI_EVENT_HOLD_ACK" },
|
||||
{ PRI_EVENT_HOLD_REJ, "PRI_EVENT_HOLD_REJ" },
|
||||
{ PRI_EVENT_RETRIEVE, "PRI_EVENT_RETRIEVE" },
|
||||
{ PRI_EVENT_RETRIEVE_ACK, "PRI_EVENT_RETRIEVE_ACK" },
|
||||
{ PRI_EVENT_RETRIEVE_REJ, "PRI_EVENT_RETRIEVE_REJ" },
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
@@ -574,74 +582,83 @@ void pri_facility_enable(struct pri *pri)
|
||||
|
||||
int pri_acknowledge(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_alerting(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_proceeding(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_proceeding(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_progress_with_cause(struct pri *pri, q931_call *call, int channel, int info, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_call_progress_with_cause(pri, call, channel, info, cause);
|
||||
}
|
||||
|
||||
int pri_progress(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_call_progress(pri, call, channel, info);
|
||||
}
|
||||
|
||||
int pri_information(struct pri *pri, q931_call *call, char digit)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_information(pri, call, digit);
|
||||
}
|
||||
|
||||
int pri_keypad_facility(struct pri *pri, q931_call *call, const char *digits)
|
||||
{
|
||||
if (!pri || !call || !digits || !digits[0])
|
||||
if (!pri || !pri_is_call_valid(pri, call) || !digits || !digits[0]) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_keypad_facility(pri, call, digits);
|
||||
}
|
||||
|
||||
int pri_notify(struct pri *pri, q931_call *call, int channel, int info)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_notify(pri, call, channel, info);
|
||||
}
|
||||
|
||||
void pri_destroycall(struct pri *pri, q931_call *call)
|
||||
{
|
||||
if (pri && call)
|
||||
if (pri && pri_is_call_valid(pri, call)) {
|
||||
q931_destroycall(pri, call);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int pri_need_more_info(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_setup_ack(pri, call, channel, nonisdn);
|
||||
}
|
||||
|
||||
int pri_answer(struct pri *pri, q931_call *call, int channel, int nonisdn)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_connect(pri, call, channel, nonisdn);
|
||||
}
|
||||
|
||||
@@ -737,7 +754,7 @@ int pri_connected_line_update(struct pri *ctrl, q931_call *call, const struct pr
|
||||
unsigned idx;
|
||||
struct q931_call *subcall;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -803,7 +820,7 @@ int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_p
|
||||
unsigned idx;
|
||||
struct q931_call *subcall;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -907,23 +924,31 @@ int pri_redirecting_update(struct pri *ctrl, q931_call *call, const struct pri_p
|
||||
/* deprecated routines, use pri_hangup */
|
||||
int pri_release(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_release(pri, call, cause);
|
||||
}
|
||||
|
||||
int pri_disconnect(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_disconnect(pri, call, cause);
|
||||
}
|
||||
#endif
|
||||
|
||||
int pri_channel_bridge(q931_call *call1, q931_call *call2)
|
||||
{
|
||||
if (!call1 || !call2)
|
||||
/*
|
||||
* There is a slight risk here if call1 or call2 is actually
|
||||
* stale. However, if they are stale then it is better to catch
|
||||
* it here than to write with these pointers.
|
||||
*/
|
||||
if (!pri_is_call_valid(NULL, call1) || !pri_is_call_valid(NULL, call2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Make sure we have compatible switchtypes */
|
||||
if (call1->pri->switchtype != call2->pri->switchtype)
|
||||
@@ -975,8 +1000,9 @@ void pri_hangup_fix_enable(struct pri *ctrl, int enable)
|
||||
|
||||
int pri_hangup(struct pri *pri, q931_call *call, int cause)
|
||||
{
|
||||
if (!pri || !call)
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
if (cause == -1)
|
||||
/* normal clear cause */
|
||||
cause = PRI_CAUSE_NORMAL_CLEARING;
|
||||
@@ -1018,26 +1044,6 @@ void pri_dump_event(struct pri *pri, pri_event *e)
|
||||
if (!pri || !e)
|
||||
return;
|
||||
pri_message(pri, "Event type: %s (%d)\n", pri_event2str(e->gen.e), e->gen.e);
|
||||
switch(e->gen.e) {
|
||||
case PRI_EVENT_DCHAN_UP:
|
||||
case PRI_EVENT_DCHAN_DOWN:
|
||||
break;
|
||||
case PRI_EVENT_CONFIG_ERR:
|
||||
pri_message(pri, "Error: %s", e->err.err);
|
||||
break;
|
||||
case PRI_EVENT_RESTART:
|
||||
pri_message(pri, "Restart on channel %d\n", e->restart.channel);
|
||||
case PRI_EVENT_RING:
|
||||
pri_message(pri, "Calling number: %s (%s, %s)\n", e->ring.callingnum, pri_plan2str(e->ring.callingplan), pri_pres2str(e->ring.callingpres));
|
||||
pri_message(pri, "Called number: %s (%s)\n", e->ring.callednum, pri_plan2str(e->ring.calledplan));
|
||||
pri_message(pri, "Channel: %d (%s) Reference number: %d\n", e->ring.channel, e->ring.flexible ? "Flexible" : "Not Flexible", e->ring.cref);
|
||||
break;
|
||||
case PRI_EVENT_HANGUP:
|
||||
pri_message(pri, "Hangup, reference number: %d, reason: %s\n", e->hangup.cref, pri_cause2str(e->hangup.cause));
|
||||
break;
|
||||
default:
|
||||
pri_message(pri, "Don't know how to dump events of type %d\n", e->gen.e);
|
||||
}
|
||||
}
|
||||
|
||||
static void pri_sr_init(struct pri_sr *req)
|
||||
@@ -1074,8 +1080,10 @@ int pri_mwi_activate(struct pri *pri, q931_call *c, char *caller, int callerplan
|
||||
int calledplan)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pri_sr_init(&req);
|
||||
pri_sr_set_connection_call_independent(&req);
|
||||
@@ -1094,8 +1102,10 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
|
||||
int calledplan)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pri_sr_init(&req);
|
||||
pri_sr_set_connection_call_independent(&req);
|
||||
@@ -1112,8 +1122,9 @@ int pri_mwi_deactivate(struct pri *pri, q931_call *c, char *caller, int callerpl
|
||||
|
||||
int pri_setup(struct pri *pri, q931_call *c, struct pri_sr *req)
|
||||
{
|
||||
if (!pri || !c)
|
||||
if (!pri || !pri_is_call_valid(pri, c)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return q931_setup(pri, c, req);
|
||||
}
|
||||
@@ -1123,8 +1134,11 @@ int pri_call(struct pri *pri, q931_call *c, int transmode, int channel, int excl
|
||||
int calledplan, int ulayer1)
|
||||
{
|
||||
struct pri_sr req;
|
||||
if (!pri || !c)
|
||||
|
||||
if (!pri || !pri_is_call_valid(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);
|
||||
@@ -1347,7 +1361,7 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
enum PRI_TIMERS_AND_COUNTERS tmr;
|
||||
|
||||
tmr = pri_timer[idx].number;
|
||||
if (0 <= ctrl->timers[tmr] || tmr == PRI_TIMER_T309) {
|
||||
if (0 <= ctrl->timers[tmr]) {
|
||||
used = pri_snprintf(buf, used, buf_size, " %s: %d\n",
|
||||
pri_timer[idx].name, ctrl->timers[tmr]);
|
||||
}
|
||||
@@ -1363,18 +1377,27 @@ char *pri_dump_info_str(struct pri *ctrl)
|
||||
|
||||
int pri_get_crv(struct pri *pri, q931_call *call, int *callmode)
|
||||
{
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_getcrv(pri, call, callmode);
|
||||
}
|
||||
|
||||
int pri_set_crv(struct pri *pri, q931_call *call, int crv, int callmode)
|
||||
{
|
||||
if (!pri || !pri_is_call_valid(pri, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_call_setcrv(pri, call, crv, callmode);
|
||||
}
|
||||
|
||||
void pri_enslave(struct pri *master, struct pri *slave)
|
||||
{
|
||||
if (master && slave)
|
||||
if (master && slave) {
|
||||
slave->callpool = &master->localpool;
|
||||
slave->nfas = 1;
|
||||
master->nfas = 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct pri_sr *pri_sr_new(void)
|
||||
@@ -1513,7 +1536,7 @@ void pri_hold_enable(struct pri *ctrl, int enable)
|
||||
|
||||
int pri_hold(struct pri *ctrl, q931_call *call)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold(ctrl, call);
|
||||
@@ -1521,7 +1544,7 @@ int pri_hold(struct pri *ctrl, q931_call *call)
|
||||
|
||||
int pri_hold_ack(struct pri *ctrl, q931_call *call)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold_ack(ctrl, call);
|
||||
@@ -1529,7 +1552,7 @@ int pri_hold_ack(struct pri *ctrl, q931_call *call)
|
||||
|
||||
int pri_hold_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_hold_rej(ctrl, call, cause);
|
||||
@@ -1537,7 +1560,7 @@ int pri_hold_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
|
||||
int pri_retrieve(struct pri *ctrl, q931_call *call, int channel)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve(ctrl, call, channel);
|
||||
@@ -1545,7 +1568,7 @@ int pri_retrieve(struct pri *ctrl, q931_call *call, int channel)
|
||||
|
||||
int pri_retrieve_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve_ack(ctrl, call, channel);
|
||||
@@ -1553,7 +1576,7 @@ int pri_retrieve_ack(struct pri *ctrl, q931_call *call, int channel)
|
||||
|
||||
int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
{
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
return q931_send_retrieve_rej(ctrl, call, cause);
|
||||
@@ -1561,8 +1584,9 @@ int pri_retrieve_rej(struct pri *ctrl, q931_call *call, int cause)
|
||||
|
||||
int pri_callrerouting_facility(struct pri *pri, q931_call *call, const char *dest, const char* original, const char* reason)
|
||||
{
|
||||
if (!pri || !call || !dest)
|
||||
if (!pri || !pri_is_call_valid(pri, call) || !dest) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return qsig_cf_callrerouting(pri, call, dest, original, reason);
|
||||
}
|
||||
@@ -1581,7 +1605,7 @@ int pri_reroute_call(struct pri *ctrl, q931_call *call, const struct pri_party_i
|
||||
struct q931_party_id local_caller;
|
||||
struct q931_party_redirecting reroute;
|
||||
|
||||
if (!ctrl || !call || !deflection) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call) || !deflection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -3180,7 +3180,7 @@ int pri_rerouting_rsp(struct pri *ctrl, q931_call *call, int invoke_id, enum PRI
|
||||
{
|
||||
enum rose_error_code rose_err;
|
||||
|
||||
if (!ctrl || !call) {
|
||||
if (!ctrl || !pri_is_call_valid(ctrl, call)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3745,25 +3745,65 @@ void rose_handle_invoke(struct pri *ctrl, q931_call *call, int msgtype, q931_ie
|
||||
/* CallingName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CallingName.name);
|
||||
|
||||
switch (msgtype) {
|
||||
case Q931_SETUP:
|
||||
case Q931_CONNECT:
|
||||
/* The caller name will automatically be reported. */
|
||||
break;
|
||||
default:
|
||||
/* Setup connected line subcommand */
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
if (!subcmd) {
|
||||
break;
|
||||
}
|
||||
subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
|
||||
q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ROSE_QSIG_CalledName:
|
||||
/* CalledName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.CalledName.name);
|
||||
|
||||
/* Setup connected line subcommand */
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
if (!subcmd) {
|
||||
switch (msgtype) {
|
||||
case Q931_SETUP:
|
||||
case Q931_CONNECT:
|
||||
/* The called name will automatically be reported. */
|
||||
pri_error(ctrl, "ERROR: Too many facility subcommands\n");
|
||||
break;
|
||||
default:
|
||||
/* Setup connected line subcommand */
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
if (!subcmd) {
|
||||
break;
|
||||
}
|
||||
subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
|
||||
q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
|
||||
break;
|
||||
}
|
||||
subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
|
||||
q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
|
||||
break;
|
||||
case ROSE_QSIG_ConnectedName:
|
||||
/* ConnectedName is put in remote_id.name */
|
||||
rose_copy_name_to_q931(ctrl, &call->remote_id.name,
|
||||
&invoke->args.qsig.ConnectedName.name);
|
||||
|
||||
switch (msgtype) {
|
||||
case Q931_SETUP:
|
||||
case Q931_CONNECT:
|
||||
/* The connected line name will automatically be reported. */
|
||||
break;
|
||||
default:
|
||||
/* Setup connected line subcommand */
|
||||
subcmd = q931_alloc_subcommand(ctrl);
|
||||
if (!subcmd) {
|
||||
break;
|
||||
}
|
||||
subcmd->cmd = PRI_SUBCMD_CONNECTED_LINE;
|
||||
q931_party_id_copy_to_pri(&subcmd->u.connected_line.id, &call->remote_id);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if 0 /* Not handled yet */
|
||||
case ROSE_QSIG_BusyName:
|
||||
|
||||
@@ -84,6 +84,7 @@ struct pri {
|
||||
int sapi;
|
||||
int tei;
|
||||
int protodisc;
|
||||
unsigned int nfas:1;/* TRUE if this D channel is involved with an NFAS group */
|
||||
unsigned int bri:1;
|
||||
unsigned int acceptinbanddisconnect:1; /* Should we allow inband progress after DISCONNECT? */
|
||||
unsigned int sendfacility:1;
|
||||
@@ -458,6 +459,8 @@ struct q931_call {
|
||||
* (Caller-ID for answered or connected-line for originated calls.)
|
||||
*/
|
||||
struct q931_party_id remote_id;
|
||||
/*! \brief Automatic Number Identification (ANI) */
|
||||
struct q931_party_number ani;
|
||||
|
||||
/*!
|
||||
* \brief Staging place for the Q.931 redirection number ie.
|
||||
@@ -540,11 +543,26 @@ struct d_ctrl_dummy {
|
||||
struct q931_call dummy_call;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Check if the given call ptr is valid.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param call Q.931 call leg.
|
||||
*
|
||||
* \retval TRUE if call ptr is valid.
|
||||
* \retval FALSE if call ptr is invalid.
|
||||
*/
|
||||
#define pri_is_call_valid(ctrl, call) \
|
||||
q931_is_call_valid(ctrl, call, __PRETTY_FUNCTION__, __LINE__)
|
||||
|
||||
int q931_is_call_valid(struct pri *ctrl, struct q931_call *call, const char *func_name, unsigned long func_line);
|
||||
|
||||
extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);
|
||||
|
||||
extern pri_event *pri_schedule_run(struct pri *pri);
|
||||
|
||||
extern void pri_schedule_del(struct pri *pri, int ev);
|
||||
int pri_schedule_check(struct pri *ctrl, int id, void (*function)(void *data), void *data);
|
||||
|
||||
extern pri_event *pri_mkerror(struct pri *pri, char *errstr);
|
||||
|
||||
|
||||
10
pri_q931.h
10
pri_q931.h
@@ -494,7 +494,15 @@ void q931_dump(struct pri *ctrl, int tei, q931_h *h, int len, int txrx);
|
||||
|
||||
void q931_destroycall(struct pri *pri, q931_call *c);
|
||||
|
||||
extern void q931_dl_indication(struct pri *pri, int event);
|
||||
enum Q931_DL_EVENT {
|
||||
Q931_DL_EVENT_NONE,
|
||||
Q931_DL_EVENT_DL_ESTABLISH_IND,
|
||||
Q931_DL_EVENT_DL_ESTABLISH_CONFIRM,
|
||||
Q931_DL_EVENT_DL_RELEASE_IND,
|
||||
Q931_DL_EVENT_DL_RELEASE_CONFIRM,
|
||||
Q931_DL_EVENT_TEI_REMOVAL,
|
||||
};
|
||||
void q931_dl_event(struct pri *link, enum Q931_DL_EVENT event);
|
||||
|
||||
int q931_send_hold(struct pri *ctrl, struct q931_call *call);
|
||||
int q931_send_hold_ack(struct pri *ctrl, struct q931_call *call);
|
||||
|
||||
28
prisched.c
28
prisched.c
@@ -184,3 +184,31 @@ void pri_schedule_del(struct pri *ctrl, int id)
|
||||
pri_error(ctrl, "Asked to delete sched id %d???\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Is the scheduled event this callback.
|
||||
*
|
||||
* \param ctrl D channel controller.
|
||||
* \param id Scheduled event id to check.
|
||||
* 0 is a disabled/unscheduled event id.
|
||||
* 1 - MAX_SCHED is a valid event id.
|
||||
* \param function Callback function to call when timeout.
|
||||
* \param data Value to give callback function when timeout.
|
||||
*
|
||||
* \return TRUE if scheduled event has the callback.
|
||||
*/
|
||||
int pri_schedule_check(struct pri *ctrl, int id, void (*function)(void *data), void *data)
|
||||
{
|
||||
/* Scheduling runs on master channels only */
|
||||
ctrl = PRI_MASTER(ctrl);
|
||||
|
||||
if (0 < id && id <= MAX_SCHED) {
|
||||
if (ctrl->pri_sched[id - 1].callback == function
|
||||
&& ctrl->pri_sched[id - 1].data == data) {
|
||||
return 1;
|
||||
}
|
||||
} else if (id) {
|
||||
pri_error(ctrl, "Asked to check sched id %d???\n", id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
52
rose.c
52
rose.c
@@ -470,6 +470,21 @@ static const struct rose_convert_error rose_etsi_errors[] = {
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* Note the first value in oid.values[] is really the first two
|
||||
* OID subidentifiers. They are compressed using this formula:
|
||||
* First_Value = (First_Subidentifier * 40) + Second_Subidentifier
|
||||
*/
|
||||
|
||||
/*! \brief ECMA private-isdn-signalling-domain prefix. */
|
||||
static const struct asn1_oid rose_qsig_isdn_domain = {
|
||||
/* *INDENT-OFF* */
|
||||
/* {iso(1) identified-organization(3) icd-ecma(12) private-isdn-signalling-domain(9)} */
|
||||
3, { 43, 12, 9 }
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
|
||||
/*! \brief Q.SIG specific invoke/result encode/decode message table */
|
||||
static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
/* *INDENT-OFF* */
|
||||
@@ -479,7 +494,7 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
* decode_invoke_args, decode_result_args
|
||||
*/
|
||||
/*
|
||||
* localValue's from Q.SIG Name-Operations
|
||||
* localValue's from Q.SIG Name-Operations 4th edition
|
||||
* { iso(1) standard(0) pss1-name(13868) name-operations(0) }
|
||||
*/
|
||||
{
|
||||
@@ -503,6 +518,34 @@ static const struct rose_convert_msg rose_qsig_msgs[] = {
|
||||
rose_dec_qsig_BusyName_ARG, NULL
|
||||
},
|
||||
|
||||
/*
|
||||
* globalValue's (OIDs) from Q.SIG Name-Operations 2nd edition
|
||||
* { iso(1) identified-organization(3) icd-ecma(12) standard(0) qsig-name(164) name-operations(0) }
|
||||
*
|
||||
* This older version of the Q.SIG switch is not supported.
|
||||
* However, we will accept receiving these messages anyway.
|
||||
*/
|
||||
{
|
||||
ROSE_QSIG_CallingName, &rose_qsig_isdn_domain, 0,
|
||||
rose_enc_qsig_CallingName_ARG, NULL,
|
||||
rose_dec_qsig_CallingName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_CalledName, &rose_qsig_isdn_domain, 1,
|
||||
rose_enc_qsig_CalledName_ARG, NULL,
|
||||
rose_dec_qsig_CalledName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_ConnectedName, &rose_qsig_isdn_domain, 2,
|
||||
rose_enc_qsig_ConnectedName_ARG, NULL,
|
||||
rose_dec_qsig_ConnectedName_ARG, NULL
|
||||
},
|
||||
{
|
||||
ROSE_QSIG_BusyName, &rose_qsig_isdn_domain, 3,
|
||||
rose_enc_qsig_BusyName_ARG, NULL,
|
||||
rose_dec_qsig_BusyName_ARG, NULL
|
||||
},
|
||||
|
||||
/*
|
||||
* localValue's from Q.SIG SS-AOC-Operations
|
||||
* { iso(1) standard(0) pss1-advice-of-charge(15050) advice-of-charge-operations(0) }
|
||||
@@ -2241,13 +2284,6 @@ const unsigned char *rose_decode(struct pri *ctrl, const unsigned char *pos,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pos < end) {
|
||||
if (ctrl->debug & PRI_DEBUG_APDU) {
|
||||
pri_message(ctrl, " %u byte(s) of trailing data not consumed.\n",
|
||||
(unsigned) (end - pos));
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@@ -382,6 +382,7 @@ static const unsigned char *rose_dec_qsig_PartyName_ARG_Backend(struct pri *ctrl
|
||||
ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
|
||||
ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
|
||||
|
||||
ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
|
||||
ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "name", tag, pos, seq_end,
|
||||
&party->name));
|
||||
|
||||
|
||||
246
rosetest.c
246
rosetest.c
@@ -994,7 +994,6 @@ static unsigned char rose_etsi_indefinite_len[] = {
|
||||
0x00, 0x00,
|
||||
0x05, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
@@ -1039,7 +1038,6 @@ static unsigned char rose_etsi_unused_indefinite_len[] = {
|
||||
0x00, 0x00,
|
||||
0x05, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
@@ -1076,45 +1074,7 @@ static unsigned char rose_etsi_unused[] = {
|
||||
0x30, 0x06,
|
||||
0x84, 0x04,
|
||||
0x31, 0x38, 0x30, 0x33,
|
||||
0x05, 0x00,
|
||||
0x00, 0x00
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_etsi_extra[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [1 0x01] <A1> Len:24 <18>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <44>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <07>
|
||||
* Sequence/C(48 0x30) <30> Len:16 <10>
|
||||
* Enumerated(10 0x0A) <0A> Len:1 <01>
|
||||
* <01>
|
||||
* Enumerated(10 0x0A) <0A> Len:1 <01>
|
||||
* <05>
|
||||
* Sequence/C(48 0x30) <30> Len:6 <06>
|
||||
* Context Specific [4 0x04] <84> Len:4 <04>
|
||||
* <31 38 30 33>
|
||||
* NULL(5 0x05) <05> Len:0 <00>
|
||||
*/
|
||||
0x91,
|
||||
0xA1, 0x18,
|
||||
0x02, 0x01,
|
||||
0x44,
|
||||
0x02, 0x01,
|
||||
0x07,
|
||||
0x30, 0x10,
|
||||
0x0A, 0x01,
|
||||
0x01,
|
||||
0x0A, 0x01,
|
||||
0x05,
|
||||
0x30, 0x06,
|
||||
0x84, 0x04,
|
||||
0x31, 0x38, 0x30, 0x33,
|
||||
0x05, 0x00,
|
||||
0x00, 0x00
|
||||
0x05, 0x00
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
@@ -2116,6 +2076,136 @@ static const struct rose_message rose_qsig_msgs[] = {
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_qsig_multiple_msg[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [10 0x0A] <AA> Len:6 <06>
|
||||
* Context Specific [0 0x00] <80> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [2 0x02] <82> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [11 0x0B] <8B> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:16 <10>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <01> - "~"
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <55> - "U"
|
||||
* Sequence/C(48 0x30) <30> Len:8 <08>
|
||||
* Context Specific [2 0x02] <82> Len:3 <03>
|
||||
* <01 30 40> - "~0@"
|
||||
* Context Specific [6 0x06] <86> Len:1 <01>
|
||||
* <01> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:19 <13>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <02> - "~"
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [0 0x00] <80> Len:11 <0B>
|
||||
* <4D 6F 64 65 6D 20 44 69-73 63 6F> - "Modem Disco"
|
||||
*/
|
||||
0x9f,
|
||||
0xaa, 0x06,
|
||||
0x80, 0x01,
|
||||
0x00,
|
||||
0x82, 0x01,
|
||||
0x00,
|
||||
0x8b, 0x01,
|
||||
0x00,
|
||||
0xa1, 0x10,
|
||||
0x02, 0x01,
|
||||
0x01,
|
||||
0x02, 0x01,
|
||||
0x55,
|
||||
0x30, 0x08,
|
||||
0x82, 0x03,
|
||||
0x01, 0x30, 0x40,
|
||||
0x86, 0x01,
|
||||
0x01,
|
||||
0xa1, 0x13,
|
||||
0x02, 0x01,
|
||||
0x02,
|
||||
0x02, 0x01,
|
||||
0x00,
|
||||
0x80, 0x0b,
|
||||
0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x44, 0x69, 0x73, 0x63, 0x6f
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_qsig_name_alt_encode_msg[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [10 0x0A] <AA> Len:6 <06>
|
||||
* Context Specific [0 0x00] <80> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [2 0x02] <82> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [11 0x0B] <8B> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:21 <15>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <1D> - "~"
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Sequence/C(48 0x30) <30> Len:13 <0D>
|
||||
* Context Specific [0 0x00] <80> Len:11 <0B>
|
||||
* <55 54 49 4C 49 54 59 20-54 45 4C> - "UTILITY TEL"
|
||||
*/
|
||||
0x9F,
|
||||
0xAA, 0x06,
|
||||
0x80, 0x01,
|
||||
0x00,
|
||||
0x82, 0x01,
|
||||
0x00,
|
||||
0x8B, 0x01,
|
||||
0x00,
|
||||
0xA1, 0x15,
|
||||
0x02, 0x01,
|
||||
0x1D,
|
||||
0x02, 0x01,
|
||||
0x00,
|
||||
0x30, 0x0D,
|
||||
0x80, 0x0B,
|
||||
0x55, 0x54, 0x49, 0x4C, 0x49, 0x54, 0x59, 0x20, 0x54, 0x45, 0x4C
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
static unsigned char rose_qsig_name_2nd_encode_msg[] = {
|
||||
/* *INDENT-OFF* */
|
||||
/*
|
||||
* Context Specific/C [10 0x0A] <AA> Len:6 <06>
|
||||
* Context Specific [0 0x00] <80> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [2 0x02] <82> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific [11 0x0B] <8B> Len:1 <01>
|
||||
* <00> - "~"
|
||||
* Context Specific/C [1 0x01] <A1> Len:26 <1A>
|
||||
* Integer(2 0x02) <02> Len:1 <01>
|
||||
* <40> - "@"
|
||||
* OID(6 0x06) <06> Len:4 <04>
|
||||
* <2B 0C 09 00> - "+~~~"
|
||||
* Context Specific [0 0x00] <80> Len:15 <0F>
|
||||
* <4D 6F 64 65 6D 20 44 69-73 63 6F 42 61 6C 6C> - "Modem DiscoBall"
|
||||
*/
|
||||
0x91,
|
||||
0xaa, 0x06,
|
||||
0x80, 0x01,
|
||||
0x00,
|
||||
0x82, 0x01,
|
||||
0x00,
|
||||
0x8b, 0x01,
|
||||
0x00,
|
||||
0xa1, 0x1a,
|
||||
0x02, 0x01,
|
||||
0x40,
|
||||
0x06, 0x04,
|
||||
0x2b, 0x0c, 0x09, 0x00,
|
||||
0x80, 0x0f,
|
||||
0x4d, 0x6f, 0x64, 0x65, 0x6d, 0x20, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x42, 0x61, 0x6c, 0x6c
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
|
||||
static const struct rose_message rose_dms100_msgs[] = {
|
||||
/* *INDENT-OFF* */
|
||||
@@ -2223,17 +2313,22 @@ static void rose_test_msg(struct pri *ctrl, unsigned index,
|
||||
if (!dec_pos) {
|
||||
pri_error(ctrl, "Error: Message:%u failed to decode header\n", index);
|
||||
} else {
|
||||
dec_pos = rose_decode(ctrl, dec_pos, dec_end, &decoded_msg);
|
||||
if (!dec_pos) {
|
||||
pri_error(ctrl, "Error: Message:%u failed to decode ROSE\n", index);
|
||||
} else {
|
||||
if (header
|
||||
&& memcmp(header, &decoded_header, sizeof(decoded_header))) {
|
||||
pri_error(ctrl, "Error: Message:%u Header did not match\n",
|
||||
while (dec_pos < dec_end) {
|
||||
dec_pos = rose_decode(ctrl, dec_pos, dec_end, &decoded_msg);
|
||||
if (!dec_pos) {
|
||||
pri_error(ctrl, "Error: Message:%u failed to decode ROSE\n",
|
||||
index);
|
||||
}
|
||||
if (memcmp(encode_msg, &decoded_msg, sizeof(decoded_msg))) {
|
||||
pri_error(ctrl, "Error: Message:%u ROSE did not match\n", index);
|
||||
break;
|
||||
} else {
|
||||
if (header
|
||||
&& memcmp(header, &decoded_header, sizeof(decoded_header))) {
|
||||
pri_error(ctrl, "Error: Message:%u Header did not match\n",
|
||||
index);
|
||||
}
|
||||
if (memcmp(encode_msg, &decoded_msg, sizeof(decoded_msg))) {
|
||||
pri_error(ctrl, "Error: Message:%u ROSE did not match\n",
|
||||
index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2271,9 +2366,12 @@ static void rose_test_exception(struct pri *ctrl, const char *name,
|
||||
if (!pos) {
|
||||
pri_error(ctrl, "Error: %s test: Message failed to decode header\n", name);
|
||||
} else {
|
||||
pos = rose_decode(ctrl, pos, end, &decoded_msg);
|
||||
if (!pos) {
|
||||
pri_error(ctrl, "Error: %s test: Message failed to decode ROSE\n", name);
|
||||
while (pos < end) {
|
||||
pos = rose_decode(ctrl, pos, end, &decoded_msg);
|
||||
if (!pos) {
|
||||
pri_error(ctrl, "Error: %s test: Message failed to decode ROSE\n", name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2294,6 +2392,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned index;
|
||||
unsigned offset;
|
||||
const char *str;
|
||||
static struct pri dummy_ctrl;
|
||||
|
||||
pri_set_message(rose_pri_message);
|
||||
@@ -2302,6 +2401,9 @@ int main(int argc, char *argv[])
|
||||
memset(&dummy_ctrl, 0, sizeof(dummy_ctrl));
|
||||
dummy_ctrl.debug = PRI_DEBUG_APDU;
|
||||
|
||||
/* For sanity specify what version of libpri we are testing. */
|
||||
pri_error(&dummy_ctrl, "libpri version tested: %s\n", pri_get_version());
|
||||
|
||||
offset = 0;
|
||||
pri_message(&dummy_ctrl, "Encode/decode message(s)\n");
|
||||
if (argc <= 1) {
|
||||
@@ -2382,30 +2484,37 @@ int main(int argc, char *argv[])
|
||||
|
||||
dummy_ctrl.switchtype = PRI_SWITCH_EUROISDN_E1;
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Extra bytes on end", rose_etsi_extra,
|
||||
sizeof(rose_etsi_extra));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Indefinite length", rose_etsi_indefinite_len,
|
||||
sizeof(rose_etsi_indefinite_len) - 2);
|
||||
rose_test_exception(&dummy_ctrl, "Indefinite length (extra)",
|
||||
rose_etsi_indefinite_len, sizeof(rose_etsi_indefinite_len));
|
||||
sizeof(rose_etsi_indefinite_len));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Unused components (indefinite length)",
|
||||
rose_etsi_unused_indefinite_len, sizeof(rose_etsi_unused_indefinite_len) - 2);
|
||||
rose_test_exception(&dummy_ctrl, "Unused components (indefinite length, extra)",
|
||||
rose_etsi_unused_indefinite_len, sizeof(rose_etsi_unused_indefinite_len));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Unused components", rose_etsi_unused,
|
||||
sizeof(rose_etsi_unused) - 2);
|
||||
rose_test_exception(&dummy_ctrl, "Unused components (extra)", rose_etsi_unused,
|
||||
sizeof(rose_etsi_unused));
|
||||
|
||||
dummy_ctrl.switchtype = PRI_SWITCH_QSIG;
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Multiple component messages",
|
||||
rose_qsig_multiple_msg, sizeof(rose_qsig_multiple_msg));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "Alternate name encoded messages",
|
||||
rose_qsig_name_alt_encode_msg, sizeof(rose_qsig_name_alt_encode_msg));
|
||||
|
||||
rose_test_exception(&dummy_ctrl, "2nd edition name encoded messages",
|
||||
rose_qsig_name_2nd_encode_msg, sizeof(rose_qsig_name_2nd_encode_msg));
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"List of operation codes:\n");
|
||||
for (index = 0; index < ROSE_Num_Operation_Codes; ++index) {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, rose_operation2str(index));
|
||||
str = rose_operation2str(index);
|
||||
if (!strncmp(str, "Invalid code:", 13)) {
|
||||
pri_error(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
} else {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
}
|
||||
}
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"************************************************************\n");
|
||||
@@ -2415,7 +2524,12 @@ int main(int argc, char *argv[])
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"List of error codes:\n");
|
||||
for (index = 0; index < ROSE_ERROR_Num_Codes; ++index) {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, rose_error2str(index));
|
||||
str = rose_error2str(index);
|
||||
if (!strncmp(str, "Invalid code:", 13)) {
|
||||
pri_error(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
} else {
|
||||
pri_message(&dummy_ctrl, "%d: %s\n", index, str);
|
||||
}
|
||||
}
|
||||
pri_message(&dummy_ctrl, "\n\n"
|
||||
"************************************************************\n");
|
||||
|
||||
Reference in New Issue
Block a user