This commit is contained in:
Super User 2007-05-30 06:14:41 +02:00
parent b53b484c91
commit 9deb150f2b
14 changed files with 161 additions and 280 deletions

View File

@ -1,4 +1,4 @@
Copyright Andreas Eversberg (jolly@jolly.de)
Copyright Andreas Eversberg (jolly@eversberg.eu)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License

View File

@ -5,7 +5,7 @@
#*---------------------------------------------------------------------------**
#* Copyright: Andreas Eversberg **
#* **
#* Makefile **
#* Makefile **
#* **
#*****************************************************************************/

2
README
View File

@ -1,5 +1,5 @@
Read the documentation at ./doc/ and visit http://isdn.jolly.de.
Read the documentation at ./doc/ and visit http://www.linux-call-router.de
Changes in Version 20021228

27
admin.h
View File

@ -120,12 +120,26 @@ struct admin_call {
int exthlc;
};
struct admin_message {
int type; /* type of message */
unsigned long ref; /* reference to individual endpoints */
union parameter param; /* parameter union */
struct admin_trace_req {
int detail;
char category[4];
char name[64];
int port;
char interface[64];
char caller[34];
char dialing[64];
};
struct admin_trace_rsp {
char text[512];
};
//struct admin_msg {
// int type; /* type of message */
// unsigned long ref; /* reference to individual endpoints */
// union parameter param; /* parameter union */
//};
struct admin_message {
int message; /* type of admin message */
union u {
@ -136,8 +150,9 @@ struct admin_message {
struct admin_response_epoint e;
struct admin_response_call c;
struct admin_call call;
struct admin_message message;
struct admin_trace trace;
// struct admin_msg msg;
struct admin_trace_req trace_req;
struct admin_trace_rsp trace_rsp;
} u;
};

View File

@ -1208,6 +1208,7 @@ next:
char *admin_trace(int sock, int argc, char *argv[])
{
static struct admin_message msg;
int i;
/* show help */
if (!strcasecmp(argv[2], "help"))
@ -1227,111 +1228,55 @@ char *admin_trace(int sock, int argc, char *argv[])
printf(" 0x10 = EP: endpoint trace\n");
printf(" 0x20 = AP: application trace\n");
printf(" 0x40 = RO: routing trace\n");
printf(" port=<mISDN port> select only given port for trace\n");
printf(" interface=<interface name> select only given interface for trace\n");
printf(" caller=<caller id> select only given caller id for trace\n");
printf(" dialing=<number> select only given dialed number for trace\n");
return(NULL);
}
tbd
/* send reload command */
/* init trace request */
memset(&msg, 0, sizeof(msg));
msg.message = ADMIN_CALL_SETUP;
if (argc > 2)
msg.message = ADMIN_TRACE_REQUEST;
msg.u.trace_req.detail = 3;
/* parse args */
i = 2;
while(i < argc)
{
SCPY(msg.u.call.interface, argv[2]);
}
if (argc > 3)
{
SCPY(msg.u.call.callerid, argv[3]);
}
if (argc > 4)
{
SCPY(msg.u.call.dialing, argv[4]);
}
if (argc > 5)
{
if (argv[5][0] == 'p')
msg.u.call.present = 1;
}
msg.u.call.bc_capa = 0x00; /*INFO_BC_SPEECH*/
msg.u.call.bc_mode = 0x00; /*INFO_BMODE_CIRCUIT*/
msg.u.call.bc_info1 = 0;
msg.u.call.hlc = 0;
msg.u.call.exthlc = 0;
if (argc > 6)
msg.u.call.bc_capa = strtol(argv[6],NULL,0);
else
msg.u.call.bc_info1 = 3 | 0x80; /* alaw, if no capability is given at all */
if (argc > 7) {
msg.u.call.bc_mode = strtol(argv[7],NULL,0);
if (msg.u.call.bc_mode) msg.u.call.bc_mode = 2;
}
if (argc > 8) {
msg.u.call.bc_info1 = strtol(argv[8],NULL,0);
if (msg.u.call.bc_info1 < 0)
msg.u.call.bc_info1 = 0;
else
msg.u.call.bc_info1 |= 0x80;
}
if (argc > 9) {
msg.u.call.hlc = strtol(argv[9],NULL,0);
if (msg.u.call.hlc < 0)
msg.u.call.hlc = 0;
else
msg.u.call.hlc |= 0x80;
}
// printf("hlc=%d\n", msg.u.call.hlc);
if (argc > 10) {
msg.u.call.exthlc = strtol(argv[10],NULL,0);
if (msg.u.call.exthlc < 0)
msg.u.call.exthlc = 0;
else
msg.u.call.exthlc |= 0x80;
if (!strcasecmp(argv[i], "brief"))
msg.u.trace_req.detail = 1;
else if (!strcasecmp(argv[i], "short"))
msg.u.trace_req.detail = 2;
else if (!strncasecmp(argv[i], "category=", 9))
SCPY(msg.u.trace_req.category, argv[i]+9);
else if (!strncasecmp(argv[i], "port=", 5))
msg.u.trace_req.port = atoi(argv[i]+5);
else if (!strncasecmp(argv[i], "interface=", 10))
SCPY(msg.u.trace_req.interface, argv[i]+10);
else if (!strncasecmp(argv[i], "caller=", 7))
SCPY(msg.u.trace_req.caller, argv[i]+7);
else if (!strncasecmp(argv[i], "dialing=", 8))
SCPY(msg.u.trace_req.dialing, argv[i]+8);
else return("Invalid trace option, try 'trace help'.");
i++;
}
/* send trace request */
if (write(sock, &msg, sizeof(msg)) != sizeof(msg))
return("Broken pipe while sending command.");
return("Broken pipe while sending trace request.");
/* receive response */
next:
if (read(sock, &msg, sizeof(msg)) != sizeof(msg))
return("Broken pipe while receiving response.");
switch(msg.message)
{
case ADMIN_CALL_SETUP_ACK:
printf("SETUP ACKNOWLEDGE\n"); fflush(stdout);
goto next;
case ADMIN_CALL_PROCEEDING:
printf("PROCEEDING\n"); fflush(stdout);
goto next;
case ADMIN_CALL_ALERTING:
printf("ALERTING\n"); fflush(stdout);
goto next;
case ADMIN_CALL_CONNECT:
printf("CONNECT\n number=%s\n", msg.u.call.callerid); fflush(stdout);
goto next;
case ADMIN_CALL_NOTIFY:
printf("NOTIFY\n notify=%d\n number=%s\n", msg.u.call.notify, msg.u.call.callerid); fflush(stdout);
goto next;
case ADMIN_CALL_DISCONNECT:
printf("DISCONNECT\n cause=%d %s\n location=%d %s\n", msg.u.call.cause, (msg.u.call.cause>0 && msg.u.call.cause<128)?isdn_cause[msg.u.call.cause].german:"", msg.u.call.location, (msg.u.call.location>=0 && msg.u.call.location<128)?isdn_location[msg.u.call.location].german:""); fflush(stdout);
goto next;
case ADMIN_CALL_RELEASE:
printf("RELEASE\n cause=%d %s\n location=%d %s\n", msg.u.call.cause, (msg.u.call.cause>0 && msg.u.call.cause<128)?isdn_cause[msg.u.call.cause].german:"", msg.u.call.location, (msg.u.call.location>=0 && msg.u.call.location<128)?isdn_location[msg.u.call.location].german:""); fflush(stdout);
break;
default:
if (msg.message != ADMIN_TRACE_RESPONSE)
return("Response not valid.");
}
printf("Command successfull.\n");
return(NULL);
printf("%s", msg.u.trace_rsp.text);
goto next;
}
@ -1399,8 +1344,6 @@ int main(int argc, char *argv[])
} else
if (!(strcasecmp(argv[1],"trace")))
{
if (argc <= 2)
goto usage;
mode = MODE_TRACE;
} else
{

View File

@ -135,13 +135,56 @@ EndpointAppPBX::~EndpointAppPBX(void)
}
/*
* trace header for application
*/
void EndpointAppPBX::trace_header(char *name, int direction)
{
char msgtext[sizeof(trace.name)];
SCPY(msgtext, name);
/* add direction */
if (direction)
{
if (p_m_ntmode)
{
if (direction == DIRECTION_OUT)
SCAT(msgtext, " N->U");
else
SCAT(msgtext, " N<-U");
} else
{
if (direction == DIRECTION_OUT)
SCAT(msgtext, " U->N");
else
SCAT(msgtext, " U<-N");
}
}
/* init trace with given values */
start_trace(0,
NULL,
nationalize(e_callerinfo.id, e_callerinfo.ntype),
e_dialinginfo.number,
direction,
CATEGORY_AP,
msgtext);
}
EPOINT_STATE_NAMES
/* set new endpoint state
*/
void EndpointAppPBX::new_state(int state)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) new state %s --> %s\n", ea_endpoint->ep_serial, state_name[e_state], state_name[state]);
if (e_state != state)
{
trace_header("NEW STATE", DIRECTION_NONE);
add_trace("state", "old", "%s", state_name[e_state]);
add_trace("state", "new", "%s", state_name[state]);
}
e_state = state;
}

