Forward DTMF as message directly from GSM BS to SIP.
[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                 if (!ifport)
848                         i++;
849                 while(ifport) {
850                         i++;
851                         ifport = ifport->next;
852                 }
853                 interface = interface->next;
854         }
855         response->am[0].u.s.interfaces = i;
856         /* remote connection count */
857         i = 0;
858         admin = admin_first;
859         while(admin) {
860                 if (admin->remote_name[0])
861                         i++;
862                 admin = admin->next;
863         }
864         response->am[0].u.s.remotes = i;
865         /* join count */
866         join = join_first;
867         i = 0;
868         while(join) {
869                 i++;
870                 join = join->next;
871         }
872         response->am[0].u.s.joins = i;
873         /* apppbx count */
874         apppbx = apppbx_first;
875         i = 0;
876         while(apppbx) {
877                 i++;
878                 apppbx = apppbx->next;
879         }
880         response->am[0].u.s.epoints = i;
881         /* port count */
882         i = 0;
883         port = port_first;
884         while(port) {
885                 i++;
886                 port = port->next;
887         }
888         response->am[0].u.s.ports = i;
889         /* attach to response chain */
890         *responsep = response;
891         responsep = &response->next;
892
893         /* create response for all instances */
894         num = (response->am[0].u.s.interfaces)
895             + (response->am[0].u.s.remotes)
896             + (response->am[0].u.s.joins)
897             + (response->am[0].u.s.epoints)
898             + (response->am[0].u.s.ports);
899         if (num == 0)
900                 return(0);
901         response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
902         memuse++;
903         response->num = num;
904         *responsep = response;
905         responsep = &response->next;
906         interface = interface_first;
907         num = 0;
908         while(interface) {
909                 ifport = interface->ifport;
910                 if (!ifport) {
911                         /* message */
912                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
913                         /* interface */
914                         SCPY(response->am[num].u.i.interface_name, interface->name);
915                         /* portnum */
916                         response->am[num].u.i.portnum = -100; /* indicate: no ifport */
917                         /* iftype */
918                         response->am[num].u.i.extension = interface->extension;
919                         /* block */
920                         num++;
921                 }
922                 while(ifport) {
923                         /* message */
924                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
925                         /* interface */
926                         SCPY(response->am[num].u.i.interface_name, interface->name);
927                         /* portnum */
928                         response->am[num].u.i.portnum = ifport->portnum;
929                         /* portname */
930                         SCPY(response->am[num].u.i.portname, ifport->portname);
931                         /* iftype */
932                         response->am[num].u.i.extension = interface->extension;
933                         /* block */
934                         response->am[num].u.i.block = ifport->block;
935                         if (ifport->mISDNport) {
936                                 mISDNport = ifport->mISDNport;
937
938                                 /* ptp */
939                                 response->am[num].u.i.ptp = mISDNport->ptp;
940                                 /* l1hold */
941                                 response->am[num].u.i.l1hold = mISDNport->l1hold;
942                                 /* l2hold */
943                                 response->am[num].u.i.l2hold = mISDNport->l2hold;
944                                 /* ntmode */
945                                 response->am[num].u.i.ntmode = mISDNport->ntmode;
946                                 /* pri */
947                                 response->am[num].u.i.pri = mISDNport->pri;
948                                 /* use */
949                                 response->am[num].u.i.use = mISDNport->use;
950                                 /* l1link */
951                                 response->am[num].u.i.l1link = mISDNport->l1link;
952                                 /* l2link */
953                                 response->am[num].u.i.l2link = mISDNport->l2link;
954                                 memcpy(response->am[num].u.i.l2mask, mISDNport->l2mask, 16);
955                                 /* los */
956                                 response->am[num].u.i.los = mISDNport->los;
957                                 /* ais */
958                                 response->am[num].u.i.ais = mISDNport->ais;
959                                 /* rdi */
960                                 response->am[num].u.i.rdi = mISDNport->rdi;
961                                 /* slip */
962                                 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
963                                 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
964                                 /* channels */
965                                 response->am[num].u.i.channels = mISDNport->b_num;
966                                 /* channel selection */
967                                 selchannel = ifport->out_channel;
968                                 if (ifport->channel_force)
969                                         SCAT(response->am[num].u.i.out_channel, "force");
970                                 while (selchannel) {
971                                         if (response->am[num].u.i.out_channel[0])
972                                                 SCAT(response->am[num].u.i.out_channel, ",");
973                                         switch (selchannel->channel) {
974                                         case CHANNEL_NO:
975                                                 SCAT(response->am[num].u.i.out_channel, "no");
976                                                 break;
977                                         case CHANNEL_ANY:
978                                                 SCAT(response->am[num].u.i.out_channel, "any");
979                                                 break;
980                                         case CHANNEL_FREE:
981                                                 SCAT(response->am[num].u.i.out_channel, "free");
982                                                 break;
983                                         default:
984                                                 SPRINT(strchr(response->am[num].u.i.out_channel, '\0'), "%d", selchannel->channel);
985                                         }
986                                         selchannel = selchannel->next;
987                                 }
988                                 selchannel = ifport->in_channel;
989                                 while (selchannel) {
990                                         switch (selchannel->channel) {
991                                         case CHANNEL_FREE:
992                                                 SCAT(response->am[num].u.i.in_channel, "free");
993                                                 break;
994                                         default:
995                                                 SPRINT(strchr(response->am[num].u.i.in_channel, '\0'), "%d", selchannel->channel);
996                                         }
997                                         selchannel = selchannel->next;
998                                 }
999                                 /* channel state */
1000                                 i = 0;
1001                                 anybusy = 0;
1002                                 while(i < mISDNport->b_num) {
1003                                         response->am[num].u.i.busy[i] = mISDNport->b_state[i];
1004                                         if (mISDNport->b_port[i])
1005                                                 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
1006                                         response->am[num].u.i.mode[i] = mISDNport->b_mode[i];
1007                                         i++;
1008                                 }
1009                         }
1010                         num++;
1011
1012                         ifport = ifport->next;
1013                 }
1014                 interface = interface->next;
1015         }
1016
1017         /* create response for all remotes */
1018         admin = admin_first;
1019         while(admin) {
1020                 if (admin->remote_name[0]) {
1021                         /* message */
1022                         response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
1023                         /* name */
1024                         SCPY(response->am[num].u.r.name, admin->remote_name);
1025                         /* */
1026                         num++;
1027                 }
1028                 admin = admin->next;
1029         }
1030
1031         /* create response for all joins */
1032         join = join_first;
1033         while(join) {
1034                 /* message */
1035                 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
1036                 /* serial */
1037                 response->am[num].u.j.serial = join->j_serial;
1038                 /* partyline */
1039                 if (join->j_type == JOIN_TYPE_PBX)
1040                         response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
1041                 /* remote application */
1042                 if (join->j_type == JOIN_TYPE_REMOTE)
1043                         SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
1044                 /* */
1045                 join = join->next;
1046                 num++;
1047         }
1048
1049         /* create response for all endpoint */
1050         apppbx = apppbx_first;
1051         while(apppbx) {
1052                 /* message */
1053                 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
1054                 /* serial */
1055                 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
1056                 /* join */
1057                 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
1058                 /* rx notification */
1059                 response->am[num].u.e.rx_state = apppbx->e_rx_state;
1060                 /* tx notification */
1061                 response->am[num].u.e.tx_state = apppbx->e_tx_state;
1062                 /* state */
1063                 switch(apppbx->e_state) {
1064                         case EPOINT_STATE_IN_SETUP:
1065                         response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
1066                         break;
1067                         case EPOINT_STATE_OUT_SETUP:
1068                         response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
1069                         break;
1070                         case EPOINT_STATE_IN_OVERLAP:
1071                         response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
1072                         break;
1073                         case EPOINT_STATE_OUT_OVERLAP:
1074                         response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
1075                         break;
1076                         case EPOINT_STATE_IN_PROCEEDING:
1077                         response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
1078                         break;
1079                         case EPOINT_STATE_OUT_PROCEEDING:
1080                         response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1081                         break;
1082                         case EPOINT_STATE_IN_ALERTING:
1083                         response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1084                         break;
1085                         case EPOINT_STATE_OUT_ALERTING:
1086                         response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1087                         break;
1088                         case EPOINT_STATE_CONNECT:
1089                         response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1090                         break;
1091                         case EPOINT_STATE_IN_DISCONNECT:
1092                         response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1093                         break;
1094                         case EPOINT_STATE_OUT_DISCONNECT:
1095                         response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1096                         break;
1097                         default:
1098                         response->am[num].u.e.state = ADMIN_STATE_IDLE;
1099                 }
1100                 /* terminal */
1101                 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1102                 /* callerid */
1103                 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1104                 /* dialing */
1105                 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1106                 /* action string */
1107                 if (apppbx->e_action)
1108                         SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1109 //              if (apppbx->e_action)
1110 //              printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1111                 /* park */
1112                 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1113                 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))
1114                         memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1115                 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1116                 /* crypt */
1117                 if (apppbx->e_crypt == CRYPT_ON)
1118                         response->am[num].u.e.crypt = 1;
1119                 /* */
1120                 apppbx = apppbx->next;
1121                 num++;
1122         }
1123
1124         /* create response for all ports */
1125         port = port_first;
1126         while(port) {
1127                 /* message */
1128                 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1129                 /* serial */
1130                 response->am[num].u.p.serial = port->p_serial;
1131                 /* name */
1132                 SCPY(response->am[num].u.p.name, port->p_name);
1133                 /* epoint */
1134                 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1135                 /* state */
1136                 switch(port->p_state) {
1137                         case PORT_STATE_IN_SETUP:
1138                         response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1139                         break;
1140                         case PORT_STATE_OUT_SETUP:
1141                         response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1142                         break;
1143                         case PORT_STATE_IN_OVERLAP:
1144                         response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1145                         break;
1146                         case PORT_STATE_OUT_OVERLAP:
1147                         response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1148                         break;
1149                         case PORT_STATE_IN_PROCEEDING:
1150                         response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1151                         break;
1152                         case PORT_STATE_OUT_PROCEEDING:
1153                         response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1154                         break;
1155                         case PORT_STATE_IN_ALERTING:
1156                         response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1157                         break;
1158                         case PORT_STATE_OUT_ALERTING:
1159                         response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1160                         break;
1161                         case PORT_STATE_CONNECT:
1162                         response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1163                         break;
1164                         case PORT_STATE_IN_DISCONNECT:
1165                         response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1166                         break;
1167                         case PORT_STATE_OUT_DISCONNECT:
1168                         response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1169                         break;
1170                         case PORT_STATE_RELEASE:
1171                         response->am[num].u.p.state = ADMIN_STATE_RELEASE;
1172                         break;
1173                         default:
1174                         response->am[num].u.p.state = ADMIN_STATE_IDLE;
1175                 }
1176                 /* isdn */
1177                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
1178                         response->am[num].u.p.isdn = 1;
1179                         pdss1 = (class Pdss1 *)port;
1180                         response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1181                         response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1182                         response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1183                 }
1184                 /* */
1185                 port = port->next;
1186                 num++;
1187         }
1188         return(0);
1189 }
1190
1191 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1192 /*
1193  * handle admin socket (non blocking)
1194  */
1195 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index);
1196
1197 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1198 {
1199         int                     new_sock;
1200         socklen_t               sock_len = sizeof(sock_address);
1201         struct admin_list       *admin;
1202
1203         /* check for new incoming connections */
1204         if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0) {
1205                 /* insert new socket */
1206                 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1207                 memuse++;
1208                 fhuse++;
1209                 admin->sockserial = sockserial++;
1210                 admin->next = admin_first;
1211                 admin_first = admin;
1212                 admin->sock = new_sock;
1213                 admin->fd.fd = new_sock;
1214                 register_fd(&admin->fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle_con, admin, 0);
1215         } else {
1216                 if (errno != EWOULDBLOCK) {
1217                         PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1218                         admin_cleanup();
1219                         return 0;
1220                 }
1221         }
1222
1223         return 0;
1224 }
1225
1226 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1227 {
1228         struct admin_list *admin = (struct admin_list *)instance;
1229         void                    *temp;
1230         struct admin_message    msg;
1231         int                     len;
1232         struct Endpoint         *epoint;
1233
1234         if ((what & LCR_FD_READ)) {
1235                 /* read command */
1236                 len = read(admin->sock, &msg, sizeof(msg));
1237                 if (len < 0) {
1238                         brokenpipe:
1239                         PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1240                         free_connection(admin);
1241                         return 0;
1242                 }
1243                 if (len == 0) {
1244                         end:
1245
1246                         /*release endpoint if exists */
1247                         if (admin->epointid) {
1248                                 epoint = find_epoint_id(admin->epointid);
1249                                 if (epoint) {
1250                                         ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
1251                                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
1252                                 }
1253                         }
1254
1255                         free_connection(admin);
1256                         return 0;
1257                 }
1258                 if (len != sizeof(msg)) {
1259                         PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1260                         free_connection(admin);
1261                         return 0;
1262                 }
1263                 /* process socket command */
1264                 if (admin->response && msg.message != ADMIN_MESSAGE) {
1265                         PERROR("Data from socket %d while sending response.\n", admin->sock);
1266                         free_connection(admin);
1267                         return 0;
1268                 }
1269                 switch (msg.message) {
1270                         case ADMIN_REQUEST_CMD_INTERFACE:
1271                         if (admin_interface(&admin->response) < 0) {
1272                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1273                                 goto response_error;
1274                         }
1275                         admin->fd.when |= LCR_FD_WRITE;
1276                         break;
1277
1278                         case ADMIN_REQUEST_CMD_ROUTE:
1279                         if (admin_route(&admin->response) < 0) {
1280                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1281                                 goto response_error;
1282                         }
1283                         admin->fd.when |= LCR_FD_WRITE;
1284                         break;
1285
1286                         case ADMIN_REQUEST_CMD_DIAL:
1287                         if (admin_dial(&admin->response, msg.u.x.message) < 0) {
1288                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1289                                 goto response_error;
1290                         }
1291                         admin->fd.when |= LCR_FD_WRITE;
1292                         break;
1293
1294                         case ADMIN_REQUEST_CMD_RELEASE:
1295                         if (admin_release(&admin->response, msg.u.x.message) < 0) {
1296                                 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1297                                 goto response_error;
1298                         }
1299                         admin->fd.when |= LCR_FD_WRITE;
1300                         break;
1301
1302                         case ADMIN_REQUEST_STATE:
1303                         if (admin_state(&admin->response) < 0) {
1304                                 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1305                                 goto response_error;
1306                         }
1307                         admin->fd.when |= LCR_FD_WRITE;
1308                         break;
1309
1310                         case ADMIN_TRACE_REQUEST:
1311                         if (admin_trace(admin, &msg.u.trace_req) < 0) {
1312                                 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1313                                 goto response_error;
1314                         }
1315                         admin->fd.when |= LCR_FD_WRITE;
1316                         break;
1317
1318                         case ADMIN_REQUEST_CMD_BLOCK:
1319                         if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) {
1320                                 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1321                                 goto response_error;
1322                         }
1323                         admin->fd.when |= LCR_FD_WRITE;
1324                         break;
1325
1326                         case ADMIN_MESSAGE:
1327                         if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
1328                                 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1329                                 goto response_error;
1330                         }
1331                         break;
1332
1333                         case ADMIN_CALL_SETUP:
1334                         if (admin_call(admin, &msg) < 0) {
1335                                 PERROR("Failed to create call for socket %d.\n", admin->sock);
1336                                 response_error:
1337                                 free_connection(admin);
1338                                 return 0;
1339                         }
1340                         break;
1341
1342                         default:
1343                         PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1344                         free_connection(admin);
1345                         return 0;
1346                 }
1347         }
1348
1349         if ((what & LCR_FD_WRITE)) {
1350                 /* write queue */
1351                 if (admin->response) {
1352                         len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1353                         if (len < 0) {
1354                                 goto brokenpipe;
1355                         }
1356                         if (len == 0)
1357                                 goto end;
1358                         if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) {
1359                                 admin->response->offset+=len;
1360                                 return 0;
1361                         } else {
1362                                 temp = admin->response;
1363                                 admin->response = admin->response->next;
1364                                 FREE(temp, 0);
1365                                 memuse--;
1366                         }
1367                 } else
1368                         admin->fd.when &= ~LCR_FD_WRITE;
1369         }
1370
1371         return 0;
1372 }
1373
1374 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)
1375 {
1376         union parameter param;
1377
1378         memset(&param, 0, sizeof(union parameter));
1379         param.bchannel.isloopback = isloopback;
1380         param.bchannel.type = type;
1381         param.bchannel.handle = handle;
1382         param.bchannel.tx_gain = tx_gain;
1383         param.bchannel.rx_gain = rx_gain;
1384         if (pipeline)
1385                 SCPY(param.bchannel.pipeline, pipeline);
1386         if (crypt_len)
1387                 memcpy(param.bchannel.crypt, crypt, crypt_len);
1388         param.bchannel.crypt_type = crypt_type;
1389         if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, &param)<0) {
1390                 PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
1391                 return;         
1392         }
1393 }
1394