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