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