View File

@ -45,7 +45,6 @@ Pdss1::Pdss1(int type, mISDNport *mISDNport, char *portname, struct port_setting
p_m_d_collect_cause = CAUSE_NOUSER;
p_m_d_collect_location = LOCATION_PRIVATE_LOCAL;
PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, %s port #%d\n", portname, mISDNport->use, (mISDNport->ntmode)?"NT":"TE", p_m_portnum);
}
@ -326,14 +325,12 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
}
/* if channel was not accepted, try to get it */
PDEBUG(DEBUG_BCHANNEL, "- our suggested channel %d was not accepted, but %d was given.\n", p_m_b_channel, channel);
ret = seize_bchannel(channel, 1); // exclusively
add_trace("channel", "available", ret<0?"no":"yes");
if (ret < 0)
{
add_trace("conclusion", NULL, "replied channel not available");
end_trace();
PDEBUG(DEBUG_BCHANNEL, "- the replied channel %d is not available (cause %d).\n", channel, -ret);
goto channelerror;
}
add_trace("conclusion", NULL, "replied channel accepted");
@ -444,7 +441,6 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
}
/* we will see, if our received channel is available */
PDEBUG(DEBUG_BCHANNEL, "- our during call-waiting, we get channel %d as first reply.\n", channel);
use_from_connect:
ret = seize_bchannel(channel, exclusive);
add_trace("channel", "available", ret<0?"no":"yes");
@ -910,7 +906,6 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
exit(-1);
}
/* send setup message to endpoit */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup: %s->%s\n", p_name, p_callerinfo.id, p_dialinginfo.number);
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
message->param.setup.isdn_port = p_m_portnum;
message->param.setup.port_type = p_type;
@ -1258,7 +1253,6 @@ void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data)
end_trace();
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect (to '%s' COLP: '%s')\n", p_name, p_dialinginfo.number, p_connectinfo.id);
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
memcpy(&message->param.connectinfo, &p_connectinfo, sizeof(struct connect_info));
message_put(message);
@ -1289,11 +1283,11 @@ void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data)
RELEASE_t *release;
msg_t *dmsg;
PDEBUG(DEBUG_ISDN, "Pdss1(%s) send release because remote disconnects AND provides no patterns (earlyb).\n", p_name);
dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, dinfo, sizeof(RELEASE_t), p_m_d_ntmode);
release = (RELEASE_t *)(dmsg->data + headerlen);
l3_trace_header(CC_RELEASE | REQUEST, DIRECTION_OUT);
enc_ie_cause(&release->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, 16); /* normal */
add_trace("reason", NULL, "no remote patterns");
end_trace();
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
@ -1451,7 +1445,6 @@ void Pdss1::release_complete_ind(unsigned long prim, unsigned long dinfo, void *
free_epointlist(p_epointlist);
}
PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete (cause %d)\n", p_name, cause);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
}
@ -1474,7 +1467,6 @@ void Pdss1::t312_timeout(unsigned long prim, unsigned long dinfo, void *data)
free_epointlist(p_epointlist);
}
PDEBUG(DEBUG_ISDN, "Pdss1(%s) t312_timeout (collected cause %d location %d)\n", p_name, p_m_d_collect_cause, p_m_d_collect_location);
new_state(PORT_STATE_RELEASE);
p_m_delete = 1;
}
@ -1493,10 +1485,7 @@ void Pdss1::notify_ind(unsigned long prim, unsigned long dinfo, void *data)
end_trace();
if (!ACTIVE_EPOINT(p_epointlist))
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) there is no active endpoint to notify to.\n", p_name);
return;
}
/* notification indicator */
if (notify < 0)
return;
@ -1556,13 +1545,11 @@ void Pdss1::hold_ind(unsigned long prim, unsigned long dinfo, void *data)
if (!ACTIVE_EPOINT(p_epointlist) || p_m_hold)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) there is no endpoint to notify hold OR we are already on hold, so we reject.\n", p_name);
dmsg = create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, dinfo, sizeof(HOLD_REJECT_t), p_m_d_ntmode);
hold_reject = (HOLD_REJECT_t *)(dmsg->data + headerlen);
l3_trace_header(CC_HOLD_REJECT | REQUEST, DIRECTION_OUT);
enc_ie_cause(&hold_reject->CAUSE, dmsg, (p_m_d_ntmode)?LOCATION_PRIVATE_LOCAL:LOCATION_PRIVATE_REMOTE, p_m_hold?101:31); /* normal unspecified / incompatible state */
add_trace("reason", NULL, "no endpoint");
end_trace();
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
@ -1628,7 +1615,6 @@ void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data)
{
cause = 101; /* incompatible state */
reject:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) we are not on hold, so we reject (cazse %d).\n", p_name, cause);
dmsg = create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, dinfo, sizeof(RETRIEVE_REJECT_t), p_m_d_ntmode);
retrieve_reject = (RETRIEVE_REJECT_t *)(dmsg->data + headerlen);
@ -1765,7 +1751,6 @@ void Pdss1::suspend_ind(unsigned long prim, unsigned long dinfo, void *data)
if (epoint->ep_park_len == len)
if (!memcmp(epoint->ep_park_callid, callid, len))
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) call id is in use, so we reject.\n", p_name);
ret = -84; /* call id in use */
goto reject;
}
@ -1907,10 +1892,7 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data)
epoint = epoint->next;
}
if (!epoint)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) no suspended call, so we reject with cause %d.\n", p_name, ret);
goto reject;
}
if (!(epointlist_new(epoint->ep_serial)))
{
@ -1922,7 +1904,6 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data)
PERROR("no memory for portlist\n");
exit(-1);
}
PDEBUG(DEBUG_ISDN, "Pdss1(%s) resume\n", p_name);
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RESUME);
message_put(message);
@ -1961,7 +1942,6 @@ void Pdss1::facility_ind(unsigned long prim, unsigned long dinfo, void *data)
if (facil_len<=0)
return;
PDEBUG(DEBUG_ISDN, "Pdss1(%s) facility\n", p_name);
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_FACILITY);
message->param.facilityinfo.len = facil_len;
memcpy(message->param.facilityinfo.data, facil, facil_len);
@ -1996,12 +1976,8 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
break;
case CC_SETUP | INDICATION:
PDEBUG((DEBUG_BCHANNEL|DEBUG_ISDN), "Pdss1(%s) setup\n", p_name);
if (p_state != PORT_STATE_IDLE)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup again, IGNORING.\n", p_name);
break;
}
setup_ind(prim, dinfo, data);
break;
@ -2018,61 +1994,55 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
end_trace();
}
end_trace;
PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup confirm (l3id=0x%x)\n", p_name, p_m_d_l3id);
break;
case CC_INFORMATION | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) information\n", p_name);
information_ind(prim, dinfo, data);
break;
case CC_SETUP_ACKNOWLEDGE | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) setup acknowledge\n", p_name);
if (p_state != PORT_STATE_OUT_SETUP)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
PERROR("Pdss1(%s) received setup_acknowledge, but we are not in outgoing setup state, IGNORING.\n", p_name);
break;
}
setup_acknowledge_ind(prim, dinfo, data);
break;
case CC_PROCEEDING | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) proceeding\n", p_name);
if (p_state != PORT_STATE_OUT_SETUP
&& p_state != PORT_STATE_OUT_OVERLAP)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
PERROR("Pdss1(%s) received proceeding, but we are not in outgoing setup OR overlap state, IGNORING.\n", p_name);
break;
}
proceeding_ind(prim, dinfo, data);
break;
case CC_ALERTING | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) alerting\n", p_name);
if (p_state != PORT_STATE_OUT_SETUP
&& p_state != PORT_STATE_OUT_OVERLAP
&& p_state != PORT_STATE_OUT_PROCEEDING)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
PERROR("Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding state, IGNORING.\n", p_name);
break;
}
alerting_ind(prim, dinfo, data);
break;
case CC_CONNECT | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect\n", p_name);
if (p_state != PORT_STATE_OUT_SETUP
&& p_state != PORT_STATE_OUT_OVERLAP
&& p_state != PORT_STATE_OUT_PROCEEDING
&& p_state != PORT_STATE_OUT_ALERTING)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING.\n", p_name);
PERROR("Pdss1(%s) received alerting, but we are not in outgoing setup OR overlap OR proceeding OR ALERTING state, IGNORING.\n", p_name);
break;
}
connect_ind(prim, dinfo, data);
if (p_m_d_notify_pending)
{
PDEBUG(DEBUG_ISDN, "received or connect, so we send pending notify message.\n");
/* send pending notify message during connect */
message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
message_free(p_m_d_notify_pending);
p_m_d_notify_pending = NULL;
@ -2081,12 +2051,11 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
case CC_CONNECT_ACKNOWLEDGE | INDICATION:
case CC_CONNECT | CONFIRM:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect_acknowlege.\n", p_name);
if (p_state == PORT_STATE_CONNECT_WAITING)
new_state(PORT_STATE_CONNECT);
if (p_m_d_notify_pending)
{
PDEBUG(DEBUG_ISDN, "received or connect-ack, so we send pending notify message.\n");
/* send pending notify message during connect-ack */
message_notify(ACTIVE_EPOINT(p_epointlist), p_m_d_notify_pending->type, &p_m_d_notify_pending->param);
message_free(p_m_d_notify_pending);
p_m_d_notify_pending = NULL;
@ -2094,53 +2063,42 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
break;
case CC_DISCONNECT | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) disconnect\n", p_name);
disconnect_ind(prim, dinfo, data);
break;
case CC_RELEASE | CONFIRM:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) release confirm\n", p_name);
case CC_RELEASE | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) release\n", p_name);
release_ind(prim, dinfo, data);
break;
case CC_RELEASE_COMPLETE | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete.\n", p_name);
release_complete_ind(prim, dinfo, data);
break;
case CC_RELEASE_COMPLETE | CONFIRM:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) release_complete (confirm).\n", p_name);
break;
case CC_NOTIFY | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) notify\n", p_name);
notify_ind(prim, dinfo, data);
break;
case CC_HOLD | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) hold\n", p_name);
hold_ind(prim, dinfo, data);
break;
case CC_RETRIEVE | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) retrieve\n", p_name);
retrieve_ind(prim, dinfo, data);
break;
case CC_SUSPEND | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) suspend\n", p_name);
suspend_ind(prim, dinfo, data);
break;
case CC_RESUME | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) resume\n", p_name);
resume_ind(prim, dinfo, data);
break;
case CC_FACILITY | INDICATION:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) facility\n", p_name);
facility_ind(prim, dinfo, data);
break;
@ -2262,7 +2220,6 @@ int Pdss1::handler(void)
/* handle destruction */
if (p_m_delete && p_m_d_l3id==0)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) doing pending release.\n", p_name);
delete this;
return(-1);
}
@ -2611,8 +2568,6 @@ void Pdss1::message_facility(unsigned long epoint_id, int message_id, union para
if (!p_m_d_ntmode)
return;
PDEBUG(DEBUG_ISDN, "Pdss1(%s) sending facility message\n", p_name);
/* sending facility */
dmsg = create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, p_m_d_l3id, sizeof(FACILITY_t), p_m_d_ntmode);
facility = (FACILITY_t *)(dmsg->data + headerlen);
@ -2632,7 +2587,6 @@ void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parame
int plan, type = -1, present;
msg_t *dmsg;
PDEBUG(DEBUG_ISDN, "Pdss1(%s) sending information message\n", p_name);
if (param->notifyinfo.notify>INFO_NOTIFY_NONE)
notify = param->notifyinfo.notify & 0x7f;
else
@ -2681,7 +2635,7 @@ void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parame
if (notify<0 && !param->notifyinfo.display[0])
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) nothing to notify, nothing to display\n", p_name);
/* nothing to notify, nothing to display */
return;
}
@ -2690,7 +2644,6 @@ void Pdss1::message_notify(unsigned long epoint_id, int message_id, union parame
if (p_state!=PORT_STATE_CONNECT)
{
/* queue notification */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) queueing notification because isdn port is not active state.\n", p_name);
if (p_m_d_notify_pending)
message_free(p_m_d_notify_pending);
p_m_d_notify_pending = message_create(ACTIVE_EPOINT(p_epointlist), p_serial, EPOINT_TO_PORT, message_id);
@ -2872,7 +2825,7 @@ void Pdss1::message_connect(unsigned long epoint_id, int message_id, union param
if (p_state!=PORT_STATE_IN_SETUP && p_state!=PORT_STATE_IN_OVERLAP && p_state!=PORT_STATE_IN_PROCEEDING && p_state!=PORT_STATE_IN_ALERTING)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) connect command only possible in setup, proceeding or alerting state.\n", p_name);
/* connect command only possible in setup, proceeding or alerting state */
return;
}
@ -3147,14 +3100,12 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet
switch(message_id)
{
case MESSAGE_INFORMATION: /* overlap dialing */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) received dialing info '%s'.\n", p_name, param->information.number);
if (p_type==PORT_TYPE_DSS1_NT_OUT
&& p_state!=PORT_STATE_OUT_OVERLAP
&& p_state!=PORT_STATE_CONNECT
&& p_state!=PORT_STATE_OUT_DISCONNECT
&& p_state!=PORT_STATE_IN_DISCONNECT)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) (internal outgoing) ignoring information, invalid state.\n", p_name);
break;
}
if (p_type==PORT_TYPE_DSS1_TE_OUT
@ -3165,8 +3116,6 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet
&& p_state!=PORT_STATE_OUT_DISCONNECT
&& p_state!=PORT_STATE_IN_DISCONNECT)
{
if (options.deb & DEBUG_ISDN)
PERROR("Pdss1(%s) (external outgoing) ignoring information, invalid state.\n", p_name);
break;
}
if ((p_type==PORT_TYPE_DSS1_NT_IN || p_type==PORT_TYPE_DSS1_TE_IN)
@ -3178,14 +3127,12 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet
&& p_state!=PORT_STATE_OUT_DISCONNECT
&& p_state!=PORT_STATE_IN_DISCONNECT)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) (incoming) ignoring information, invalid state.\n", p_name);
break;
}
message_information(epoint_id, message_id, param);
break;
case MESSAGE_SETUP: /* dial-out command received from epoint */
PDEBUG((DEBUG_ISDN | DEBUG_BCHANNEL), "Pdss1(%s) isdn port received setup from '%s' to '%s'\n", p_name, param->setup.callerinfo.id, param->setup.dialinginfo.number);
if (p_state!=PORT_STATE_IDLE
&& p_state!=PORT_STATE_CONNECT)
{
@ -3226,64 +3173,53 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet
break;
case MESSAGE_NOTIFY: /* display and notifications */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received notification: display='%s' notify=%d phone=%s\n", p_name, p_callerinfo.id, param->notifyinfo.display, param->notifyinfo.notify, param->notifyinfo.id);
message_notify(epoint_id, message_id, param);
break;
case MESSAGE_FACILITY: /* facility message */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received facility.\n", p_name, p_callerinfo.id);
message_facility(epoint_id, message_id, param);
break;
case MESSAGE_OVERLAP: /* more information is needed */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received setup acknowledge\n", p_name, p_callerinfo.id);
if (p_state!=PORT_STATE_IN_SETUP)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring setup acknowledge because isdn port is not incoming setup state.\n", p_name);
break;
}
message_overlap(epoint_id, message_id, param);
break;
case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received proceeding\n", p_name, p_callerinfo.id);
if (p_state!=PORT_STATE_IN_SETUP
&& p_state!=PORT_STATE_IN_OVERLAP)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: proceeding command not possible in current state.\n", p_name);
break;
}
message_proceeding(epoint_id, message_id, param);
break;
case MESSAGE_ALERTING: /* call of endpoint is ringing */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received alerting\n", p_name, p_callerinfo.id);
if (p_state!=PORT_STATE_IN_SETUP
&& p_state!=PORT_STATE_IN_OVERLAP
&& p_state!=PORT_STATE_IN_PROCEEDING)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: alerting command not possible in current state.\n", p_name);
break;
}
message_alerting(epoint_id, message_id, param);
break;
case MESSAGE_CONNECT: /* call of endpoint is connected */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received connect\n", p_name, p_callerinfo.id);
if (p_state!=PORT_STATE_IN_SETUP
&& p_state!=PORT_STATE_IN_OVERLAP
&& p_state!=PORT_STATE_IN_PROCEEDING
&& p_state!=PORT_STATE_IN_ALERTING
&& !(p_state==PORT_STATE_CONNECT && p_m_d_ntmode))
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: connect command not possible in current state.\n", p_name);
break;
}
message_connect(epoint_id, message_id, param);
break;
case MESSAGE_DISCONNECT: /* call has been disconnected */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received disconnect cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
if (p_state!=PORT_STATE_IN_SETUP
&& p_state!=PORT_STATE_IN_OVERLAP
&& p_state!=PORT_STATE_IN_PROCEEDING
@ -3295,24 +3231,21 @@ int Pdss1::message_epoint(unsigned long epoint_id, int message_id, union paramet
&& p_state!=PORT_STATE_CONNECT
&& p_state!=PORT_STATE_CONNECT_WAITING)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: disconnect command not possible in current state.\n", p_name);
break;
}
message_disconnect(epoint_id, message_id, param);
break;
case MESSAGE_RELEASE: /* release isdn port */
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received release cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
if (p_state==PORT_STATE_RELEASE)
{
PDEBUG(DEBUG_ISDN, "Pdss1(%s) ignoring: release command not possible in RELEASE state.\n", p_name);
break;
}
message_release(epoint_id, message_id, param);
break;
default:
PDEBUG(DEBUG_ISDN, "Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message);
PERROR("Pdss1(%s) isdn port with (caller id %s) received a wrong message: %d\n", p_name, p_callerinfo.id, message);
}
return(1);
@ -3460,14 +3393,14 @@ int stack2manager_nt(void *dat, void *arg)
break;
case CC_RELEASE_CR | INDICATION:
PDEBUG(DEBUG_ISDN, "%s: unhandled message from stack: call ref released (l3id=0x%x)\n", __FUNCTION__, hh->dinfo);
PERROR("unhandled message from stack: call ref released (l3id=0x%x)\n", hh->dinfo);
break;
case CC_DISCONNECT | INDICATION:
// fall throug
default:
PDEBUG(DEBUG_ISDN, "%s: unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", __FUNCTION__, hh->prim, hh->dinfo, msg->len);
PERROR("unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, msg->len);
return(-EINVAL);
}
free_msg(msg);
@ -3494,7 +3427,6 @@ int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg)
if (port->p_type == PORT_TYPE_DSS1_TE_IN || port->p_type == PORT_TYPE_DSS1_TE_OUT)
{
pdss1 = (class Pdss1 *)port;
//PDEBUG(DEBUG_ISDN, "comparing dinfo = 0x%x with l3id 0x%x\n", frm->dinfo, pdss1->p_m_d_l3id);
/* check out correct stack */
if (pdss1->p_m_mISDNport == mISDNport)
/* check out correct id */
@ -3541,11 +3473,11 @@ int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg)
if (frm->prim == (CC_RELEASE_CR | INDICATION))
{
PDEBUG(DEBUG_ISDN, "unhandled message from stack: call ref released (l3id=0x%x)\n", frm->dinfo);
PERROR("unhandled message from stack: call ref released (l3id=0x%x)\n", frm->dinfo);
free_msg(msg);
return(0);
}
PDEBUG(DEBUG_ISDN, "unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
PERROR("unhandled message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, msg->len);
return(-EINVAL);
}

View File

@ -193,7 +193,7 @@ static void bchannel_activate(struct mISDNport *mISDNport, int i)
/* if we are active, we configure our channel */
if (mISDNport->b_state[i] == B_STATE_ACTIVE)
{
unsigned char buffer[mISDN_HEADER_LEN+ISDN_PRELOAD];
unsigned char buffer[mISDN_HEADER_LEN+(ISDN_PRELOAD<<3)];
iframe_t *pre = (iframe_t *)buffer; /* preload data */
unsigned char *p = (unsigned char *)&pre->data.p;
@ -527,7 +527,7 @@ int PmISDN::handler(void)
elapsed = 1000 * (now_tv.sec - p_last_tv_sec)
+ (now_tv.usec/1000) - p_last_tv_msec;
/* gap was greater preload, so only fill up to preload level */
if (elapsed > ISDN_PRELOAD)
if (elapsed > (ISDN_PRELOAD<<3))
{
elapsed = ISDN_PRELOAD << 3
}
@ -1610,20 +1610,6 @@ struct mISDNport *mISDN_port_open(int port, int ptp, int ptmp)
PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
nt = 1;
break;
case ISDN_PID_L0_TE_U:
PDEBUG(DEBUG_ISDN, "TE-mode BRI U interface line\n");
break;
case ISDN_PID_L0_NT_U:
PDEBUG(DEBUG_ISDN, "NT-mode BRI U interface port\n");
nt = 1;
break;
case ISDN_PID_L0_TE_UP2:
PDEBUG(DEBUG_ISDN, "TE-mode BRI Up2 interface line\n");
break;
case ISDN_PID_L0_NT_UP2:
PDEBUG(DEBUG_ISDN, "NT-mode BRI Up2 interface port\n");
nt = 1;
break;
case ISDN_PID_L0_TE_E1:
PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
pri = 1;
@ -2098,20 +2084,6 @@ void mISDN_port_info(void)
if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
printf(" HFC multiport card");
#endif
break;
case ISDN_PID_L0_TE_U:
printf("TE-mode BRI U interface line");
break;
case ISDN_PID_L0_NT_U:
nt = 1;
printf("NT-mode BRI U interface port");
break;
case ISDN_PID_L0_TE_UP2:
printf("TE-mode BRI Up2 interface line");
break;
case ISDN_PID_L0_NT_UP2:
nt = 1;
printf("NT-mode BRI Up2 interface port");
break;
case ISDN_PID_L0_TE_E1:
pri = 1;

7
main.c
View File

@ -264,13 +264,6 @@ int main(int argc, char *argv[])
goto free;
}
/* check if we have a jitter limit that makes sense */
if (ISDN_JITTERLIMIT < 256)
{
fprintf(stderr, "The ISDN_JITTERLIMIT must be at least 256 samples.\n");
goto free;
}
/* init crc */
crc_init();

2
main.h
View File

@ -113,7 +113,7 @@ void _printerror(const char *function, int line, const char *fmt, ...);
extern "C" {
#endif
#include <isdn_net.h>
#include <net_l3.h>
#include <../i4lnet/net_l3.h>
#ifdef __cplusplus
}
#endif

View File

@ -35,7 +35,7 @@ struct options options = {
"", /* dummy caller id */
0, /* use tones by dsp.o */
0, /* by default use priority 0 */
"pbx@jolly.de" /* source mail adress */
"lcr@your.machine" /* source mail adress */
};
/* read options

View File

@ -1,5 +1,3 @@
define and change dsp conference ids
make asterisk call implementation
new interface.conf (add remove ports by admin)

87
trace.c
View File

@ -11,8 +11,7 @@
#include "main.h"
struct trace trace[MAX_NESTED_TRACES];
int trace_current = -1;
struct trace trace;
char trace_string[MX_TRACE_ELEMENTS * 100 + 400];
static char *spaces[11] = {
@ -35,27 +34,23 @@ static char *spaces[11] = {
*/
void start_trace(int port, char *interface, char *caller, char *dialing, int direction, char *category, char *name);
{
if (++trace_current == MAX_NESTED_TRACES)
{
PERROR("maximum nesting level of traces exceeding: %d, exitting!\n", MAX_NESTED_TRACES);
PERROR("last trace=%s\n", trace[MAX_NESTED_TRACE-1].name);
exit(-1);
}
memset(trace[trace_current], 0, sizeof(struct trace));
trace[trace_current].port = port;
if (trace.name[0])
PERROR("trace already started (name=%s)\n", trace.name);
memset(trace, 0, sizeof(struct trace));
trace.port = port;
if (interface) if (interface[0])
SCPY(trace[trace_current].interface, interface);
SCPY(trace.interface, interface);
if (caller) if (caller[0])
SCPY(trace[trace_current].caller, caller);
SCPY(trace.caller, caller);
if (dialing) if (dialing[0])
SCPY(trace[trace_current].dialing, dialing);
trace[trace_current].direction = direction;
SCPY(trace.dialing, dialing);
trace.direction = direction;
if (category) if (category[0])
SCPY(trace[trace_current].category, category);
SCPY(trace.category, category);
if (name) if (name[0])
SCPY(trace[trace_current].name, name);
trace[trace_current].sec = now_tv.tv_sec;
trace[trace_current].usec = now_tv.tv_usec;
SCPY(trace.name, name);
trace.sec = now_tv.tv_sec;
trace.usec = now_tv.tv_usec;
}
@ -68,19 +63,8 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
{
va_list args;
/* check nesting */
if (trace_current < 0)
{
PERROR("add_trace called without start_trace, exitting.\n");
exit(0);
}
/* check for space */
if (trace[trace_current].elements == MAX_TRACE_ELEMENTS)
{
PERROR("trace with name=%s exceeds the maximum number of elements (%d)\n", trace.name, MAX_TRACE_ELEMENTS);
return;
}
if (!trace.name[0])
PERROR("trace not started\n");
/* check for required name value */
if (!name)
@ -93,18 +77,18 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
}
/* write name, sub and value */
SCPY(trace[trace_current].element[trace[trace_current].elements].name, name);
SCPY(trace.element[trace.elements].name, name);
if (sub) if (sub[0])
SCPY(trace[trace_current].element[trace[trace_current].elements].sub, sub);
SCPY(trace.element[trace.elements].sub, sub);
if (fmt) if (fmt[0])
{
va_start(args, fmt);
VUNPRINT(trace[trace_current].element[trace[trace_current].element].value, sizeof(trace[trace_current].element[trace[trace_current].elements].value)-1, fmt, args);
VUNPRINT(trace.element[trace.element].value, sizeof(trace.element[trace.elements].value)-1, fmt, args);
va_end(args);
}
/* increment elements */
trace[trace_current].elements++;
trace.elements++;
}
@ -114,12 +98,8 @@ void add_trace(char *name, char *sub, const char *fmt, ...);
*/
void end_trace(void);
{
/* check nesting */
if (trace_current < 0)
{
PERROR("end_trace called without start_trace, exitting.\n");
exit(0);
}
if (!trace.name[0])
PERROR("trace not started\n");
/* process log file */
if (options.log[0])
@ -128,8 +108,7 @@ void end_trace(void);
fwrite(string, strlen(string), 1, fp);
}
/* reduce nesting level */
trace_current--;
memset(trace, 0, sizeof(struct trace));
}
@ -137,7 +116,7 @@ void end_trace(void);
* prints trace to socket or log
* detail: 1 = brief, 2=short, 3=long
*/
static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, int direction, char *category);
static char *print_trace(int detail, int port, char *interface, char *caller, char *dialing, char *category);
{
trace_string[0] = '\0';
char buffer[256];
@ -155,8 +134,6 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
if (!!strcasecmp(caller, trace.caller)) return;
if (dialing && dialing[0] && trace.dialing[0])
if (!!strcasecmp(dialing, trace.dialing)) return;
if (direction && trace.direction)
if (direction != trace.direction) return;
if (category && category[0] && trace.category[0])
if (!!strcasecmp(category, trace.category)) return;
@ -237,9 +214,14 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
buffer[0] = '\0';
SCAT(trace_string, buffer);
if (trace.element[i].sub[0])
SPRINT(buffer, " %s=%s", trace.element[i].sub, value);
SPRINT(buffer, " %s=", trace.element[i].sub, value);
else
SPRINT(buffer, " %s", value);
SPRINT(buffer, " ", value);
SCAT(trace_string, buffer);
if (strchr(value, ' '))
SPRINT(buffer, "'%s'", value);
else
SPRINT(buffer, "%s", value);
SCAT(trace_string, buffer);
i++;
}
@ -257,9 +239,14 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
SPRINT(buffer, " ");
SCAT(trace_string, buffer);
if (trace.element[i].sub[0])
SPRINT(buffer, " : %s%s = %s\n", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
SPRINT(buffer, " : %s%s = ", trace.element[i].sub, spaces[strlen(trace.element[i].sub)], value);
else
SPRINT(buffer, " : %s\n", value);
SPRINT(buffer, " : ", value);
SCAT(trace_string, buffer);
if (strchr(value, ' '))
SPRINT(buffer, "'%s'\n", value);
else
SPRINT(buffer, "%s\n", value);
SCAT(trace_string, buffer);
i++;
}

View File

@ -15,8 +15,6 @@ struct trace_element {
char value[64];
};
#define MAX_NESTED_TRACES 1
#define MAX_TRACE_ELEMENTS 32
struct trace {
/* header */
@ -28,7 +26,7 @@ struct trace {
unsigned long sec, usec;
/* type */
char category[32];
char category[4];
char name[64];
/* elements */