Incremented version number of lcr in develop branch.
[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                 /* no ref, but address */
703                 message_bchannel_from_remote(NULL, msg->param.bchannel.type, msg->param.bchannel.handle);
704                 return(0);
705         }
706         
707         /* check for ref */
708         if (!msg->ref) {
709                 PERROR("Remote application did not send us a valid ref with a message.\n");
710                 return(-1);
711         }
712
713         /* find join instance */
714         join = join_first;
715         while(join) {
716                 if (join->j_type == JOIN_TYPE_REMOTE) {
717                         joinremote = (class JoinRemote *)join;
718                         if (joinremote->j_remote_ref == msg->ref)
719                                 break;
720                 }
721                 join = join->next;
722         }
723         if (join) {
724                 if (admin->sock != joinremote->j_remote_id) {
725                         PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, joinremote->j_remote_name, admin->remote_name);
726                         return(-1);
727                 }
728                 /* send message */
729                 joinremote->message_remote(msg->type, &msg->param);
730
731                 return(0);
732         }
733
734         /* find port instance */
735         port = port_first;
736         while(port) {
737                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_REMOTE) {
738                         remote = (class Premote *) port;
739                         if (remote->p_m_r_ref == msg->ref)
740                                 break;
741                 }
742                 port = port->next;
743         }
744         if (port) {
745                 if (admin->sock != remote->p_m_r_remote_id) {
746                         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);
747                         return(-1);
748                 }
749
750                 /* send message */
751                 remote->message_remote(msg->type, &msg->param);
752
753                 return(0);
754         }
755
756         PDEBUG(DEBUG_LOG, "No remote instance found with ref %d. (May have been already released.)\n", msg->ref);
757         return(0);
758
759 }
760
761
762 /*
763  * this function is called for every message to remote socket
764  */
765 int admin_message_from_lcr(int remote_id, unsigned int ref, int message_type, union parameter *param)
766 {
767         struct admin_list       *admin;
768         struct admin_queue      **responsep;    /* response pointer */
769
770         /* searching for admin id
771          * maybe there is no given remote application
772          */
773         admin = admin_first;
774         while(admin) {
775                 if (admin->remote_name[0] && admin->sock==remote_id)
776                         break;
777                 admin = admin->next;
778         }
779         /* no given remote application connected */
780         if (!admin)
781                 return(-1);
782
783         /* seek to end of response list */
784         responsep = &admin->response;
785         while(*responsep) {
786                 responsep = &(*responsep)->next;
787         }
788
789         /* create state response */
790         *responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
791         memuse++;
792         (*responsep)->num = 1;
793
794         /* message */
795         (*responsep)->am[0].message = ADMIN_MESSAGE;
796         (*responsep)->am[0].u.msg.type = message_type;
797         (*responsep)->am[0].u.msg.ref = ref;
798         memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
799         admin->fd.when |= LCR_FD_WRITE;
800         return(0);
801 }
802
803
804 /*
805  * do state debugging
806  */
807 int admin_state(struct admin_queue **responsep)
808 {
809         class Port              *port;
810         class EndpointAppPBX    *apppbx;
811         class Join              *join;
812         class Pdss1             *pdss1;
813         struct interface        *interface;
814         struct interface_port   *ifport;
815         struct mISDNport        *mISDNport;
816         struct select_channel   *selchannel;
817         int                     i;
818         int                     num;
819         int                     anybusy;
820         struct admin_queue      *response;
821         struct admin_list       *admin;
822         struct tm               *now_tm;
823         time_t                  now;
824
825         /* create state response */
826         response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
827         memuse++;
828         response->num = 1;
829         /* message */
830         response->am[0].message = ADMIN_RESPONSE_STATE;
831         /* version */
832         SCPY(response->am[0].u.s.version_string, VERSION_STRING);
833         /* time */
834         time(&now);
835         now_tm = localtime(&now);
836         memcpy(&response->am[0].u.s.tm, now_tm, sizeof(struct tm));
837         /* log file */
838         SCPY(response->am[0].u.s.logfile, options.log);
839         /* interface count */
840         i = 0;
841         interface = interface_first;
842         while(interface) {
843                 ifport = interface->ifport;
844                 while(ifport) {
845                         i++;
846                         ifport = ifport->next;
847                 }
848                 interface = interface->next;
849         }
850         response->am[0].u.s.interfaces = i;
851         /* remote connection count */
852         i = 0;
853         admin = admin_first;
854         while(admin) {
855                 if (admin->remote_name[0])
856                         i++;
857                 admin = admin->next;
858         }
859         response->am[0].u.s.remotes = i;
860         /* join count */
861         join = join_first;
862         i = 0;
863         while(join) {
864                 i++;
865                 join = join->next;
866         }
867         response->am[0].u.s.joins = i;
868         /* apppbx count */
869         apppbx = apppbx_first;
870         i = 0;
871         while(apppbx) {
872                 i++;
873                 apppbx = apppbx->next;
874         }
875         response->am[0].u.s.epoints = i;
876         /* port count */
877         i = 0;
878         port = port_first;
879         while(port) {
880                 i++;
881                 port = port->next;
882         }
883         response->am[0].u.s.ports = i;
884         /* attach to response chain */
885         *responsep = response;
886         responsep = &response->next;
887
888         /* create response for all instances */
889         num = (response->am[0].u.s.interfaces)
890             + (response->am[0].u.s.remotes)
891             + (response->am[0].u.s.joins)
892             + (response->am[0].u.s.epoints)
893             + (response->am[0].u.s.ports);
894         if (num == 0)
895                 return(0);
896         response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
897         memuse++;
898         response->num = num;
899         *responsep = response;
900         responsep = &response->next;
901         interface = interface_first;
902         num = 0;
903         while(interface) {
904                 ifport = interface->ifport;
905                 while(ifport) {
906                         /* message */
907                         response->am[num].message = ADMIN_RESPONSE_S_INTERFACE;
908                         /* interface */
909                         SCPY(response->am[num].u.i.interface_name, interface->name);
910                         /* portnum */
911                         response->am[num].u.i.portnum = ifport->portnum;
912                         /* portname */
913                         SCPY(response->am[num].u.i.portname, ifport->portname);
914                         /* iftype */
915                         response->am[num].u.i.extension = interface->extension;
916                         /* block */
917                         response->am[num].u.i.block = ifport->block;
918                         if (ifport->mISDNport) {
919                                 mISDNport = ifport->mISDNport;
920
921                                 /* ptp */
922                                 response->am[num].u.i.ptp = mISDNport->ptp;
923                                 /* l1hold */
924                                 response->am[num].u.i.l1hold = mISDNport->l1hold;
925                                 /* l2hold */
926                                 response->am[num].u.i.l2hold = mISDNport->l2hold;
927                                 /* ntmode */
928                                 response->am[num].u.i.ntmode = mISDNport->ntmode;
929                                 /* pri */
930                                 response->am[num].u.i.pri = mISDNport->pri;
931                                 /* use */
932                                 response->am[num].u.i.use = mISDNport->use;
933                                 /* l1link */
934                                 response->am[num].u.i.l1link = mISDNport->l1link;
935                                 /* l2link */
936                                 response->am[num].u.i.l2link = mISDNport->l2link;
937                                 memcpy(response->am[num].u.i.l2mask, mISDNport->l2mask, 16);
938                                 /* los */
939                                 response->am[num].u.i.los = mISDNport->los;
940                                 /* ais */
941                                 response->am[num].u.i.ais = mISDNport->ais;
942                                 /* rdi */
943                                 response->am[num].u.i.rdi = mISDNport->rdi;
944                                 /* slip */
945                                 response->am[num].u.i.slip_tx = mISDNport->slip_tx;
946                                 response->am[num].u.i.slip_rx = mISDNport->slip_rx;
947                                 /* channels */
948                                 response->am[num].u.i.channels = mISDNport->b_num;
949                                 /* channel selection */
950                                 selchannel = ifport->out_channel;
951                                 if (ifport->channel_force)
952                                         SCAT(response->am[num].u.i.out_channel, "force");
953                                 while (selchannel) {
954                                         if (response->am[num].u.i.out_channel[0])
955                                                 SCAT(response->am[num].u.i.out_channel, ",");
956                                         switch (selchannel->channel) {
957                                         case CHANNEL_NO:
958                                                 SCAT(response->am[num].u.i.out_channel, "no");
959                                                 break;
960                                         case CHANNEL_ANY:
961                                                 SCAT(response->am[num].u.i.out_channel, "any");
962                                                 break;
963                                         case CHANNEL_FREE:
964                                                 SCAT(response->am[num].u.i.out_channel, "free");
965                                                 break;
966                                         default:
967                                                 SPRINT(strchr(response->am[num].u.i.out_channel, '\0'), "%d", selchannel->channel);
968                                         }
969                                         selchannel = selchannel->next;
970                                 }
971                                 selchannel = ifport->in_channel;
972                                 while (selchannel) {
973                                         switch (selchannel->channel) {
974                                         case CHANNEL_FREE:
975                                                 SCAT(response->am[num].u.i.in_channel, "free");
976                                                 break;
977                                         default:
978                                                 SPRINT(strchr(response->am[num].u.i.in_channel, '\0'), "%d", selchannel->channel);
979                                         }
980                                         selchannel = selchannel->next;
981                                 }
982                                 /* channel state */
983                                 i = 0;
984                                 anybusy = 0;
985                                 while(i < mISDNport->b_num) {
986                                         response->am[num].u.i.busy[i] = mISDNport->b_state[i];
987                                         if (mISDNport->b_port[i])
988                                                 response->am[num].u.i.port[i] = mISDNport->b_port[i]->p_serial;
989                                         response->am[num].u.i.mode[i] = mISDNport->b_mode[i];
990                                         i++;
991                                 }
992                         }
993                         num++;
994
995                         ifport = ifport->next;
996                 }
997                 interface = interface->next;
998         }
999
1000         /* create response for all remotes */
1001         admin = admin_first;
1002         while(admin) {
1003                 if (admin->remote_name[0]) {
1004                         /* message */
1005                         response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
1006                         /* name */
1007                         SCPY(response->am[num].u.r.name, admin->remote_name);
1008                         /* */
1009                         num++;
1010                 }
1011                 admin = admin->next;
1012         }
1013
1014         /* create response for all joins */
1015         join = join_first;
1016         while(join) {
1017                 /* message */
1018                 response->am[num].message = ADMIN_RESPONSE_S_JOIN;
1019                 /* serial */
1020                 response->am[num].u.j.serial = join->j_serial;
1021                 /* partyline */
1022                 if (join->j_type == JOIN_TYPE_PBX)
1023                         response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
1024                 /* remote application */
1025                 if (join->j_type == JOIN_TYPE_REMOTE)
1026                         SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote_name);
1027                 /* */
1028                 join = join->next;
1029                 num++;
1030         }
1031
1032         /* create response for all endpoint */
1033         apppbx = apppbx_first;
1034         while(apppbx) {
1035                 /* message */
1036                 response->am[num].message = ADMIN_RESPONSE_S_EPOINT;
1037                 /* serial */
1038                 response->am[num].u.e.serial = apppbx->ea_endpoint->ep_serial;
1039                 /* join */
1040                 response->am[num].u.e.join = apppbx->ea_endpoint->ep_join_id;
1041                 /* rx notification */
1042                 response->am[num].u.e.rx_state = apppbx->e_rx_state;
1043                 /* tx notification */
1044                 response->am[num].u.e.tx_state = apppbx->e_tx_state;
1045                 /* state */
1046                 switch(apppbx->e_state) {
1047                         case EPOINT_STATE_IN_SETUP:
1048                         response->am[num].u.e.state = ADMIN_STATE_IN_SETUP;
1049                         break;
1050                         case EPOINT_STATE_OUT_SETUP:
1051                         response->am[num].u.e.state = ADMIN_STATE_OUT_SETUP;
1052                         break;
1053                         case EPOINT_STATE_IN_OVERLAP:
1054                         response->am[num].u.e.state = ADMIN_STATE_IN_OVERLAP;
1055                         break;
1056                         case EPOINT_STATE_OUT_OVERLAP:
1057                         response->am[num].u.e.state = ADMIN_STATE_OUT_OVERLAP;
1058                         break;
1059                         case EPOINT_STATE_IN_PROCEEDING:
1060                         response->am[num].u.e.state = ADMIN_STATE_IN_PROCEEDING;
1061                         break;
1062                         case EPOINT_STATE_OUT_PROCEEDING:
1063                         response->am[num].u.e.state = ADMIN_STATE_OUT_PROCEEDING;
1064                         break;
1065                         case EPOINT_STATE_IN_ALERTING:
1066                         response->am[num].u.e.state = ADMIN_STATE_IN_ALERTING;
1067                         break;
1068                         case EPOINT_STATE_OUT_ALERTING:
1069                         response->am[num].u.e.state = ADMIN_STATE_OUT_ALERTING;
1070                         break;
1071                         case EPOINT_STATE_CONNECT:
1072                         response->am[num].u.e.state = ADMIN_STATE_CONNECT;
1073                         break;
1074                         case EPOINT_STATE_IN_DISCONNECT:
1075                         response->am[num].u.e.state = ADMIN_STATE_IN_DISCONNECT;
1076                         break;
1077                         case EPOINT_STATE_OUT_DISCONNECT:
1078                         response->am[num].u.e.state = ADMIN_STATE_OUT_DISCONNECT;
1079                         break;
1080                         default:
1081                         response->am[num].u.e.state = ADMIN_STATE_IDLE;
1082                 }
1083                 /* terminal */
1084                 SCPY(response->am[num].u.e.terminal, apppbx->e_ext.number);
1085                 /* callerid */
1086                 SCPY(response->am[num].u.e.callerid, apppbx->e_callerinfo.id);
1087                 /* dialing */
1088                 SCPY(response->am[num].u.e.dialing, apppbx->e_dialinginfo.id);
1089                 /* action string */
1090                 if (apppbx->e_action)
1091                         SCPY(response->am[num].u.e.action, action_defs[apppbx->e_action->index].name);
1092 //              if (apppbx->e_action)
1093 //              printf("action=%s\n",action_defs[apppbx->e_action->index].name);
1094                 /* park */
1095                 response->am[num].u.e.park = apppbx->ea_endpoint->ep_park;
1096                 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))
1097                         memcpy(response->am[num].u.e.park_callid, apppbx->ea_endpoint->ep_park_callid, apppbx->ea_endpoint->ep_park_len);
1098                 response->am[num].u.e.park_len = apppbx->ea_endpoint->ep_park_len;
1099                 /* crypt */
1100                 if (apppbx->e_crypt == CRYPT_ON)
1101                         response->am[num].u.e.crypt = 1;
1102                 /* */
1103                 apppbx = apppbx->next;
1104                 num++;
1105         }
1106
1107         /* create response for all ports */
1108         port = port_first;
1109         while(port) {
1110                 /* message */
1111                 response->am[num].message = ADMIN_RESPONSE_S_PORT;
1112                 /* serial */
1113                 response->am[num].u.p.serial = port->p_serial;
1114                 /* name */
1115                 SCPY(response->am[num].u.p.name, port->p_name);
1116                 /* epoint */
1117                 response->am[num].u.p.epoint = ACTIVE_EPOINT(port->p_epointlist);
1118                 /* state */
1119                 switch(port->p_state) {
1120                         case PORT_STATE_IN_SETUP:
1121                         response->am[num].u.p.state = ADMIN_STATE_IN_SETUP;
1122                         break;
1123                         case PORT_STATE_OUT_SETUP:
1124                         response->am[num].u.p.state = ADMIN_STATE_OUT_SETUP;
1125                         break;
1126                         case PORT_STATE_IN_OVERLAP:
1127                         response->am[num].u.p.state = ADMIN_STATE_IN_OVERLAP;
1128                         break;
1129                         case PORT_STATE_OUT_OVERLAP:
1130                         response->am[num].u.p.state = ADMIN_STATE_OUT_OVERLAP;
1131                         break;
1132                         case PORT_STATE_IN_PROCEEDING:
1133                         response->am[num].u.p.state = ADMIN_STATE_IN_PROCEEDING;
1134                         break;
1135                         case PORT_STATE_OUT_PROCEEDING:
1136                         response->am[num].u.p.state = ADMIN_STATE_OUT_PROCEEDING;
1137                         break;
1138                         case PORT_STATE_IN_ALERTING:
1139                         response->am[num].u.p.state = ADMIN_STATE_IN_ALERTING;
1140                         break;
1141                         case PORT_STATE_OUT_ALERTING:
1142                         response->am[num].u.p.state = ADMIN_STATE_OUT_ALERTING;
1143                         break;
1144                         case PORT_STATE_CONNECT:
1145                         response->am[num].u.p.state = ADMIN_STATE_CONNECT;
1146                         break;
1147                         case PORT_STATE_IN_DISCONNECT:
1148                         response->am[num].u.p.state = ADMIN_STATE_IN_DISCONNECT;
1149                         break;
1150                         case PORT_STATE_OUT_DISCONNECT:
1151                         response->am[num].u.p.state = ADMIN_STATE_OUT_DISCONNECT;
1152                         break;
1153                         case PORT_STATE_RELEASE:
1154                         response->am[num].u.p.state = ADMIN_STATE_RELEASE;
1155                         break;
1156                         default:
1157                         response->am[num].u.p.state = ADMIN_STATE_IDLE;
1158                 }
1159                 /* isdn */
1160                 if ((port->p_type & PORT_CLASS_mISDN_MASK) == PORT_CLASS_DSS1) {
1161                         response->am[num].u.p.isdn = 1;
1162                         pdss1 = (class Pdss1 *)port;
1163                         response->am[num].u.p.isdn_chan = pdss1->p_m_b_channel;
1164                         response->am[num].u.p.isdn_hold = pdss1->p_m_hold;
1165                         response->am[num].u.p.isdn_ces = pdss1->p_m_d_ces;
1166                 }
1167                 /* */
1168                 port = port->next;
1169                 num++;
1170         }
1171         return(0);
1172 }
1173
1174 int sockserial = 1; // must start with 1, because 0 is used if no serial is set
1175 /*
1176  * handle admin socket (non blocking)
1177  */
1178 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index);
1179
1180 int admin_handle(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1181 {
1182         int                     new_sock;
1183         socklen_t               sock_len = sizeof(sock_address);
1184         struct admin_list       *admin;
1185
1186         /* check for new incoming connections */
1187         if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0) {
1188                 /* insert new socket */
1189                 admin = (struct admin_list *)MALLOC(sizeof(struct admin_list));
1190                 memuse++;
1191                 fhuse++;
1192                 admin->sockserial = sockserial++;
1193                 admin->next = admin_first;
1194                 admin_first = admin;
1195                 admin->sock = new_sock;
1196                 admin->fd.fd = new_sock;
1197                 register_fd(&admin->fd, LCR_FD_READ | LCR_FD_EXCEPT, admin_handle_con, admin, 0);
1198         } else {
1199                 if (errno != EWOULDBLOCK) {
1200                         PERROR("Failed to accept connection from socket \"%s\". (errno=%d) Closing socket.\n", sock_address.sun_path, errno);
1201                         admin_cleanup();
1202                         return 0;
1203                 }
1204         }
1205
1206         return 0;
1207 }
1208
1209 int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int index)
1210 {
1211         struct admin_list *admin = (struct admin_list *)instance;
1212         void                    *temp;
1213         struct admin_message    msg;
1214         int                     len;
1215         struct Endpoint         *epoint;
1216
1217         if ((what & LCR_FD_READ)) {
1218                 /* read command */
1219                 len = read(admin->sock, &msg, sizeof(msg));
1220                 if (len < 0) {
1221                         brokenpipe:
1222                         PDEBUG(DEBUG_LOG, "Broken pipe on socket %d. (errno=%d).\n", admin->sock, errno);
1223                         free_connection(admin);
1224                         return 0;
1225                 }
1226                 if (len == 0) {
1227                         end:
1228
1229                         /*release endpoint if exists */
1230                         if (admin->epointid) {
1231                                 epoint = find_epoint_id(admin->epointid);
1232                                 if (epoint) {
1233                                         ((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
1234                                                 release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
1235                                 }
1236                         }
1237
1238                         free_connection(admin);
1239                         return 0;
1240                 }
1241                 if (len != sizeof(msg)) {
1242                         PERROR("Short/long read on socket %d. (len=%d != size=%d).\n", admin->sock, len, sizeof(msg));
1243                         free_connection(admin);
1244                         return 0;
1245                 }
1246                 /* process socket command */
1247                 if (admin->response && msg.message != ADMIN_MESSAGE) {
1248                         PERROR("Data from socket %d while sending response.\n", admin->sock);
1249                         free_connection(admin);
1250                         return 0;
1251                 }
1252                 switch (msg.message) {
1253                         case ADMIN_REQUEST_CMD_INTERFACE:
1254                         if (admin_interface(&admin->response) < 0) {
1255                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1256                                 goto response_error;
1257                         }
1258                         admin->fd.when |= LCR_FD_WRITE;
1259                         break;
1260
1261                         case ADMIN_REQUEST_CMD_ROUTE:
1262                         if (admin_route(&admin->response) < 0) {
1263                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1264                                 goto response_error;
1265                         }
1266                         admin->fd.when |= LCR_FD_WRITE;
1267                         break;
1268
1269                         case ADMIN_REQUEST_CMD_DIAL:
1270                         if (admin_dial(&admin->response, msg.u.x.message) < 0) {
1271                                 PERROR("Failed to create dial response for socket %d.\n", admin->sock);
1272                                 goto response_error;
1273                         }
1274                         admin->fd.when |= LCR_FD_WRITE;
1275                         break;
1276
1277                         case ADMIN_REQUEST_CMD_RELEASE:
1278                         if (admin_release(&admin->response, msg.u.x.message) < 0) {
1279                                 PERROR("Failed to create release response for socket %d.\n", admin->sock);
1280                                 goto response_error;
1281                         }
1282                         admin->fd.when |= LCR_FD_WRITE;
1283                         break;
1284
1285                         case ADMIN_REQUEST_STATE:
1286                         if (admin_state(&admin->response) < 0) {
1287                                 PERROR("Failed to create state response for socket %d.\n", admin->sock);
1288                                 goto response_error;
1289                         }
1290                         admin->fd.when |= LCR_FD_WRITE;
1291                         break;
1292
1293                         case ADMIN_TRACE_REQUEST:
1294                         if (admin_trace(admin, &msg.u.trace_req) < 0) {
1295                                 PERROR("Failed to create trace response for socket %d.\n", admin->sock);
1296                                 goto response_error;
1297                         }
1298                         admin->fd.when |= LCR_FD_WRITE;
1299                         break;
1300
1301                         case ADMIN_REQUEST_CMD_BLOCK:
1302                         if (admin_block(&admin->response, msg.u.x.portnum, msg.u.x.block) < 0) {
1303                                 PERROR("Failed to create block response for socket %d.\n", admin->sock);
1304                                 goto response_error;
1305                         }
1306                         admin->fd.when |= LCR_FD_WRITE;
1307                         break;
1308
1309                         case ADMIN_MESSAGE:
1310                         if (admin_message_to_lcr(&msg.u.msg, admin) < 0) {
1311                                 PERROR("Failed to deliver message for socket %d.\n", admin->sock);
1312                                 goto response_error;
1313                         }
1314                         break;
1315
1316                         case ADMIN_CALL_SETUP:
1317                         if (admin_call(admin, &msg) < 0) {
1318                                 PERROR("Failed to create call for socket %d.\n", admin->sock);
1319                                 response_error:
1320                                 free_connection(admin);
1321                                 return 0;
1322                         }
1323                         break;
1324
1325                         default:
1326                         PERROR("Invalid message %d from socket %d.\n", msg.message, admin->sock);
1327                         free_connection(admin);
1328                         return 0;
1329                 }
1330         }
1331
1332         if ((what & LCR_FD_WRITE)) {
1333                 /* write queue */
1334                 if (admin->response) {
1335                         len = write(admin->sock, ((unsigned char *)(admin->response->am))+admin->response->offset, sizeof(struct admin_message)*(admin->response->num)-admin->response->offset);
1336                         if (len < 0) {
1337                                 goto brokenpipe;
1338                         }
1339                         if (len == 0)
1340                                 goto end;
1341                         if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset)) {
1342                                 admin->response->offset+=len;
1343                                 return 0;
1344                         } else {
1345                                 temp = admin->response;
1346                                 admin->response = admin->response->next;
1347                                 FREE(temp, 0);
1348                                 memuse--;
1349                         }
1350                 } else
1351                         admin->fd.when &= ~LCR_FD_WRITE;
1352         }
1353
1354         return 0;
1355 }
1356
1357 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)
1358 {
1359         union parameter param;
1360
1361         memset(&param, 0, sizeof(union parameter));
1362         param.bchannel.isloopback = isloopback;
1363         param.bchannel.type = type;
1364         param.bchannel.handle = handle;
1365         param.bchannel.tx_gain = tx_gain;
1366         param.bchannel.rx_gain = rx_gain;
1367         if (pipeline)
1368                 SCPY(param.bchannel.pipeline, pipeline);
1369         if (crypt_len)
1370                 memcpy(param.bchannel.crypt, crypt, crypt_len);
1371         param.bchannel.crypt_type = crypt_type;
1372         if (admin_message_from_lcr(remote_id, ref, MESSAGE_BCHANNEL, &param)<0) {
1373                 PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
1374                 return;         
1375         }
1376 }
1377