Adding interface support for remote app (chan_lcr).
[lcr.git] / socket_server.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** Socket link server                                                        **
9 **                                                                           **
10 \*****************************************************************************/
11
12 #include "main.h"
13 #include <sys/socket.h>
14 #include <sys/un.h>
15 #include <curses.h>
16 #include "config.h"
17
18
19 char socket_name[128];
20 int sock = -1;
21 struct sockaddr_un sock_address;
22 extern unsigned int new_remote;
23
24 struct admin_list *admin_first = NULL;
25 static struct lcr_fd admin_fd;
26
27 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index);
28
29 /*
30  * initialize admin socket 
31  */
32 int admin_init(void)
33 {
34         /* open and bind socket */
35         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
36                 PERROR("Failed to create admin socket. (errno=%d)\n", errno);
37                 return(-1);
38         }
39         fhuse++;
40         memset(&sock_address, 0, sizeof(sock_address));
41         SPRINT(socket_name, SOCKET_NAME, options.lock);
42         sock_address.sun_family = AF_UNIX;
43         UCPY(sock_address.sun_path, socket_name);
44         unlink(socket_name);
45         if (bind(sock, (struct sockaddr *)(&sock_address), SUN_LEN(&sock_address)) < 0) {
46                 close(sock);
47                 unlink(socket_name);
48                 fhuse--;
49                 sock = -1;
50                 PERROR("Failed to bind admin socket to \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
51                 return(-1);
52         }
53         if (listen(sock, 5) < 0) {
54                 close(sock);
55                 unlink(socket_name);
56                 fhuse--;
57                 sock = -1;
58                 PERROR("Failed to listen to socket \"%s\". (errno=%d)\n", sock_address.sun_path, errno);
59                 return(-1);
60         }
61         memset(&admin_fd, 0, sizeof(admin_fd));
62         admin_fd.fd = sock;
63         register_fd(&admin_fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle, NULL, 0);
64         if (chmod(socket_name, options.socketrights) < 0) {
65                 PERROR("Failed to change socket rights to %d. (errno=%d)\n", options.socketrights, errno);
66         }
67         if (chown(socket_name, options.socketuser, options.socketgroup) < 0) {
68                 PERROR("Failed to change socket user/group to %d/%d. (errno=%d)\n", options.socketuser, options.socketgroup, errno);
69         }
70
71         return(0);
72 }
73
74
75 /*
76  * free connection
77  * also releases all remote joins
78  */
79 void free_connection(struct admin_list *admin)
80 {
81         struct admin_queue *response;
82         void *temp;
83         union parameter param;
84         class Join *join, *joinnext;
85         struct mISDNport *mISDNport;
86         int i, ii;
87         struct admin_list **adminp;
88         class Port *port, *portnext;
89         class Premote *remote;
90
91         /* free remote joins */
92         if (admin->remote_name[0]) {
93                 start_trace(-1,
94                         NULL,
95                         NULL,
96                         NULL,
97                         DIRECTION_NONE,
98                         0,
99                         0,
100                         "REMOTE APP release");
101                 add_trace("app", "name", "%s", admin->remote_name);
102                 end_trace();
103                 /* release all exported channels */
104                 mISDNport = mISDNport_first;
105                 while(mISDNport) {
106                         i = 0;
107                         ii = mISDNport->b_num;
108                         while(i < ii) {
109                                 if (mISDNport->b_remote_id[i] == admin->sock) {
110                                         mISDNport->b_state[i] = B_STATE_IDLE;
111                                         unsched_timer(&mISDNport->b_timer[i]);
112                                         mISDNport->b_remote_id[i] = 0;
113                                         mISDNport->b_remote_ref[i] = 0;
114                                 }
115                                 i++;
116                         }
117                         mISDNport = mISDNport->next;
118                 }
119                 /* release join */
120                 join = join_first;
121                 while(join) {
122                         joinnext = join->next;
123                         if (join->j_type==JOIN_TYPE_REMOTE) if (((class JoinRemote *)join)->j_remote_id == admin->sock) {
124                                 memset(&param, 0, sizeof(param));
125                                 param.disconnectinfo.cause = CAUSE_OUTOFORDER;
126                                 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
127                                 ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, &param);
128                                 /* join is now destroyed, so we go to next join */
129                         }
130                         join = joinnext;
131                 }
132                 /* release remote port */
133                 port = port_first;
134                 while(port) {
135                         portnext = port->next;
136                         if ((port->p_type & PORT_CLASS_MASK) == PORT_CLASS_REMOTE) {
137                                 remote = (class Premote *) port;
138                                 if (remote->p_m_r_remote_id == admin->sock) {
139                                         memset(&param, 0, sizeof(param));
140                                         param.disconnectinfo.cause = CAUSE_OUTOFORDER;
141                                         param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
142                                         remote->message_remote(MESSAGE_RELEASE, &param);
143                                         /* port is now destroyed, so we go to next join */
144                                 }
145                         }
146                         port = portnext;
147                 }
148         }
149
150         if (admin->sock >= 0) {
151                 unregister_fd(&admin->fd);
152                 close(admin->sock);
153                 fhuse--;
154         }
155         response = admin->response;
156         while (response) {
157                 temp = response->next;
158                 FREE(response, 0);
159                 memuse--;
160                 response = (struct admin_queue *)temp;
161         }
162
163         adminp = &admin_first;
164         while(*adminp) {
165                 if (*adminp == admin)
166                         break;
167                 adminp = &((*adminp)->next);
168         }
169         if (*adminp)
170                 *adminp = (*adminp)->next;
171
172         FREE(admin, 0);
173         memuse--;
174 }
175
176
177 /*
178  * cleanup admin socket 
179  */
180 void admin_cleanup(void)
181 {
182         struct admin_list *admin, *next;;
183
184         admin = admin_first;
185         while(admin) {
186                 next = admin->next;
187                 free_connection(admin);
188                 admin = next;
189         }
190
191         if (sock >= 0) {
192                 unregister_fd(&admin_fd);
193                 close(sock);
194                 fhuse--;
195         }
196
197         unlink(socket_name);
198 }
199
200
201 /*
202  * do interface reload
203  */
204 int admin_interface(struct admin_queue **responsep)
205 {
206         struct admin_queue      *response;      /* response pointer */
207         const char              *err_txt = "";
208         int                     err = 0;
209
210         if (read_interfaces()) {
211                 relink_interfaces();
212                 free_interfaces(interface_first);
213                 interface_first = interface_newlist;
214                 interface_newlist = NULL;
215         } else {
216                 err_txt = interface_error;
217                 err = -1;
218         }
219         /* create state response */
220         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
221         memuse++;
222         response->num = 1;
223         /* message */
224         response->am[0].message = ADMIN_RESPONSE_CMD_INTERFACE;
225         /* error */
226         response->am[0].u.x.error = err;
227         /* message */
228         SCPY(response->am[0].u.x.message, err_txt);
229         /* attach to response chain */
230         *responsep = response;
231         responsep = &response->next;
232         return(0);
233 }
234
235
236 /*
237  * do route reload
238  */
239 int admin_route(struct admin_queue **responsep)
240 {
241         struct route_ruleset    *ruleset_new;
242         struct admin_queue      *response;      /* response pointer */
243         char                    err_txt[256] = "";
244         int                     err = 0;
245 #if 0
246         int                     n;
247 #endif
248         class EndpointAppPBX    *apppbx;
249
250 #if 0
251         n = 0;
252         apppbx = apppbx_first;
253         while(apppbx) {
254                 n++;
255                 apppbx = apppbx->next;
256         }
257         if (apppbx_first) {
258                 SPRINT(err_txt, "Cannot reload routing, because %d endpoints active\n", n);
259                 err = -1;
260                 goto response;
261         }
262 #endif
263         if (!(ruleset_new = ruleset_parse())) {
264                 SPRINT(err_txt, ruleset_error);
265                 err = -1;
266                 goto response;
267         }
268         ruleset_free(ruleset_first);
269         ruleset_first = ruleset_new;
270         ruleset_main = getrulesetbyname("main");
271         if (!ruleset_main) {
272                 SPRINT(err_txt, "Ruleset reloaded, but rule 'main' not found.\n");
273                 err = -1;
274         }
275         apppbx = apppbx_first;
276         while(apppbx) {
277                 if (apppbx->e_action) {
278                         switch(apppbx->e_action->index) {
279                                 case ACTION_INTERNAL:
280                                 apppbx->e_action = &action_internal;
281                                 break;
282                                 case ACTION_EXTERNAL:
283                                 apppbx->e_action = &action_external;
284                                 break;
285                                 case ACTION_REMOTE:
286                                 apppbx->e_action = &action_remote;
287                                 break;
288                                 case ACTION_VBOX_RECORD:
289                                 apppbx->e_action = &action_vbox;
290                                 break;
291                                 case ACTION_PARTYLINE:
292                                 apppbx->e_action = &action_partyline;
293                                 break;
294                                 default:
295                                 goto release;
296                         }
297                 } else if (apppbx->e_state != EPOINT_STATE_CONNECT) {
298                         release:
299                         unsched_timer(&apppbx->e_callback_timeout);
300                         apppbx->e_action = NULL;
301                         apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
302                         start_trace(-1,
303                                 NULL,
304                                 numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype, options.national, options.international),
305                                 apppbx->e_dialinginfo.id,
306                                 DIRECTION_NONE,
307                                 CATEGORY_EP,
308                                 apppbx->ea_endpoint->ep_serial,
309                                 "KICK (reload routing)");
310                         end_trace();
311                 }
312
313                 unsched_timer(&apppbx->e_action_timeout);
314                 apppbx->e_rule = NULL;
315                 apppbx->e_ruleset = NULL;
316
317                 apppbx = apppbx->next;
318         }
319
320         response:
321         /* create state response */
322         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
323         memuse++;
324         response->num = 1;
325         /* message */
326         response->am[0].message = ADMIN_RESPONSE_CMD_ROUTE;
327         /* error */
328         response->am[0].u.x.error = err;
329         /* message */
330         SCPY(response->am[0].u.x.message, err_txt);
331         /* attach to response chain */
332         *responsep = response;
333         responsep = &response->next;
334         return(0);
335 }
336
337
338 /*
339  * do dialing
340  */
341 int admin_dial(struct admin_queue **responsep, char *message)
342 {
343         struct extension        ext;            /* temporary extension's settings */
344         struct admin_queue      *response;      /* response pointer */
345         char                    *p;             /* pointer to dialing digits */
346
347         /* create state response */
348         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
349         memuse++;
350         response->num = 1;
351         /* message */
352         response->am[0].message = ADMIN_RESPONSE_CMD_DIAL;
353
354         /* process request */
355         if (!(p = strchr(message,':'))) {
356                 response->am[0].u.x.error = -EINVAL;
357                 SPRINT(response->am[0].u.x.message, "no seperator ':' in message to seperate number from extension");
358                 goto out;
359         }
360         *p++ = 0;
361
362         /* modify extension */
363         if (!read_extension(&ext, message)) {
364                 response->am[0].u.x.error = -EINVAL;
365                 SPRINT(response->am[0].u.x.message, "extension doesn't exist");
366                 goto out;
367         }
368         SCPY(ext.next, p);
369         write_extension(&ext, message);
370
371         out:
372         /* attach to response chain */
373         *responsep = response;
374         responsep = &response->next;
375         return(0);
376 }
377
378
379 /*
380  * do tracing
381  */
382 int admin_trace(struct admin_list *admin, struct admin_trace_req *trace)
383 {
384         memcpy(&admin->trace, trace, sizeof(struct admin_trace_req));
385         return(0);
386 }
387
388
389 /*
390  * do blocking
391  * 
392  * 0 = make port available
393  * 1 = make port administratively blocked
394  * 2 = unload port
395  * the result is returned:
396  * 0 = port is now available
397  * 1 = port is now blocked
398  * 2 = port cannot be loaded or has been unloaded
399  * -1 = port doesn't exist
400  */
401 int admin_block(struct admin_queue **responsep, int portnum, int block)
402 {
403         struct admin_queue      *response;      /* response pointer */
404         struct interface        *interface;
405         struct interface_port   *ifport;
406
407         /* create block response */
408         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
409         memuse++;
410         response->num = 1;
411         /* message */
412         response->am[0].message = ADMIN_RESPONSE_CMD_BLOCK;
413         response->am[0].u.x.portnum = portnum;
414
415         /* search for port */
416         ifport = NULL;
417         interface = interface_first;
418         while(interface) {
419                 ifport = interface->ifport;
420                 while(ifport) {
421                         if (ifport->portnum == portnum)
422                                 break;
423                         ifport = ifport->next;
424                 }
425                 if (ifport)
426                         break;
427                 interface = interface->next;
428         }
429         /* not found, we return -1 */
430         if (!ifport) {
431                 response->am[0].u.x.block = -1;
432                 response->am[0].u.x.error = 1;
433                 SPRINT(response->am[0].u.x.message, "Port %d does not exist.", portnum);
434                 goto out;
435         }
436
437         /* no interface */
438         if (!ifport->mISDNport) {
439                 /* not loaded anyway */
440                 if (block >= 2) {
441                         response->am[0].u.x.block = 2;
442                         goto out;
443                 }
444
445                 /* try loading interface */
446                 ifport->block = block;
447                 load_port(ifport);
448
449                 /* port cannot load */
450                 if (ifport->block >= 2) {
451                         response->am[0].u.x.block = 2;
452                         response->am[0].u.x.error = 1;
453                         SPRINT(response->am[0].u.x.message, "Port %d will not load.", portnum);
454                         goto out;
455                 }
456
457                 /* port loaded */
458                 response->am[0].u.x.block = ifport->block;
459                 goto out;
460         }
461
462         /* if we shall unload interface */
463         if (block >= 2) {
464                 mISDNport_close(ifport->mISDNport);
465                 ifport->mISDNport = 0;
466                 ifport->block = 2;
467                 goto out;
468         }
469         
470         /* port new blocking state */
471         ifport->block = response->am[0].u.x.block = block;
472
473         out:
474         /* attach to response chain */
475         *responsep = response;
476         responsep = &response->next;
477         return(0);
478 }
479
480
481 /*
482  * do release
483  */
484 int admin_release(struct admin_queue **responsep, char *message)
485 {
486         unsigned int            id;
487         struct admin_queue      *response;      /* response pointer */
488         class EndpointAppPBX    *apppbx;
489
490         /* create state response */
491         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
492         memuse++;
493         response->num = 1;
494         /* message */
495         response->am[0].message = ADMIN_RESPONSE_CMD_RELEASE;
496
497         id = atoi(message);
498         apppbx = apppbx_first;
499         while(apppbx) {
500                 if (apppbx->ea_endpoint->ep_serial == id)
501                         break;
502                 apppbx = apppbx->next;
503         }
504         if (!apppbx) {
505                 response->am[0].u.x.error = -EINVAL;
506                 SPRINT(response->am[0].u.x.message, "Given endpoint %d doesn't exist.", id);
507                 goto out;
508         }
509
510         unsched_timer(&apppbx->e_callback_timeout);
511         apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
512
513         out:
514         /* attach to response chain */
515         *responsep = response;
516         responsep = &response->next;
517         return(0);
518 }
519
520
521 /*
522  * do call
523  */
524 int admin_call(struct admin_list *admin, struct admin_message *msg)
525 {
526         class Endpoint          *epoint;
527         class EndpointAppPBX    *apppbx;
528
529         if (!(epoint = new Endpoint(0, 0)))
530                 FATAL("No memory for Endpoint instance\n");
531         if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing
532                 FATAL("No memory for Endpoint Application instance\n");
533         apppbx->e_adminid = admin->sockserial;
534         admin->epointid = epoint->ep_serial;
535         SCPY(apppbx->e_callerinfo.id, nationalize_callerinfo(msg->u.call.callerid, &apppbx->e_callerinfo.ntype, options.national, options.international));
536         if (msg->u.call.present)
537                 apppbx->e_callerinfo.present = INFO_PRESENT_ALLOWED;
538         else
539                 apppbx->e_callerinfo.present = INFO_PRESENT_RESTRICTED;
540         apppbx->e_callerinfo.screen = INFO_SCREEN_NETWORK;
541
542
543         apppbx->e_capainfo.bearer_capa = msg->u.call.bc_capa;
544         apppbx->e_capainfo.bearer_mode = msg->u.call.bc_mode;
545         apppbx->e_capainfo.bearer_info1 = msg->u.call.bc_info1;
546         apppbx->e_capainfo.hlc = msg->u.call.hlc;
547         apppbx->e_capainfo.exthlc = msg->u.call.exthlc;
548         SCPY(apppbx->e_dialinginfo.id, msg->u.call.dialing);
549         SCPY(apppbx->e_dialinginfo.interfaces, msg->u.call.interface);
550         apppbx->e_dialinginfo.sending_complete = 1;
551
552         apppbx->new_state(PORT_STATE_OUT_SETUP);
553         apppbx->out_setup(0);
554         return(0);
555 }
556
557
558 /*
559  * this function is called for response whenever a call state changes.
560  */
561 void admin_call_response(int adminid, int message, const char *connected, int cause, int location, int notify_progress)
562 {
563         struct admin_list       *admin;
564         struct admin_queue      *response, **responsep; /* response pointer */
565
566         /* searching for admin id
567          * maybe there is no admin instance, because the calling port was not
568          * initiated by admin_call */
569         admin = admin_first;
570         while(admin) {
571                 if (adminid == admin->sockserial)
572                         break;
573                 admin = admin->next;
574         }
575         if (!admin)
576                 return;
577
578         /* seek to end of response list */
579         response = admin->response;
580         responsep = &admin->response;
581         while(response) {
582                 responsep = &response->next;
583                 response = response->next;
584         }
585
586         /* create state response */
587         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
588         memuse++;
589         response->num = 1;
590         /* message */
591         response->am[0].message = message;
592
593         SCPY(response->am[0].u.call.callerid, connected);
594         response->am[0].u.call.cause = cause;
595         response->am[0].u.call.location = location;
596         response->am[0].u.call.notify_progress = notify_progress;
597
598         /* attach to response chain */
599         *responsep = response;
600         responsep = &response->next;
601         admin->fd.when |= LCR_FD_WRITE;
602 }
603
604
605 /*
606  * send data to the remote socket join instance
607  */
608 int admin_message_to_lcr(struct admin_msg *msg, struct admin_list *admin)
609 {
610         struct mISDNport                *mISDNport;
611         class Join                      *join;
612         class JoinRemote                *joinremote = NULL; /* make GCC happy */
613         class Port                      *port;
614         class Premote                   *remote = NULL; /* make GCC happy */
615         struct admin_list               *temp;
616
617         /* hello message */
618         if (msg->type == MESSAGE_HELLO) {
619                 if (admin->remote_name[0]) {
620                         PERROR("Remote application repeats hello message.\n");
621                         return(-1);
622                 }
623                 /* look for second application */
624                 temp = admin_first;
625                 while(temp) {
626                         if (!strcmp(temp->remote_name, msg->param.hello.application))
627                                 break;
628                         temp = temp->next;
629                 }
630                 if (temp) {
631                         PERROR("Remote application connects twice??? (ignoring)\n");
632                         return(-1);
633                 }
634                 /* set remote socket instance */
635                 SCPY(admin->remote_name, msg->param.hello.application);
636                 start_trace(-1,
637                         NULL,
638                         NULL,
639                         NULL,
640                         DIRECTION_NONE,
641                         0,
642                         0,
643                         "REMOTE APP registers");
644                 add_trace("app", "name", "%s", admin->remote_name);
645                 end_trace();
646                 return(0);
647         }
648
649         /* check we have no application name */
650         if (!admin->remote_name[0]) {
651                 PERROR("Remote application did not send us a hello message.\n");
652                 return(-1);
653         }
654
655         /* new join. the reply (NEWREF assignment) is sent from constructor */
656         if (msg->type == MESSAGE_NEWREF) {
657                 if (msg->param.newref.mode) {
658                         char name[32];
659                         /* find remote port */
660                         mISDNport = mISDNport_first;
661                         while(mISDNport) {
662                                 if (mISDNport->ifport->remote && !strcmp(mISDNport->ifport->remote_app, admin->remote_name))
663                                         break;
664                                 mISDNport = mISDNport->next;
665                         }
666                         if (!mISDNport) {
667                                 unsigned int remote_ref = new_remote++;
668                                 union parameter param;
669
670                                 memset(&param, 0, sizeof(union parameter));
671                                 admin_message_from_lcr(mISDNport->ifport->remote, remote_ref, MESSAGE_NEWREF, &param);
672                                 memset(&param, 0, sizeof(union parameter));
673                                 param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
674                                 param.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
675                                 admin_message_from_lcr(mISDNport->ifport->remote, remote_ref, MESSAGE_RELEASE, &param);
676                                 return 0;
677                         }
678                         /* creating port object, transparent until setup with hdlc */
679                         SPRINT(name, "%s-%s-in", mISDNport->ifport->interface->name, mISDNport->ifport->remote_app);
680                         if (!(remote = new Premote(PORT_TYPE_REMOTE_IN, mISDNport, name, NULL, 0, 0, B_MODE_TRANSPARENT, admin->sock)))
681
682                                 FATAL("Cannot create Port instance.\n");
683                 } else {
684                         /* create new join instance */
685                         join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
686                         if (!join) {
687                                 FATAL("No memory for remote join instance\n");
688                                 return(-1);
689                         }
690                 }
691                 return(0);
692         }
693
694         /* bchannel message
695          * no ref given for *_ack */
696         if (msg->type == MESSAGE_BCHANNEL)
697         if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK
698          || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK
699          || msg->param.bchannel.type == BCHANNEL_RELEASE) {
700 #warning TODO: depending on the mode (join / remoteport) forward message
701                 /* no ref, but address */
702                 message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle);
703                 return(0);
704         }
705         
706         /* check for ref */
707         if (!msg->ref) {
708                 PERROR("Remote application did not send us a valid ref with a message.\n");
709                 return(-1);
710         }
711
712         /* find join instance */
713         join = join_first;
714         while(join) {
715                 if (join->j_type != JOIN_TYPE_REMOTE) {
716                         joinremote = (class JoinRemote *)join;
717                         if (joinremote->j_remote_ref == msg->ref)
718                                 break;
719                 }
720                 join = join->next;
721         }
722         if (join) {
723                 if (admin->sock != joinremote->j_remote_id) {
724                         PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name);
725                         return(-1);
726                 }
727                 /* send message */
728                 joinremote->message_remote(msg->type, &msg->param);
729
730                 return(0);
731         }
732
733         /* find port instance */
734         port = port_first;
735         while(port) {
736                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
737                         remote = (class Premote *) port;
738                         if (remote->p_m_r_ref == msg->ref)
739                                 break;
740                 }
741                 port = port->next;
742         }
743         if (port) {
744                 if (admin->sock != remote->p_m_r_remote_id) {
745                         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);
746                         return(-1);
747                 }
748
749                 /* send message */
750                 remote->message_remote(msg->type, &msg->param);
751
752                 return(0);
753         }
754
755         PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref);
756         return(0);
757
758 }
759
760
761 /*
762  * this function is called for every message to remote socket
763  */
764 int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param)
765 {
766         struct admin_list       *admin;
767         struct admin_queue      **responsep;    /* response pointer */
768
769         /* searching for admin id
770          * maybe there is no given remote application
771          */
772         admin = admin_first;
773         while(admin) {
774                 if (admin->remote_name[0] && admin->sock==remote_id)
775                         break;
776                 admin = admin->next;
777         }
778         /* no given remote application connected */
779         if (!admin)
780                 return(-1);
781
782         /* seek to end of response list */
783         responsep = &admin->response;
784         while(*responsep) {
785                 responsep = &(*responsep)->next;
786         }
787
788         /* create state response */
789         *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
790         memuse++;
791         (*responsep)->num = 1;
792
793         /* message */
794         (*responsep)->am[0].message = ADMIN_MESSAGE;
795         (*responsep)->am[0].u.msg.type = message_type;
796         (*responsep)->am[0].u.msg.ref = ref;
797         memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
798         admin->fd.when |= LCR_FD_WRITE;
799         return(0);
800 }
801
802
803 /*
804  * do state debugging
805  */
806 int admin_state(struct admin_queue **responsep)
807 {
808         class Port              *port;
809         class EndpointAppPBX    *apppbx;
810         class Join              *join;
811         class Pdss1             *pdss1;
812         struct interface        *interface;
813         struct interface_port   *ifport;
814         struct mISDNport        *mISDNport;
815         struct select_channel   *selchannel;
816         int                     i;
817         int                     num;
818         int                     anybusy;
819         struct admin_queue      *response;
820         struct admin_list       *admin;
821         struct tm               *now_tm;
822         time_t                  now;
823
824         /* create state response */
825         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
826         memuse++;
827         response->num = 1;
828         /* message */
829         response->am[0].message = ADMIN_RESPONSE_STATE;
830         /* version */
831         SCPY(response->am[0].u.s.version_string, VERSION_STRING);
832         /* time */
833         time(&now);
834         now_tm = localtime(&now);
835         memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
836         /* log file */
837         SCPY(response->am[0].u.s.logfile, options.log);
838         /* interface count */
839         i = 0;
840         interface = interface_first;
841         while(interface) {
842                 ifport = interface->ifport;
843                 while(ifport) {
844                         i++;
845                         ifport = ifport->next;
846                 }
847                 interface = interface->next;
848         }
849         response->am[0].u.s.interfaces = i;
850         /* remote connection count */
851         i = 0;
852         admin = admin_first;
853         while(admin) {
854                 if (admin->remote_name[0])
855                         i++;
856                 admin = admin->next;
857         }
858         response->am[0].u.s.remotes = i;
859         /* join count */
860         join = join_first;
861         i = 0;
862         while(join) {
863                 i++;
864                 join = join->next;
865         }
866         response->am[0].u.s.joins = i;
867         /* apppbx count */
868         apppbx = apppbx_first;
869         i = 0;
870         while(apppbx) {
871                 i++;
872                 apppbx = apppbx->next;
873         }
874         response->am[0].u.s.epoints = i;
875         /* port count */
876         i = 0;
877         port = port_first;
878         while(port) {
879                 i++;
880                 port = port->next;
881         }
882         response->am[0].u.s.ports = i;
883         /* attach to response chain */
884         *responsep = response;
885         responsep = &response->next;
886
887         /* create response for all instances */
888         num = (response->am[0].u.s.interfaces)
889             + (response->am[0].u.s.remotes)
890             + (response->am[0].u.s.joins)
891             + (response->am[0].u.s.epoints)
892             + (response->am[0].u.s.ports);
893         if (num == 0)
894                 return(0);
895         response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
896         memuse++;
897         response->num = num;
898         *responsep = response;
899         responsep = &response->next;
900         interface = interface_first;
901         num = 0;
902         while(interface) {
903                 ifport = interface->ifport;
904                 while(ifport) {
905                         /* message */
906                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
907                         /* interface */
908                         SCPY(response->am[num].u.i.interface_name, interface->name);
909                         /* portnum */
910                         response->am[num].u.i.portnum = ifport->portnum;
911                         /* portname */
912                         SCPY(response->am[num].u.i.portname, ifport->portname);
913                         /* iftype */
914                         response->am[num].u.i.extension = interface->extension;
915                         /* block */
916                         response->am[num].u.i.block = ifport->block;
917                         if (ifport->mISDNport) {
918                                 mISDNport = ifport->mISDNport;
919
920                                 /* ptp */
921                                 response->am[num].u.i.ptp = mISDNport->ptp;
922                                 /* l1hold */
923                                 response->am[num].u.i.l1hold = mISDNport->l1hold;
924                                 /* l2hold */
925                                 response->am[num].u.i.l2hold = mISDNport->l2hold;
926                                 /* ntmode */
927                                 response->am[num].u.i.ntmode = mISDNport->ntmode;
928                                 /* pri */
929                                 response->am[num].u.i.pri = mISDNport->pri;
930                                 /* use */
931                                 response->am[num].u.i.use = mISDNport->use;
932                                 /* l1link */
933                                 response->am[num].u.i.l1link = mISDNport->l1link;
934                                 /* l2link */
935                                 response->am[num].u.i.l2link = mISDNport->l2link;
936                                 memcpy(response->am[num].u.i.l2mask, mISDNport->l2mask, 16);
937                                 /* los */
938                                 response->am[num].u.i.los = mISDNport->los;
939                                 /* ais */
940                                 response->am[num].u.i.ais = mISDNport->ais;
941                                 /* rdi */
942                                 response->am[num].u.i.rdi = mISDNport->rdi;
943                                 /* slip */
944                                 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
945                                 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
946                                 /* channels */
947                                 response->am[num].u.i.channels = mISDNport->b_num;
948                                 /* channel selection */
949                                 selchannel = ifport->out_channel;
950                                 if (ifport->channel_force)
951                                         SCAT(response->am[num].u.i.out_channel, "force");
952                                 while (selchannel) {
953                                         if (response->am[num].u.i.out_channel[0])
954                                                 SCAT(response->am[num].u.i.out_channel, ",");
955                                         switch (selchannel->channel) {
956                                         case CHANNEL_NO:
957                                                 SCAT(response->am[num].u.i.out_channel, "no");
958                                                 break;
959                                         case CHANNEL_ANY:
960                                                 SCAT(response->am[num].u.i.out_channel, "any");
961                                                 break;
962                                         case CHANNEL_FREE:
963                                                 SCAT(response->am[num].u.i.out_channel, "free");
964                                                 break;
965                                         default:
966                                                 SPRINT(strchr(response->am[num].u.i.out_channel, '\0'), "%d", selchannel->channel);
967                                         }
968                                         selchannel = selchannel->next;
969                                 }
970                                 selchannel = ifport->in_channel;
971                                 while (selchannel) {
972                                         switch (selchannel->channel) {
973                                         case CHANNEL_FREE:
974                                                 SCAT(response->am[num].u.i.in_channel, "free");
975                                                 break;
976                                         default:
977                                                 SPRINT(strchr(response->am[num].u.i.in_channel, '\0'), "%d", selchannel->channel);
978                                         }
979                                         selchannel = selchannel->next;
980                                 }
981                                 /* channel state */
982                                 i = 0;
983                                 anybusy = 0;
984                                 while(i < mISDNport->b_num) {
985                                         response->am[num].u.i.busy[i] = mISDNport->b_state[i];
986                                         if (mISDNport->b_port[i])
987                                                 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
988                                         response->am[num].u.i.mode[i] = mISDNport->b_mode[i];
989                                         i++;
990                                 }
991                         }
992                         num++;
993
994                         ifport = ifport->next;
995                 }
996                 interface = interface->next;
997         }
998
999         /* create response for all remotes */
1000         admin = admin_first;
1001         while(admin) {
1002                 if (admin->remote_name[0]) {
1003                         /* message */
1004                         response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
1005                         /* name */
1006                         SCPY(response->am[num].u.r.name, admin->remote_name);
1007                         /* */
1008                         num++;
1009                 }
1010                 admin = admin->next;
1011         }
1012
1013         /* create response for all joins */
1014         join = join_first;
1015         while(join) {
1016                 /* message */
1017                 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
1018                 /* serial */
1019                 response->am[num].u.j.serial = join->j_serial;
1020                 /* partyline */
1021                 if (join->j_type == JOIN_TYPE_PBX)
1022                         response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
1023                 /* remote application */
1024                 if (join->j_type == JOIN_TYPE_REMOTE)
1025                         SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
1026                 /* */
1027                 join = join->next;
1028                 num++;
1029         }
1030
1031         /* create response for all endpoint */
1032         apppbx = apppbx_first;
1033         while(apppbx) {
1034                 /* message */
1035                 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
1036                 /* serial */
1037                 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
1038                 /* join */
1039                 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
1040                 /* rx notification */
1041                 response->am[num].u.e.rx_state = apppbx->e_rx_state;
1042                 /* tx notification */
1043                 response->am[num].u.e.tx_state = apppbx->e_tx_state;
1044                 /* state */
1045                 switch(apppbx->e_state) {
1046                         case EPOINT_STATE_IN_SETUP:
1047                         response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
1048                         break;
1049                         case EPOINT_STATE_OUT_SETUP:
1050                         response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
1051                         break;
1052                         case EPOINT_STATE_IN_OVERLAP:
1053                         response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
1054                         break;
1055                         case EPOINT_STATE_OUT_OVERLAP:
1056                         response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
1057                         break;
1058                         case EPOINT_STATE_IN_PROCEEDING:
1059                         response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
1060                         break;
1061                         case EPOINT_STATE_OUT_PROCEEDING:
1062                         response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1063                         break;
1064                         case EPOINT_STATE_IN_ALERTING:
1065                         response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1066                         break;
1067                         case EPOINT_STATE_OUT_ALERTING:
1068                         response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1069                         break;
1070                         case EPOINT_STATE_CONNECT:
1071                         response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1072                         break;
1073                         case EPOINT_STATE_IN_DISCONNECT:
1074                         response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1075                         break;
1076                         case EPOINT_STATE_OUT_DISCONNECT:
1077                         response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1078                         break;
1079                         default:
1080                         response->am[num].u.e.state = ADMIN_STATE_IDLE;
1081                 }
1082                 /* terminal */
1083                 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1084                 /* callerid */
1085                 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1086                 /* dialing */
1087                 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1088                 /* action string */
1089                 if (apppbx->e_action)
1090                         SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1091 //              if (apppbx->e_action)
1092 //              printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1093                 /* park */
1094                 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1095                 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))
1096                         memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1097                 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1098                 /* crypt */
1099                 if (apppbx->e_crypt == CRYPT_ON)
1100                         response->am[num].u.e.crypt = 1;
1101                 /* */
1102                 apppbx = apppbx->next;
1103                 num++;
1104         }
1105
1106         /* create response for all ports */
1107         port = port_first;
1108         while(port) {
1109                 /* message */
1110                 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1111                 /* serial */
1112                 response->am[num].u.p.serial = port->p_serial;
1113                 /* name */
1114                 SCPY(response->am[num].u.p.name, port->p_name);
1115                 /* epoint */
1116                 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1117                 /* state */
1118                 switch(port->p_state) {
1119                         case PORT_STATE_IN_SETUP:
1120                         response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1121                         break;
1122                         case PORT_STATE_OUT_SETUP:
1123                         response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1124                         break;
1125                         case PORT_STATE_IN_OVERLAP:
1126                         response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1127                         break;
1128                         case PORT_STATE_OUT_OVERLAP:
1129                         response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1130                         break;
1131                         case PORT_STATE_IN_PROCEEDING:
1132                         response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1133                         break;
1134                         case PORT_STATE_OUT_PROCEEDING:
1135                         response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1136                         break;
1137                         case PORT_STATE_IN_ALERTING:
1138                         response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1139                         break;
1140                         case PORT_STATE_OUT_ALERTING:
1141                         response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1142                         break;
1143                         case PORT_STATE_CONNECT:
1144                         response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1145                         break;
1146                         case PORT_STATE_IN_DISCONNECT:
1147                         response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1148                         break;
1149                         case PORT_STATE_OUT_DISCONNECT:
1150                         response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1151                         break;
1152                         case PORT_STATE_RELEASE:
1153                         response->am[num].u.p.state = ADMIN_STATE_RELEASE;
1154                         break;
1155                         default:
1156                         response->am[num].u.p.state = ADMIN_STATE_IDLE;
1157                 }
1158                 /* isdn */
1159                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
1160                         response->am[num].u.p.isdn = 1;
1161                         pdss1 = (class Pdss1 *)port;
1162                         response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1163                         response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1164                         response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1165                 }
1166                 /* */
1167                 port = port->next;
1168                 num++;
1169         }
1170         return(0);
1171 }
1172
1173 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1174 /*
1175  * handle admin socket (non blocking)
1176  */
1177 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index);
1178
1179 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1180 {
1181         int                     new_sock;
1182         socklen_t               sock_len = sizeof(sock_address);
1183         struct admin_list       *admin;
1184
1185         /* check for new incoming connections */
1186         if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0) {
1187                 /* insert new socket */
1188                 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1189                 memuse++;
1190                 fhuse++;
1191                 admin->sockserial = sockserial++;
1192                 admin->next = admin_first;
1193                 admin_first = admin;
1194                 admin->sock = new_sock;
1195                 admin->fd.fd = new_sock;
1196                 register_fd(&admin->fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle_con, admin, 0);
1197         } else {
1198                 if (errno != EWOULDBLOCK) {
1199                         PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1200                         admin_cleanup();
1201                         return 0;
1202                 }
1203         }
1204
1205         return 0;
1206 }
1207
1208 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1209 {
1210         struct admin_list *admin = (struct admin_list *)instance;
1211         void                    *temp;
1212         struct admin_message    msg;
1213         int                     len;
1214         struct Endpoint         *epoint;
1215
1216         if ((what & LCR_FD_READ)) {
1217                 /* read command */
1218                 len = read(admin->sock, &msg, sizeof(msg));
1219                 if (len < 0) {
1220                         brokenpipe:
1221                         PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1222                         free_connection(admin);
1223                         return 0;
1224                 }
1225                 if (len == 0) {
1226                         end:
1227
1228                         /*release endpoint if exists */
1229                         if (admin->epointid) {
1230                                 epoint = find_epoint_id(admin->epointid);
1231                                 if (epoint) {
1232                                         ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
1233                                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
1234                                 }
1235                         }
1236
1237                         free_connection(admin);
1238                         return 0;
1239                 }
1240                 if (len != sizeof(msg)) {
1241                         PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1242                         free_connection(admin);
1243                         return 0;
1244                 }
1245                 /* process socket command */
1246                 if (admin->response && msg.message != ADMIN_MESSAGE) {
1247                         PERROR("Data from socket %d while sending response.\n", admin->sock);
1248                         free_connection(admin);
1249                         return 0;
1250                 }
1251                 switch (msg.message) {
1252                         case ADMIN_REQUEST_CMD_INTERFACE:
1253                         if (admin_interface(&admin->response) < 0) {
1254                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1255                                 goto response_error;
1256                         }
1257                         admin->fd.when |= LCR_FD_WRITE;
1258                         break;
1259
1260                         case ADMIN_REQUEST_CMD_ROUTE:
1261                         if (admin_route(&admin->response) < 0) {
1262                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1263                                 goto response_error;
1264                         }
1265                         admin->fd.when |= LCR_FD_WRITE;
1266                         break;
1267
1268                         case ADMIN_REQUEST_CMD_DIAL:
1269                         if (admin_dial(&admin->response, msg.u.x.message) < 0) {
1270                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1271                                 goto response_error;
1272                         }
1273                         admin->fd.when |= LCR_FD_WRITE;
1274                         break;
1275
1276                         case ADMIN_REQUEST_CMD_RELEASE:
1277                         if (admin_release(&admin->response, msg.u.x.message) < 0) {
1278                                 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1279                                 goto response_error;
1280                         }
1281                         admin->fd.when |= LCR_FD_WRITE;
1282                         break;
1283
1284                         case ADMIN_REQUEST_STATE:
1285                         if (admin_state(&admin->response) < 0) {
1286                                 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1287                                 goto response_error;
1288                         }
1289                         admin->fd.when |= LCR_FD_WRITE;
1290                         break;
1291
1292                         case ADMIN_TRACE_REQUEST:
1293                         if (admin_trace(admin, &msg.u.trace_req) < 0) {
1294                                 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1295                                 goto response_error;
1296                         }
1297                         admin->fd.when |= LCR_FD_WRITE;
1298                         break;
1299
1300                         case ADMIN_REQUEST_CMD_BLOCK:
1301                         if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) {
1302                                 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1303                                 goto response_error;
1304                         }
1305                         admin->fd.when |= LCR_FD_WRITE;
1306                         break;
1307
1308                         case ADMIN_MESSAGE:
1309                         if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
1310                                 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1311                                 goto response_error;
1312                         }
1313                         break;
1314
1315                         case ADMIN_CALL_SETUP:
1316                         if (admin_call(admin, &msg) < 0) {
1317                                 PERROR("Failed to create call for socket %d.\n", admin->sock);
1318                                 response_error:
1319                                 free_connection(admin);
1320                                 return 0;
1321                         }
1322                         break;
1323
1324                         default:
1325                         PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1326                         free_connection(admin);
1327                         return 0;
1328                 }
1329         }
1330
1331         if ((what & LCR_FD_WRITE)) {
1332                 /* write queue */
1333                 if (admin->response) {
1334                         len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1335                         if (len < 0) {
1336                                 goto brokenpipe;
1337                         }
1338                         if (len == 0)
1339                                 goto end;
1340                         if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) {
1341                                 admin->response->offset+=len;
1342                                 return 0;
1343                         } else {
1344                                 temp = admin->response;
1345                                 admin->response = admin->response->next;
1346                                 FREE(temp, 0);
1347                                 memuse--;
1348                         }
1349                 } else
1350                         admin->fd.when &= ~LCR_FD_WRITE;
1351         }
1352
1353         return 0;
1354 }
1355
1356 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)
1357 {
1358         union parameter param;
1359
1360         memset(&param, 0, sizeof(union parameter));
1361         param.bchannel.isloopback = isloopback;
1362         param.bchannel.type = type;
1363         param.bchannel.handle = handle;
1364         param.bchannel.tx_gain = tx_gain;
1365         param.bchannel.rx_gain = rx_gain;
1366         if (pipeline)
1367                 SCPY(param.bchannel.pipeline, pipeline);
1368         if (crypt_len)
1369                 memcpy(param.bchannel.crypt, crypt, crypt_len);
1370         param.bchannel.crypt_type = crypt_type;
1371         if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, &param)<0) {
1372                 PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
1373                 return;         
1374         }
1375 }
1376