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