alpha phase is open, this means:
it compiles! it runs! it calls without known bug yet! comments to jolly@eversberg.eu
This commit is contained in:
parent
a54078ccf0
commit
5a22e57828
24
Makefile
24
Makefile
|
@ -124,14 +124,14 @@ endpointapp.o: endpointapp.cpp *.h Makefile
|
|||
apppbx.o: apppbx.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) apppbx.cpp -o apppbx.o
|
||||
|
||||
call.o: call.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) call.cpp -o call.o
|
||||
join.o: join.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) join.cpp -o join.o
|
||||
|
||||
callpbx.o: callpbx.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) callpbx.cpp -o callpbx.o
|
||||
joinpbx.o: joinpbx.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) joinpbx.cpp -o joinpbx.o
|
||||
|
||||
callasterisk.o: callasterisk.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) callasterisk.cpp -o callasterisk.o
|
||||
joinasterisk.o: joinasterisk.cpp *.h Makefile
|
||||
$(CC) -c $(CFLAGS) joinasterisk.cpp -o joinasterisk.o
|
||||
|
||||
cause.o: cause.c *.h Makefile
|
||||
$(CC) -c $(CFLAGS) cause.c -o cause.o
|
||||
|
@ -180,9 +180,9 @@ $(LCR): main.o \
|
|||
action_vbox.o \
|
||||
action_efi.o \
|
||||
mail.o \
|
||||
call.o \
|
||||
callpbx.o \
|
||||
callasterisk.o \
|
||||
join.o \
|
||||
joinpbx.o \
|
||||
joinasterisk.o \
|
||||
admin_server.o \
|
||||
trace.o
|
||||
$(LD) $(LIBDIR) \
|
||||
|
@ -207,9 +207,9 @@ $(LCR): main.o \
|
|||
action_vbox.o \
|
||||
action_efi.o \
|
||||
mail.o \
|
||||
call.o \
|
||||
callpbx.o \
|
||||
callasterisk.o \
|
||||
join.o \
|
||||
joinpbx.o \
|
||||
joinasterisk.o \
|
||||
admin_server.o \
|
||||
trace.o \
|
||||
$(LIBS) -o $(LCR)
|
||||
|
|
2
README
2
README
|
@ -354,7 +354,9 @@ Changes in Version 1.0
|
|||
- Asterisk channel driver integrated
|
||||
- Multiplexing calls to multiple extensions
|
||||
- Removed all VoIP stuff to make core fast and stable (Use Asterisk for VoIP.)
|
||||
- Fixed a bug that caused some isdn connections to hang during disconnect
|
||||
- Many bug fixes
|
||||
- Many minor improvements
|
||||
- New bugs of course...
|
||||
- Rename of 'Call' instances to 'Join', because they join parties together.
|
||||
|
||||
|
|
114
action.cpp
114
action.cpp
|
@ -71,12 +71,12 @@ char *numberrize_callerinfo(char *string, int ntype)
|
|||
*/
|
||||
void EndpointAppPBX::_action_init_call(int asterisk)
|
||||
{
|
||||
class Call *call;
|
||||
class Join *join;
|
||||
struct port_list *portlist = ea_endpoint->ep_portlist;
|
||||
struct admin_list *admin;
|
||||
|
||||
/* a created call, this should never happen */
|
||||
if (ea_endpoint->ep_call_id)
|
||||
if (ea_endpoint->ep_join_id)
|
||||
{
|
||||
if (options.deb & DEBUG_EPOINT)
|
||||
PERROR("EPOINT(%d): We already have a call instance, this should never happen!\n", ea_endpoint->ep_serial);
|
||||
|
@ -102,13 +102,13 @@ void EndpointAppPBX::_action_init_call(int asterisk)
|
|||
set_tone(portlist,"cause_22");
|
||||
return;
|
||||
}
|
||||
call = new CallAsterisk(ea_endpoint->ep_serial);
|
||||
join = new JoinAsterisk(ea_endpoint->ep_serial);
|
||||
}
|
||||
else
|
||||
call = new CallPBX(ea_endpoint);
|
||||
if (!call)
|
||||
join = new JoinPBX(ea_endpoint);
|
||||
if (!join)
|
||||
FATAL("No memoy for Call instance.\n");
|
||||
ea_endpoint->ep_call_id = call->c_serial;
|
||||
ea_endpoint->ep_join_id = join->c_serial;
|
||||
}
|
||||
void EndpointAppPBX::action_init_call(void)
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ void EndpointAppPBX::action_dialing_internal(void)
|
|||
set_tone(portlist, "proceeding");
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
new_state(EPOINT_STATE_IN_PROCEEDING);
|
||||
|
||||
/* create bearer/caller/dialinginfo */
|
||||
|
@ -217,7 +217,7 @@ void EndpointAppPBX::action_dialing_internal(void)
|
|||
trace_header("ACTION extension (calling)", DIRECTION_NONE);
|
||||
add_trace("extension", NULL, dialinginfo.id);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
|
||||
|
@ -342,7 +342,7 @@ void EndpointAppPBX::action_dialing_external(void)
|
|||
{
|
||||
trace_header("ACTION extern (calling denied)", DIRECTION_NONE);
|
||||
end_trace();
|
||||
release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
set_tone(portlist, "cause_82");
|
||||
denied:
|
||||
message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
|
||||
|
@ -359,7 +359,7 @@ void EndpointAppPBX::action_dialing_external(void)
|
|||
{
|
||||
trace_header("ACTION extern (national calls denied)", DIRECTION_NONE);
|
||||
end_trace();
|
||||
release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
set_tone(portlist, "cause_83");
|
||||
goto denied;
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ void EndpointAppPBX::action_dialing_external(void)
|
|||
{
|
||||
trace_header("ACTION extern (international calls denied)", DIRECTION_NONE);
|
||||
end_trace();
|
||||
release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, 0);
|
||||
set_tone(portlist, "cause_84");
|
||||
goto denied;
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ void EndpointAppPBX::action_dialing_external(void)
|
|||
if (dialinginfo.interfaces[0])
|
||||
add_trace("interfaces", NULL, dialinginfo.interfaces);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
|
||||
|
@ -457,7 +457,7 @@ void EndpointAppPBX::action_dialing_vbox_record(void)
|
|||
set_tone(portlist, "proceeding");
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
new_state(EPOINT_STATE_IN_PROCEEDING);
|
||||
|
||||
memset(&dialinginfo, 0, sizeof(dialinginfo));
|
||||
|
@ -477,7 +477,7 @@ void EndpointAppPBX::action_dialing_vbox_record(void)
|
|||
trace_header("ACTION vbox-record (calling)", DIRECTION_NONE);
|
||||
add_trace("extension", NULL, "%s", dialinginfo.id);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.callerinfo, &e_callerinfo, sizeof(struct caller_info));
|
||||
|
@ -491,13 +491,13 @@ void EndpointAppPBX::action_dialing_vbox_record(void)
|
|||
*/
|
||||
void EndpointAppPBX::action_init_partyline(void)
|
||||
{
|
||||
class Call *call;
|
||||
class CallPBX *callpbx;
|
||||
class Join *join;
|
||||
class JoinPBX *joinpbx;
|
||||
struct port_list *portlist = ea_endpoint->ep_portlist;
|
||||
struct message *message;
|
||||
struct route_param *rparam;
|
||||
int partyline;
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
|
||||
portlist = ea_endpoint->ep_portlist;
|
||||
|
||||
|
@ -522,30 +522,30 @@ void EndpointAppPBX::action_init_partyline(void)
|
|||
}
|
||||
partyline = rparam->integer_value;
|
||||
|
||||
/* don't create call if partyline exists */
|
||||
call = call_first;
|
||||
while(call)
|
||||
/* don't create join if partyline exists */
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
if (call->c_type == CALL_TYPE_PBX)
|
||||
if (join->c_type == JOIN_TYPE_PBX)
|
||||
{
|
||||
callpbx = (class CallPBX *)call;
|
||||
if (callpbx->c_partyline == rparam->integer_value)
|
||||
joinpbx = (class JoinPBX *)join;
|
||||
if (joinpbx->c_partyline == rparam->integer_value)
|
||||
break;
|
||||
}
|
||||
call = call->next;
|
||||
join = join->next;
|
||||
}
|
||||
if (!call)
|
||||
if (!join)
|
||||
{
|
||||
/* create call */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new call instance.\n", ea_endpoint->ep_serial);
|
||||
if (!(call = new CallPBX(ea_endpoint)))
|
||||
FATAL("No memory for Call object\n");
|
||||
/* create join */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new join instance.\n", ea_endpoint->ep_serial);
|
||||
if (!(join = new JoinPBX(ea_endpoint)))
|
||||
FATAL("No memory for join object\n");
|
||||
} else
|
||||
{
|
||||
//NOTE: callpbx must be set here
|
||||
/* add relation to existing call */
|
||||
if (!(relation=callpbx->add_relation()))
|
||||
FATAL("No memory for Call relation\n");
|
||||
//NOTE: joinpbx must be set here
|
||||
/* add relation to existing join */
|
||||
if (!(relation=joinpbx->add_relation()))
|
||||
FATAL("No memory for join relation\n");
|
||||
relation->type = RELATION_TYPE_SETUP;
|
||||
relation->channel_state = CHANNEL_STATE_CONNECT;
|
||||
relation->rx_state = NOTIFY_STATE_ACTIVE;
|
||||
|
@ -553,19 +553,19 @@ void EndpointAppPBX::action_init_partyline(void)
|
|||
relation->epoint_id = ea_endpoint->ep_serial;
|
||||
|
||||
}
|
||||
ea_endpoint->ep_call_id = call->c_serial;
|
||||
ea_endpoint->ep_join_id = join->c_serial;
|
||||
|
||||
set_tone(portlist, "proceeding");
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
new_state(EPOINT_STATE_IN_PROCEEDING);
|
||||
|
||||
/* send setup to call */
|
||||
/* send setup to join */
|
||||
trace_header("ACTION partyline (calling)", DIRECTION_NONE);
|
||||
add_trace("room", NULL, "%d", partyline);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_SETUP);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
message->param.setup.partyline = partyline;
|
||||
memcpy(&message->param.setup.dialinginfo, &e_dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &e_redirinfo, sizeof(struct redir_info));
|
||||
|
@ -683,7 +683,7 @@ void EndpointAppPBX::action_dialing_login(void)
|
|||
SCPY(message->param.connectinfo.display, apply_callerid_display(message->param.connectinfo.id, message->param.connectinfo.itype, message->param.connectinfo.ntype, message->param.connectinfo.present, message->param.connectinfo.screen, message->param.connectinfo.extension, message->param.connectinfo.name));
|
||||
message->param.connectinfo.ntype = e_ext.callerid_type;
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
|
||||
/* set our caller id */
|
||||
SCPY(e_callerinfo.id, e_ext.callerid);
|
||||
|
@ -1047,7 +1047,7 @@ void EndpointAppPBX::_action_redial_reply(int in)
|
|||
SPRINT(message->param.notifyinfo.display, "(%d) %s", e_select+1, (last[0])?last:"- empty -");
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s sending display:%s\n", ea_endpoint->ep_serial, e_ext.number, message->param.notifyinfo.display);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
|
||||
/* process dialing redial
|
||||
|
@ -1120,7 +1120,7 @@ void EndpointAppPBX::action_dialing_powerdial(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
|
||||
|
||||
/* do dialing */
|
||||
SCPY(e_dialinginfo.id, e_ext.last_out[0]);
|
||||
|
@ -1321,7 +1321,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
set_tone(portlist, "proceeding");
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
break;
|
||||
|
||||
case '2':
|
||||
|
@ -1332,7 +1332,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
set_tone(portlist, "ringpbx");
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
break;
|
||||
|
||||
case '3':
|
||||
|
@ -1357,7 +1357,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
/* display callerid if desired for extension */
|
||||
SCPY(message->param.connectinfo.display, apply_callerid_display(message->param.connectinfo.id, message->param.connectinfo.itype, message->param.connectinfo.ntype, message->param.connectinfo.present, message->param.connectinfo.screen, message->param.connectinfo.extension, message->param.connectinfo.name));
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
|
||||
port = find_port_id(portlist->port_id);
|
||||
if (port)
|
||||
|
@ -1376,7 +1376,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
set_tone(portlist, "test");
|
||||
break;
|
||||
|
||||
|
@ -1390,7 +1390,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
set_tone(portlist, "hold");
|
||||
break;
|
||||
|
||||
|
@ -1412,7 +1412,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
set_tone(portlist, causestr);
|
||||
break;
|
||||
|
||||
|
@ -1459,7 +1459,7 @@ void EndpointAppPBX::action_dialing_test(void)
|
|||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
memcpy(&message->param.connectinfo, &e_connectinfo, sizeof(message->param.connectinfo));
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
set_tone(portlist, "hold");
|
||||
break;
|
||||
}
|
||||
|
@ -1752,7 +1752,7 @@ void EndpointAppPBX::action_dialing_calculator(void)
|
|||
SPRINT(message->param.notifyinfo.display, ">%s", e_extdialing);
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s displaying interpreted dialing '%s' internal values: %f %f\n", ea_endpoint->ep_serial, e_ext.number, e_extdialing, value1, value2);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1906,7 +1906,7 @@ void EndpointAppPBX::action_dialing_disconnect(void)
|
|||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_portlist->port_id, EPOINT_TO_PORT, MESSAGE_NOTIFY);
|
||||
SCPY(message->param.notifyinfo.display, display);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
e_action = NULL;
|
||||
}
|
||||
|
@ -1988,7 +1988,7 @@ nesting?:
|
|||
SPRINT(message->param.notifyinfo.display, ">%s %s%s%s", numbering->prefix, numb_actions[numbering->action], (numbering->param[0])?" ":"", numbering->param);
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s selected a new menu '%s' sending display:%s\n", ea_endpoint->ep_serial, e_ext.number, numb_actions[numbering->action], message->param.notifyinfo.display);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, message->paramea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2112,7 +2112,7 @@ void EndpointAppPBX::action_init_pick(void)
|
|||
if (extensions) if (extensions[0])
|
||||
add_trace("extensions", NULL, "%s", extensions);
|
||||
end_trace();
|
||||
pick_call(extensions);
|
||||
pick_join(extensions);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2238,7 +2238,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
|
||||
goto end;
|
||||
}
|
||||
release(RELEASE_CALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, 0);
|
||||
release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, 0);
|
||||
e_action = e_action->next;
|
||||
if (!e_action)
|
||||
{
|
||||
|
@ -2287,7 +2287,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
SCPY(message->param.notifyinfo.display,get_isdn_cause(LOCATION_PRIVATE_LOCAL, epoint->e_ext.display_cause, param->disconnectinfo.location, param->disconnectinfo.cause));
|
||||
}
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, message->param, portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
set_tone(portlist,"cause_1c");
|
||||
|
@ -2397,7 +2397,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
} else
|
||||
if ((rparam = routeparam(e_action, PARAM_ALERTING)))
|
||||
{
|
||||
|
@ -2405,7 +2405,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_ALERTING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
} else
|
||||
if ((rparam = routeparam(e_action, PARAM_PROCEEDING)))
|
||||
{
|
||||
|
@ -2413,7 +2413,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
memset(&e_connectinfo, 0, sizeof(e_connectinfo));
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
|
||||
if (action_defs[e_action->index].init_func)
|
||||
|
@ -2468,7 +2468,7 @@ void EndpointAppPBX::process_dialing(void)
|
|||
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): terminal %s displaying interpreted dialing '%s'\n", ea_endpoint->ep_serial, e_ext.number, message->param.notifyinfo.display);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
|
||||
end:
|
||||
|
|
|
@ -43,7 +43,7 @@ void EndpointAppPBX::action_init_efi(void)
|
|||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
message->param.disconnectinfo.cause = CAUSE_FACILITYREJECTED;
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
set_tone(portlist,"cause_22");
|
||||
return;
|
||||
|
@ -114,7 +114,7 @@ void EndpointAppPBX::efi_message_eof(void)
|
|||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
message->param.disconnectinfo.cause = CAUSE_NORMAL;
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
set_tone(portlist,"cause_10");
|
||||
// set_tone_efi("ich_wiederhole");
|
||||
|
|
|
@ -102,7 +102,7 @@ void EndpointAppPBX::action_init_vbox_play(void)
|
|||
e_dtmf = 1;
|
||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_CONNECT);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
|
||||
|
||||
/* initialize the vbox */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) initializing answering vbox state\n", ea_endpoint->ep_serial);
|
||||
|
@ -679,7 +679,7 @@ void EndpointAppPBX::vbox_handler(void)
|
|||
SPRINT(message->param.notifyinfo.display, e_vbox_display, counter);
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) terminal %s pending display:%s\n", ea_endpoint->ep_serial, e_ext.number, message->param.notifyinfo.display);
|
||||
message_put(message);
|
||||
logmessage(message);
|
||||
logmessage(message->type, &message->param, ea_endpoint->ep_portlist->port_id, DIRECTION_OUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
admin.h
18
admin.h
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -29,7 +29,7 @@ enum { /* messages */
|
|||
ADMIN_RESPONSE_S_INTERFACE,
|
||||
ADMIN_RESPONSE_S_PORT,
|
||||
ADMIN_RESPONSE_S_EPOINT,
|
||||
ADMIN_RESPONSE_S_CALL,
|
||||
ADMIN_RESPONSE_S_JOIN,
|
||||
ADMIN_CALL_SETUP,
|
||||
ADMIN_CALL_SETUP_ACK,
|
||||
ADMIN_CALL_PROCEEDING,
|
||||
|
@ -55,7 +55,7 @@ struct admin_response_state {
|
|||
struct tm tm;
|
||||
char logfile[128];
|
||||
int interfaces;
|
||||
int calls;
|
||||
int joins;
|
||||
int epoints;
|
||||
int ports;
|
||||
};
|
||||
|
@ -76,16 +76,16 @@ struct admin_response_interface {
|
|||
unsigned long port[256]; /* current port */
|
||||
};
|
||||
|
||||
struct admin_response_call {
|
||||
unsigned long serial; /* call serial number */
|
||||
struct admin_response_join {
|
||||
unsigned long serial; /* join serial number */
|
||||
unsigned long partyline;
|
||||
};
|
||||
|
||||
struct admin_response_epoint {
|
||||
unsigned long serial;
|
||||
unsigned long call; /* link to call */
|
||||
// int call_notify; /* if relation notified on hold */
|
||||
// int call_hold; /* if relation on hold */
|
||||
unsigned long join; /* link to join */
|
||||
// int join_notify; /* if relation notified on hold */
|
||||
// int join_hold; /* if relation on hold */
|
||||
int rx_state;
|
||||
int tx_state;
|
||||
int state;
|
||||
|
@ -152,7 +152,7 @@ struct admin_message {
|
|||
struct admin_response_interface i;
|
||||
struct admin_response_port p;
|
||||
struct admin_response_epoint e;
|
||||
struct admin_response_call c;
|
||||
struct admin_response_join j;
|
||||
struct admin_call call;
|
||||
struct admin_msg msg;
|
||||
struct admin_trace_req trace_req;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** LCR **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -21,8 +21,8 @@
|
|||
#include <sys/un.h>
|
||||
#include <curses.h>
|
||||
#include "macro.h"
|
||||
#include "call.h"
|
||||
#include "callpbx.h"
|
||||
#include "join.h"
|
||||
#include "joinpbx.h"
|
||||
#include "extension.h"
|
||||
#include "message.h"
|
||||
#include "admin.h"
|
||||
|
@ -73,7 +73,7 @@ char red = 1,
|
|||
white = 7;
|
||||
|
||||
#define LOGLINES 128
|
||||
char logline[LOGLINES][256];
|
||||
char logline[LOGLINES][512];
|
||||
unsigned long logcur = 0;
|
||||
int logfh = -1;
|
||||
char logfile[128];
|
||||
|
@ -357,7 +357,7 @@ int debug_epoint(struct admin_message *msg, struct admin_message *m, int line, i
|
|||
}
|
||||
/* loop all related ports */
|
||||
ltee = 0;
|
||||
j = msg->u.s.interfaces+msg->u.s.calls+msg->u.s.epoints;
|
||||
j = msg->u.s.interfaces+msg->u.s.joins+msg->u.s.epoints;
|
||||
jj = j + msg->u.s.ports;
|
||||
while(j < jj)
|
||||
{
|
||||
|
@ -388,39 +388,39 @@ int debug_epoint(struct admin_message *msg, struct admin_message *m, int line, i
|
|||
|
||||
return(line);
|
||||
}
|
||||
int debug_call(struct admin_message *msg, struct admin_message *m, int line, int i)
|
||||
int debug_join(struct admin_message *msg, struct admin_message *m, int line, int i)
|
||||
{
|
||||
unsigned long call = m[i].u.c.serial;
|
||||
unsigned long join = m[i].u.j.serial;
|
||||
char buffer[256];
|
||||
int j, jj;
|
||||
|
||||
color(white);
|
||||
SPRINT(buffer,"CALL(%d)", call);
|
||||
SPRINT(buffer,"JOIN(%d)", join);
|
||||
addstr(buffer);
|
||||
if (m[i].u.c.partyline)
|
||||
if (m[i].u.j.partyline)
|
||||
{
|
||||
color(cyan);
|
||||
addstr(" partyline=");
|
||||
color(white);
|
||||
SPRINT(buffer, "%d\n", m[i].u.c.partyline);
|
||||
SPRINT(buffer, "%d\n", m[i].u.j.partyline);
|
||||
addstr(buffer);
|
||||
}
|
||||
/* find number of epoints */
|
||||
j = msg->u.s.interfaces+msg->u.s.calls;
|
||||
j = msg->u.s.interfaces+msg->u.s.joins;
|
||||
jj = j + msg->u.s.epoints;
|
||||
i = 0;
|
||||
while(j < jj)
|
||||
{
|
||||
if (m[j].u.e.call == call)
|
||||
if (m[j].u.e.join == join)
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
/* loop all related endpoints */
|
||||
j = msg->u.s.interfaces+msg->u.s.calls;
|
||||
j = msg->u.s.interfaces+msg->u.s.joins;
|
||||
jj = j + msg->u.s.epoints;
|
||||
while(j < jj)
|
||||
{
|
||||
if (m[j].u.e.call == call)
|
||||
if (m[j].u.e.join == join)
|
||||
{
|
||||
i--;
|
||||
move(++line>1?line:1, 1);
|
||||
|
@ -443,7 +443,7 @@ char *admin_state(int sock)
|
|||
{
|
||||
struct admin_message msg,
|
||||
*m;
|
||||
char buffer[256],
|
||||
char buffer[512],
|
||||
*p;
|
||||
int line, offset = 0;
|
||||
int i, ii, j, jj, k;
|
||||
|
@ -483,7 +483,7 @@ char *admin_state(int sock)
|
|||
cleanup_curses();
|
||||
return("Response not valid. Expecting state response.");
|
||||
}
|
||||
num = msg.u.s.interfaces + msg.u.s.calls + msg.u.s.epoints + msg.u.s.ports;
|
||||
num = msg.u.s.interfaces + msg.u.s.joins + msg.u.s.epoints + msg.u.s.ports;
|
||||
m = (struct admin_message *)MALLOC(num*sizeof(struct admin_message));
|
||||
off=0;
|
||||
if (num)
|
||||
|
@ -520,9 +520,9 @@ char *admin_state(int sock)
|
|||
j++;
|
||||
}
|
||||
i = 0;
|
||||
while(i < msg.u.s.calls)
|
||||
while(i < msg.u.s.joins)
|
||||
{
|
||||
if (m[j].message != ADMIN_RESPONSE_S_CALL)
|
||||
if (m[j].message != ADMIN_RESPONSE_S_JOIN)
|
||||
{
|
||||
FREE(m, 0);
|
||||
cleanup_curses();
|
||||
|
@ -705,7 +705,7 @@ char *admin_state(int sock)
|
|||
if (m[i].u.i.port[j])
|
||||
{
|
||||
/* search for port */
|
||||
l = msg.u.s.interfaces+msg.u.s.calls+msg.u.s.epoints;
|
||||
l = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints;
|
||||
ll = l+msg.u.s.ports;
|
||||
while(l < ll)
|
||||
{
|
||||
|
@ -769,12 +769,12 @@ char *admin_state(int sock)
|
|||
if (show_calls == 1)
|
||||
{
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.calls;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
/* for each endpoint... */
|
||||
if (!m[i].u.e.call)
|
||||
if (!m[i].u.e.join)
|
||||
{
|
||||
move(++line>1?line:1, 0);
|
||||
color(white);
|
||||
|
@ -809,20 +809,20 @@ char *admin_state(int sock)
|
|||
anything = 1;
|
||||
}
|
||||
j = msg.u.s.interfaces;
|
||||
jj = j+msg.u.s.calls;
|
||||
jj = j+msg.u.s.joins;
|
||||
while(j < jj)
|
||||
{
|
||||
/* for each call... */
|
||||
move(++line>1?line:1, 0);
|
||||
color(white);
|
||||
SPRINT(buffer, "(%d):", m[j].u.c.serial);
|
||||
SPRINT(buffer, "(%d):", m[j].u.j.serial);
|
||||
addstr(buffer);
|
||||
i = msg.u.s.interfaces+msg.u.s.calls;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
/* for each endpoint... */
|
||||
if (m[i].u.e.call == m[j].u.c.serial)
|
||||
if (m[i].u.e.join == m[j].u.j.serial)
|
||||
{
|
||||
color(white);
|
||||
SPRINT(buffer, " (%d)", m[i].u.e.serial);
|
||||
|
@ -859,7 +859,7 @@ char *admin_state(int sock)
|
|||
{
|
||||
/* show all ports with no epoint */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.calls+msg.u.s.epoints;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints;
|
||||
ii = i+msg.u.s.ports;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -879,11 +879,11 @@ char *admin_state(int sock)
|
|||
|
||||
/* show all epoints with no call */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.calls;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
if (!m[i].u.e.call)
|
||||
if (!m[i].u.e.join)
|
||||
{
|
||||
move(++line>1?line:1, 4);
|
||||
if (line+2 >= LINES) goto end;
|
||||
|
@ -897,15 +897,15 @@ char *admin_state(int sock)
|
|||
line++;
|
||||
if (line+2 >= LINES) goto end;
|
||||
|
||||
/* show all calls */
|
||||
/* show all joins */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces;
|
||||
ii = i+msg.u.s.calls;
|
||||
ii = i+msg.u.s.joins;
|
||||
while(i < ii)
|
||||
{
|
||||
move(++line>1?line:1, 0);
|
||||
if (line+2 >= LINES) goto end;
|
||||
line = debug_call(&msg, m, line, i);
|
||||
line = debug_join(&msg, m, line, i);
|
||||
if (line+2 >= LINES) goto end;
|
||||
i++;
|
||||
anything = 1;
|
||||
|
@ -934,7 +934,7 @@ char *admin_state(int sock)
|
|||
{
|
||||
move(line++>1?line-1:1, 0);
|
||||
SCPY(buffer, logline[l % LOGLINES]);
|
||||
if (COLS < (int)sizeof(buffer))
|
||||
if (COLS < (int)strlen(buffer))
|
||||
buffer[COLS] = '\0';
|
||||
addstr(buffer);
|
||||
l++;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** Socket link **
|
||||
** Socket link server **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
@ -93,24 +93,24 @@ void free_connection(struct admin_list *admin)
|
|||
struct admin_queue *response;
|
||||
void *temp;
|
||||
union parameter param;
|
||||
class Call *call, *callnext;
|
||||
class Join *join, *joinnext;
|
||||
|
||||
/* free asterisk joins */
|
||||
if (admin->asterisk)
|
||||
{
|
||||
call = call_first;
|
||||
while(call)
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
callnext = call->next;
|
||||
if (call->c_type == CALL_TYPE_ASTERISK)
|
||||
joinnext = join->next;
|
||||
if (join->c_type == JOIN_TYPE_ASTERISK)
|
||||
{
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.disconnectinfo.cause = CAUSE_OUTOFORDER;
|
||||
param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
((class CallAsterisk *)call)->message_asterisk(0, MESSAGE_RELEASE, ¶m);
|
||||
/* call is now destroyed, so we go to next call */
|
||||
((class JoinAsterisk *)join)->message_asterisk(0, MESSAGE_RELEASE, ¶m);
|
||||
/* join is now destroyed, so we go to next join */
|
||||
}
|
||||
call = callnext;
|
||||
join = joinnext;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,7 +595,7 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i
|
|||
*/
|
||||
int admin_message_to_join(struct admin_msg *msg)
|
||||
{
|
||||
class Call *call;
|
||||
class Join *join;
|
||||
struct admin_list *admin;
|
||||
|
||||
/* dummy callref means: asterisk is here */
|
||||
|
@ -618,17 +618,17 @@ int admin_message_to_join(struct admin_msg *msg)
|
|||
admin->asterisk = 1;
|
||||
}
|
||||
|
||||
/* find call instance */
|
||||
call = call_first;
|
||||
while(call)
|
||||
/* find join instance */
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
if (call->c_serial == msg->ref)
|
||||
if (join->c_serial == msg->ref)
|
||||
break;
|
||||
call = call->next;
|
||||
join = join->next;
|
||||
}
|
||||
|
||||
/* create call instance if not existing */
|
||||
if (!call)
|
||||
/* create join instance if not existing */
|
||||
if (!join)
|
||||
{
|
||||
if (msg->ref < 2000000000)
|
||||
{
|
||||
|
@ -636,16 +636,16 @@ int admin_message_to_join(struct admin_msg *msg)
|
|||
return(-1);
|
||||
}
|
||||
|
||||
/* create new call instance */
|
||||
call = new CallAsterisk(0); // must have no serial, because no endpoint is connected
|
||||
if (!call)
|
||||
FATAL("No memory for Asterisk Call instance\n");
|
||||
/* create new join instance */
|
||||
join = new JoinAsterisk(0); // must have no serial, because no endpoint is connected
|
||||
if (!join)
|
||||
FATAL("No memory for Asterisk join instance\n");
|
||||
}
|
||||
|
||||
/* send message */
|
||||
if (call->c_type != CALL_TYPE_ASTERISK)
|
||||
FATAL("Call instance %d must be of type Call Asterisk\n", call->c_serial);
|
||||
((class CallAsterisk *)call)->message_asterisk(msg->ref, msg->type, &msg->param);
|
||||
if (join->c_type != JOIN_TYPE_ASTERISK)
|
||||
FATAL("join instance %d must be of type join Asterisk\n", join->c_serial);
|
||||
((class JoinAsterisk *)join)->message_asterisk(msg->ref, msg->type, &msg->param);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -708,7 +708,7 @@ int admin_state(struct admin_queue **responsep)
|
|||
|
||||
class Port *port;
|
||||
class EndpointAppPBX *apppbx;
|
||||
class Call *call;
|
||||
class Join *join;
|
||||
class Pdss1 *pdss1;
|
||||
struct interface *interface;
|
||||
struct interface_port *ifport;
|
||||
|
@ -744,15 +744,15 @@ int admin_state(struct admin_queue **responsep)
|
|||
interface = interface->next;
|
||||
}
|
||||
response->am[0].u.s.interfaces = i;
|
||||
/* call count */
|
||||
call = call_first;
|
||||
/* join count */
|
||||
join = join_first;
|
||||
i = 0;
|
||||
while(call)
|
||||
while(join)
|
||||
{
|
||||
i++;
|
||||
call = call->next;
|
||||
join = join->next;
|
||||
}
|
||||
response->am[0].u.s.calls = i;
|
||||
response->am[0].u.s.joins = i;
|
||||
/* apppbx count */
|
||||
apppbx = apppbx_first;
|
||||
i = 0;
|
||||
|
@ -776,7 +776,7 @@ int admin_state(struct admin_queue **responsep)
|
|||
responsep = &response->next;
|
||||
|
||||
/* create response for all interfaces */
|
||||
num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.calls)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports);
|
||||
num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.joins)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports);
|
||||
if (num == 0)
|
||||
return(0);
|
||||
response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
|
||||
|
@ -837,19 +837,19 @@ int admin_state(struct admin_queue **responsep)
|
|||
interface = interface->next;
|
||||
}
|
||||
|
||||
/* create response for all calls */
|
||||
call = call_first;
|
||||
while(call)
|
||||
/* create response for all joins */
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
/* message */
|
||||
response->am[num].message = ADMIN_RESPONSE_S_CALL;
|
||||
response->am[num].message = ADMIN_RESPONSE_S_JOIN;
|
||||
/* serial */
|
||||
response->am[num].u.c.serial = call->c_serial;
|
||||
response->am[num].u.j.serial = join->c_serial;
|
||||
/* partyline */
|
||||
if (call->c_type == CALL_TYPE_PBX)
|
||||
response->am[num].u.c.partyline = ((class CallPBX *)call)->c_partyline;
|
||||
if (join->c_type == JOIN_TYPE_PBX)
|
||||
response->am[num].u.j.partyline = ((class JoinPBX *)join)->c_partyline;
|
||||
/* */
|
||||
call = call->next;
|
||||
join = join->next;
|
||||
num++;
|
||||
}
|
||||
|
||||
|
@ -861,8 +861,8 @@ int admin_state(struct admin_queue **responsep)
|
|||
response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
|
||||
/* serial */
|
||||
response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
|
||||
/* call */
|
||||
response->am[num].u.e.call = apppbx->ea_endpoint->ep_call_id;
|
||||
/* join */
|
||||
response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
|
||||
/* rx notification */
|
||||
response->am[num].u.e.rx_state = apppbx->e_rx_state;
|
||||
/* tx notification */
|
||||
|
|
846
apppbx.cpp
846
apppbx.cpp
File diff suppressed because it is too large
Load Diff
50
apppbx.h
50
apppbx.h
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -12,9 +12,9 @@
|
|||
|
||||
enum { /* release actions: see epoint.release */
|
||||
RELEASE_NONE,
|
||||
RELEASE_CALL, /* call, hold */
|
||||
RELEASE_PORT_CALLONLY, /* call, port */
|
||||
RELEASE_ALL, /* call, hold, port */
|
||||
RELEASE_JOIN, /* join, hold */
|
||||
RELEASE_PORT_JOINONLY, /* join, port */
|
||||
RELEASE_ALL, /* join, hold, port */
|
||||
};
|
||||
|
||||
enum { /* states as viewed from io port (state of calls are always connected) */
|
||||
|
@ -92,8 +92,8 @@ class EndpointAppPBX : public EndpointApp
|
|||
// int e_knocking; /* true, if knocking */
|
||||
// double e_knocktime; /* next time to knock */
|
||||
|
||||
// char e_call_tone[64], e_hold_tone[64]; /* current tone */
|
||||
int e_call_pattern/*, e_hold_pattern*/; /* pattern available */
|
||||
// char e_join_tone[64], e_hold_tone[64]; /* current tone */
|
||||
int e_join_pattern/*, e_hold_pattern*/; /* pattern available */
|
||||
|
||||
/* action */
|
||||
char e_dialing_queue[32]; /* holds dialing during setup state */
|
||||
|
@ -111,9 +111,9 @@ class EndpointAppPBX : public EndpointApp
|
|||
int e_multipoint_cause; /* cause value of disconnected multiport calls (highest priority) */
|
||||
int e_multipoint_location; /* location of cause with highest priority */
|
||||
|
||||
/* call relation */
|
||||
int e_call_cause;
|
||||
int e_call_location;
|
||||
/* join relation */
|
||||
int e_join_cause;
|
||||
int e_join_location;
|
||||
|
||||
/* callback */
|
||||
char e_cbdialing[256]; /* dialing information after callback */
|
||||
|
@ -205,22 +205,22 @@ class EndpointAppPBX : public EndpointApp
|
|||
void port_facility(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void port_suspend(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void port_resume(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void ea_message_call(unsigned long call_id, int message, union parameter *param);
|
||||
void call_crypt(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_mISDNsignal(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_setup(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_information(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_overlap(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_proceeding(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_alerting(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_connect(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_disconnect_release(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_notify(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void call_facility(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void ea_message_join(unsigned long join_id, int message, union parameter *param);
|
||||
void join_crypt(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_mISDNsignal(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_setup(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_information(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_overlap(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_proceeding(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_alerting(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_connect(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_disconnect_release(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_notify(struct port_list *portlist, int message_type, union parameter *param);
|
||||
void join_facility(struct port_list *portlist, int message_type, union parameter *param);
|
||||
|
||||
/* epoint */
|
||||
void new_state(int state);
|
||||
void release(int release, int calllocation, int callcause, int portlocation, int portcause);
|
||||
void release(int release, int joinlocation, int joincause, int portlocation, int portcause);
|
||||
void notify_active(void);
|
||||
void keypad_function(char digit);
|
||||
void set_tone(struct port_list *portlist, char *tone);
|
||||
|
@ -297,8 +297,8 @@ class EndpointAppPBX : public EndpointApp
|
|||
void process_hangup(int cause, int location);
|
||||
|
||||
/* facility function */
|
||||
void pick_call(char *extension);
|
||||
void join_call(void);
|
||||
void pick_join(char *extension);
|
||||
void join_join(void);
|
||||
void encrypt_shared(void);
|
||||
void encrypt_keyex(void);
|
||||
void encrypt_off(void);
|
||||
|
@ -345,7 +345,7 @@ class EndpointAppPBX : public EndpointApp
|
|||
void cryptman_timeout(int secs);
|
||||
|
||||
void message_disconnect_port(struct port_list *portlist, int cause, int location, char *display);
|
||||
void logmessage(struct message *messsage);
|
||||
void logmessage(int message_type, union parameter *param, unsigned long port_id, int dir);
|
||||
void trace_header(char *name, int direction);
|
||||
void screen(int out, char *id, int idsize, int *type, int *present, struct interface *interface);
|
||||
};
|
||||
|
|
12
crypt.cpp
12
crypt.cpp
|
@ -1524,7 +1524,7 @@ void EndpointAppPBX::cryptman_msg2user(int msg, char *text)
|
|||
{
|
||||
struct message *message;
|
||||
/* send message */
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = msg;
|
||||
if (!text)
|
||||
text = "";
|
||||
|
@ -1803,7 +1803,7 @@ void EndpointAppPBX::encrypt_shared(void)
|
|||
if (e_crypt != CRYPT_OFF)
|
||||
{
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = CU_INFO_REQ;
|
||||
message_put(message);
|
||||
return;
|
||||
|
@ -1885,7 +1885,7 @@ void EndpointAppPBX::encrypt_shared(void)
|
|||
// SPRINT(e_crypt_display, "Shared Key");
|
||||
e_crypt = CRYPT_SWAIT;
|
||||
/* sending activation */
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = CU_ACTS_REQ;
|
||||
message->param.crypt.len = key_len;
|
||||
memcpy(message->param.crypt.data, key, key_len);
|
||||
|
@ -1905,7 +1905,7 @@ void EndpointAppPBX::encrypt_keyex(void)
|
|||
if (e_crypt != CRYPT_OFF)
|
||||
{
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) encryption in progress, so we request the current message.\n", ea_endpoint->ep_serial);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = CU_INFO_REQ;
|
||||
message_put(message);
|
||||
return;
|
||||
|
@ -1937,7 +1937,7 @@ void EndpointAppPBX::encrypt_keyex(void)
|
|||
message_put(message);
|
||||
e_crypt = CRYPT_KWAIT;
|
||||
/* sending activation */
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = CU_ACTK_REQ;
|
||||
message_put(message);
|
||||
#endif /* CRYPTO */
|
||||
|
@ -1975,7 +1975,7 @@ void EndpointAppPBX::encrypt_off(void)
|
|||
message_put(message);
|
||||
e_crypt = CRYPT_RELEASE;
|
||||
/* sending activation */
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_call_id, EPOINT_TO_CALL, MESSAGE_CRYPT);
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CRYPT);
|
||||
message->param.crypt.type = CU_DACT_REQ;
|
||||
message_put(message);
|
||||
}
|
||||
|
|
63
dss1.cpp
63
dss1.cpp
|
@ -1121,7 +1121,7 @@ void Pdss1::disconnect_ind(unsigned long prim, unsigned long dinfo, void *data)
|
|||
cause = 16;
|
||||
|
||||
/* release if we are remote sends us no tones */
|
||||
if (p_m_mISDNport->earlyb)
|
||||
if (!p_m_mISDNport->earlyb)
|
||||
{
|
||||
RELEASE_t *release;
|
||||
msg_t *dmsg;
|
||||
|
@ -1242,7 +1242,7 @@ void Pdss1::release_ind(unsigned long prim, unsigned long dinfo, void *data)
|
|||
p_m_delete = 1;
|
||||
}
|
||||
|
||||
/* CC_RELEASE_COMPLETE INDICATION */
|
||||
/* CC_RELEASE_COMPLETE INDICATION (a reject) */
|
||||
void Pdss1::release_complete_ind(unsigned long prim, unsigned long dinfo, void *data)
|
||||
{
|
||||
int headerlen = (p_m_d_ntmode)?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
||||
|
@ -1867,9 +1867,10 @@ void Pdss1::message_isdn(unsigned long prim, unsigned long dinfo, void *data)
|
|||
}
|
||||
p_m_d_l3id = 0;
|
||||
p_m_delete = 1;
|
||||
#warning remove me
|
||||
PDEBUG(DEBUG_LOG, "JOLLY release cr %d\n", p_serial);
|
||||
/* sending release to endpoint in case we still have an endpoint
|
||||
* NOTE: this only happens if the stack releases due to layer1
|
||||
* or layer2 breakdown. otherwhise a release is received first.
|
||||
* this is because we don't get any response if a release_complete is received (or a release in release state)
|
||||
*/
|
||||
while(p_epointlist)
|
||||
{
|
||||
|
@ -1968,12 +1969,17 @@ int Pdss1::handler(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (p_m_delete && p_m_d_l3id==0)
|
||||
printf("ping! %d", p_serial);
|
||||
if ((ret = PmISDN::handler()))
|
||||
return(ret);
|
||||
|
||||
/* handle destruction */
|
||||
if (p_m_delete && p_m_d_l3id==0)
|
||||
{
|
||||
#warning remove
|
||||
PDEBUG(DEBUG_LOG, "JOLLY destroy object %d\n", p_serial);
|
||||
|
||||
delete this;
|
||||
return(-1);
|
||||
}
|
||||
|
@ -2665,8 +2671,8 @@ void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union pa
|
|||
char *p = NULL;
|
||||
|
||||
/* we reject during incoming setup when we have no tones. also if we are in outgoing setup state */
|
||||
if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
|
||||
|| p_state==PORT_STATE_OUT_SETUP)
|
||||
// if ((p_state==PORT_STATE_IN_SETUP && !p_m_mISDNport->tones)
|
||||
if (/* ||*/ p_state==PORT_STATE_OUT_SETUP)
|
||||
{
|
||||
/* sending release to endpoint */
|
||||
while(p_epointlist)
|
||||
|
@ -2691,7 +2697,7 @@ void Pdss1::message_disconnect(unsigned long epoint_id, int message_id, union pa
|
|||
return;
|
||||
}
|
||||
|
||||
/* NT-MODE in setup state we must send PROCEEDING first */
|
||||
/* workarround: NT-MODE in setup state we must send PROCEEDING first to make it work */
|
||||
if (p_state==PORT_STATE_IN_SETUP)
|
||||
{
|
||||
CALL_PROCEEDING_t *proceeding;
|
||||
|
@ -2745,9 +2751,11 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
class Endpoint *epoint;
|
||||
char *p = NULL;
|
||||
|
||||
/* if we have incoming disconnected, we may release */
|
||||
if (p_state==PORT_STATE_IN_DISCONNECT
|
||||
|| p_state==PORT_STATE_OUT_DISCONNECT)
|
||||
/*
|
||||
* we may only release during incomming disconnect state.
|
||||
* this means that the endpoint doesnt require audio anymore
|
||||
*/
|
||||
if (p_state == PORT_STATE_IN_DISCONNECT)
|
||||
{
|
||||
/* sending release */
|
||||
dmsg = create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, p_m_d_l3id, sizeof(RELEASE_t), p_m_d_ntmode);
|
||||
|
@ -2758,16 +2766,24 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
end_trace();
|
||||
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
|
||||
new_state(PORT_STATE_RELEASE);
|
||||
/* remove epoint */
|
||||
free_epointid(epoint_id);
|
||||
// wait for callref to be released
|
||||
return;
|
||||
|
||||
}
|
||||
/* if we are on outgoing/incoming call setup, we may release complete */
|
||||
if (p_state==PORT_STATE_OUT_SETUP
|
||||
|| p_state==PORT_STATE_IN_SETUP
|
||||
// NOTE: a bug in mISDNuser (see disconnect_req_out !!!)
|
||||
|| p_state==PORT_STATE_OUT_PROCEEDING)
|
||||
/*
|
||||
* if we are on incoming call setup, we may reject by sending a release_complete
|
||||
* also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
|
||||
*/
|
||||
if (p_state==PORT_STATE_IN_SETUP
|
||||
|| p_state==PORT_STATE_OUT_SETUP)
|
||||
// // NOTE: a bug in mISDNuser (see disconnect_req_out !!!)
|
||||
// || p_state==PORT_STATE_OUT_DISCO)
|
||||
{
|
||||
/* sending release */
|
||||
#warning remove me
|
||||
PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
|
||||
/* sending release complete */
|
||||
dmsg = create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, p_m_d_l3id, sizeof(RELEASE_COMPLETE_t), p_m_d_ntmode);
|
||||
release_complete = (RELEASE_COMPLETE_t *)(dmsg->data + headerlen);
|
||||
l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE | REQUEST, DIRECTION_OUT);
|
||||
|
@ -2776,9 +2792,10 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
end_trace();
|
||||
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
|
||||
new_state(PORT_STATE_RELEASE);
|
||||
|
||||
/* remove epoint */
|
||||
free_epointid(epoint_id);
|
||||
#if 0
|
||||
/* remove process */
|
||||
l1l2l3_trace_header(p_m_mISDNport, this, CC_RELEASE_CR | REQUEST, DIRECTION_OUT);
|
||||
add_trace("callref", NULL, "0x%x", p_m_d_l3id);
|
||||
end_trace();
|
||||
|
@ -2789,9 +2806,13 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
}
|
||||
p_m_d_l3id = 0;
|
||||
p_m_delete = 1;
|
||||
#endif
|
||||
// wait for callref to be released
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
wirklich erst proceeding?:
|
||||
/* NT-MODE in setup state we must send PROCEEDING first */
|
||||
if (p_m_d_ntmode && p_state==PORT_STATE_IN_SETUP)
|
||||
{
|
||||
|
@ -2811,6 +2832,7 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
end_trace();
|
||||
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sending disconnect */
|
||||
dmsg = create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, p_m_d_l3id, sizeof(DISCONNECT_t), p_m_d_ntmode);
|
||||
|
@ -2832,9 +2854,12 @@ void Pdss1::message_release(unsigned long epoint_id, int message_id, union param
|
|||
enc_ie_display(&disconnect->DISPLAY, dmsg, (unsigned char *)p);
|
||||
end_trace();
|
||||
msg_queue_tail(&p_m_mISDNport->downqueue, dmsg);
|
||||
new_state(PORT_STATE_RELEASE);
|
||||
new_state(PORT_STATE_OUT_DISCONNECT);
|
||||
/* remove epoint */
|
||||
free_epointid(epoint_id);
|
||||
// p_m_delete = 1;
|
||||
// wait for release and callref to be released
|
||||
#warning remove me
|
||||
PDEBUG(DEBUG_LOG, "JOLLY sending disconnect %d\n", p_serial);
|
||||
}
|
||||
|
||||
|
||||
|
|
20
endpoint.cpp
20
endpoint.cpp
|
@ -1,11 +1,11 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** The Endpoint is the link between the call and the port. **
|
||||
** The Endpoint is the link between the join and the port. **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
@ -37,16 +37,16 @@ class Endpoint *find_epoint_id(unsigned long epoint_id)
|
|||
|
||||
|
||||
/*
|
||||
* endpoint constructor (link with either port or call id)
|
||||
* endpoint constructor (link with either port or join id)
|
||||
*/
|
||||
Endpoint::Endpoint(unsigned long port_id, unsigned long call_id, unsigned long use_epoint_id)
|
||||
Endpoint::Endpoint(unsigned long port_id, unsigned long join_id, unsigned long use_epoint_id)
|
||||
{
|
||||
class Port *port;
|
||||
class Endpoint **epointpointer;
|
||||
int earlyb = 0;
|
||||
|
||||
/* epoint structure */
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Allocating enpoint %d and connecting it with:%s%s\n", epoint_serial, epoint_serial, (port_id)?" ioport":"", (call_id)?" call":"");
|
||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Allocating enpoint %d and connecting it with:%s%s\n", epoint_serial, epoint_serial, (port_id)?" ioport":"", (join_id)?" join":"");
|
||||
|
||||
ep_portlist = NULL;
|
||||
ep_app = NULL;
|
||||
|
@ -65,7 +65,7 @@ Endpoint::Endpoint(unsigned long port_id, unsigned long call_id, unsigned long u
|
|||
else
|
||||
ep_serial = epoint_serial++;
|
||||
|
||||
/* link to call or port */
|
||||
/* link to join or port */
|
||||
if (port_id)
|
||||
{
|
||||
port = find_port_id(port_id);
|
||||
|
@ -77,7 +77,7 @@ Endpoint::Endpoint(unsigned long port_id, unsigned long call_id, unsigned long u
|
|||
FATAL("No memory for portlist.\n");
|
||||
}
|
||||
}
|
||||
ep_call_id = call_id;
|
||||
ep_join_id = join_id;
|
||||
|
||||
ep_park = 0;
|
||||
ep_park_len = 0;
|
||||
|
@ -101,9 +101,9 @@ Endpoint::~Endpoint(void)
|
|||
delete ep_app;
|
||||
|
||||
/* free relations */
|
||||
if (ep_call_id)
|
||||
if (ep_join_id)
|
||||
{
|
||||
PERROR("warning: still relation to call.\n");
|
||||
PERROR("warning: still relation to join.\n");
|
||||
}
|
||||
|
||||
/* free portlist */
|
||||
|
@ -158,7 +158,7 @@ struct port_list *Endpoint::portlist_new(unsigned long port_id, int port_type, i
|
|||
portlistpointer = &((*portlistpointer)->next);
|
||||
*portlistpointer = portlist;
|
||||
|
||||
/* link to call or port */
|
||||
/* link to join or port */
|
||||
portlist->port_id = port_id;
|
||||
portlist->port_type = port_type;
|
||||
portlist->early_b = earlyb;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -22,7 +22,7 @@ struct port_list {
|
|||
class Endpoint
|
||||
{
|
||||
public:
|
||||
Endpoint(unsigned long port_id, unsigned long call_id, unsigned long use_epoint_id);
|
||||
Endpoint(unsigned long port_id, unsigned long join_id, unsigned long use_epoint_id);
|
||||
~Endpoint();
|
||||
class Endpoint *next; /* next in list */
|
||||
unsigned long ep_serial; /* a unique serial to identify */
|
||||
|
@ -36,8 +36,8 @@ class Endpoint
|
|||
struct port_list *portlist_new(unsigned long port_id, int port_type, int earlyb);
|
||||
void free_portlist(struct port_list *portlist);
|
||||
|
||||
/* call relation */
|
||||
unsigned long ep_call_id; /* link to call */
|
||||
/* join relation */
|
||||
unsigned long ep_join_id; /* link to join */
|
||||
|
||||
/* if still used by threads */
|
||||
int ep_use;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -42,7 +42,7 @@ void EndpointApp::ea_message_port(unsigned long port_id, int message_type, union
|
|||
PDEBUG(DEBUG_EPOINT, "%s: Spare function.\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
void EndpointApp::ea_message_call(unsigned long port_id, int message_type, union parameter *param)
|
||||
void EndpointApp::ea_message_join(unsigned long join_id, int message_type, union parameter *param)
|
||||
{
|
||||
PDEBUG(DEBUG_EPOINT, "%s: Spare function.\n", __FUNCTION__);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -20,6 +20,6 @@ class EndpointApp
|
|||
class Endpoint *ea_endpoint;
|
||||
virtual int handler(void);
|
||||
virtual void ea_message_port(unsigned long port_id, int message, union parameter *param);
|
||||
virtual void ea_message_call(unsigned long call_id, int message, union parameter *param);
|
||||
virtual void ea_message_join(unsigned long join_id, int message, union parameter *param);
|
||||
};
|
||||
|
||||
|
|
343
h323.cpp
343
h323.cpp
|
@ -1,343 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** h323 port **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "main.h"
|
||||
|
||||
|
||||
/*
|
||||
* initialize h323 port
|
||||
*/
|
||||
H323Port::H323Port(int type, char *portname, struct port_settings *settings) : Port(type, portname, settings)
|
||||
{
|
||||
p_h323_channel_in = p_h323_channel_out = NULL;
|
||||
p_h323_connect = NULL;
|
||||
|
||||
/* configure device */
|
||||
switch (type)
|
||||
{
|
||||
case PORT_TYPE_H323_IN:
|
||||
break;
|
||||
case PORT_TYPE_H323_OUT:
|
||||
SPRINT(p_name, "H323_outgoing_port_#%lu", p_serial);
|
||||
break;
|
||||
}
|
||||
if (options.law == 'u')
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* destructor
|
||||
*/
|
||||
H323Port::~H323Port()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* endpoint sends messages to the interface
|
||||
*/
|
||||
int H323Port::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
|
||||
{
|
||||
H323Connection *connection;
|
||||
H323Connection::CallEndReason h323_cause;
|
||||
char name[sizeof(p_name)];
|
||||
|
||||
if (Port::message_epoint(epoint_id, message_id, param))
|
||||
return(1);
|
||||
|
||||
switch(message_id)
|
||||
{
|
||||
case MESSAGE_mISDNSIGNAL: /* isdn command */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) mISDN signal not supported.\n", p_name);
|
||||
break;
|
||||
|
||||
case MESSAGE_INFORMATION: /* additional digits from endpoint */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received more digit information: '%s'\n", p_name, p_callerinfo.id, param->information.number);
|
||||
/* queue to be done */
|
||||
if (p_state != PORT_STATE_OUT_OVERLAP)
|
||||
{
|
||||
PERROR("H323Port(%s) additinal digits are only possible in outgoing overlap state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
if (strlen(param->information.number)>30)
|
||||
{
|
||||
PERROR("H323Port(%s) information string too long.\n", p_name);
|
||||
break;
|
||||
}
|
||||
SCAT((char *)p_dialinginfo.number, param->information.number);
|
||||
break;
|
||||
|
||||
case MESSAGE_PROCEEDING: /* call of endpoint is proceeding */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received proceeding\n", p_name, p_callerinfo.id);
|
||||
if (p_state != PORT_STATE_IN_OVERLAP)
|
||||
{
|
||||
PERROR("H323Port(%s) proceeding command only possible in setup state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
p_state = PORT_STATE_IN_PROCEEDING;
|
||||
break;
|
||||
|
||||
case MESSAGE_ALERTING: /* call of endpoint is ringing */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received alerting\n", p_name, p_callerinfo.id);
|
||||
if (p_state != PORT_STATE_IN_OVERLAP
|
||||
&& p_state != PORT_STATE_IN_PROCEEDING)
|
||||
{
|
||||
PERROR("H323Port(%s) alerting command only possible in setup or proceeding state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
p_state = PORT_STATE_IN_ALERTING;
|
||||
UCPY(name, p_name);
|
||||
mutex_h323.Signal();
|
||||
connection = h323_ep->FindConnectionWithLock(name);
|
||||
if (connection)
|
||||
{
|
||||
if (options.h323_ringconnect && !p_callerinfo.intern[0])
|
||||
{
|
||||
connection->AnsweringCall(H323Connection::AnswerCallNow);
|
||||
p_state = PORT_STATE_CONNECT;
|
||||
} else
|
||||
connection->AnsweringCall(H323Connection::AnswerCallPending);
|
||||
connection->Unlock();
|
||||
}
|
||||
mutex_h323.Wait();
|
||||
break;
|
||||
|
||||
case MESSAGE_CONNECT: /* call of endpoint is connected */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received connect\n", p_name, p_callerinfo.id);
|
||||
if (p_state != PORT_STATE_IN_OVERLAP
|
||||
&& p_state != PORT_STATE_IN_PROCEEDING
|
||||
&& p_state != PORT_STATE_IN_ALERTING)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) connect command only possible in setup, proceeding or alerting state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
new_state(PORT_STATE_CONNECT);
|
||||
/* copy connected information */
|
||||
memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
|
||||
p_connectinfo.itype = INFO_ITYPE_H323;
|
||||
UCPY(name, p_name);
|
||||
mutex_h323.Signal();
|
||||
connection = h323_ep->FindConnectionWithLock(name);
|
||||
if (connection)
|
||||
{
|
||||
int type, present, screen;
|
||||
PString connect_number;
|
||||
/* modify connectinfo (COLP) */
|
||||
if (p_connectinfo.present!=INFO_PRESENT_NULL)
|
||||
{
|
||||
connect_number = p_connectinfo.id;
|
||||
switch(p_connectinfo.ntype)
|
||||
{
|
||||
case INFO_NTYPE_SUBSCRIBER:
|
||||
type = Q931::SubscriberType;
|
||||
break;
|
||||
case INFO_NTYPE_NATIONAL:
|
||||
type = Q931::NationalType;
|
||||
break;
|
||||
case INFO_NTYPE_INTERNATIONAL:
|
||||
type = Q931::InternationalType;
|
||||
break;
|
||||
default: /* INFO_TYPE_UNKNOWN */
|
||||
type = Q931::UnknownType;
|
||||
}
|
||||
switch(p_connectinfo.present)
|
||||
{
|
||||
case INFO_PRESENT_RESTRICTED:
|
||||
present = 1;
|
||||
break;
|
||||
case INFO_PRESENT_NOTAVAIL:
|
||||
present = 2;
|
||||
break;
|
||||
default: /* INFO_PRESENT_ALLOWED */
|
||||
present = 0;
|
||||
}
|
||||
switch(p_connectinfo.screen)
|
||||
{
|
||||
case INFO_SCREEN_USER:
|
||||
screen = 0;
|
||||
break;
|
||||
default: /* INFO_SCREEN_NETWORK */
|
||||
screen = 3;
|
||||
}
|
||||
#if 0
|
||||
if (p_h323_connect)
|
||||
{
|
||||
//PDEBUG(DEBUG_H323, "DDDEBUG: number %s, type=%d, present %d, screen %d\n", p_connectinfo.id, type, present, screen);
|
||||
((Q931 *)p_h323_connect)->SetConnectedNumber(connect_number, Q931::ISDNPlan, type, present, screen);
|
||||
}
|
||||
else
|
||||
PERROR("missing p_h323_connect\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
connection->AnsweringCall(H323Connection::AnswerCallNow);
|
||||
connection->Unlock();
|
||||
}
|
||||
mutex_h323.Wait();
|
||||
break;
|
||||
|
||||
case MESSAGE_DISCONNECT: /* call has been disconnected */
|
||||
#if 0
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received disconnect cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
|
||||
/* we just play what we hear from the remote site */
|
||||
if (p_state == PORT_STATE_IN_OVERLAP
|
||||
|| p_state == PORT_STATE_IN_PROCEEDING)
|
||||
{
|
||||
/* copy connected information */
|
||||
memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
|
||||
UCPY(name, p_name);
|
||||
mutex_h323.Signal();
|
||||
connection = h323_ep->FindConnectionWithLock(name);
|
||||
if (connection)
|
||||
{
|
||||
connection->AnsweringCall(H323Connection::AnswerCallNow);
|
||||
connection->Unlock();
|
||||
}
|
||||
mutex_h323.Wait();
|
||||
}
|
||||
new_state(PORT_STATE_DISCONNECT);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MESSAGE_RELEASE: /* release h323 port */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received disconnect cause=%d\n", p_name, p_callerinfo.id, param->disconnectinfo.cause);
|
||||
if (p_state != PORT_STATE_IN_OVERLAP
|
||||
&& p_state != PORT_STATE_IN_PROCEEDING
|
||||
&& p_state != PORT_STATE_IN_ALERTING
|
||||
&& p_state != PORT_STATE_OUT_SETUP
|
||||
&& p_state != PORT_STATE_OUT_OVERLAP
|
||||
&& p_state != PORT_STATE_OUT_PROCEEDING
|
||||
&& p_state != PORT_STATE_OUT_ALERTING
|
||||
&& p_state != PORT_STATE_CONNECT)
|
||||
{
|
||||
PERROR("H323Port(%s) disconnect command only possible in setup, proceeding, alerting or connect state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(param->disconnectinfo.cause)
|
||||
{
|
||||
case 1:
|
||||
h323_cause = H323Connection::EndedByNoUser;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
h323_cause = H323Connection::EndedByUnreachable;
|
||||
break;
|
||||
|
||||
case 17:
|
||||
h323_cause = H323Connection::EndedByRemoteBusy;
|
||||
break;
|
||||
|
||||
case 18:
|
||||
h323_cause = H323Connection::EndedByNoEndPoint;
|
||||
break;
|
||||
|
||||
case 19:
|
||||
h323_cause = H323Connection::EndedByNoAnswer;
|
||||
break;
|
||||
|
||||
case 21:
|
||||
h323_cause = H323Connection::EndedByRefusal;
|
||||
break;
|
||||
|
||||
case 27:
|
||||
h323_cause = H323Connection::EndedByHostOffline;
|
||||
break;
|
||||
|
||||
case 47:
|
||||
h323_cause = H323Connection::EndedByConnectFail;
|
||||
break;
|
||||
|
||||
case 65:
|
||||
h323_cause = H323Connection::EndedByCapabilityExchange;
|
||||
break;
|
||||
|
||||
case 42:
|
||||
h323_cause = H323Connection::EndedByRemoteCongestion;
|
||||
break;
|
||||
|
||||
case 41:
|
||||
h323_cause = H323Connection::EndedByTemporaryFailure;
|
||||
break;
|
||||
|
||||
default:
|
||||
h323_cause = H323Connection::EndedByRemoteUser;
|
||||
break;
|
||||
}
|
||||
UCPY(name, p_name);
|
||||
mutex_h323.Signal();
|
||||
h323_ep->ClearCall(name, h323_cause);
|
||||
mutex_h323.Wait();
|
||||
|
||||
delete this;
|
||||
break;
|
||||
|
||||
case MESSAGE_SETUP: /* dial-out command received from epoint */
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port received setup from '%s' to '%s'\n", p_name, param->setup.callerinfo.id, param->setup.dialinginfo.number);
|
||||
if (p_type!=PORT_TYPE_H323_OUT)
|
||||
{
|
||||
PERROR("H323Port(%s) cannot dial because h323 port not of outgoing type.\n", p_name);
|
||||
break;
|
||||
}
|
||||
if (p_state != PORT_STATE_IDLE)
|
||||
{
|
||||
PERROR("H323Port(%s) error: dialing command only possible in idle state.\n", p_name);
|
||||
break;
|
||||
}
|
||||
|
||||
/* link relation */
|
||||
if (p_epointlist)
|
||||
{
|
||||
PERROR("H323Port(%s) software error: epoint pointer is set in idle state, how bad!! exitting.\n", p_name);
|
||||
exit(-1);
|
||||
}
|
||||
if (!(epointlist_new(epoint_id)))
|
||||
{
|
||||
PERROR("no memory for epointlist\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* copy setup infos to port */
|
||||
memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
|
||||
memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
|
||||
memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
|
||||
memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
|
||||
|
||||
p_state = PORT_STATE_OUT_SETUP;
|
||||
|
||||
UCPY(name, p_name);
|
||||
mutex_h323.Signal();
|
||||
h323_ep->Call(name, param->setup.callerinfo.id, param->setup.dialinginfo.number);
|
||||
mutex_h323.Wait();
|
||||
break;
|
||||
|
||||
default:
|
||||
PDEBUG(DEBUG_H323, "H323Port(%s) h323 port with (caller id %s) received an unsupported message: %d\n", p_name, p_callerinfo.id, message_id);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
27
h323.h
27
h323.h
|
@ -1,27 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** h323-port header file **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
||||
/* h323 port class */
|
||||
class H323_chan;
|
||||
class H323Port : public Port
|
||||
{
|
||||
public:
|
||||
H323Port(int type, char *portname, struct port_settings *settings);
|
||||
~H323Port();
|
||||
int message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
|
||||
H323_chan *p_h323_channel_in; /* channels of port */
|
||||
H323_chan *p_h323_channel_out;
|
||||
void *p_h323_connect; /* q931 object of connect PDU */
|
||||
};
|
||||
|
||||
|
189
h323_chan.cpp
189
h323_chan.cpp
|
@ -1,189 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// H323_chan class //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// constructor
|
||||
//
|
||||
H323_chan::H323_chan(const PString &token, BOOL isEncoding) : PIndirectChannel()
|
||||
{
|
||||
d_token = token;
|
||||
// d_isEncoding = isEncoding;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 channel constuctor of channel (%scoding)\n", (isEncoding)?"en":"de");
|
||||
|
||||
transfering = FALSE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// destructor
|
||||
//
|
||||
H323_chan::~H323_chan(void)
|
||||
{
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 channel destuctor\n");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Closes the
|
||||
//
|
||||
BOOL H323_chan::Close(void)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 channel Close\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// IsOpen
|
||||
//
|
||||
BOOL H323_chan::IsOpen(void) const
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 channel IsOpen\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Read
|
||||
//
|
||||
BOOL H323_chan::Read(void *buf, PINDEX len)
|
||||
{
|
||||
int nr_words;
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = d_token;
|
||||
PTime Now;
|
||||
PTimeInterval diff;
|
||||
|
||||
nr_words = len/2;
|
||||
|
||||
// cout << "H323 channel Read " << nr_words << " words" << endl;
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("H323 channel Read() cannot find port with token %s\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
lastReadCount = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nr_words = port->read_audio((unsigned char *)buf, nr_words, 0);
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
// delay
|
||||
if (!transfering)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 channel Read(%s) sending to h323 the first time\n", token_string);
|
||||
start = Now;
|
||||
transfering = TRUE;
|
||||
elapsed = 0;
|
||||
}
|
||||
diff = Now-start;
|
||||
elapsed += nr_words*125;
|
||||
if (elapsed > (diff.GetMilliSeconds()*1000))
|
||||
usleep(elapsed - (diff.GetMilliSeconds()*1000));
|
||||
|
||||
lastReadCount = 2 * nr_words;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Write
|
||||
//
|
||||
BOOL H323_chan::Write(const void *buf, PINDEX len)
|
||||
{
|
||||
int nr_words;
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = d_token;
|
||||
PTime Now;
|
||||
PTimeInterval diff;
|
||||
unsigned char *data_temp;
|
||||
unsigned long length_temp;
|
||||
struct message *message;
|
||||
|
||||
nr_words = len / 2;
|
||||
|
||||
// cout << "H323 channel Write " << nr_words << " words" << endl;
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("H323 channel Write() cannot find port with token %s\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
lastReadCount = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// send data message
|
||||
length_temp = len;
|
||||
data_temp = (unsigned char *)buf;
|
||||
while(length_temp)
|
||||
{
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
|
||||
message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
|
||||
memcpy(message->param.data.data, data_temp, message->param.data.len);
|
||||
message->param.data.compressed = 0;
|
||||
/* { // testin with law data
|
||||
int i=0;
|
||||
while (i<message->param.data.len)
|
||||
{
|
||||
((unsigned char *)message->param.data.data)[i] = audio_s16_to_law[((signed short*)data_temp)[i] & 0xffff];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
message->param.data.len = message->param.data.len/2;
|
||||
message->param.data.compressed = 1;
|
||||
*/
|
||||
message->param.data.port_type = port->p_type;
|
||||
message->param.data.port_id = port->p_serial;
|
||||
message_put(message);
|
||||
if (length_temp <= sizeof(message->param.data.data))
|
||||
break;
|
||||
data_temp += sizeof(message->param.data.data);
|
||||
length_temp -= sizeof(message->param.data.data);
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
// delay
|
||||
if (!transfering)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 channel Write(%s) receiving from h323 the first time\n", token_string);
|
||||
start = Now;
|
||||
transfering = TRUE;
|
||||
elapsed = 0;
|
||||
}
|
||||
diff = Now-start;
|
||||
elapsed += nr_words*125;
|
||||
if (elapsed > (diff.GetMilliSeconds()*1000))
|
||||
usleep(elapsed - (diff.GetMilliSeconds()*1000));
|
||||
|
||||
lastWriteCount = 2 * nr_words;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
34
h323_chan.h
34
h323_chan.h
|
@ -1,34 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// h323_chan header file //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef H323_CHAN_HEADER
|
||||
#define H323_CHAN_HEADER
|
||||
|
||||
class H323_chan : public PIndirectChannel
|
||||
{
|
||||
public:
|
||||
H323_chan(const PString &token, BOOL isEncoding);
|
||||
~H323_chan(void);
|
||||
BOOL Close(void);
|
||||
BOOL IsOpen(void) const;
|
||||
BOOL Read(void *buf, PINDEX len);
|
||||
BOOL Write(const void *buf, PINDEX len);
|
||||
|
||||
private:
|
||||
PString d_token;
|
||||
PTime start;
|
||||
BOOL transfering;
|
||||
PInt64 elapsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
648
h323_con.cpp
648
h323_con.cpp
|
@ -1,648 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// h323_con connection class //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// constructor
|
||||
//
|
||||
H323_con::H323_con(H323_ep &endpoint, unsigned callReference) : H323Connection(endpoint, callReference)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 connection constuctor\n");
|
||||
|
||||
SetAudioJitterDelay(0, 0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// destructor
|
||||
//
|
||||
H323_con::~H323_con()
|
||||
{
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = callToken;
|
||||
struct message *message;
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
// get ioport
|
||||
port = (class H323Port *)find_port_with_token((char *)token_string);
|
||||
if (!port)
|
||||
{
|
||||
PERROR("no port with token '%s'\n", token_string);
|
||||
} else
|
||||
{
|
||||
/* sending release (if not already) */
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
|
||||
message->param.disconnectinfo.cause = 16;
|
||||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
message_put(message);
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 connection destuctor\n");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// AnswerCallResponse (incoming call)
|
||||
//
|
||||
H323Connection::AnswerCallResponse H323_con::OnAnswerCall(const PString &, const H323SignalPDU &setupPDU, H323SignalPDU &connectPDU)
|
||||
{
|
||||
class H323Port *port;
|
||||
const char *calleraddress;
|
||||
char callerip[32], *extension;
|
||||
const char *dialing = NULL;
|
||||
const H225_Setup_UUIE &setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
|
||||
const H225_ArrayOf_AliasAddress &adr = setup.m_destinationAddress;
|
||||
PINDEX i;
|
||||
const unsigned char *token_string = callToken;
|
||||
struct message *message;
|
||||
class Endpoint *epoint;
|
||||
|
||||
const Q931 setup_q931 = setupPDU.GetQ931();
|
||||
PString calling_number;
|
||||
PString redir_number;
|
||||
unsigned type, plan, present, screen, reason;
|
||||
|
||||
struct caller_info *callerinfo;
|
||||
struct dialing_info *dialinginfo;
|
||||
struct capa_info *capainfo;
|
||||
struct redir_info *redirinfo;
|
||||
char option[64] = "";
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 connection incoming call\n");
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
// alloc new h323 port structure
|
||||
if (!(port = new H323Port(PORT_TYPE_H323_IN, (char *)token_string, NULL)))
|
||||
{
|
||||
mutex_h323.Signal();
|
||||
return AnswerCallDenied;
|
||||
}
|
||||
callerinfo = &port->p_callerinfo;
|
||||
redirinfo = &port->p_redirinfo;
|
||||
capainfo = &port->p_capainfo;
|
||||
dialinginfo = &port->p_dialinginfo;
|
||||
|
||||
memset(callerinfo, 0, sizeof(struct caller_info));
|
||||
memset(redirinfo, 0, sizeof(struct redir_info));
|
||||
memset(capainfo, 0, sizeof(struct capa_info));
|
||||
memset(dialinginfo, 0, sizeof(struct dialing_info));
|
||||
|
||||
callerinfo->itype = INFO_ITYPE_H323;
|
||||
|
||||
// get calling party information
|
||||
if (setup_q931.GetCallingPartyNumber(calling_number, &plan, &type, &present, &screen))
|
||||
{
|
||||
SCPY(callerinfo->id, calling_number.GetPointer());
|
||||
switch (present)
|
||||
{
|
||||
case 1:
|
||||
callerinfo->present = INFO_PRESENT_RESTRICTED;
|
||||
break;
|
||||
case 2:
|
||||
callerinfo->present = INFO_PRESENT_NOTAVAIL;
|
||||
break;
|
||||
default:
|
||||
callerinfo->present = INFO_PRESENT_ALLOWED;
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case Q931::InternationalType:
|
||||
callerinfo->ntype = INFO_NTYPE_INTERNATIONAL;
|
||||
break;
|
||||
case Q931::NationalType:
|
||||
callerinfo->ntype = INFO_NTYPE_NATIONAL;
|
||||
break;
|
||||
case Q931::SubscriberType:
|
||||
callerinfo->ntype = INFO_NTYPE_SUBSCRIBER;
|
||||
break;
|
||||
default:
|
||||
callerinfo->ntype = INFO_NTYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
switch (screen)
|
||||
{
|
||||
case 0:
|
||||
callerinfo->screen = INFO_SCREEN_USER;
|
||||
break;
|
||||
default:
|
||||
callerinfo->screen = INFO_SCREEN_NETWORK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
redirinfo->itype = INFO_ITYPE_H323;
|
||||
// get redirecting number information
|
||||
if (setup_q931.GetRedirectingNumber(redir_number, &plan, &type, &present, &screen, &reason))
|
||||
{
|
||||
SCPY(redirinfo->id, redir_number.GetPointer());
|
||||
switch (present)
|
||||
{
|
||||
case 1:
|
||||
redirinfo->present = INFO_PRESENT_RESTRICTED;
|
||||
break;
|
||||
case 2:
|
||||
redirinfo->present = INFO_PRESENT_NOTAVAIL;
|
||||
break;
|
||||
default:
|
||||
redirinfo->present = INFO_PRESENT_ALLOWED;
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case Q931::InternationalType:
|
||||
redirinfo->ntype = INFO_NTYPE_INTERNATIONAL;
|
||||
break;
|
||||
case Q931::NationalType:
|
||||
redirinfo->ntype = INFO_NTYPE_NATIONAL;
|
||||
break;
|
||||
case Q931::SubscriberType:
|
||||
redirinfo->ntype = INFO_NTYPE_SUBSCRIBER;
|
||||
break;
|
||||
default:
|
||||
redirinfo->ntype = INFO_NTYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
switch (screen)
|
||||
{
|
||||
case 0:
|
||||
redirinfo->screen = INFO_SCREEN_USER;
|
||||
break;
|
||||
default:
|
||||
redirinfo->screen = INFO_SCREEN_NETWORK;
|
||||
break;
|
||||
}
|
||||
switch (reason)
|
||||
{
|
||||
case 1:
|
||||
redirinfo->reason = INFO_REDIR_BUSY;
|
||||
break;
|
||||
case 2:
|
||||
redirinfo->reason = INFO_REDIR_NORESPONSE;
|
||||
break;
|
||||
case 15:
|
||||
redirinfo->reason = INFO_REDIR_UNCONDITIONAL;
|
||||
break;
|
||||
case 10:
|
||||
redirinfo->reason = INFO_REDIR_CALLDEFLECT;
|
||||
break;
|
||||
case 9:
|
||||
redirinfo->reason = INFO_REDIR_OUTOFORDER;
|
||||
break;
|
||||
default:
|
||||
redirinfo->reason = INFO_REDIR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get remote party h323-address information
|
||||
calleraddress = GetRemotePartyAddress();
|
||||
callerip[0] = '\0';
|
||||
if (calleraddress)
|
||||
{
|
||||
if (strstr(calleraddress, "ip$"))
|
||||
{
|
||||
SCPY(callerip, strstr(calleraddress, "ip$")+3);
|
||||
if (strchr(callerip, ':'))
|
||||
*strchr(callerip, ':') = '\0';
|
||||
memmove(strstr(calleraddress, "ip$"), strstr(calleraddress, "ip$")+3, strlen(strstr(calleraddress, "ip$")+3)+1);
|
||||
}
|
||||
if (strchr(calleraddress, ':'))
|
||||
*strchr(calleraddress, ':') = '\0';
|
||||
}
|
||||
|
||||
// get dialing information
|
||||
for(i=0; i<adr.GetSize(); i++)
|
||||
if (adr[i].GetTag() == H225_AliasAddress::e_dialedDigits)
|
||||
dialing = H323GetAliasAddressString(adr[i]);
|
||||
if (!dialing)
|
||||
dialing = "";
|
||||
|
||||
// fill port's information
|
||||
if (calleraddress)
|
||||
SCPY(callerinfo->voip, (char *)calleraddress);
|
||||
capainfo->bearer_mode = INFO_BMODE_CIRCUIT;
|
||||
capainfo->bearer_info1 = (options.law=='u')?INFO_INFO1_ULAW:INFO_INFO1_ALAW;
|
||||
capainfo->bearer_capa = INFO_BC_SPEECH;
|
||||
|
||||
// change to incoming setup state
|
||||
port->new_state(PORT_STATE_IN_OVERLAP);
|
||||
|
||||
// allocate new endpoint
|
||||
if (!(epoint = new Endpoint(port->p_serial, 0)))
|
||||
{
|
||||
// error allocating endpoint
|
||||
PDEBUG(DEBUG_H323, "h323-connection(%s) rejecting call because cannot create epoint for '%s'\n", port->p_name, callerinfo->id);
|
||||
delete port;
|
||||
port = NULL;
|
||||
mutex_h323.Signal();
|
||||
return AnswerCallDenied;
|
||||
}
|
||||
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
|
||||
{
|
||||
PERROR("no memory for application\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (!(port->epointlist_new(epoint->ep_serial)))
|
||||
{
|
||||
PERROR("no memory for epointlist\n");
|
||||
exit(-1);
|
||||
}
|
||||
port->set_tone(NULL, "");
|
||||
|
||||
// send setup message to endpoint
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
|
||||
message->param.setup.port_type = port->p_type;
|
||||
|
||||
// before we start, we may check for h323_gateway entry
|
||||
if (callerip[0])
|
||||
{
|
||||
extension = parse_h323gateway(callerip, option, sizeof(option));
|
||||
if (extension)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "h323-connection(%s) gateway '%s' is mapped to extension '%s' (option= '%s')\n", port->p_name, callerip, extension, option);
|
||||
SCPY(callerinfo->id, extension);
|
||||
SCPY(callerinfo->intern, extension);
|
||||
callerinfo->itype = INFO_ITYPE_INTERN;
|
||||
callerinfo->screen = INFO_SCREEN_NETWORK;
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "h323-connection(%s) gateway '%s' is not mapped to any extension. (port_type=0x%x)\n", port->p_name, callerip, port->p_type);
|
||||
// get the default dialing external dialing string
|
||||
}
|
||||
}
|
||||
|
||||
// default dialing for extenal calls
|
||||
if (!callerinfo->intern[0] && !dialing[0])
|
||||
dialing = options.h323_icall_prefix;
|
||||
|
||||
// dialing information
|
||||
if (callerip[0] || dialing[0])
|
||||
{
|
||||
SCPY(dialinginfo->number, (char *)dialing);
|
||||
dialinginfo->ntype = INFO_NTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
memcpy(&message->param.setup.callerinfo, callerinfo, sizeof(struct caller_info));
|
||||
memcpy(&message->param.setup.dialinginfo, dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.capainfo, capainfo, sizeof(struct capa_info));
|
||||
message->param.setup.dtmf = 1;
|
||||
message_put(message);
|
||||
|
||||
port->p_h323_connect = &(connectPDU.GetQ931());
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
if (!strcasecmp(option, "connect") || !strcasecmp(option, "dtmf"))
|
||||
{
|
||||
port->new_state(PORT_STATE_CONNECT);
|
||||
return AnswerCallNow;
|
||||
} else
|
||||
{
|
||||
return AnswerCallDeferred;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// OnOutgoingCall (outgoing call)
|
||||
//
|
||||
BOOL H323_con::OnOutgoingCall(const H323SignalPDU &connectPDU)
|
||||
{
|
||||
class H323Port *port;
|
||||
const char *calleraddress;
|
||||
char callerip[32];
|
||||
const unsigned char *token_string = callToken;
|
||||
struct message *message;
|
||||
// H225_Connect_UUIE &connect_uuie = connectPDU.m_h323_uu_pdu.m_h323_message_body;
|
||||
|
||||
const Q931 connect_q931 = connectPDU.GetQ931();
|
||||
PString connect_number;
|
||||
unsigned type = 0, plan = 0, present = 0, screen = 0;
|
||||
struct connect_info *connectinfo;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 connection outgoing call is connected.\n");
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR(" cannot find port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return FALSE;
|
||||
}
|
||||
connectinfo = &port->p_connectinfo;
|
||||
|
||||
if (port->p_type == PORT_TYPE_H323_IN)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint OnConnectionEstablished() incoming port\n");
|
||||
}
|
||||
if (port->p_type == PORT_TYPE_H323_OUT)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint OnConnectionEstablished() outgoing port\n");
|
||||
if (port->p_state==PORT_STATE_OUT_SETUP
|
||||
|| port->p_state==PORT_STATE_OUT_OVERLAP
|
||||
|| port->p_state==PORT_STATE_OUT_PROCEEDING
|
||||
|| port->p_state==PORT_STATE_OUT_ALERTING)
|
||||
{
|
||||
// get remote party h323-address information
|
||||
calleraddress = GetRemotePartyAddress();
|
||||
callerip[0] = '\0';
|
||||
if (calleraddress)
|
||||
{
|
||||
if (strchr(calleraddress, '$'))
|
||||
{
|
||||
SCPY(callerip, strchr(calleraddress, '$'));
|
||||
callerip[sizeof(callerip)-1] = '\0';
|
||||
if (strchr(callerip, ':'))
|
||||
*strchr(callerip, ':') = '\0';
|
||||
}
|
||||
SCPY(connectinfo->voip, (char *)calleraddress);
|
||||
}
|
||||
|
||||
// get COLP
|
||||
memset(connectinfo, 0, sizeof(struct connect_info));
|
||||
connectinfo->itype = INFO_ITYPE_H323;
|
||||
if (connect_q931.GetConnectedNumber(connect_number, &plan, &type, &present, &screen))
|
||||
{
|
||||
SCPY(connectinfo->id, connect_number.GetPointer());
|
||||
switch (present)
|
||||
{
|
||||
case 1:
|
||||
connectinfo->present = INFO_PRESENT_RESTRICTED;
|
||||
break;
|
||||
case 2:
|
||||
connectinfo->present = INFO_PRESENT_NOTAVAIL;
|
||||
break;
|
||||
default:
|
||||
connectinfo->present = INFO_PRESENT_ALLOWED;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case Q931::InternationalType:
|
||||
connectinfo->ntype = INFO_NTYPE_INTERNATIONAL;
|
||||
break;
|
||||
case Q931::NationalType:
|
||||
connectinfo->ntype = INFO_NTYPE_NATIONAL;
|
||||
break;
|
||||
case Q931::SubscriberType:
|
||||
connectinfo->ntype = INFO_NTYPE_SUBSCRIBER;
|
||||
break;
|
||||
default:
|
||||
connectinfo->ntype = INFO_NTYPE_UNKNOWN;
|
||||
}
|
||||
switch (screen)
|
||||
{
|
||||
case 0:
|
||||
connectinfo->screen = INFO_SCREEN_USER;
|
||||
break;
|
||||
default:
|
||||
connectinfo->screen = INFO_SCREEN_NETWORK;
|
||||
}
|
||||
}
|
||||
port->new_state(PORT_STATE_CONNECT);
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
|
||||
memcpy(&message->param.connectinfo, connectinfo, sizeof(struct connect_info));
|
||||
message_put(message);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
return H323Connection::OnOutgoingCall(connectPDU);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// send setup information to the called h323 user
|
||||
//
|
||||
BOOL H323_con::OnSendSignalSetup(H323SignalPDU &setupPDU)
|
||||
{
|
||||
H225_Setup_UUIE &setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
|
||||
H225_ArrayOf_AliasAddress &adr = setup.m_sourceAddress;
|
||||
H225_AliasAddress new_alias;
|
||||
PString calling_number;
|
||||
PString calling_alias;
|
||||
PString dialing_number;
|
||||
PString redir_number;
|
||||
int type, present, screen, reason;
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = callToken;
|
||||
|
||||
struct caller_info *callerinfo;
|
||||
struct dialing_info *dialinginfo;
|
||||
struct capa_info *capainfo;
|
||||
struct redir_info *redirinfo;
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR(" no port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return FALSE;
|
||||
}
|
||||
callerinfo = &port->p_callerinfo;
|
||||
redirinfo = &port->p_redirinfo;
|
||||
capainfo = &port->p_capainfo;
|
||||
dialinginfo = &port->p_dialinginfo;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323-connection sending modified setup signal '%s'->'%s'\n", callerinfo->id, dialinginfo->number);
|
||||
|
||||
|
||||
if (callerinfo->present!=INFO_PRESENT_NULL)
|
||||
{
|
||||
calling_alias = numberrize_callerinfo(callerinfo->id, callerinfo->ntype);
|
||||
H323SetAliasAddress(calling_alias, new_alias);
|
||||
adr.SetSize(adr.GetSize()+1);
|
||||
adr[adr.GetSize()-1] = new_alias;
|
||||
|
||||
calling_number = callerinfo->id;
|
||||
switch(callerinfo->ntype)
|
||||
{
|
||||
case INFO_NTYPE_SUBSCRIBER:
|
||||
type = Q931::SubscriberType;
|
||||
break;
|
||||
case INFO_NTYPE_NATIONAL:
|
||||
type = Q931::NationalType;
|
||||
break;
|
||||
case INFO_NTYPE_INTERNATIONAL:
|
||||
type = Q931::InternationalType;
|
||||
break;
|
||||
default: /* INFO_NTYPE_UNKNOWN */
|
||||
type = Q931::UnknownType;
|
||||
}
|
||||
|
||||
switch(callerinfo->present)
|
||||
{
|
||||
case INFO_PRESENT_RESTRICTED:
|
||||
present = 1;
|
||||
break;
|
||||
case INFO_PRESENT_NOTAVAIL:
|
||||
present = 2;
|
||||
break;
|
||||
default: /* INFO_PRESENT_ALLOWED */
|
||||
present = 0;
|
||||
}
|
||||
switch(callerinfo->screen)
|
||||
{
|
||||
case INFO_SCREEN_USER:
|
||||
screen = 0;
|
||||
break;
|
||||
default: /* INFO_SCREEN_NETWORK */
|
||||
screen = 3;
|
||||
}
|
||||
|
||||
Q931 &new_q931 = setupPDU.GetQ931();
|
||||
new_q931.SetCallingPartyNumber(calling_number, Q931::ISDNPlan, type, present, screen);
|
||||
}
|
||||
|
||||
if (redirinfo->present!=INFO_PRESENT_NULL)
|
||||
{
|
||||
if (redirinfo->present==INFO_PRESENT_ALLOWED)
|
||||
{
|
||||
redir_number = callerinfo->id;
|
||||
} else
|
||||
redir_number = "";
|
||||
|
||||
switch(redirinfo->ntype)
|
||||
{
|
||||
case INFO_NTYPE_SUBSCRIBER:
|
||||
type = Q931::SubscriberType;
|
||||
break;
|
||||
case INFO_NTYPE_NATIONAL:
|
||||
type = Q931::NationalType;
|
||||
break;
|
||||
case INFO_NTYPE_INTERNATIONAL:
|
||||
type = Q931::InternationalType;
|
||||
break;
|
||||
default: /* INFO_TYPE_UNKNOWN */
|
||||
type = Q931::UnknownType;
|
||||
}
|
||||
|
||||
switch(redirinfo->present)
|
||||
{
|
||||
case INFO_PRESENT_RESTRICTED:
|
||||
present = 1;
|
||||
break;
|
||||
case INFO_PRESENT_NOTAVAIL:
|
||||
present = 2;
|
||||
break;
|
||||
default: /* INFO_PRESENT_ALLOWED */
|
||||
present = 0;
|
||||
}
|
||||
|
||||
switch(redirinfo->reason)
|
||||
{
|
||||
case INFO_REDIR_BUSY:
|
||||
reason = 1;
|
||||
break;
|
||||
case INFO_REDIR_NORESPONSE:
|
||||
reason = 2;
|
||||
break;
|
||||
case INFO_REDIR_UNCONDITIONAL:
|
||||
reason = 15;
|
||||
break;
|
||||
case INFO_REDIR_OUTOFORDER:
|
||||
reason = 9;
|
||||
break;
|
||||
case INFO_REDIR_CALLDEFLECT:
|
||||
reason = 10;
|
||||
break;
|
||||
default: /* INFO_REDIR_UNKNOWN */
|
||||
reason = 0;
|
||||
}
|
||||
|
||||
Q931 &new_q931 = setupPDU.GetQ931();
|
||||
new_q931.SetRedirectingNumber(redir_number, Q931::ISDNPlan, type, present, screen, reason);
|
||||
}
|
||||
|
||||
if (dialinginfo->number[0])
|
||||
{
|
||||
dialing_number = dialinginfo->number;
|
||||
|
||||
Q931 &new_q931 = setupPDU.GetQ931();
|
||||
new_q931.SetCalledPartyNumber(dialing_number);
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
return H323Connection::OnSendSignalSetup(setupPDU);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// callback for start of channel
|
||||
//
|
||||
BOOL H323_con::OnStartLogicalChannel(H323Channel &channel)
|
||||
{
|
||||
if (!H323Connection::OnStartLogicalChannel(channel))
|
||||
{
|
||||
PERROR("starting logical channel failed!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 connection starting logical channel using \"%s\" codec %s :%s\n",
|
||||
channel.GetCapability().GetFormatName().GetPointer(),
|
||||
(channel.GetDirection()==H323Channel::IsTransmitter)?"transmit":"receive",
|
||||
callToken.GetPointer());
|
||||
|
||||
return H323Connection::OnStartLogicalChannel(channel);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// user input received
|
||||
//
|
||||
void H323_con::OnUserInputString (const PString &value)
|
||||
{
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = callToken;
|
||||
const unsigned char *value_string = value;
|
||||
struct message *message;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323-connection received user input'%s'\n", value_string);
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("no port with token '%s'\n", token_string);
|
||||
} else
|
||||
{
|
||||
while(*value_string)
|
||||
{
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
|
||||
message->param.dtmf = *value_string++;
|
||||
message_put(message);
|
||||
}
|
||||
#if 0
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
|
||||
SCPY(message->param.information.number, (char *)value_string);
|
||||
message_put(message);
|
||||
#endif
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
}
|
||||
|
35
h323_con.h
35
h323_con.h
|
@ -1,35 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// h323_con connection header file //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef H323_CON_HEADER
|
||||
#define H323_CON_HEADER
|
||||
|
||||
class H323_chan;
|
||||
class H323_con : public H323Connection
|
||||
{
|
||||
public:
|
||||
|
||||
H323_con(H323_ep &endpoint, unsigned callReference);
|
||||
~H323_con();
|
||||
AnswerCallResponse OnAnswerCall(const PString &, const H323SignalPDU &, H323SignalPDU &);
|
||||
BOOL OnOutgoingCall(const H323SignalPDU &connectPDU);
|
||||
BOOL OnSendSignalSetup(H323SignalPDU &);
|
||||
BOOL OnStartLogicalChannel(H323Channel &channel);
|
||||
void OnUserInputString (const PString &value);
|
||||
H323SignalPDU *GetConnectPDU(void);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // H323_CON_HEADER
|
||||
|
||||
|
503
h323_ep.cpp
503
h323_ep.cpp
|
@ -1,503 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// h323_ep class //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
NOTE:
|
||||
|
||||
The code was inspired by the isdn2h323 gateway my marco bode.
|
||||
Thanx to marco budde for lerarning to program h323 and c++ from your code.
|
||||
His homepage is www.telos.de, there you'll find the isdn2h323 gateway.
|
||||
|
||||
Also thanx to others who write documents and applications for OpenH323.
|
||||
|
||||
Andreas Eversberg
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include "main.h"
|
||||
|
||||
//#include <gsmcodec.h>
|
||||
//#include <g7231codec.h>
|
||||
//#include <g729codec.h>
|
||||
//#include "g726codec.h"
|
||||
//#include <speexcodec.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// constructor
|
||||
//
|
||||
H323_ep::H323_ep(void)
|
||||
{
|
||||
terminalType = e_GatewayOnly;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint constuctor\n");
|
||||
}
|
||||
|
||||
//
|
||||
// destructor
|
||||
//
|
||||
H323_ep::~H323_ep()
|
||||
{
|
||||
// clear all calls to remote endpoints
|
||||
ClearAllCalls();
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint destuctor\n");
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// create connection
|
||||
//
|
||||
H323Connection *H323_ep::CreateConnection(unsigned callReference)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint create connection\n");
|
||||
|
||||
return new H323_con(*this, callReference);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// on establishment of conneciton
|
||||
//
|
||||
void H323_ep::OnConnectionEstablished(H323Connection &connection, const PString &token)
|
||||
{
|
||||
const unsigned char *token_string = token;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint connection established to: %s\n", token_string);
|
||||
|
||||
H323EndPoint::OnConnectionEstablished(connection, token);
|
||||
}
|
||||
|
||||
//
|
||||
// on remote alerting
|
||||
//
|
||||
BOOL H323_ep::OnAlerting(H323Connection &connection, const H323SignalPDU &alertingPDU, const PString &user)
|
||||
{
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = connection.GetCallToken();
|
||||
const unsigned char *user_string = user;
|
||||
struct message *message;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint alerting at: %s\n", user_string);
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port=(class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("cannot find port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return FALSE;
|
||||
}
|
||||
if (port->p_state==PORT_STATE_OUT_SETUP
|
||||
|| port->p_state==PORT_STATE_OUT_OVERLAP
|
||||
|| port->p_state==PORT_STATE_OUT_PROCEEDING)
|
||||
{
|
||||
port->new_state(PORT_STATE_OUT_ALERTING);
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_ALERTING);
|
||||
message_put(message);
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// on clearing of connection
|
||||
//
|
||||
void H323_ep::OnConnectionCleared(H323Connection &connection, const PString &token)
|
||||
{
|
||||
int cause;
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = token;
|
||||
struct message *message;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint connection cleared.\n");
|
||||
|
||||
mutex_h323.Wait();
|
||||
|
||||
if (!(port=(class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("cannot find port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(connection.GetCallEndReason())
|
||||
{
|
||||
case H323Connection::EndedByRemoteUser:
|
||||
case H323Connection::EndedByCallerAbort:
|
||||
case H323Connection::EndedByGatekeeper:
|
||||
case H323Connection::EndedByCallForwarded:
|
||||
cause = 16; // normal call clearing
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByRefusal:
|
||||
case H323Connection::EndedBySecurityDenial:
|
||||
cause = 21; // call rejected
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByNoAnswer:
|
||||
cause = 19; // no answer from user
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByTransportFail:
|
||||
cause = 47; // resource unavaiable, unspecified
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByNoBandwidth:
|
||||
cause = 49; // quality of service not available
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByNoUser:
|
||||
cause = 1; // unallocated number
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByCapabilityExchange:
|
||||
cause = 65; // bearer capability not implemented
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByRemoteBusy:
|
||||
cause = 17; // user busy
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByRemoteCongestion:
|
||||
cause = 42; // switching equipment congestion
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByUnreachable:
|
||||
cause = 2; // no route ...
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByNoEndPoint:
|
||||
case H323Connection::EndedByConnectFail:
|
||||
cause = 18; // no user responding
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByHostOffline:
|
||||
cause = 27; // destination out of order
|
||||
break;
|
||||
|
||||
case H323Connection::EndedByTemporaryFailure:
|
||||
cause = 41; // temporary failure
|
||||
break;
|
||||
|
||||
default:
|
||||
cause = 31; // normal, unspecified
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// delete channels
|
||||
if (port->p_h323_channel_in)
|
||||
delete port->p_h323_channel_in;
|
||||
port->p_h323_channel_in = NULL;
|
||||
if (port->p_h323_channel_out)
|
||||
delete port->p_h323_channel_out;
|
||||
port->p_h323_channel_out = NULL;
|
||||
|
||||
/* release endpoint */
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
|
||||
message->param.disconnectinfo.cause = cause;
|
||||
message->param.disconnectinfo.location = LOCATION_BEYOND;
|
||||
message_put(message);
|
||||
|
||||
/* delete port */
|
||||
delete port;
|
||||
|
||||
mutex_h323.Signal();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// open audio channel
|
||||
//
|
||||
BOOL H323_ep::OpenAudioChannel(H323Connection &connection, BOOL isEncoding, unsigned bufferSize, H323AudioCodec &codec)
|
||||
{
|
||||
H323_chan *channel;
|
||||
class H323Port *port;
|
||||
const unsigned char *token_string = connection.GetCallToken();
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint audio channel open (isEndcoding=%d).\n", isEncoding);
|
||||
|
||||
// disable the silence detection
|
||||
codec.SetSilenceDetectionMode (H323AudioCodec::NoSilenceDetection);
|
||||
|
||||
// create channels
|
||||
if (isEncoding)
|
||||
{
|
||||
channel = new H323_chan(connection.GetCallToken(), TRUE);
|
||||
} else
|
||||
{
|
||||
channel = new H323_chan(connection.GetCallToken(), FALSE);
|
||||
}
|
||||
if (!channel)
|
||||
{
|
||||
PERROR("channel for token '%s' not set", token_string);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// return the channel object
|
||||
mutex_h323.Wait();
|
||||
if (!(port=(class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("cannot find port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// set channels
|
||||
if (isEncoding)
|
||||
{
|
||||
port->p_h323_channel_out = channel;
|
||||
} else
|
||||
{
|
||||
port->p_h323_channel_in = channel;
|
||||
}
|
||||
|
||||
mutex_h323.Signal();
|
||||
return codec.AttachChannel(channel, FALSE);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// open video channel
|
||||
//
|
||||
BOOL H323_ep::OpenVideoChannel(H323Connection &connection, BOOL isEncoding, H323VideoCodec &codec)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint video channel open (isEndcoding=%d).\n", isEncoding);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// initialize H323 endpoint
|
||||
//
|
||||
BOOL H323_ep::Init(void)
|
||||
{
|
||||
H323ListenerTCP *listener;
|
||||
int pri;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint initialize\n");
|
||||
|
||||
// add keypad capability
|
||||
H323_UserInputCapability::AddAllCapabilities(capabilities, 0, P_MAX_INDEX);
|
||||
|
||||
/* will add codec in order of priority 1 = highest, 0 = don't use */
|
||||
pri = 1;
|
||||
while (pri < 256)
|
||||
{
|
||||
#warning codecs are temporarily disabled due to api change
|
||||
#if 0
|
||||
if (options.h323_gsm_pri == pri)
|
||||
{
|
||||
H323_GSM0610Capability * gsm_cap;
|
||||
MicrosoftGSMAudioCapability * msgsm_cap;
|
||||
|
||||
SetCapability(0, 0, gsm_cap = new H323_GSM0610Capability);
|
||||
gsm_cap->SetTxFramesInPacket(options.h323_gsm_opt);
|
||||
SetCapability(0, 0, msgsm_cap = new MicrosoftGSMAudioCapability);
|
||||
msgsm_cap->SetTxFramesInPacket(options.h323_gsm_opt);
|
||||
}
|
||||
if (options.h323_g726_pri == pri)
|
||||
{
|
||||
if (options.h323_g726_opt > 4)
|
||||
SetCapability(0, 0, new H323_G726_Capability(*this, H323_G726_Capability::e_40k));
|
||||
if (options.h323_g726_opt > 3)
|
||||
SetCapability(0, 0, new H323_G726_Capability(*this, H323_G726_Capability::e_32k));
|
||||
if (options.h323_g726_opt > 2)
|
||||
SetCapability(0, 0, new H323_G726_Capability(*this, H323_G726_Capability::e_24k));
|
||||
SetCapability(0, 0, new H323_G726_Capability(*this, H323_G726_Capability::e_16k));
|
||||
}
|
||||
if (options.h323_g7231_pri == pri)
|
||||
{
|
||||
#if 0
|
||||
SetCapability(0, 0, new H323_G7231Capability(FALSE));
|
||||
#endif
|
||||
}
|
||||
if (options.h323_g729a_pri == pri)
|
||||
{
|
||||
#if 0
|
||||
SetCapability(0, 0, new H323_G729Capability());
|
||||
#endif
|
||||
}
|
||||
if (options.h323_lpc10_pri == pri)
|
||||
{
|
||||
SetCapability(0, 0, new H323_LPC10Capability(*this));
|
||||
}
|
||||
if (options.h323_speex_pri == pri)
|
||||
{
|
||||
if (options.h323_speex_opt > 5)
|
||||
SetCapability(0, 0, new SpeexNarrow6AudioCapability());
|
||||
if (options.h323_speex_opt > 4)
|
||||
SetCapability(0, 0, new SpeexNarrow5AudioCapability());
|
||||
if (options.h323_speex_opt > 3)
|
||||
SetCapability(0, 0, new SpeexNarrow4AudioCapability());
|
||||
if (options.h323_speex_opt > 2)
|
||||
SetCapability(0, 0, new SpeexNarrow3AudioCapability());
|
||||
SetCapability(0, 0, new SpeexNarrow2AudioCapability());
|
||||
}
|
||||
if (options.h323_xspeex_pri == pri)
|
||||
{
|
||||
if (options.h323_xspeex_opt > 5)
|
||||
SetCapability(0, 0, new XiphSpeexNarrow6AudioCapability());
|
||||
if (options.h323_xspeex_opt > 4)
|
||||
SetCapability(0, 0, new XiphSpeexNarrow5AudioCapability());
|
||||
if (options.h323_xspeex_opt > 3)
|
||||
SetCapability(0, 0, new XiphSpeexNarrow4AudioCapability());
|
||||
if (options.h323_xspeex_opt > 2)
|
||||
SetCapability(0, 0, new XiphSpeexNarrow3AudioCapability());
|
||||
SetCapability(0, 0, new XiphSpeexNarrow2AudioCapability());
|
||||
}
|
||||
#endif
|
||||
if (options.h323_law_pri == pri)
|
||||
{
|
||||
H323_G711Capability * g711uCap;
|
||||
H323_G711Capability * g711aCap;
|
||||
SetCapability(0, 0, g711uCap = new H323_G711Capability (H323_G711Capability::ALaw/*, H323_G711Capability::At64k*/));
|
||||
#warning H323_law frame size is disabled due to bug in OpenH323
|
||||
// g711uCap->SetTxFramesInPacket(options.h323_law_opt);
|
||||
SetCapability(0, 0, g711aCap = new H323_G711Capability (H323_G711Capability::muLaw/*, H323_G711Capability::At64k*/));
|
||||
// g711aCap->SetTxFramesInPacket(options.h323_law_opt);
|
||||
}
|
||||
pri++;
|
||||
}
|
||||
|
||||
// h323 user is the hostname or given by h323_name
|
||||
if (options.h323_name[0] == '\0')
|
||||
{
|
||||
if (getenv("HOSTNAME") == NULL)
|
||||
{
|
||||
cout << "OpenH323: Environment variable HOSTNAME not set. Please specify 'h323_name' in options.conf" << endl;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
SetLocalUserName((options.h323_name[0])?options.h323_name:getenv("HOSTNAME"));
|
||||
|
||||
// create listener
|
||||
if (options.h323_icall)
|
||||
{
|
||||
PIPSocket::Address interfaceAddress(INADDR_ANY);
|
||||
listener = new H323ListenerTCP(*this, interfaceAddress, options.h323_port);
|
||||
if (!StartListener(listener))
|
||||
{
|
||||
cout << "OpenH323: Could not open H323 port " << listener->GetListenerPort() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
cout << "OpenH323: Waiting for incoming H323 connections on port " << listener->GetListenerPort() << endl;
|
||||
}
|
||||
|
||||
// register with gatekeeper
|
||||
if (options.h323_gatekeeper)
|
||||
{
|
||||
if (options.h323_gatekeeper_host[0] == '\0')
|
||||
{
|
||||
if (DiscoverGatekeeper(new H323TransportUDP(*this)))
|
||||
{
|
||||
cout << "OpenH323: Registering with gatekeeper " << gatekeeper->GetIdentifier() << " (automatically)" << endl;
|
||||
} else
|
||||
{
|
||||
cout << "OpenH323: Gatekeeper not found." << endl;
|
||||
sleep(2);
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (SetGatekeeper(options.h323_gatekeeper_host) == TRUE)
|
||||
{
|
||||
cout << "OpenH323: Registering with gatekeeper " << gatekeeper->GetIdentifier() << " (automatically)" << endl;
|
||||
} else
|
||||
{
|
||||
cout << "OpenH323: Gatekeeper at " << gatekeeper->GetIdentifier() << " not found." << endl;
|
||||
sleep(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// make an outgoing h323 call
|
||||
//
|
||||
|
||||
BOOL H323_ep::Call(char *token_string, char *caller, char *host)
|
||||
{
|
||||
PString address;
|
||||
PString token = "";
|
||||
BOOL failed = FALSE;
|
||||
class H323Port *port;
|
||||
struct message *message;
|
||||
char *newtoken_string;
|
||||
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint call to host '%s'\n", host);
|
||||
|
||||
address = host;
|
||||
|
||||
if (!MakeCall(address, token))
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint call to host '%s'\n", host);
|
||||
failed = TRUE;
|
||||
}
|
||||
|
||||
// set new token
|
||||
mutex_h323.Wait();
|
||||
if (!(port=(class H323Port *)find_port_with_token((char *)token_string)))
|
||||
{
|
||||
PERROR("cannot find port with token '%s'\n", token_string);
|
||||
mutex_h323.Signal();
|
||||
return FALSE;
|
||||
}
|
||||
if (failed == TRUE)
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "call of port '%s' failed.\n", token_string);
|
||||
message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
|
||||
message->param.disconnectinfo.cause = 31;
|
||||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
message_put(message);
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_H323, "changing port name from '%s' to token '%s'\n", token_string, token.GetPointer());
|
||||
newtoken_string = token.GetPointer();
|
||||
SCPY(port->p_name, newtoken_string);
|
||||
}
|
||||
mutex_h323.Signal();
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint call to host '%s'\n", host);
|
||||
|
||||
if (failed == TRUE)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void H323_ep::SetEndpointTypeInfo(H225_EndpointType &info) const
|
||||
{
|
||||
// H225_VoiceCaps voicecaps;
|
||||
PDEBUG(DEBUG_H323, "H323 endpoint set endpoint type info *TBD*\n");
|
||||
|
||||
H323EndPoint::SetEndpointTypeInfo(info);
|
||||
|
||||
// protocols.SetTag(H225_SupportedProtocols::e_voice);
|
||||
// (H225_VoiceCaps&)protocols = voicecaps;
|
||||
// a_protocols.SetSize(1);
|
||||
// a_protocols[0] = protocols;
|
||||
|
||||
// gateway.IncludeOptionalField(H225_GatewayInfo::e_protocol);
|
||||
// gateway.m_protocol = a_protocols;
|
||||
// info.m_gateway = gateway;
|
||||
}
|
37
h323_ep.h
37
h323_ep.h
|
@ -1,37 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PBX4Linux //
|
||||
// //
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright: Andreas Eversberg //
|
||||
// //
|
||||
// h323_ep endpoint header file //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef H323_EP_HEADER
|
||||
#define H323_EP_HEADER
|
||||
|
||||
class H323_con;
|
||||
class H323_ep : public H323EndPoint
|
||||
{
|
||||
public:
|
||||
H323_ep(void);
|
||||
~H323_ep();
|
||||
H323Connection *CreateConnection(unsigned callReference);
|
||||
void OnConnectionEstablished(H323Connection &connection, const PString &token);
|
||||
BOOL OnAlerting(H323Connection &connection, const H323SignalPDU &alertingPDU, const PString &user);
|
||||
void OnConnectionCleared(H323Connection &connection, const PString &token);
|
||||
BOOL OpenAudioChannel(H323Connection &connection, BOOL isEncoding, unsigned bufferSize, H323AudioCodec &codec);
|
||||
BOOL OpenVideoChannel(H323Connection &connection, BOOL isEncoding, H323VideoCodec &codec);
|
||||
BOOL Init(void);
|
||||
void SetEndpointTypeInfo (H225_EndpointType & info) const;
|
||||
BOOL Call(char *token_string, char *caller, char *host);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // H323_EP_HEADER
|
||||
|
137
h323conf.c
137
h323conf.c
|
@ -1,137 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** parse h323 gateway config file **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "main.h"
|
||||
|
||||
/* parse h323_gateway.conf
|
||||
*
|
||||
* searches for the given ip and returns the extension or NULL if not found
|
||||
*/
|
||||
char *parse_h323gateway(char *ip, char *opt, int opt_size)
|
||||
{
|
||||
FILE *fp=NULL;
|
||||
char filename[256];
|
||||
char *p;
|
||||
unsigned int line,i;
|
||||
char buffer[256];
|
||||
static char host_ip[32], extension[32], option[64];
|
||||
int found = 0;
|
||||
|
||||
SPRINT(filename, "%s/h323_gateway.conf", INSTALL_DATA);
|
||||
|
||||
if (!(fp = fopen(filename, "r")))
|
||||
{
|
||||
PERROR("Cannot open h323 gateway map: \"%s\"\n", filename);
|
||||
return(0);
|
||||
}
|
||||
|
||||
line=0;
|
||||
while((fgets(buffer, sizeof(buffer), fp)))
|
||||
{
|
||||
line++;
|
||||
buffer[sizeof(buffer)-1] = '\0';
|
||||
if (buffer[0]) buffer[strlen(buffer)-1] = '\0';
|
||||
p = buffer;
|
||||
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
if (*p==0 || *p=='#') /* ignore comments and empty line */
|
||||
continue;
|
||||
|
||||
host_ip[0]=0;
|
||||
extension[0]=0;
|
||||
option[0]=0;
|
||||
|
||||
i=0; /* read host ip */
|
||||
while(*p > 32)
|
||||
{
|
||||
if (i+1 >= sizeof(host_ip))
|
||||
{
|
||||
PERROR_RUNTIME("Error in %s (line %d): ip too long.\n",filename,line);
|
||||
break;
|
||||
}
|
||||
host_ip[i+1] = '\0';
|
||||
host_ip[i++] = *p++;
|
||||
}
|
||||
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p!=0 && *p!='#') /* extension */
|
||||
{
|
||||
i=0; /* read extension */
|
||||
while(*p > 32)
|
||||
{
|
||||
if (i+1 >= sizeof(extension))
|
||||
{
|
||||
PERROR_RUNTIME("Error in %s (line %d): extension too long.\n",filename,line);
|
||||
break;
|
||||
}
|
||||
extension[i+1] = '\0';
|
||||
extension[i++] = *p++;
|
||||
}
|
||||
while(*p <= 32) /* skip spaces */
|
||||
{
|
||||
if (*p == 0)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*p!=0 && *p!='#') /* option */
|
||||
{
|
||||
i=0; /* read option */
|
||||
while(*p > 32)
|
||||
{
|
||||
if (i+1 >= sizeof(option))
|
||||
{
|
||||
PERROR_RUNTIME("Error in %s (line %d): option too long.\n",filename,line);
|
||||
break;
|
||||
}
|
||||
option[i+1] = '\0';
|
||||
option[i++] = *p++;
|
||||
}
|
||||
// ignoring more
|
||||
}
|
||||
|
||||
if (!!strcasecmp(ip, host_ip))
|
||||
continue;
|
||||
|
||||
if (extension[0] == '\0')
|
||||
continue;
|
||||
|
||||
found = 1;
|
||||
break; /* found entry */
|
||||
}
|
||||
|
||||
if (fp) fclose(fp);
|
||||
|
||||
if (found)
|
||||
{
|
||||
UNCPY(opt, option, opt_size-1);
|
||||
opt[opt_size-1] = '\0';
|
||||
return(extension);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
14
h323conf.h
14
h323conf.h
|
@ -1,14 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** h323gw header file **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
char *parse_h323gateway(char *ip, char *opt, int opt_size);
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call functions **
|
||||
** join functions **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
@ -23,25 +23,25 @@
|
|||
//#define __u32 unsigned long
|
||||
//#include "linux/isdnif.h"
|
||||
|
||||
unsigned long call_serial = 1; /* must be 1, because 0== no call */
|
||||
unsigned long join_serial = 1; /* must be 1, because 0== no join */
|
||||
|
||||
//CALL_STATES
|
||||
//JOIN_STATES
|
||||
|
||||
class Call *call_first = NULL;
|
||||
class Join *join_first = NULL;
|
||||
|
||||
/*
|
||||
* find the call with call_id
|
||||
* find the join with join_id
|
||||
*/
|
||||
class Call *find_call_id(unsigned long call_id)
|
||||
class Join *find_join_id(unsigned long join_id)
|
||||
{
|
||||
class Call *call = call_first;
|
||||
class Join *join = join_first;
|
||||
|
||||
while(call)
|
||||
while(join)
|
||||
{
|
||||
//printf("comparing: '%s' with '%s'\n", name, call->c_name);
|
||||
if (call->c_serial == call_id)
|
||||
return(call);
|
||||
call = call->next;
|
||||
//printf("comparing: '%s' with '%s'\n", name, join->c_name);
|
||||
if (join->c_serial == join_id)
|
||||
return(join);
|
||||
join = join->next;
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
@ -49,37 +49,37 @@ class Call *find_call_id(unsigned long call_id)
|
|||
|
||||
|
||||
/*
|
||||
* constructor for a new call
|
||||
* constructor for a new join
|
||||
*/
|
||||
Call::Call(void)
|
||||
Join::Join(void)
|
||||
{
|
||||
class Call **callp;
|
||||
class Join **joinp;
|
||||
|
||||
c_serial = call_serial++;
|
||||
c_type = CALL_TYPE_NONE;
|
||||
c_serial = join_serial++;
|
||||
c_type = JOIN_TYPE_NONE;
|
||||
|
||||
/* attach to chain */
|
||||
next = NULL;
|
||||
callp = &call_first;
|
||||
while(*callp)
|
||||
callp = &((*callp)->next);
|
||||
*callp = this;
|
||||
joinp = &join_first;
|
||||
while(*joinp)
|
||||
joinp = &((*joinp)->next);
|
||||
*joinp = this;
|
||||
|
||||
classuse++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call descructor
|
||||
* join descructor
|
||||
*/
|
||||
Call::~Call()
|
||||
Join::~Join()
|
||||
{
|
||||
class Call *cl, **clp;
|
||||
class Join *cl, **clp;
|
||||
|
||||
classuse--;
|
||||
|
||||
cl = call_first;
|
||||
clp = &call_first;
|
||||
cl = join_first;
|
||||
clp = &join_first;
|
||||
while(cl)
|
||||
{
|
||||
if (cl == this)
|
||||
|
@ -88,46 +88,46 @@ Call::~Call()
|
|||
cl = cl->next;
|
||||
}
|
||||
if (!cl)
|
||||
FATAL("software error, call not in chain!\n");
|
||||
FATAL("software error, join not in chain!\n");
|
||||
*clp = cl->next; /* detach from chain */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* epoint sends a message to a call
|
||||
/* epoint sends a message to a join
|
||||
*
|
||||
*/
|
||||
void Call::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
void Join::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* call process is called from the main loop
|
||||
/* join process is called from the main loop
|
||||
* it processes the current calling state.
|
||||
* returns 0 if call nothing was done
|
||||
* returns 0 if nothing was done
|
||||
*/
|
||||
int Call::handler(void)
|
||||
int Join::handler(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* free all call structures */
|
||||
void call_free(void)
|
||||
/* free all join structures */
|
||||
void join_free(void)
|
||||
{
|
||||
|
||||
if (!call_first)
|
||||
if (!join_first)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "no more pending call(s), done!\n");
|
||||
PDEBUG(DEBUG_JOIN, "no more pending join(s), done!\n");
|
||||
return;
|
||||
}
|
||||
while(call_first)
|
||||
while(join_first)
|
||||
{
|
||||
if (options.deb & DEBUG_CALL)
|
||||
if (options.deb & DEBUG_JOIN)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "freeing pending call\n");
|
||||
PDEBUG(DEBUG_JOIN, "freeing pending join\n");
|
||||
}
|
||||
|
||||
delete call_first;
|
||||
delete join_first;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +1,38 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call header file **
|
||||
** join header file **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
enum { CALL_TYPE_NONE, CALL_TYPE_PBX, CALL_TYPE_ASTERISK};
|
||||
enum { JOIN_TYPE_NONE, JOIN_TYPE_PBX, JOIN_TYPE_ASTERISK};
|
||||
|
||||
/* call
|
||||
/* join
|
||||
*
|
||||
* abstraction for pbx calls and asterisk calls
|
||||
*/
|
||||
|
||||
|
||||
class Call
|
||||
class Join
|
||||
{
|
||||
public:
|
||||
Call();
|
||||
virtual ~Call();
|
||||
class Call *next; /* next node in list of calls */
|
||||
Join();
|
||||
virtual ~Join();
|
||||
class Join *next; /* next node in list of joins */
|
||||
virtual void message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
virtual int handler(void);
|
||||
|
||||
unsigned long c_type; /* call type (pbx or asterisk) */
|
||||
unsigned long c_serial; /* serial/unique number of call */
|
||||
unsigned long c_type; /* join type (pbx or asterisk) */
|
||||
unsigned long c_serial; /* serial/unique number of join */
|
||||
};
|
||||
|
||||
void call_free(void);
|
||||
void join_free(void);
|
||||
|
||||
extern class Call *call_first;
|
||||
extern class Join *join_first;
|
||||
|
||||
class Call *find_call_id(unsigned long call_id);
|
||||
class Join *find_join_id(unsigned long join_id);
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call functions for channel driver **
|
||||
** join functions for channel driver **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
@ -25,41 +25,41 @@
|
|||
|
||||
|
||||
/*
|
||||
* constructor for a new call
|
||||
* the call will have a relation to the calling endpoint
|
||||
* constructor for a new join
|
||||
* the join will have a relation to the calling endpoint
|
||||
*/
|
||||
CallAsterisk::CallAsterisk(unsigned long serial) : Call()
|
||||
JoinAsterisk::JoinAsterisk(unsigned long serial) : Join()
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "Constructor(new call)");
|
||||
PDEBUG(DEBUG_JOIN, "Constructor(new join)");
|
||||
|
||||
c_type = CALL_TYPE_ASTERISK;
|
||||
c_type = JOIN_TYPE_ASTERISK;
|
||||
|
||||
c_epoint_id = serial;
|
||||
if (c_epoint_id)
|
||||
PDEBUG(DEBUG_CALL, "New call connected to endpoint id %lu\n", c_epoint_id);
|
||||
PDEBUG(DEBUG_JOIN, "New join connected to endpoint id %lu\n", c_epoint_id);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call descructor
|
||||
* join descructor
|
||||
*/
|
||||
CallAsterisk::~CallAsterisk()
|
||||
JoinAsterisk::~JoinAsterisk()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* call process is called from the main loop
|
||||
/* join process is called from the main loop
|
||||
* it processes the current calling state.
|
||||
* returns 0 if call nothing was done
|
||||
* returns 0 if join nothing was done
|
||||
*/
|
||||
int CallAsterisk::handler(void)
|
||||
int JoinAsterisk::handler(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void CallAsterisk::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
void JoinAsterisk::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
{
|
||||
/* if endpoint has just been removed, but still a message in the que */
|
||||
if (epoint_id != c_epoint_id)
|
||||
|
@ -68,7 +68,7 @@ void CallAsterisk::message_epoint(unsigned long epoint_id, int message_type, uni
|
|||
/* look for asterisk's interface */
|
||||
if (admin_message_from_join(epoint_id, message_type, param)<0)
|
||||
{
|
||||
PERROR("No socket with asterisk found, this shall not happen. Closing socket shall cause release of all asterisk calls\n");
|
||||
PERROR("No socket with asterisk found, this shall not happen. Closing socket shall cause release of all asterisk joins\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ void CallAsterisk::message_epoint(unsigned long epoint_id, int message_type, uni
|
|||
}
|
||||
}
|
||||
|
||||
void CallAsterisk::message_asterisk(unsigned long callref, int message_type, union parameter *param)
|
||||
void JoinAsterisk::message_asterisk(unsigned long ref, int message_type, union parameter *param)
|
||||
{
|
||||
struct message *message;
|
||||
|
||||
|
@ -88,13 +88,13 @@ void CallAsterisk::message_asterisk(unsigned long callref, int message_type, uni
|
|||
{
|
||||
class Endpoint *epoint;
|
||||
|
||||
if (!(epoint = new Endpoint(0, c_serial, callref)))
|
||||
if (!(epoint = new Endpoint(0, c_serial, ref)))
|
||||
FATAL("No memory for Endpoint instance\n");
|
||||
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
|
||||
FATAL("No memory for Endpoint Application instance\n");
|
||||
}
|
||||
|
||||
message = message_create(c_serial, c_epoint_id, CALL_TO_EPOINT, message_type);
|
||||
message = message_create(c_serial, c_epoint_id, JOIN_TO_EPOINT, message_type);
|
||||
memcpy(&message->param, param, sizeof(message->param));
|
||||
message_put(message);
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** LCR **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call header file for Asterisk interface **
|
||||
** join header file for Asterisk interface **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
class CallAsterisk : public Call
|
||||
class JoinAsterisk : public Join
|
||||
{
|
||||
public:
|
||||
CallAsterisk(unsigned long serial);
|
||||
~CallAsterisk();
|
||||
JoinAsterisk(unsigned long serial);
|
||||
~JoinAsterisk();
|
||||
void message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
void message_asterisk(unsigned long callref, int message_type, union parameter *param);
|
||||
void message_asterisk(unsigned long ref, int message_type, union parameter *param);
|
||||
int handler(void);
|
||||
|
||||
unsigned long c_epoint_id;
|
|
@ -1,11 +1,11 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call functions **
|
||||
** join functions **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
|
||||
/* notify endpoint about state change (if any) */
|
||||
static int notify_state_change(int call_id, int epoint_id, int old_state, int new_state)
|
||||
static int notify_state_change(int join_id, int epoint_id, int old_state, int new_state)
|
||||
{
|
||||
int notify_off = 0, notify_on = 0;
|
||||
struct message *message;
|
||||
|
@ -102,16 +102,16 @@ static int notify_state_change(int call_id, int epoint_id, int old_state, int ne
|
|||
break;
|
||||
}
|
||||
|
||||
if (call_id && notify_off)
|
||||
if (join_id && notify_off)
|
||||
{
|
||||
message = message_create(call_id, epoint_id, CALL_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
message = message_create(join_id, epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
message->param.notifyinfo.notify = notify_off;
|
||||
message_put(message);
|
||||
}
|
||||
|
||||
if (call_id && notify_on)
|
||||
if (join_id && notify_on)
|
||||
{
|
||||
message = message_create(call_id, epoint_id, CALL_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
message = message_create(join_id, epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
message->param.notifyinfo.notify = notify_on;
|
||||
message_put(message);
|
||||
}
|
||||
|
@ -120,30 +120,30 @@ static int notify_state_change(int call_id, int epoint_id, int old_state, int ne
|
|||
}
|
||||
|
||||
|
||||
/* debug function for call */
|
||||
void callpbx_debug(class CallPBX *callpbx, char *function)
|
||||
/* debug function for join */
|
||||
void joinpbx_debug(class JoinPBX *joinpbx, char *function)
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
struct port_list *portlist;
|
||||
class Endpoint *epoint;
|
||||
class Port *port;
|
||||
char buffer[512];
|
||||
|
||||
if (!(options.deb & DEBUG_CALL))
|
||||
if (!(options.deb & DEBUG_JOIN))
|
||||
return;
|
||||
|
||||
PDEBUG(DEBUG_CALL, "CALL(%d) start (called from %s)\n", callpbx->c_serial, function);
|
||||
PDEBUG(DEBUG_JOIN, "join(%d) start (called from %s)\n", joinpbx->c_serial, function);
|
||||
|
||||
relation = callpbx->c_relation;
|
||||
relation = joinpbx->c_relation;
|
||||
|
||||
if (!relation)
|
||||
PDEBUG(DEBUG_CALL, "call has no relations\n");
|
||||
PDEBUG(DEBUG_JOIN, "join has no relations\n");
|
||||
while(relation)
|
||||
{
|
||||
epoint = find_epoint_id(relation->epoint_id);
|
||||
if (!epoint)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "warning: relations epoint id=%ld doesn't exists!\n", relation->epoint_id);
|
||||
PDEBUG(DEBUG_JOIN, "warning: relations epoint id=%ld doesn't exists!\n", relation->epoint_id);
|
||||
relation = relation->next;
|
||||
continue;
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ void callpbx_debug(class CallPBX *callpbx, char *function)
|
|||
UPRINT(strchr(buffer,0), "<port %ld doesn't exist>,", portlist->port_id);
|
||||
portlist = portlist->next;
|
||||
}
|
||||
// UPRINT(strchr(buffer,0), " endpoint=%d on=%s hold=%s", epoint->ep_serial, (epoint->ep_call_id==callpbx->c_serial)?"yes":"no", (epoint->get_hold_id()==callpbx->c_serial)?"yes":"no");
|
||||
UPRINT(strchr(buffer,0), " endpoint=%d on=%s", epoint->ep_serial, (epoint->ep_call_id==callpbx->c_serial)?"yes":"no");
|
||||
// UPRINT(strchr(buffer,0), " endpoint=%d on=%s hold=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->c_serial)?"yes":"no", (epoint->get_hold_id()==joinpbx->c_serial)?"yes":"no");
|
||||
UPRINT(strchr(buffer,0), " endpoint=%d on=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->c_serial)?"yes":"no");
|
||||
switch(relation->type)
|
||||
{
|
||||
case RELATION_TYPE_CALLING:
|
||||
|
@ -225,29 +225,29 @@ void callpbx_debug(class CallPBX *callpbx, char *function)
|
|||
UPRINT(strchr(buffer,0), " rx_state=unknown");
|
||||
break;
|
||||
}
|
||||
PDEBUG(DEBUG_CALL, "%s\n", buffer);
|
||||
PDEBUG(DEBUG_JOIN, "%s\n", buffer);
|
||||
relation = relation->next;
|
||||
}
|
||||
|
||||
PDEBUG(DEBUG_CALL, "end\n");
|
||||
PDEBUG(DEBUG_JOIN, "end\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* constructor for a new call
|
||||
* the call will have a relation to the calling endpoint
|
||||
* constructor for a new join
|
||||
* the join will have a relation to the calling endpoint
|
||||
*/
|
||||
CallPBX::CallPBX(class Endpoint *epoint) : Call()
|
||||
JoinPBX::JoinPBX(class Endpoint *epoint) : Join()
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
// char filename[256];
|
||||
|
||||
if (!epoint)
|
||||
FATAL("epoint is NULL.\n");
|
||||
|
||||
PDEBUG(DEBUG_CALL, "creating new call and connecting it to the endpoint.\n");
|
||||
PDEBUG(DEBUG_JOIN, "creating new join and connecting it to the endpoint.\n");
|
||||
|
||||
c_type = CALL_TYPE_PBX;
|
||||
c_type = JOIN_TYPE_PBX;
|
||||
c_caller[0] = '\0';
|
||||
c_caller_id[0] = '\0';
|
||||
c_dialed[0] = '\0';
|
||||
|
@ -259,44 +259,44 @@ CallPBX::CallPBX(class Endpoint *epoint) : Call()
|
|||
c_multilocation = LOCATION_PRIVATE_LOCAL;
|
||||
|
||||
/* initialize a relation only to the calling interface */
|
||||
relation = c_relation = (struct call_relation *)MALLOC(sizeof(struct call_relation));
|
||||
relation = c_relation = (struct join_relation *)MALLOC(sizeof(struct join_relation));
|
||||
cmemuse++;
|
||||
relation->type = RELATION_TYPE_CALLING;
|
||||
relation->channel_state = CHANNEL_STATE_HOLD; /* audio is assumed on a new call */
|
||||
relation->tx_state = NOTIFY_STATE_ACTIVE; /* new calls always assumed to be active */
|
||||
relation->rx_state = NOTIFY_STATE_ACTIVE; /* new calls always assumed to be active */
|
||||
relation->channel_state = CHANNEL_STATE_HOLD; /* audio is assumed on a new join */
|
||||
relation->tx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
|
||||
relation->rx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
|
||||
relation->epoint_id = epoint->ep_serial;
|
||||
|
||||
|
||||
if (options.deb & DEBUG_CALL)
|
||||
callpbx_debug(this, "CallPBX::Constructor(new call)");
|
||||
if (options.deb & DEBUG_JOIN)
|
||||
joinpbx_debug(this, "JoinPBX::Constructor(new join)");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call descructor
|
||||
* join descructor
|
||||
*/
|
||||
CallPBX::~CallPBX()
|
||||
JoinPBX::~JoinPBX()
|
||||
{
|
||||
struct call_relation *relation, *rtemp;
|
||||
struct join_relation *relation, *rtemp;
|
||||
|
||||
relation = c_relation;
|
||||
while(relation)
|
||||
{
|
||||
rtemp = relation->next;
|
||||
FREE(relation, sizeof(struct call_relation));
|
||||
FREE(relation, sizeof(struct join_relation));
|
||||
cmemuse--;
|
||||
relation = rtemp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* bridge sets the audio flow of all bchannels assiociated to 'this' call
|
||||
/* bridge sets the audio flow of all bchannels assiociated to 'this' join
|
||||
* also it changes and notifies active/hold/conference states
|
||||
*/
|
||||
void CallPBX::bridge(void)
|
||||
void JoinPBX::bridge(void)
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
struct message *message;
|
||||
int numconnect = 0, relations = 0;
|
||||
class Endpoint *epoint;
|
||||
|
@ -325,7 +325,7 @@ void CallPBX::bridge(void)
|
|||
portlist = epoint->ep_portlist;
|
||||
if (!portlist)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d ignoring relation without port object.\n", c_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d ignoring relation without port object.\n", c_serial);
|
||||
//#warning testing: keep on hold until single audio stream available
|
||||
relation->channel_state = CHANNEL_STATE_HOLD;
|
||||
relation = relation->next;
|
||||
|
@ -333,7 +333,7 @@ void CallPBX::bridge(void)
|
|||
}
|
||||
if (portlist->next)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d ignoring relation with ep%d due to port_list.\n", c_serial, epoint->ep_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d ignoring relation with ep%d due to port_list.\n", c_serial, epoint->ep_serial);
|
||||
//#warning testing: keep on hold until single audio stream available
|
||||
relation->channel_state = CHANNEL_STATE_HOLD;
|
||||
relation = relation->next;
|
||||
|
@ -342,16 +342,16 @@ void CallPBX::bridge(void)
|
|||
port = find_port_id(portlist->port_id);
|
||||
if (!port)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d ignoring relation without existing port object.\n", c_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d ignoring relation without existing port object.\n", c_serial);
|
||||
relation = relation->next;
|
||||
continue;
|
||||
}
|
||||
if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d ignoring relation ep%d because it's port is not mISDN.\n", c_serial, epoint->ep_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port is not mISDN.\n", c_serial, epoint->ep_serial);
|
||||
if (allmISDN)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d not all endpoints are mISDN.\n", c_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d not all endpoints are mISDN.\n", c_serial);
|
||||
allmISDN = 0;
|
||||
}
|
||||
relation = relation->next;
|
||||
|
@ -361,7 +361,7 @@ void CallPBX::bridge(void)
|
|||
relation = relation->next;
|
||||
}
|
||||
|
||||
PDEBUG(DEBUG_CALL, "CALL%d members=%d %s\n", c_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)");
|
||||
PDEBUG(DEBUG_JOIN, "join%d members=%d %s\n", c_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)");
|
||||
/* we notify all relations about rxdata. */
|
||||
relation = c_relation;
|
||||
while(relation)
|
||||
|
@ -379,17 +379,17 @@ void CallPBX::bridge(void)
|
|||
&& relations>1 // no conf with one member
|
||||
&& allmISDN) // no conf if any member is not mISDN
|
||||
{
|
||||
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
|
||||
message->param.mISDNsignal.conf = c_serial<<16 | c_pid;
|
||||
PDEBUG(DEBUG_CALL, "CALL%d EP%d +on+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
||||
PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
||||
message_put(message);
|
||||
} else
|
||||
{
|
||||
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
|
||||
message->param.mISDNsignal.conf = 0;
|
||||
PDEBUG(DEBUG_CALL, "CALL%d EP%d +off+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
||||
PDEBUG(DEBUG_JOIN, "join%d EP%d +off+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
||||
message_put(message);
|
||||
}
|
||||
|
||||
|
@ -399,10 +399,10 @@ void CallPBX::bridge(void)
|
|||
* - any without mISDN
|
||||
* in this case we bridge
|
||||
*/
|
||||
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message->param.mISDNsignal.message = mISDNSIGNAL_CALLDATA;
|
||||
message->param.mISDNsignal.calldata = (relations==2 && !allmISDN);
|
||||
PDEBUG(DEBUG_CALL, "CALL%d EP%d set calldata=%d\n", c_serial, relation->epoint_id, message->param.mISDNsignal.calldata);
|
||||
message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
|
||||
message->param.mISDNsignal.message = mISDNSIGNAL_JOINDATA;
|
||||
message->param.mISDNsignal.joindata = (relations==2 && !allmISDN);
|
||||
PDEBUG(DEBUG_JOIN, "join%d EP%d set joindata=%d\n", c_serial, relation->epoint_id, message->param.mISDNsignal.joindata);
|
||||
message_put(message);
|
||||
|
||||
relation = relation->next;
|
||||
|
@ -411,15 +411,15 @@ void CallPBX::bridge(void)
|
|||
/* two people just exchange their states */
|
||||
if (relations==2 && !c_partyline)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d 2 relations / no partyline\n", c_serial);
|
||||
PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", c_serial);
|
||||
relation = c_relation;
|
||||
relation->tx_state = notify_state_change(c_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
|
||||
relation->next->tx_state = notify_state_change(c_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
|
||||
} else
|
||||
/* one member in a call, so we put her on hold */
|
||||
/* one member in a join, so we put her on hold */
|
||||
if (relations==1 || numconnect==1)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d 1 member or only 1 connected, put on hold\n");
|
||||
PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n");
|
||||
relation = c_relation;
|
||||
while(relation)
|
||||
{
|
||||
|
@ -432,7 +432,7 @@ void CallPBX::bridge(void)
|
|||
} else
|
||||
/* if conference/partyline or (more than two members and more than one is connected), so we set conference state */
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "CALL%d %d members, %d connected, signal conference\n", relations, numconnect);
|
||||
PDEBUG(DEBUG_JOIN, "join%d %d members, %d connected, signal conference\n", relations, numconnect);
|
||||
relation = c_relation;
|
||||
while(relation)
|
||||
{
|
||||
|
@ -448,9 +448,9 @@ void CallPBX::bridge(void)
|
|||
/*
|
||||
* bridging is only possible with two connected endpoints
|
||||
*/
|
||||
void CallPBX::bridge_data(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param)
|
||||
void JoinPBX::bridge_data(unsigned long epoint_from, struct join_relation *relation_from, union parameter *param)
|
||||
{
|
||||
struct call_relation *relation_to;
|
||||
struct join_relation *relation_to;
|
||||
|
||||
/* if we are alone */
|
||||
if (!c_relation->next)
|
||||
|
@ -480,20 +480,20 @@ void CallPBX::bridge_data(unsigned long epoint_from, struct call_relation *relat
|
|||
* will be delivered to the port
|
||||
*/
|
||||
//printf("from %d, to %d\n", relation_from->epoint_id, relation_to->epoint_id);
|
||||
message_forward(c_serial, relation_to->epoint_id, CALL_TO_EPOINT, param);
|
||||
message_forward(c_serial, relation_to->epoint_id, JOIN_TO_EPOINT, param);
|
||||
}
|
||||
|
||||
/* release call from endpoint
|
||||
* if the call has two relations, all relations are freed and the call will be
|
||||
/* release join from endpoint
|
||||
* if the join has two relations, all relations are freed and the join will be
|
||||
* destroyed
|
||||
* on outgoing relations, the cause is collected, if not connected
|
||||
* returns if call has been destroyed
|
||||
* returns if join has been destroyed
|
||||
*/
|
||||
int CallPBX::release(struct call_relation *relation, int location, int cause)
|
||||
int JoinPBX::release(struct join_relation *relation, int location, int cause)
|
||||
{
|
||||
struct call_relation *reltemp, **relationpointer;
|
||||
struct join_relation *reltemp, **relationpointer;
|
||||
struct message *message;
|
||||
class Call *call;
|
||||
class Join *join;
|
||||
int destroy = 0;
|
||||
|
||||
/* remove from bridge */
|
||||
|
@ -501,7 +501,7 @@ int CallPBX::release(struct call_relation *relation, int location, int cause)
|
|||
{
|
||||
relation->channel_state = CHANNEL_STATE_HOLD;
|
||||
c_updatebridge = 1; /* update bridge flag */
|
||||
// note: if call is not released, bridge must be updated
|
||||
// note: if join is not released, bridge must be updated
|
||||
}
|
||||
|
||||
/* detach given interface */
|
||||
|
@ -518,73 +518,73 @@ int CallPBX::release(struct call_relation *relation, int location, int cause)
|
|||
if (!reltemp)
|
||||
FATAL("relation not in list of our relations. this must not happen.\n");
|
||||
*relationpointer = reltemp->next;
|
||||
FREE(reltemp, sizeof(struct call_relation));
|
||||
FREE(reltemp, sizeof(struct join_relation));
|
||||
cmemuse--;
|
||||
relation = reltemp = NULL; // just in case of reuse fault;
|
||||
|
||||
/* if no more relation */
|
||||
if (!c_relation)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "call is completely removed.\n");
|
||||
/* there is no more endpoint related to the call */
|
||||
PDEBUG(DEBUG_JOIN, "join is completely removed.\n");
|
||||
/* there is no more endpoint related to the join */
|
||||
destroy = 1;
|
||||
delete this;
|
||||
// end of call object!
|
||||
PDEBUG(DEBUG_CALL, "call completely removed!\n");
|
||||
// end of join object!
|
||||
PDEBUG(DEBUG_JOIN, "join completely removed!\n");
|
||||
} else
|
||||
/* if call is a party line */
|
||||
/* if join is a party line */
|
||||
if (c_partyline)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "call is a conference room, so we keep it alive until the last party left.\n");
|
||||
PDEBUG(DEBUG_JOIN, "join is a conference room, so we keep it alive until the last party left.\n");
|
||||
} else
|
||||
/* if only one relation left */
|
||||
if (!c_relation->next)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "call has one relation left, so we send it a release with the given cause %d.\n", cause);
|
||||
message = message_create(c_serial, c_relation->epoint_id, CALL_TO_EPOINT, MESSAGE_RELEASE);
|
||||
PDEBUG(DEBUG_JOIN, "join has one relation left, so we send it a release with the given cause %d.\n", cause);
|
||||
message = message_create(c_serial, c_relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
|
||||
message->param.disconnectinfo.cause = cause;
|
||||
message->param.disconnectinfo.location = location;
|
||||
message_put(message);
|
||||
destroy = 1;
|
||||
delete this;
|
||||
// end of call object!
|
||||
PDEBUG(DEBUG_CALL, "call completely removed!\n");
|
||||
// end of join object!
|
||||
PDEBUG(DEBUG_JOIN, "join completely removed!\n");
|
||||
}
|
||||
|
||||
call = call_first;
|
||||
while(call)
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
if (options.deb & DEBUG_CALL && call->c_type==CALL_TYPE_PBX)
|
||||
callpbx_debug((class CallPBX *)call, "call_release{all calls left}");
|
||||
call = call->next;
|
||||
if (options.deb & DEBUG_JOIN && join->c_type==JOIN_TYPE_PBX)
|
||||
joinpbx_debug((class JoinPBX *)join, "join_release{all joins left}");
|
||||
join = join->next;
|
||||
}
|
||||
PDEBUG(DEBUG_CALL, "call_release(): ended.\n");
|
||||
PDEBUG(DEBUG_JOIN, "join_release(): ended.\n");
|
||||
return(destroy);
|
||||
}
|
||||
|
||||
/* count number of relations in a call
|
||||
/* count number of relations in a join
|
||||
*/
|
||||
int callpbx_countrelations(unsigned long call_id)
|
||||
int joinpbx_countrelations(unsigned long join_id)
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
int i;
|
||||
class Call *call;
|
||||
class CallPBX *callpbx;
|
||||
class Join *join;
|
||||
class JoinPBX *joinpbx;
|
||||
|
||||
call = find_call_id(call_id);
|
||||
join = find_join_id(join_id);
|
||||
|
||||
if (!call)
|
||||
if (!join)
|
||||
return(0);
|
||||
|
||||
if (call->c_type != CALL_TYPE_ASTERISK)
|
||||
if (join->c_type != JOIN_TYPE_ASTERISK)
|
||||
return(2);
|
||||
|
||||
if (call->c_type != CALL_TYPE_PBX)
|
||||
if (join->c_type != JOIN_TYPE_PBX)
|
||||
return(0);
|
||||
callpbx = (class CallPBX *)call;
|
||||
joinpbx = (class JoinPBX *)join;
|
||||
|
||||
i = 0;
|
||||
relation = callpbx->c_relation;
|
||||
relation = joinpbx->c_relation;
|
||||
while(relation)
|
||||
{
|
||||
i++;
|
||||
|
@ -594,9 +594,9 @@ int callpbx_countrelations(unsigned long call_id)
|
|||
return(i);
|
||||
}
|
||||
|
||||
void CallPBX::remove_relation(struct call_relation *relation)
|
||||
void JoinPBX::remove_relation(struct join_relation *relation)
|
||||
{
|
||||
struct call_relation *temp, **tempp;
|
||||
struct join_relation *temp, **tempp;
|
||||
|
||||
if (!relation)
|
||||
return;
|
||||
|
@ -612,46 +612,46 @@ void CallPBX::remove_relation(struct call_relation *relation)
|
|||
}
|
||||
if (!temp)
|
||||
{
|
||||
PERROR("relation not in call.\n");
|
||||
PERROR("relation not in join.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PDEBUG(DEBUG_CALL, "removing relation.\n");
|
||||
PDEBUG(DEBUG_JOIN, "removing relation.\n");
|
||||
*tempp = relation->next;
|
||||
FREE(temp, sizeof(struct call_relation));
|
||||
FREE(temp, sizeof(struct join_relation));
|
||||
cmemuse--;
|
||||
}
|
||||
|
||||
|
||||
struct call_relation *CallPBX::add_relation(void)
|
||||
struct join_relation *JoinPBX::add_relation(void)
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
|
||||
if (!c_relation)
|
||||
{
|
||||
PERROR("there is no first relation to this call\n");
|
||||
PERROR("there is no first relation to this join\n");
|
||||
return(NULL);
|
||||
}
|
||||
relation = c_relation;
|
||||
while(relation->next)
|
||||
relation = relation->next;
|
||||
|
||||
relation->next = (struct call_relation *)MALLOC(sizeof(struct call_relation));
|
||||
relation->next = (struct join_relation *)MALLOC(sizeof(struct join_relation));
|
||||
cmemuse++;
|
||||
/* the record pointer is set at the first time the data is received for the relation */
|
||||
|
||||
// if (options.deb & DEBUG_CALL)
|
||||
// callpbx_debug(call, "add_relation");
|
||||
// if (options.deb & DEBUG_JOIN)
|
||||
// joinpbx_debug(join, "add_relation");
|
||||
return(relation->next);
|
||||
}
|
||||
|
||||
/* epoint sends a message to a call
|
||||
/* epoint sends a message to a join
|
||||
*
|
||||
*/
|
||||
void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
|
||||
{
|
||||
class Call *cl;
|
||||
struct call_relation *relation, *reltemp;
|
||||
class Join *cl;
|
||||
struct join_relation *relation, *reltemp;
|
||||
int num;
|
||||
int new_state;
|
||||
struct message *message;
|
||||
|
@ -664,20 +664,20 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
return;
|
||||
}
|
||||
|
||||
// if (options.deb & DEBUG_CALL)
|
||||
// if (options.deb & DEBUG_JOIN)
|
||||
// {
|
||||
// PDEBUG(DEBUG_CALL, "message %d received from ep%d.\n", message, epoint->ep_serial);
|
||||
// callpbx_debug(call,"Call::message_epoint");
|
||||
// PDEBUG(DEBUG_JOIN, "message %d received from ep%d.\n", message, epoint->ep_serial);
|
||||
// joinpbx_debug(join,"Join::message_epoint");
|
||||
// }
|
||||
if (options.deb & DEBUG_CALL)
|
||||
if (options.deb & DEBUG_JOIN)
|
||||
{
|
||||
if (message_type != MESSAGE_DATA)
|
||||
{
|
||||
cl = call_first;
|
||||
cl = join_first;
|
||||
while(cl)
|
||||
{
|
||||
if (cl->c_type == CALL_TYPE_PBX)
|
||||
callpbx_debug((class CallPBX *)cl, "Call::message_epoint{all calls before processing}");
|
||||
if (cl->c_type == JOIN_TYPE_PBX)
|
||||
joinpbx_debug((class JoinPBX *)cl, "Join::message_epoint{all joins before processing}");
|
||||
cl = cl->next;
|
||||
}
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
}
|
||||
if (!relation)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "no relation back to the endpoint found, ignoring (call=%d, endpoint=%d)\n", c_serial, epoint_id);
|
||||
PDEBUG(DEBUG_JOIN, "no relation back to the endpoint found, ignoring (join=%d, endpoint=%d)\n", c_serial, epoint_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -701,13 +701,13 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
{
|
||||
/* process channel message */
|
||||
case MESSAGE_CHANNEL:
|
||||
PDEBUG(DEBUG_CALL, "call received channel message: %d.\n", param->channel);
|
||||
PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->channel);
|
||||
if (relation->channel_state != param->channel)
|
||||
{
|
||||
relation->channel_state = param->channel;
|
||||
c_updatebridge = 1; /* update bridge flag */
|
||||
if (options.deb & DEBUG_CALL)
|
||||
callpbx_debug(this, "Call::message_epoint{after setting new channel state}");
|
||||
if (options.deb & DEBUG_JOIN)
|
||||
joinpbx_debug(this, "Join::message_epoint{after setting new channel state}");
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -726,8 +726,8 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
{
|
||||
relation->rx_state = new_state;
|
||||
c_updatebridge = 1;
|
||||
if (options.deb & DEBUG_CALL)
|
||||
callpbx_debug(this, "Call::message_epoint{after setting new rx state}");
|
||||
if (options.deb & DEBUG_JOIN)
|
||||
joinpbx_debug(this, "Join::message_epoint{after setting new rx state}");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -738,7 +738,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
{
|
||||
if (reltemp->epoint_id!=epoint_id && reltemp->epoint_id)
|
||||
{
|
||||
message = message_create(c_serial, reltemp->epoint_id, CALL_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
message = message_create(c_serial, reltemp->epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY);
|
||||
memcpy(&message->param, param, sizeof(union parameter));
|
||||
message_put(message);
|
||||
}
|
||||
|
@ -766,7 +766,7 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
if (relation->type == RELATION_TYPE_SETUP)
|
||||
{
|
||||
if (release(relation, LOCATION_PRIVATE_LOCAL, CAUSE_NONSELECTED))
|
||||
return; // must return, because call IS destroyed
|
||||
return; // must return, because join IS destroyed
|
||||
goto release_again;
|
||||
}
|
||||
relation = relation->next;
|
||||
|
@ -785,15 +785,15 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
/* send current cause */
|
||||
release(relation, param->disconnectinfo.location, param->disconnectinfo.cause);
|
||||
}
|
||||
return; // must return, because call may be destroyed
|
||||
return; // must return, because join may be destroyed
|
||||
}
|
||||
|
||||
/* process party line */
|
||||
if (message_type == MESSAGE_SETUP) if (param->setup.partyline)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "respsone with connect in partyline mode.\n");
|
||||
PDEBUG(DEBUG_JOIN, "respsone with connect in partyline mode.\n");
|
||||
c_partyline = param->setup.partyline;
|
||||
message = message_create(c_serial, epoint_id, CALL_TO_EPOINT, MESSAGE_CONNECT);
|
||||
message = message_create(c_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_CONNECT);
|
||||
message->param.setup.partyline = c_partyline;
|
||||
message_put(message);
|
||||
c_updatebridge = 1; /* update bridge flag */
|
||||
|
@ -802,8 +802,8 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
{
|
||||
if (message_type == MESSAGE_DISCONNECT)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "releasing after receiving disconnect, because call in partyline mode.\n");
|
||||
message = message_create(c_serial, epoint_id, CALL_TO_EPOINT, MESSAGE_RELEASE);
|
||||
PDEBUG(DEBUG_JOIN, "releasing after receiving disconnect, because join in partyline mode.\n");
|
||||
message = message_create(c_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
|
||||
message->param.disconnectinfo.cause = CAUSE_NORMAL;
|
||||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
message_put(message);
|
||||
|
@ -812,17 +812,17 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
}
|
||||
if (c_partyline)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "ignoring message, because call in partyline mode.\n");
|
||||
PDEBUG(DEBUG_JOIN, "ignoring message, because join in partyline mode.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* count relations */
|
||||
num=callpbx_countrelations(c_serial);
|
||||
num=joinpbx_countrelations(c_serial);
|
||||
|
||||
/* check number of relations */
|
||||
if (num > 2)
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "call has more than two relations so there is no need to send a message.\n");
|
||||
PDEBUG(DEBUG_JOIN, "join has more than two relations so there is no need to send a message.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -845,35 +845,35 @@ void CallPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
|
|||
while((number = strsep(&numbers, ",")))
|
||||
{
|
||||
if (out_setup(epoint_id, message_type, param, number))
|
||||
return; // call destroyed
|
||||
return; // join destroyed
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (out_setup(epoint_id, message_type, param, NULL))
|
||||
return; // call destroyed
|
||||
return; // join destroyed
|
||||
break;
|
||||
|
||||
default:
|
||||
PDEBUG(DEBUG_CALL, "no need to send a message because there is no other endpoint than the calling one.\n");
|
||||
PDEBUG(DEBUG_JOIN, "no need to send a message because there is no other endpoint than the calling one.\n");
|
||||
}
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_CALL, "sending message ep%ld -> ep%ld.\n", epoint_id, relation->epoint_id);
|
||||
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, message_type);
|
||||
PDEBUG(DEBUG_JOIN, "sending message ep%ld -> ep%ld.\n", epoint_id, relation->epoint_id);
|
||||
message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
|
||||
memcpy(&message->param, param, sizeof(union parameter));
|
||||
message_put(message);
|
||||
PDEBUG(DEBUG_CALL, "message sent.\n");
|
||||
PDEBUG(DEBUG_JOIN, "message sent.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* call process is called from the main loop
|
||||
/* join process is called from the main loop
|
||||
* it processes the current calling state.
|
||||
* returns 0 if call nothing was done
|
||||
* returns 0 if join nothing was done
|
||||
*/
|
||||
int CallPBX::handler(void)
|
||||
int JoinPBX::handler(void)
|
||||
{
|
||||
// struct call_relation *relation;
|
||||
// struct join_relation *relation;
|
||||
// char dialing[32][32];
|
||||
// int port[32];
|
||||
// int found;
|
||||
|
@ -928,22 +928,22 @@ int track_notify(int oldstate, int notify)
|
|||
* setup to exactly one endpoint
|
||||
* if it fails, the calling endpoint is released.
|
||||
* if other outgoing endpoints already exists, they are release as well.
|
||||
* note: if this functions fails, it will destroy its own call object!
|
||||
* note: if this functions fails, it will destroy its own join object!
|
||||
*/
|
||||
int CallPBX::out_setup(unsigned long epoint_id, int message_type, union parameter *param, char *newnumber)
|
||||
int JoinPBX::out_setup(unsigned long epoint_id, int message_type, union parameter *param, char *newnumber)
|
||||
{
|
||||
struct call_relation *relation;
|
||||
struct join_relation *relation;
|
||||
struct message *message;
|
||||
class Endpoint *epoint;
|
||||
|
||||
PDEBUG(DEBUG_CALL, "no endpoint found, so we will create an endpoint and send the setup message we have.\n");
|
||||
PDEBUG(DEBUG_JOIN, "no endpoint found, so we will create an endpoint and send the setup message we have.\n");
|
||||
/* create a new relation */
|
||||
if (!(relation=add_relation()))
|
||||
FATAL("No memory for relation.\n");
|
||||
relation->type = RELATION_TYPE_SETUP;
|
||||
relation->channel_state = CHANNEL_STATE_HOLD; /* audio is assumed on a new call */
|
||||
relation->tx_state = NOTIFY_STATE_ACTIVE; /* new calls always assumed to be active */
|
||||
relation->rx_state = NOTIFY_STATE_ACTIVE; /* new calls always assumed to be active */
|
||||
relation->channel_state = CHANNEL_STATE_HOLD; /* audio is assumed on a new join */
|
||||
relation->tx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
|
||||
relation->rx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
|
||||
/* create a new endpoint */
|
||||
epoint = new Endpoint(0, c_serial, 0);
|
||||
if (!epoint)
|
||||
|
@ -952,14 +952,14 @@ int CallPBX::out_setup(unsigned long epoint_id, int message_type, union paramete
|
|||
FATAL("No memory for Endpoint Application instance\n");
|
||||
relation->epoint_id = epoint->ep_serial;
|
||||
/* send setup message to new endpoint */
|
||||
//printf("JOLLY DEBUG: %d\n",call_countrelations(c_serial));
|
||||
//i if (options.deb & DEBUG_CALL)
|
||||
// callpbx_debug(call, "Call::message_epoint");
|
||||
message = message_create(c_serial, relation->epoint_id, CALL_TO_EPOINT, message_type);
|
||||
//printf("JOLLY DEBUG: %d\n",join_countrelations(c_serial));
|
||||
//i if (options.deb & DEBUG_JOIN)
|
||||
// joinpbx_debug(join, "Join::message_epoint");
|
||||
message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
|
||||
memcpy(&message->param, param, sizeof(union parameter));
|
||||
if (newnumber)
|
||||
SCPY(message->param.setup.dialinginfo.id, newnumber);
|
||||
PDEBUG(DEBUG_CALL, "setup message sent to ep %d with number='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id);
|
||||
PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id);
|
||||
message_put(message);
|
||||
return(0);
|
||||
}
|
|
@ -1,34 +1,34 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
** **
|
||||
** call header file for pbx calls **
|
||||
** join header file for pbx joins **
|
||||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
||||
/* call
|
||||
/* join
|
||||
*
|
||||
* calls connect interfaces together
|
||||
* calls are linked in a chain
|
||||
* interfaces can have 0, 1 or more references to a call
|
||||
* the call can have many references to interfaces
|
||||
* calls receive and send messages
|
||||
* joins connect interfaces together
|
||||
* joins are linked in a chain
|
||||
* interfaces can have 0, 1 or more references to a join
|
||||
* the join can have many references to interfaces
|
||||
* joins receive and send messages
|
||||
*/
|
||||
|
||||
#define RECORD_BUFFER_SIZE 16000
|
||||
|
||||
enum { /* relation types */
|
||||
RELATION_TYPE_CALLING, /* initiator of a call */
|
||||
RELATION_TYPE_CALLING, /* initiator of a join */
|
||||
RELATION_TYPE_SETUP, /* interface which is to be set up */
|
||||
RELATION_TYPE_CONNECT, /* interface is connected */
|
||||
};
|
||||
|
||||
enum { /* relation audio state */
|
||||
CHANNEL_STATE_CONNECT, /* endpoint is connected to the call voice transmission in both dirs */
|
||||
CHANNEL_STATE_CONNECT, /* endpoint is connected to the join voice transmission in both dirs */
|
||||
CHANNEL_STATE_HOLD, /* endpoint is on hold state, no audio */
|
||||
};
|
||||
|
||||
|
@ -40,23 +40,23 @@ enum { /* states that results from last notification */
|
|||
};
|
||||
|
||||
|
||||
struct call_relation { /* relation to an interface */
|
||||
struct call_relation *next; /* next node */
|
||||
struct join_relation { /* relation to an interface */
|
||||
struct join_relation *next; /* next node */
|
||||
int type; /* type of relation */
|
||||
unsigned long epoint_id; /* interface to link call to */
|
||||
unsigned long epoint_id; /* interface to link join to */
|
||||
int channel_state; /* if audio is available */
|
||||
int rx_state; /* current state of what we received from endpoint */
|
||||
int tx_state; /* current state of what we sent to endpoint */
|
||||
};
|
||||
|
||||
class CallPBX : public Call
|
||||
class JoinPBX : public Join
|
||||
{
|
||||
public:
|
||||
CallPBX(class Endpoint *epoint);
|
||||
~CallPBX();
|
||||
JoinPBX(class Endpoint *epoint);
|
||||
~JoinPBX();
|
||||
void message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
int handler(void);
|
||||
int release(struct call_relation *relation, int location, int cause);
|
||||
int release(struct join_relation *relation, int location, int cause);
|
||||
|
||||
char c_caller[32]; /* caller number */
|
||||
char c_caller_id[32]; /* caller id to signal */
|
||||
|
@ -64,20 +64,20 @@ class CallPBX : public Call
|
|||
char c_todial[32]; /* overlap dialing (part not signalled yet) */
|
||||
int c_multicause, c_multilocation;
|
||||
|
||||
int c_pid; /* pid of call to generate bridge id */
|
||||
int c_pid; /* pid of join to generate bridge id */
|
||||
int c_updatebridge; /* bridge must be updated */
|
||||
struct call_relation *c_relation; /* list of endpoints that are related to the call */
|
||||
struct join_relation *c_relation; /* list of endpoints that are related to the join */
|
||||
|
||||
int c_partyline; /* if set, call is conference room */
|
||||
int c_partyline; /* if set, join is conference room */
|
||||
|
||||
void bridge(void);
|
||||
void bridge_data(unsigned long epoint_from, struct call_relation *relation_from, union parameter *param);
|
||||
void remove_relation(struct call_relation *relation);
|
||||
struct call_relation *add_relation(void);
|
||||
void bridge_data(unsigned long epoint_from, struct join_relation *relation_from, union parameter *param);
|
||||
void remove_relation(struct join_relation *relation);
|
||||
struct join_relation *add_relation(void);
|
||||
int out_setup(unsigned long epoint_id, int message, union parameter *param, char *newnumber);
|
||||
};
|
||||
|
||||
void callpbx_debug(class CallPBX *callpbx, char *function);
|
||||
int callpbx_countrelations(unsigned long call_id);
|
||||
void joinpbx_debug(class JoinPBX *joinpbx, char *function);
|
||||
int joinpbx_countrelations(unsigned long join_id);
|
||||
int track_notify(int oldstate, int notify);
|
||||
|
20
mISDN.cpp
20
mISDN.cpp
|
@ -62,7 +62,7 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
|
|||
p_m_echo = 0;
|
||||
p_m_tone = 0;
|
||||
p_m_rxoff = 0;
|
||||
p_m_calldata = 0;
|
||||
p_m_joindata = 0;
|
||||
p_m_dtmf = !mISDNport->ifport->nodtmf;
|
||||
p_m_timeout = 0;
|
||||
p_m_timer = 0;
|
||||
|
@ -910,8 +910,8 @@ int PmISDN::handler(void)
|
|||
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
|
||||
message->param.state = p_state;
|
||||
message_put(message);
|
||||
return(1);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0); /* nothing done */
|
||||
|
@ -998,7 +998,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
|
|||
/* calls will not process any audio data unless
|
||||
* the call is connected OR interface features audio during call setup.
|
||||
*/
|
||||
//printf("%d -> %d prim=%x calldata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_calldata, p_m_mISDNport->earlyb);
|
||||
//printf("%d -> %d prim=%x joindata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_joindata, p_m_mISDNport->earlyb);
|
||||
#ifndef DEBUG_COREBRIDGE
|
||||
if (p_state!=PORT_STATE_CONNECT
|
||||
&& !p_m_mISDNport->earlyb)
|
||||
|
@ -1031,7 +1031,7 @@ void PmISDN::bchannel_receive(iframe_t *frm)
|
|||
p = (unsigned char *)&frm->data.p;
|
||||
|
||||
/* send data to epoint */
|
||||
if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
|
||||
if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
|
||||
{
|
||||
length_temp = frm->len;
|
||||
data_temp = p;
|
||||
|
@ -1222,13 +1222,13 @@ void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union
|
|||
//if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
|
||||
break;
|
||||
|
||||
case mISDNSIGNAL_CALLDATA:
|
||||
if (p_m_calldata != param->mISDNsignal.calldata)
|
||||
case mISDNSIGNAL_JOINDATA:
|
||||
if (p_m_joindata != param->mISDNsignal.joindata)
|
||||
{
|
||||
p_m_calldata = param->mISDNsignal.calldata;
|
||||
PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
|
||||
p_m_joindata = param->mISDNsignal.joindata;
|
||||
PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
|
||||
} else
|
||||
PDEBUG(DEBUG_BCHANNEL, "we already have calldata=%d.\n", p_m_calldata);
|
||||
PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
|
||||
break;
|
||||
|
||||
case mISDNSIGNAL_DELAY:
|
||||
|
@ -1370,7 +1370,7 @@ int mISDN_handler(void)
|
|||
if (isdnport)
|
||||
{
|
||||
/* call bridges in user space OR crypto OR recording */
|
||||
if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
|
||||
if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
|
||||
{
|
||||
/* rx IS required */
|
||||
if (isdnport->p_m_rxoff)
|
||||
|
|
4
mISDN.h
4
mISDN.h
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** PBX4Linux **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -118,7 +118,7 @@ class PmISDN : public Port
|
|||
// int p_m_nodata; /* all parties within a conf are isdn ports, so pure bridging is possible */
|
||||
int p_m_txdata; /* get what we transmit */
|
||||
int p_m_dtmf; /* dtmf decoding is enabled */
|
||||
int p_m_calldata; /* the call requires data due to no briging capability */
|
||||
int p_m_joindata; /* the call requires data due to no briging capability */
|
||||
|
||||
int p_m_load; /* current data in dsp tx buffer */
|
||||
unsigned long p_m_last_tv_sec; /* time stamp of last handler call, (to sync audio data */
|
||||
|
|
75
main.c
75
main.c
|
@ -185,7 +185,7 @@ int main(int argc, char *argv[])
|
|||
struct message *message;
|
||||
class Port *port;
|
||||
class Endpoint *epoint;
|
||||
class Call *call;
|
||||
class Join *join;
|
||||
int i;
|
||||
int all_idle;
|
||||
char prefix_string[64];
|
||||
|
@ -195,7 +195,7 @@ int main(int argc, char *argv[])
|
|||
created_lock = 0, created_signal = 0, created_debug = 0;
|
||||
#ifdef DEBUG_DURATION
|
||||
time_t durationupdate;
|
||||
double idle_duration, isdn_duration, port_duration, epoint_duration, call_duration, message_duration, admin_duration;
|
||||
double idle_duration, isdn_duration, port_duration, epoint_duration, join_duration, message_duration, admin_duration;
|
||||
double start_d;
|
||||
#endif
|
||||
int idletime = 0, idlecheck = 0;
|
||||
|
@ -527,23 +527,23 @@ BUDETECT
|
|||
start_d = now_d;
|
||||
#endif
|
||||
|
||||
/* loop through all calls and call their handler */
|
||||
call_again:
|
||||
call = call_first;
|
||||
while(call)
|
||||
/* loop through all joins and call their handler */
|
||||
join_again:
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
debug_prefix = "call";
|
||||
debug_prefix = "join";
|
||||
debug_count++;
|
||||
ret = call->handler();
|
||||
ret = join->handler();
|
||||
if (ret)
|
||||
all_idle = 0;
|
||||
if (ret < 0) /* call has been destroyed */
|
||||
goto call_again;
|
||||
call = call->next;
|
||||
if (ret < 0) /* join has been destroyed */
|
||||
goto join_again;
|
||||
join = join->next;
|
||||
}
|
||||
#ifdef DEBUG_DURATION
|
||||
GET_NOW();
|
||||
call_duration += (now_d - start_d);
|
||||
join_duration += (now_d - start_d);
|
||||
start_d = now_d;
|
||||
#endif
|
||||
|
||||
|
@ -575,33 +575,33 @@ BUDETECT
|
|||
}
|
||||
break;
|
||||
|
||||
case EPOINT_TO_CALL:
|
||||
debug_prefix = "msg epoint->call";
|
||||
call = find_call_id(message->id_to);
|
||||
if (call)
|
||||
case EPOINT_TO_JOIN:
|
||||
debug_prefix = "msg epoint->join";
|
||||
join = find_join_id(message->id_to);
|
||||
if (join)
|
||||
{
|
||||
call->message_epoint(message->id_from, message->type, &message->param);
|
||||
join->message_epoint(message->id_from, message->type, &message->param);
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from endpoint %d to call %d. call doesn't exist anymore\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from endpoint %d to join %d. join doesn't exist anymore\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
}
|
||||
break;
|
||||
|
||||
case CALL_TO_EPOINT:
|
||||
debug_prefix = "msg call->epoint";
|
||||
case JOIN_TO_EPOINT:
|
||||
debug_prefix = "msg join->epoint";
|
||||
epoint = find_epoint_id(message->id_to);
|
||||
if (epoint)
|
||||
{
|
||||
if (epoint->ep_app)
|
||||
{
|
||||
epoint->ep_app->ea_message_call(message->id_from, message->type, &message->param);
|
||||
epoint->ep_app->ea_message_join(message->id_from, message->type, &message->param);
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from call %d to endpoint %d. endpoint doesn't have an application.\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from join %d to endpoint %d. endpoint doesn't have an application.\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
}
|
||||
} else
|
||||
{
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from call %d to endpoint %d. endpoint doesn't exist anymore.\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
PDEBUG(DEBUG_MSG, "Warning: message %s from join %d to endpoint %d. endpoint doesn't exist anymore.\n", messages_txt[message->type], message->id_from, message->id_to);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -665,15 +665,15 @@ BUDETECT
|
|||
if (durationupdate != now)
|
||||
{
|
||||
durationupdate = now;
|
||||
printf("Idle:%3d ISDN:%3d Port:%3d Epoint:%3d Call:%3d Message:%3d Admin:%3d\n",
|
||||
printf("Idle:%3d ISDN:%3d Port:%3d Epoint:%3d Join:%3d Message:%3d Admin:%3d\n",
|
||||
(int)(idle_duration*100),
|
||||
(int)(isdn_duration*100),
|
||||
(int)(port_duration*100),
|
||||
(int)(epoint_duration*100),
|
||||
(int)(call_duration*100),
|
||||
(int)(join_duration*100),
|
||||
(int)(message_duration*100),
|
||||
(int)(admin_duration*100));
|
||||
idle_duration = isdn_duration = port_duration = epoint_duration = call_duration = message_duration = admin_duration = 0;
|
||||
idle_duration = isdn_duration = port_duration = epoint_duration = join_duration = message_duration = admin_duration = 0;
|
||||
}
|
||||
#else
|
||||
GET_NOW();
|
||||
|
@ -686,7 +686,12 @@ BUDETECT
|
|||
idletime += 4000;
|
||||
}
|
||||
}
|
||||
printf("LCR terminated\n");
|
||||
SPRINT(tracetext, "%s terminated", NAME);
|
||||
printf("%s\n", tracetext);
|
||||
start_trace(0, NULL, NULL, NULL, 0, 0, 0, tracetext);
|
||||
if (ret)
|
||||
add_trace("error", NULL, "%d", ret);
|
||||
end_trace();
|
||||
ret=0;
|
||||
|
||||
/* free all */
|
||||
|
@ -725,7 +730,7 @@ free:
|
|||
}
|
||||
epoint_first = NULL;
|
||||
debug_count++;
|
||||
call_free();
|
||||
join_free();
|
||||
|
||||
/* free interfaces */
|
||||
if (interface_first)
|
||||
|
@ -796,9 +801,9 @@ free:
|
|||
ret = -1; \
|
||||
}
|
||||
MEMCHECK("",memuse)
|
||||
MEMCHECK("memory block(s) left (port.cpp)",pmemuse)
|
||||
MEMCHECK("memory block(s) left (epoint.cpp)",ememuse)
|
||||
MEMCHECK("memory block(s) left (call.cpp)",cmemuse)
|
||||
MEMCHECK("memory block(s) left (port.cpp ...)",pmemuse)
|
||||
MEMCHECK("memory block(s) left (epoint*.cpp ...)",ememuse)
|
||||
MEMCHECK("memory block(s) left (join*.cpp)",cmemuse)
|
||||
MEMCHECK("memory block(s) left (message.c)",mmemuse)
|
||||
MEMCHECK("memory block(s) left (route.c)",rmemuse)
|
||||
MEMCHECK("memory block(s) left (args)",amemuse)
|
||||
|
@ -807,14 +812,6 @@ free:
|
|||
MEMCHECK("file handler(s) left",fhuse)
|
||||
|
||||
/* take me out */
|
||||
if (ret == 999)
|
||||
exit(0);
|
||||
SPRINT(tracetext, "%s exit", NAME);
|
||||
printf("%s\n", tracetext);
|
||||
start_trace(0, NULL, NULL, NULL, 0, 0, 0, tracetext);
|
||||
if (ret)
|
||||
add_trace("error", NULL, "%d", ret);
|
||||
end_trace();
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
|
10
main.h
10
main.h
|
@ -1,6 +1,6 @@
|
|||
/*****************************************************************************\
|
||||
** **
|
||||
** LCR **
|
||||
** Linux Call Router **
|
||||
** **
|
||||
**---------------------------------------------------------------------------**
|
||||
** Copyright: Andreas Eversberg **
|
||||
|
@ -44,7 +44,7 @@ void debug(const char *function, int line, char *prefix, char *buffer);
|
|||
//#define DEBUG_KNOCK 0x0140
|
||||
#define DEBUG_VBOX 0x0180
|
||||
#define DEBUG_EPOINT 0x0200
|
||||
#define DEBUG_CALL 0x0400
|
||||
#define DEBUG_JOIN 0x0400
|
||||
#define DEBUG_VERSATEL 0x0800
|
||||
#define DEBUG_CRYPT 0x1000
|
||||
#define DEBUG_ROUTE 0x2000
|
||||
|
@ -130,9 +130,9 @@ extern "C" {
|
|||
#include "mISDN.h"
|
||||
#include "dss1.h"
|
||||
#include "vbox.h"
|
||||
#include "call.h"
|
||||
#include "callpbx.h"
|
||||
#include "callasterisk.h"
|
||||
#include "join.h"
|
||||
#include "joinpbx.h"
|
||||
#include "joinasterisk.h"
|
||||
#include "cause.h"
|
||||
#include "alawulaw.h"
|
||||
#include "tones.h"
|
||||
|
|
10
message.h
10
message.h
|
@ -120,7 +120,7 @@ enum { /* diversion types */
|
|||
enum { /* isdnsignal */
|
||||
mISDNSIGNAL_VOLUME, /* change volume */
|
||||
mISDNSIGNAL_CONF, /* joint/split conference */
|
||||
mISDNSIGNAL_CALLDATA, /* data required by call instance */
|
||||
mISDNSIGNAL_JOINDATA, /* data required by join instance */
|
||||
mISDNSIGNAL_ECHO, /* enable/disable echoe */
|
||||
mISDNSIGNAL_DELAY, /* use delay or adaptive jitter */
|
||||
};
|
||||
|
@ -261,7 +261,7 @@ struct param_mISDNsignal {
|
|||
int rxvol;
|
||||
int txvol;
|
||||
int conf;
|
||||
int calldata;
|
||||
int joindata;
|
||||
int tone;
|
||||
int echo;
|
||||
int delay;
|
||||
|
@ -287,7 +287,7 @@ union parameter {
|
|||
struct park_info parkinfo; /* MESSAGE_SUSPEND, MESSAGE_RESUME */
|
||||
int state; /* MESSAGE_TIMEOUT */
|
||||
int knock; /* MESSAGE_KNOCK 0=off !0=on */
|
||||
int channel; /* MESSAGE_CHANNEL see RELATION_CHANNEL_* (call.h) */
|
||||
int channel; /* MESSAGE_CHANNEL see RELATION_CHANNEL_* (join.h) */
|
||||
struct param_data data; /* MESSAGE_DATA */
|
||||
struct param_play play; /* MESSAGE_VBOX_PLAY */
|
||||
int speed; /* MESSAGE_VBOX_PLAY_SPEED */
|
||||
|
@ -299,8 +299,8 @@ union parameter {
|
|||
|
||||
enum { /* message flow */
|
||||
PORT_TO_EPOINT,
|
||||
EPOINT_TO_CALL,
|
||||
CALL_TO_EPOINT,
|
||||
EPOINT_TO_JOIN,
|
||||
JOIN_TO_EPOINT,
|
||||
EPOINT_TO_PORT,
|
||||
};
|
||||
|
||||
|
|
2
trace.c
2
trace.c
|
@ -208,7 +208,7 @@ static char *print_trace(int detail, int port, char *interface, char *caller, ch
|
|||
SCAT(trace_string, "--");
|
||||
}
|
||||
if (trace.serial)
|
||||
SPRINT(buffer, "(%d): %s", trace.serial, trace.name[0]?trace.name:"<unknown>");
|
||||
SPRINT(buffer, "(%lu): %s", trace.serial, trace.name[0]?trace.name:"<unknown>");
|
||||
else
|
||||
SPRINT(buffer, ": %s", trace.name[0]?trace.name:"<unknown>");
|
||||
SCAT(trace_string, buffer);
|
||||
|
|
Loading…
Reference in New Issue