/*
* free connection
- * also releases all remote joins
*/
void free_connection(struct admin_list *admin)
{
struct admin_queue *response;
void *temp;
union parameter param;
- class Join *join, *joinnext;
- struct mISDNport *mISDNport;
- int i, ii;
- struct admin_list **adminp;
class Port *port, *portnext;
class Premote *remote;
+ struct admin_list **adminp;
- /* free remote joins */
+ /* free remote ports */
if (admin->remote_name[0]) {
start_trace(-1,
NULL,
"REMOTE APP release");
add_trace("app", "name", "%s", admin->remote_name);
end_trace();
- /* release all exported channels */
- mISDNport = mISDNport_first;
- while(mISDNport) {
- i = 0;
- ii = mISDNport->b_num;
- while(i < ii) {
- if (mISDNport->b_remote_id[i] == admin->sock) {
- mISDNport->b_state[i] = B_STATE_IDLE;
- unsched_timer(&mISDNport->b_timer[i]);
- mISDNport->b_remote_id[i] = 0;
- mISDNport->b_remote_ref[i] = 0;
- }
- i++;
- }
- mISDNport = mISDNport->next;
- }
- /* release join */
- join = join_first;
- while(join) {
- joinnext = join->next;
- if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock) {
- memset(¶m, 0, sizeof(param));
- param.disconnectinfo.cause = CAUSE_OUTOFORDER;
- param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, ¶m);
- /* join is now destroyed, so we go to next join */
- }
- join = joinnext;
- }
/* release remote port */
port = port_first;
while(port) {
portnext = port->next;
if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_REMOTE) {
remote = (class Premote *) port;
- if (remote->p_m_r_remote_id == admin->sock) {
+ if (remote->p_r_remote_id == admin->sock) {
memset(¶m, 0, sizeof(param));
param.disconnectinfo.cause = CAUSE_OUTOFORDER;
param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
case ACTION_EXTERNAL:
apppbx->e_action = &action_external;
break;
- case ACTION_REMOTE:
- apppbx->e_action = &action_remote;
- break;
case ACTION_VBOX_RECORD:
apppbx->e_action = &action_vbox;
break;
goto out;
}
+#ifdef WITH_MISDN
/* no interface */
if (!ifport->mISDNport) {
/* not loaded anyway */
/* try loading interface */
ifport->block = block;
- load_port(ifport);
+ load_mISDN_port(ifport);
/* port cannot load */
if (ifport->block >= 2) {
ifport->block = 2;
goto out;
}
+#endif
/* port new blocking state */
ifport->block = response->am[0].u.x.block = block;
if (!(epoint = new Endpoint(0, 0)))
FATAL("No memory for Endpoint instance\n");
- if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing
+ if (!(epoint->ep_app = apppbx = new EndpointAppPBX(epoint, 1))) // outgoing
FATAL("No memory for Endpoint Application instance\n");
apppbx->e_adminid = admin->sockserial;
admin->epointid = epoint->ep_serial;
*/
int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin)
{
- struct mISDNport *mISDNport;
- class Join *join;
- class JoinRemote *joinremote = NULL; /* make GCC happy */
class Port *port;
class Premote *remote = NULL; /* make GCC happy */
+ struct interface *interface;
struct admin_list *temp;
/* hello message */
return(-1);
}
- /* new join. the reply (NEWREF assignment) is sent from constructor */
+ /* new remote instance. the reply (NEWREF assignment) is sent from constructor */
if (msg->type == MESSAGE_NEWREF) {
- if (msg->param.newref.mode) {
- char name[32];
- /* find remote port */
- mISDNport = mISDNport_first;
- while(mISDNport) {
- if (mISDNport->ifport->remote && !strcmp(mISDNport->ifport->remote_app, admin->remote_name))
+ char name[32];
+ /* find remote port */
+ interface = interface_first;
+ while(interface) {
+ /* interface must match the remote application */
+ if (interface->remote && !strcmp(interface->remote_app, admin->remote_name)) {
+ /* interface must match the name, if given */
+ if (!msg->param.newref.interface[0] || !strcmp(msg->param.newref.interface, interface->name))
break;
- mISDNport = mISDNport->next;
- }
- if (!mISDNport) {
- union parameter param;
-
- /* create new join instance */
- join = joinremote = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
- if (!join) {
- FATAL("No memory for remote join instance\n");
- return(-1);
- }
- memset(¶m, 0, sizeof(union parameter));
- param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
- admin_message_from_lcr(joinremote->j_remote_id, joinremote->j_remote_ref, MESSAGE_RELEASE, ¶m);
- return 0;
- }
- /* creating port object, transparent until setup with hdlc */
- SPRINT(name, "%s-%s-in", mISDNport->ifport->interface->name, mISDNport->ifport->remote_app);
- if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT, admin->sock)))
-
- FATAL("Cannot create Port instance.\n");
- } else {
- /* create new join instance */
- join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
- if (!join) {
- FATAL("No memory for remote join instance\n");
- return(-1);
}
+ interface = interface->next;
}
- return(0);
- }
+ if (!interface) {
+ union parameter param;
+ unsigned int ref = new_remote++;
- /* bchannel message
- * no ref given for *_ack */
- if (msg->type == MESSAGE_BCHANNEL)
- if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK
- || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK
- || msg->param.bchannel.type == BCHANNEL_RELEASE) {
- /* no ref, but address */
- message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle);
+ start_trace(-1,
+ NULL,
+ NULL,
+ NULL,
+ DIRECTION_NONE,
+ 0,
+ 0,
+ "REMOTE APP illegal interface");
+ add_trace("app", "name", "%s", admin->remote_name);
+ add_trace("interface", "name", "%s", msg->param.newref.interface);
+ end_trace();
+ memset(¶m, 0, sizeof(union parameter));
+ param.newref.direction = 0;
+ admin_message_from_lcr(admin->sock, ref, MESSAGE_NEWREF, ¶m);
+ memset(¶m, 0, sizeof(union parameter));
+ param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
+ param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
+ admin_message_from_lcr(admin->sock, ref, MESSAGE_RELEASE, ¶m);
+ return 0;
+ }
+ /* creating port object, transparent until setup with hdlc */
+ SPRINT(name, "%s-%s-in", interface->name, interface->remote_app);
+ if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, name, NULL, interface, admin->sock)))
+
+ FATAL("Cannot create Port instance.\n");
return(0);
}
-
+
/* check for ref */
if (!msg->ref) {
PERROR("Remote application did not send us a valid ref with a message.\n");
return(-1);
}
- /* find join instance */
- join = join_first;
- while(join) {
- if (join->j_type == JOIN_TYPE_REMOTE) {
- joinremote = (class JoinRemote *)join;
- if (joinremote->j_remote_ref == msg->ref)
- break;
- }
- join = join->next;
- }
- if (join) {
- if (admin->sock != joinremote->j_remote_id) {
- PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name);
- return(-1);
- }
- /* send message */
- joinremote->message_remote(msg->type, &msg->param);
-
- return(0);
- }
-
/* find port instance */
port = port_first;
while(port) {
if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
remote = (class Premote *) port;
- if (remote->p_m_r_ref == msg->ref)
+ if (remote->p_r_ref == msg->ref)
break;
}
port = port->next;
}
if (port) {
- if (admin->sock != remote->p_m_r_remote_id) {
- PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_m_r_remote_app, admin->remote_name);
+ if (admin->sock != remote->p_r_remote_id) {
+ PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, remote->p_r_remote_app, admin->remote_name);
return(-1);
}
class Port *port;
class EndpointAppPBX *apppbx;
class Join *join;
+#ifdef WITH_MISDN
class Pdss1 *pdss1;
- struct interface *interface;
- struct interface_port *ifport;
struct mISDNport *mISDNport;
struct select_channel *selchannel;
+#endif
+ struct interface *interface;
+ struct interface_port *ifport;
int i;
int num;
- int anybusy;
struct admin_queue *response;
struct admin_list *admin;
struct tm *now_tm;
response->am[num].u.i.extension = interface->extension;
/* block */
response->am[num].u.i.block = ifport->block;
+#ifdef WITH_MISDN
if (ifport->mISDNport) {
mISDNport = ifport->mISDNport;
}
/* channel state */
i = 0;
- anybusy = 0;
while(i < mISDNport->b_num) {
response->am[num].u.i.busy[i] = mISDNport->b_state[i];
if (mISDNport->b_port[i])
i++;
}
}
+#endif
num++;
ifport = ifport->next;
/* serial */
response->am[num].u.j.serial = join->j_serial;
/* partyline */
- if (join->j_type == JOIN_TYPE_PBX)
+ if (join->j_type == JOIN_TYPE_PBX) {
response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
- /* remote application */
- if (join->j_type == JOIN_TYPE_REMOTE)
- SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
+ response->am[num].u.j.threepty = ((class JoinPBX *)join)->j_3pty;
+ }
/* */
join = join->next;
num++;
if (apppbx->ea_endpoint->ep_park && apppbx->ea_endpoint->ep_park_len && apppbx->ea_endpoint->ep_park_len<=(int)sizeof(response->am[num].u.e.park_callid))
memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
+#ifdef WITH_CRYPT
/* crypt */
if (apppbx->e_crypt == CRYPT_ON)
response->am[num].u.e.crypt = 1;
+#endif
/* */
apppbx = apppbx->next;
num++;
default:
response->am[num].u.p.state = ADMIN_STATE_IDLE;
}
+#ifdef WITH_MISDN
/* isdn */
if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
response->am[num].u.p.isdn = 1;
response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
}
+#endif
/* */
port = port->next;
num++;
if (len < 0) {
brokenpipe:
PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
- free_connection(admin);
- return 0;
- }
- if (len == 0) {
end:
-
/*release endpoint if exists */
if (admin->epointid) {
epoint = find_epoint_id(admin->epointid);
- if (epoint) {
- ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
+ if (epoint && epoint->ep_app_type == EAPP_TYPE_PBX) {
+ ((class EndpointAppPBX *)epoint->ep_app)->
release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
}
}
free_connection(admin);
return 0;
}
+ if (len == 0)
+ goto end;
if (len != sizeof(msg)) {
PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
- free_connection(admin);
- return 0;
+ goto end;
}
/* process socket command */
if (admin->response && msg.message != ADMIN_MESSAGE) {
PERROR("Data from socket %d while sending response.\n", admin->sock);
- free_connection(admin);
- return 0;
+ goto end;
}
switch (msg.message) {
case ADMIN_REQUEST_CMD_INTERFACE:
if (admin_call(admin, &msg) < 0) {
PERROR("Failed to create call for socket %d.\n", admin->sock);
response_error:
- free_connection(admin);
- return 0;
+ goto end;
}
break;
default:
PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
- free_connection(admin);
- return 0;
+ goto end;
}
}
return 0;
}
-void message_bchannel_to_remote(unsigned int remote_id, unsigned int ref, int type, unsigned int handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type, int isloopback)
-{
- union parameter param;
-
- memset(¶m, 0, sizeof(union parameter));
- param.bchannel.isloopback = isloopback;
- param.bchannel.type = type;
- param.bchannel.handle = handle;
- param.bchannel.tx_gain = tx_gain;
- param.bchannel.rx_gain = rx_gain;
- if (pipeline)
- SCPY(param.bchannel.pipeline, pipeline);
- if (crypt_len)
- memcpy(param.bchannel.crypt, crypt, crypt_len);
- param.bchannel.crypt_type = crypt_type;
- if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, ¶m)<0) {
- PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
- return;
- }
-}
-