fc49cf902f02986e8453eee17ae2babfb6901d8e
[lcr.git] / chan_lcr.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** Asterisk socket client                                                    **
9 **                                                                           **
10 \*****************************************************************************/
11
12 /*
13
14 Registering to LCR:
15
16 To connect, open an LCR socket and send a MESSAGE_HELLO to socket with
17 the application name. This name is unique an can be used for routing calls.
18 Now the channel driver is linked to LCR and can receive and make calls.
19
20
21 Call is initiated by LCR:
22
23 If a call is received from LCR, a MESSAGE_NEWREF is received first.
24 A new chan_call instance is created. The call reference (ref) is given by
25 MESSAGE_NEWREF. The state is CHAN_LCR_STATE_IN_PREPARE.
26 After receiving MESSAGE_SETUP from LCR, the ast_channel instance is created
27 using ast_channel_alloc(1).  The setup information is given to asterisk.
28 The new Asterisk instance pointer (ast) is stored to chan_call structure.
29 The state changes to CHAN_LCR_STATE_IN_SETUP.
30
31
32 Call is initiated by Asterisk:
33
34 If a call is requested from Asterisk, a new chan_call instance is created.
35 The new Asterisk instance pointer (ast) is stored to chan_call structure.
36 The current call ref is set to 0, the state is CHAN_LCR_STATE_OUT_PREPARE.
37 If the call is received (lcr_call) A MESSASGE_NEWREF is sent to LCR requesting
38 a new call reference (ref).
39 Further dialing information is queued.
40 After the new callref is received by special MESSAGE_NEWREF reply, new ref
41 is stored in the chan_call structure. 
42 The setup information is sent to LCR using MESSAGE_SETUP.
43 The state changes to CHAN_LCR_STATE_OUT_SETUP.
44
45
46 Call is in process:
47
48 During call process, messages are received and sent.
49 The state changes accordingly.
50 Any message is allowed to be sent to LCR at any time except MESSAGE_RELEASE.
51 If a MESSAGE_OVERLAP is received, further dialing is required.
52 Queued dialing information, if any, is sent to LCR using MESSAGE_DIALING.
53 In this case, the state changes to CHAN_LCR_STATE_OUT_DIALING.
54
55
56 Call is released by LCR:
57
58 A MESSAGE_RELEASE is received with the call reference (ref) to be released.
59 The current ref is set to 0, to indicate released reference.
60 The state changes to CHAN_LCR_STATE_RELEASE.
61 ast_queue_hangup() is called, if asterisk instance (ast) exists, if not,
62 the chan_call instance is destroyed.
63 After lcr_hangup() is called-back by Asterisk, the chan_call instance
64 is destroyed, because the current ref is set to 0 and the state equals
65 CHAN_LCR_STATE_RELEASE.
66 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, see the proceedure
67 "Call is released by Asterisk".
68
69
70 Call is released by Asterisk:
71
72 lcr_hangup() is called-back by Asterisk. If the call reference (ref) is set,
73 a MESSAGE_RELEASE is sent to LCR and the chan_call instance is destroyed.
74 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, the new state is
75 set to CHAN_LCR_STATE_RELEASE.
76 Later, if the MESSAGE_NEWREF reply is received, a MESSAGE_RELEASE is sent to
77 LCR and the chan_call instance is destroyed.
78 If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
79 "Call is released by LCR".
80
81 */
82
83 #include <stdio.h>
84 #include <stdlib.h>
85 #include <string.h>
86 #include <stdarg.h>
87 #include <errno.h>
88 #include <sys/types.h>
89 #include <time.h>
90 //#include <signal.h>
91 #include <unistd.h>
92 #include <fcntl.h>
93 #include <sys/ioctl.h>
94 #include <sys/socket.h>
95 #include <sys/un.h>
96
97 #include <semaphore.h>
98
99 #include <asterisk/module.h>
100 #include <asterisk/channel.h>
101 #include <asterisk/config.h>
102 #include <asterisk/logger.h>
103 #include <asterisk/pbx.h>
104 #include <asterisk/options.h>
105 #include <asterisk/io.h>
106 #include <asterisk/frame.h>
107 #include <asterisk/translate.h>
108 #include <asterisk/cli.h>
109 #include <asterisk/musiconhold.h>
110 #include <asterisk/dsp.h>
111 #include <asterisk/translate.h>
112 #include <asterisk/file.h>
113 #include <asterisk/callerid.h>
114 #include <asterisk/indications.h>
115 #include <asterisk/app.h>
116 #include <asterisk/features.h>
117 #include <asterisk/sched.h>
118
119 #include "extension.h"
120 #include "message.h"
121 #include "callerid.h"
122 #include "lcrsocket.h"
123 #include "cause.h"
124 #include "bchannel.h"
125 #include "options.h"
126 #include "chan_lcr.h"
127
128 CHAN_LCR_STATE // state description structure
129 MESSAGES // message text
130
131 unsigned char flip_bits[256];
132
133 int lcr_debug=1;
134 int mISDN_created=1;
135
136 char lcr_type[]="lcr";
137
138 pthread_t chan_tid;
139 ast_mutex_t chan_lock; /* global lock */
140 ast_mutex_t log_lock; /* logging log */
141 int quit;
142
143 int glob_channel = 0;
144
145 int lcr_sock = -1;
146
147 struct admin_list {
148         struct admin_list *next;
149         struct admin_message msg;
150 } *admin_first = NULL;
151
152 static struct ast_channel_tech lcr_tech;
153
154 /*
155  * logging
156  */
157 void chan_lcr_log(int type, const char *file, int line, const char *function, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...)
158 {
159         char buffer[1024];
160         char call_text[128] = "NULL";
161         char ast_text[128] = "NULL";
162         va_list args;
163
164         ast_mutex_lock(&log_lock);
165
166         va_start(args,fmt);
167         vsnprintf(buffer,sizeof(buffer)-1,fmt,args);
168         buffer[sizeof(buffer)-1]=0;
169         va_end(args);
170
171         if (call)
172                 sprintf(call_text, "%ld", call->ref);
173         if (ast)
174                 strncpy(ast_text, ast->name, sizeof(ast_text)-1);
175         ast_text[sizeof(ast_text)-1] = '\0';
176         
177         ast_log(type, file, line, function, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
178
179         ast_mutex_unlock(&log_lock);
180 }
181
182 /*
183  * channel and call instances
184  */
185 struct chan_call *call_first;
186
187 struct chan_call *find_call_ref(unsigned long ref)
188 {
189         struct chan_call *call = call_first;
190
191         while(call)
192         {
193                 if (call->ref == ref)
194                         break;
195                 call = call->next;
196         }
197         return(call);
198 }
199
200 #if 0
201 struct chan_call *find_call_ast(struct ast_channel *ast)
202 {
203         struct chan_call *call = call_first;
204
205         while(call)
206         {
207                 if (call->ast == ast)
208                         break;
209                 call = call->next;
210         }
211         return(call);
212 }
213
214 struct chan_call *find_call_handle(unsigned long handle)
215 {
216         struct chan_call *call = call_first;
217
218         while(call)
219         {
220                 if (call->bchannel_handle == handle)
221                         break;
222                 call = call->next;
223         }
224         return(call);
225 }
226 #endif
227
228 void free_call(struct chan_call *call)
229 {
230         struct chan_call **temp = &call_first;
231
232         while(*temp)
233         {
234                 if (*temp == call)
235                 {
236                         *temp = (*temp)->next;
237                         if (call->pipe[0] > -1)
238                                 close(call->pipe[0]);
239                         if (call->pipe[1] > -1)
240                                 close(call->pipe[1]);
241                         if (call->bchannel)
242                         {
243                                 if (call->bchannel->call != call)
244                                         CERROR(call, NULL, "Linked bchannel structure has no link to us.\n");
245                                 call->bchannel->call = NULL;
246                         }
247                         if (call->bridge_call)
248                         {
249                                 if (call->bridge_call->bridge_call != call)
250                                         CERROR(call, NULL, "Linked call structure has no link to us.\n");
251                                 call->bridge_call->bridge_call = NULL;
252                         }
253                         CDEBUG(call, NULL, "Call instance freed.\n");
254                         free(call);
255                         return;
256                 }
257                 temp = &((*temp)->next);
258         }
259         CERROR(call, NULL, "Call instance not found in list.\n");
260 }
261
262 struct chan_call *alloc_call(void)
263 {
264         struct chan_call **callp = &call_first;
265
266         while(*callp)
267                 callp = &((*callp)->next);
268
269         *callp = (struct chan_call *)calloc(1, sizeof(struct chan_call));
270         if (*callp)
271                 memset(*callp, 0, sizeof(struct chan_call));
272         if (pipe((*callp)->pipe) < 0) {
273                 CERROR(*callp, NULL, "Failed to create pipe.\n");
274                 free_call(*callp);
275                 return(NULL);
276         }
277         CDEBUG(*callp, NULL, "Call instance allocated.\n");
278         return(*callp);
279 }
280
281
282 unsigned short new_bridge_id(void)
283 {
284         struct chan_call *call;
285         unsigned short id = 1;
286
287         /* search for lowest bridge id that is not in use and not 0 */
288         while(id)
289         {
290                 call = call_first;
291                 while(call)
292                 {
293                         if (call->bridge_id == id)
294                                 break;
295                         call = call->next;
296                 }
297                 if (!call)
298                         break;
299                 id++;
300         }
301         CDEBUG(NULL, NULL, "New bridge ID %d.\n", id);
302         return(id);
303 }
304
305
306 /*
307  * enque message to LCR
308  */
309 int send_message(int message_type, unsigned long ref, union parameter *param)
310 {
311         struct admin_list *admin, **adminp;
312
313         if (lcr_sock < 0) {
314                 CDEBUG(NULL, NULL, "Ignoring message %d, because socket is closed.\n", message_type);
315                 return -1;
316         }
317         CDEBUG(NULL, NULL, "Sending %s to socket.\n", messages_txt[message_type]);
318
319         adminp = &admin_first;
320         while(*adminp)
321                 adminp = &((*adminp)->next);
322         admin = (struct admin_list *)calloc(1, sizeof(struct admin_list));
323         if (!admin) {
324                 CERROR(NULL, NULL, "No memory for message to LCR.\n");
325                 return -1;
326         }
327         *adminp = admin;
328
329         admin->msg.message = ADMIN_MESSAGE;
330         admin->msg.u.msg.type = message_type;
331         admin->msg.u.msg.ref = ref;
332         memcpy(&admin->msg.u.msg.param, param, sizeof(union parameter));
333
334         return(0);
335 }
336
337 /*
338  * send setup info to LCR
339  * this function is called, when asterisk call is received and ref is received
340  */
341 static void send_setup_to_lcr(struct chan_call *call)
342 {
343         union parameter newparam;
344         struct ast_channel *ast = call->ast;
345
346         if (!call->ast || !call->ref)
347                 return;
348
349         CDEBUG(call, call->ast, "Sending setup to LCR. (interface=%s dialstring=%s)\n", call->interface, call->dialstring);
350
351         /* send setup message to LCR */
352         memset(&newparam, 0, sizeof(union parameter));
353         newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;     
354         newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
355         strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
356         strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
357         newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;      
358         newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
359         if (ast->cid.cid_num) if (ast->cid.cid_num[0])
360                 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
361         if (ast->cid.cid_name) if (ast->cid.cid_name[0])
362                 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
363         if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
364         {
365                 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
366                 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;       
367                 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;    
368         }
369         switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
370         {
371                 case AST_PRES_ALLOWED:
372                 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
373                 break;
374                 case AST_PRES_RESTRICTED:
375                 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
376                 break;
377                 case AST_PRES_UNAVAILABLE:
378                 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
379                 break;
380                 default:
381                 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
382         }
383         switch(ast->cid.cid_ton)
384         {
385                 case 4:
386                 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
387                 break;
388                 case 2:
389                 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
390                 break;
391                 case 1:
392                 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
393                 break;
394                 default:
395                 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
396         }
397         newparam.setup.capainfo.bearer_capa = ast->transfercapability;
398         newparam.setup.capainfo.bearer_info1 = (options.law=='a')?3:2;
399         newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
400         newparam.setup.capainfo.hlc = INFO_HLC_NONE;
401         newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
402         send_message(MESSAGE_SETUP, call->ref, &newparam);
403
404         /* change to outgoing setup state */
405         call->state = CHAN_LCR_STATE_OUT_SETUP;
406 }
407
408 /*
409  * send dialing info to LCR
410  * this function is called, when setup acknowledge is received and dialing
411  * info is available.
412  */
413 static void send_dialque_to_lcr(struct chan_call *call)
414 {
415         union parameter newparam;
416
417         if (!call->ast || !call->ref || !call->dialque[0])
418                 return;
419         
420         CDEBUG(call, call->ast, "Sending dial queue to LCR. (dialing=%s)\n", call->dialque);
421
422         /* send setup message to LCR */
423         memset(&newparam, 0, sizeof(union parameter));
424         strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
425         call->dialque[0] = '\0';
426         send_message(MESSAGE_INFORMATION, call->ref, &newparam);
427 }
428
429 /*
430  * in case of a bridge, the unsupported message can be forwarded directly
431  * to the remote call.
432  */
433 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
434 {
435         /* check bridge */
436         if (!call) return;
437         if (!call->bridge_call) return;
438         CDEBUG(call, NULL, "Sending message due briding.\n");
439         send_message(message_type, call->bridge_call->ref, param);
440 }
441
442 /*
443  * send release message to LCR and import bchannel if exported
444  */
445 static void send_release_and_import(struct chan_call *call, int cause, int location)
446 {
447         union parameter newparam;
448
449         /* importing channel */
450         if (call->bchannel) {
451                 memset(&newparam, 0, sizeof(union parameter));
452                 newparam.bchannel.type = BCHANNEL_RELEASE;
453                 newparam.bchannel.handle = call->bchannel->handle;
454                 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
455         }
456         /* sending release */
457         memset(&newparam, 0, sizeof(union parameter));
458         newparam.disconnectinfo.cause = cause;
459         newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
460         send_message(MESSAGE_RELEASE, call->ref, &newparam);
461 }
462
463 /*
464  * check if extension matches and start asterisk
465  * if it can match, proceed
466  * if not, release
467  */
468 static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int complete)
469 {
470         int cause, ret;
471         union parameter newparam;
472
473         CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", ast->exten, ast->context, complete?"yes":"no");
474         
475         if (complete)
476         {
477                 /* if not match */
478                 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
479                 {
480                         CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at context '%s' - releasing.\n", ast->exten, ast->context);
481                         cause = 1;
482                         goto release;
483                 }
484                 if (!ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad))
485                 {
486                         CDEBUG(call, ast, "Got 'sending complete', but extension '%s' would match at context '%s', if more digits would be dialed - releasing.\n", ast->exten, ast->context);
487                         cause = 28;
488                         goto release;
489                 }
490                 CDEBUG(call, ast, "Got 'sending complete', extensions matches.\n");
491                 /* send setup acknowledge to lcr */
492                 memset(&newparam, 0, sizeof(union parameter));
493                 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
494
495                 /* change state */
496                 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
497
498                 goto start;
499         }
500
501         if (ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
502         {
503                 /* send setup acknowledge to lcr */
504                 if (call->state != CHAN_LCR_STATE_IN_DIALING) {
505                         memset(&newparam, 0, sizeof(union parameter));
506                         send_message(MESSAGE_OVERLAP, call->ref, &newparam);
507                 }
508
509                 /* change state */
510                 call->state = CHAN_LCR_STATE_IN_DIALING;
511
512                 /* if match, start pbx */
513                 if (ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad)) {
514                         CDEBUG(call, ast, "Extensions matches.\n");
515                         goto start;
516                 }
517
518                 /* if can match */
519                 CDEBUG(call, ast, "Extensions may match, if more digits are dialed.\n");
520                 return;
521         }
522
523         /* if not match */
524         cause = 1;
525         release:
526         /* release lcr */
527         CDEBUG(call, ast, "Releasing due to extension missmatch.\n");
528         send_release_and_import(call, cause, LOCATION_PRIVATE_LOCAL);
529         call->ref = 0;
530         /* release asterisk */
531         ast->hangupcause = call->cause;
532         /* change to release state */
533         call->state = CHAN_LCR_STATE_RELEASE;
534         ast_hangup(ast); // call will be destroyed here
535         return;
536         
537         start:
538         /* send setup to asterisk */
539         CDEBUG(call, ast, "Starting call to Asterisk due to matching extension.\n");
540         ret = ast_pbx_start(ast);
541         if (ret < 0)
542         {
543                 cause = (ret==-2)?34:27;
544                 goto release;
545         }
546         call->pbx_started = 1;
547         return;
548 }
549
550 /*
551  * incoming setup from LCR
552  */
553 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
554 {
555         struct ast_channel *ast;
556
557         CDEBUG(call, NULL, "Incomming setup from LCR. (callerid %s, dialing %s)\n", param->setup.callerinfo.id, param->setup.dialinginfo.id);
558
559         /* create asterisk channel instrance */
560         ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
561         if (!ast)
562         {
563                 /* release */
564                 CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
565                 send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
566                 /* remove call */
567                 free_call(call);
568                 return;
569         }
570         /* link together */
571         call->ast = ast;
572         ast->tech_pvt = call;
573         ast->tech = &lcr_tech;
574         ast->fds[0] = call->pipe[0];
575         
576         /* fill setup information */
577         if (param->setup.dialinginfo.id)
578                 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
579         if (param->setup.context[0])
580                 strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1);
581         else
582                 strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1);
583         if (param->setup.callerinfo.id[0])
584                 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
585         if (param->setup.callerinfo.name[0])
586                 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
587         if (param->setup.redirinfo.id[0])
588                 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international));
589         switch (param->setup.callerinfo.present)
590         {
591                 case INFO_PRESENT_ALLOWED:
592                         ast->cid.cid_pres = AST_PRES_ALLOWED;
593                 break;
594                 case INFO_PRESENT_RESTRICTED:
595                         ast->cid.cid_pres = AST_PRES_RESTRICTED;
596                 break;
597                 default:
598                         ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
599         }
600         switch (param->setup.callerinfo.ntype)
601         {
602                 case INFO_NTYPE_SUBSCRIBER:
603                         ast->cid.cid_ton = 4;
604                 break;
605                 case INFO_NTYPE_NATIONAL:
606                         ast->cid.cid_ton = 2;
607                 break;
608                 case INFO_NTYPE_INTERNATIONAL:
609                         ast->cid.cid_ton = 1;
610                 break;
611                 default:
612                         ast->cid.cid_ton = 0;
613         }
614         ast->transfercapability = param->setup.capainfo.bearer_capa;
615         strncpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international), sizeof(call->oad)-1);
616
617         /* configure channel */
618         ast->nativeformats = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
619         ast->readformat = ast->rawreadformat = ast->nativeformats;
620         ast->writeformat = ast->rawwriteformat =  ast->nativeformats;
621         ast->priority = 1;
622         ast->hangupcause = 0;
623
624         /* change state */
625         call->state = CHAN_LCR_STATE_IN_SETUP;
626
627         lcr_start_pbx(call, ast, param->setup.dialinginfo.sending_complete);
628 }
629
630 /*
631  * incoming setup acknowledge from LCR
632  */
633 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
634 {
635         if (!call->ast) return;
636
637         CDEBUG(call, call->ast, "Incomming setup acknowledge from LCR.\n");
638
639         /* send pending digits in dialque */
640         if (call->dialque[0])
641                 send_dialque_to_lcr(call);
642         /* change to overlap state */
643         call->state = CHAN_LCR_STATE_OUT_DIALING;
644 }
645
646 /*
647  * incoming proceeding from LCR
648  */
649 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
650 {
651         CDEBUG(call, call->ast, "Incomming proceeding from LCR.\n");
652
653         /* change state */
654         call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
655         /* send event to asterisk */
656         if (call->ast && call->pbx_started)
657                 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
658 }
659
660 /*
661  * incoming alerting from LCR
662  */
663 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
664 {
665         CDEBUG(call, call->ast, "Incomming alerting from LCR.\n");
666
667         /* change state */
668         call->state = CHAN_LCR_STATE_OUT_ALERTING;
669         /* send event to asterisk */
670         if (call->ast && call->pbx_started)
671                 ast_queue_control(call->ast, AST_CONTROL_RINGING);
672 }
673
674 /*
675  * incoming connect from LCR
676  */
677 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
678 {
679         union parameter newparam;
680
681         CDEBUG(call, call->ast, "Incomming connect (answer) from LCR.\n");
682
683         /* change state */
684         call->state = CHAN_LCR_STATE_CONNECT;
685         /* request bchannel */
686         if (!call->bchannel) {
687                 CDEBUG(call, call->ast, "Requesting B-channel.\n");
688                 memset(&newparam, 0, sizeof(union parameter));
689                 newparam.bchannel.type = BCHANNEL_REQUEST;
690                 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
691         }
692         /* copy connectinfo */
693         memcpy(&call->connectinfo, &param->connectinfo, sizeof(struct connect_info));
694         /* send event to asterisk */
695         if (call->ast && call->pbx_started)
696                 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
697 }
698
699 /*
700  * incoming disconnect from LCR
701  */
702 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
703 {
704         struct ast_channel *ast = call->ast;
705
706         CDEBUG(call, call->ast, "Incomming disconnect from LCR. (cause=%d)\n", param->disconnectinfo.cause);
707
708         /* change state */
709         call->state = CHAN_LCR_STATE_IN_DISCONNECT;
710         /* save cause */
711         call->cause = param->disconnectinfo.cause;
712         call->location = param->disconnectinfo.location;
713         /* if bridge, forward disconnect and return */
714 #ifdef TODO
715         feature flag
716         if (call->bridge_call)
717         {
718                 CDEBUG(call, call->ast, "Only signal disconnect via bridge.\n");
719                 bridge_message_if_bridged(call, message_type, param);
720                 return;
721         }
722 #endif
723         /* release lcr with same cause */
724         send_release_and_import(call, call->cause, call->location);
725         call->ref = 0;
726         /* change to release state */
727         call->state = CHAN_LCR_STATE_RELEASE;
728         /* release asterisk */
729         if (ast)
730         {
731                 ast->hangupcause = call->cause;
732                 if (call->pbx_started)
733                         ast_queue_hangup(ast);
734                 else {
735                         ast_hangup(ast); // call will be destroyed here
736                 }
737         }
738 }
739
740 /*
741  * incoming setup acknowledge from LCR
742  */
743 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
744 {
745         struct ast_channel *ast = call->ast;
746
747         CDEBUG(call, call->ast, "Incomming release from LCR, releasing ref. (cause=%d)\n", param->disconnectinfo.cause);
748
749         /* release ref */
750         call->ref = 0;
751         /* change to release state */
752         call->state = CHAN_LCR_STATE_RELEASE;
753         /* copy release info */
754         if (!call->cause)
755         {
756                call->cause = param->disconnectinfo.cause;
757                call->location = param->disconnectinfo.location;
758         }
759         /* if we have an asterisk instance, send hangup, else we are done */
760         if (ast)
761         {
762                 ast->hangupcause = call->cause;
763                 if (call->pbx_started)
764                         ast_queue_hangup(ast);
765                 else {
766                         ast_hangup(ast); // call will be destroyed here
767                 }
768         } else
769         {
770                 free_call(call);
771         }
772         
773 }
774
775 /*
776  * incoming information from LCR
777  */
778 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
779 {
780         struct ast_channel *ast = call->ast;
781         struct ast_frame fr;
782         char *p;
783
784         CDEBUG(call, call->ast, "Incoming information from LCR. (dialing=%s)\n", param->information.id);
785         
786         if (!ast) return;
787
788         /* pbx not started */
789         if (!call->pbx_started)
790         {
791                 CDEBUG(call, call->ast, "Asterisk not started, adding digits to number.\n");
792                 strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
793                 lcr_start_pbx(call, ast, param->information.sending_complete);
794                 return;
795         }
796         
797         /* copy digits */
798         p = param->information.id;
799         if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
800         {
801                 CDEBUG(call, call->ast, "Asterisk is started, sending DTMF frame.\n");
802                 while (*p)
803                 {
804                         /* send digit to asterisk */
805                         memset(&fr, 0, sizeof(fr));
806                         fr.frametype = AST_FRAME_DTMF;
807                         fr.subclass = *p;
808                         fr.delivery = ast_tv(0, 0);
809                         ast_queue_frame(call->ast, &fr);
810                         p++;
811                 }
812         }
813         /* use bridge to forware message not supported by asterisk */
814         if (call->state == CHAN_LCR_STATE_CONNECT) {
815                 CDEBUG(call, call->ast, "Call is connected, briding.\n");
816                 bridge_message_if_bridged(call, message_type, param);
817         }
818 }
819
820 /*
821  * incoming information from LCR
822  */
823 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
824 {
825         CDEBUG(call, call->ast, "Incomming notify from LCR. (notify=%d)\n", param->notifyinfo.notify);
826
827         if (!call->ast) return;
828
829         /* use bridge to forware message not supported by asterisk */
830         bridge_message_if_bridged(call, message_type, param);
831 }
832
833 /*
834  * incoming information from LCR
835  */
836 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
837 {
838         CDEBUG(call, call->ast, "Incomming facility from LCR.\n");
839
840         if (!call->ast) return;
841
842         /* use bridge to forware message not supported by asterisk */
843         bridge_message_if_bridged(call, message_type, param);
844 }
845
846 /*
847  * got dtmf from bchannel
848  */
849 void lcr_in_dtmf(struct chan_call *call, int val)
850 {
851         struct ast_channel *ast = call->ast;
852         struct ast_frame fr;
853
854         if (!ast)
855                 return;
856         if (!call->pbx_started)
857                 return;
858
859         CDEBUG(call, call->ast, "Frowarding DTMF digit '%c' to Asterisk.\n", val);
860
861         /* send digit to asterisk */
862         memset(&fr, 0, sizeof(fr));
863         fr.frametype = AST_FRAME_DTMF;
864         fr.subclass = val;
865         fr.delivery = ast_tv(0, 0);
866         ast_queue_frame(call->ast, &fr);
867 }
868
869 /*
870  * message received from LCR
871  */
872 int receive_message(int message_type, unsigned long ref, union parameter *param)
873 {
874         struct bchannel *bchannel;
875         struct chan_call *call;
876         union parameter newparam;
877
878         memset(&newparam, 0, sizeof(union parameter));
879
880         /* handle bchannel message*/
881         if (message_type == MESSAGE_BCHANNEL)
882         {
883                 switch(param->bchannel.type)
884                 {
885                         case BCHANNEL_ASSIGN:
886                         CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx)\n", param->bchannel.handle);
887                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
888                         {
889                                 CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
890                                 return(-1);
891                         }
892                         /* create bchannel */
893                         bchannel = alloc_bchannel(param->bchannel.handle);
894                         if (!bchannel)
895                         {
896                                 CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
897                                 return(-1);
898                         }
899
900                         /* configure channel */
901                         bchannel->b_tx_gain = param->bchannel.tx_gain;
902                         bchannel->b_rx_gain = param->bchannel.rx_gain;
903                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
904                         if (param->bchannel.crypt_len)
905                         {
906                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
907                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
908                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
909                         }
910                         bchannel->b_txdata = 0;
911                         bchannel->b_dtmf = 1;
912                         bchannel->b_tx_dejitter = 1;
913
914                         /* in case, ref is not set, this bchannel instance must
915                          * be created until it is removed again by LCR */
916                         /* link to call */
917                         call = find_call_ref(ref);
918                         if (call)
919                         {
920                                 bchannel->call = call;
921                                 call->bchannel = bchannel;
922                                 if (call->dtmf)
923                                         bchannel_dtmf(bchannel, 1);
924 #ifdef TODO
925 hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor dem b-kanal verfügbar waren
926 #endif
927                                 if (call->bridge_id) {
928                                         CDEBUG(call, call->ast, "Join bchannel, because call is already bridged.\n");
929                                         bchannel_join(bchannel, call->bridge_id);
930                                 }
931                         }
932                         if (bchannel_create(bchannel))
933                                 bchannel_activate(bchannel, 1);
934                         /* acknowledge */
935                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
936                         newparam.bchannel.handle = param->bchannel.handle;
937                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
938                         /* if call has released before bchannel is assigned */
939                         if (!call) {
940                                 newparam.bchannel.type = BCHANNEL_RELEASE;
941                                 newparam.bchannel.handle = param->bchannel.handle;
942                                 send_message(MESSAGE_BCHANNEL, 0, &newparam);
943                         }
944
945                         break;
946
947                         case BCHANNEL_REMOVE:
948                         CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle);
949                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
950                         {
951                                 CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
952                                 return(-1);
953                         }
954                         /* unklink from call and destroy bchannel */
955                         free_bchannel(bchannel);
956
957                         /* acknowledge */
958                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
959                         newparam.bchannel.handle = param->bchannel.handle;
960                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
961                         
962                         break;
963
964                         default:
965                         CDEBUG(NULL, NULL, "Received unknown bchannel message %d.\n", param->bchannel.type);
966                 }
967                 return(0);
968         }
969
970         /* handle new ref */
971         if (message_type == MESSAGE_NEWREF)
972         {
973                 if (param->direction)
974                 {
975                         /* new ref from lcr */
976                         CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
977                         if (!ref || find_call_ref(ref))
978                         {
979                                 CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref);
980                                 return(-1);
981                         }
982                         /* allocate new call instance */
983                         call = alloc_call();
984                         /* new state */
985                         call->state = CHAN_LCR_STATE_IN_PREPARE;
986                         /* set ref */
987                         call->ref = ref;
988                         /* wait for setup (or release from asterisk) */
989                 } else
990                 {
991                         /* new ref, as requested from this remote application */
992                         CDEBUG(NULL, NULL, "Received new ref by LCR, as requested from chan_lcr. (ref=%ld)\n", ref);
993                         call = find_call_ref(0);
994                         if (!call)
995                         {
996                                 /* send release, if ref does not exist */
997                                 CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
998                                 send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
999                                 return(0);
1000                         }
1001                         /* store new ref */
1002                         call->ref = ref;
1003                         /* send pending setup info */
1004                         if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
1005                                 send_setup_to_lcr(call);
1006                         /* release if asterisk has signed off */
1007                         else if (call->state == CHAN_LCR_STATE_RELEASE)
1008                         {
1009                                 /* send release */
1010                                 if (call->cause)
1011                                         send_release_and_import(call, call->cause, call->location);
1012                                 else
1013                                         send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
1014                                 /* free call */
1015                                 free_call(call);
1016                                 return(0);
1017                         }
1018                 }
1019                 return(0);
1020         }
1021
1022         /* check ref */
1023         if (!ref)
1024         {
1025                 CERROR(NULL, NULL, "Received message %d without ref.\n", message_type);
1026                 return(-1);
1027         }
1028         call = find_call_ref(ref);
1029         if (!call)
1030         {
1031                 /* ignore ref that is not used (anymore) */
1032                 CDEBUG(NULL, NULL, "Message %d from LCR ignored, because no call instance found.\n", message_type);
1033                 return(0);
1034         }
1035
1036         /* handle messages */
1037         switch(message_type)
1038         {
1039                 case MESSAGE_SETUP:
1040                 lcr_in_setup(call, message_type, param);
1041                 break;
1042
1043                 case MESSAGE_OVERLAP:
1044                 lcr_in_overlap(call, message_type, param);
1045                 break;
1046
1047                 case MESSAGE_PROCEEDING:
1048                 lcr_in_proceeding(call, message_type, param);
1049                 break;
1050
1051                 case MESSAGE_ALERTING:
1052                 lcr_in_alerting(call, message_type, param);
1053                 break;
1054
1055                 case MESSAGE_CONNECT:
1056                 lcr_in_connect(call, message_type, param);
1057                 break;
1058
1059                 case MESSAGE_DISCONNECT:
1060                 lcr_in_disconnect(call, message_type, param);
1061                 break;
1062
1063                 case MESSAGE_RELEASE:
1064                 lcr_in_release(call, message_type, param);
1065                 break;
1066
1067                 case MESSAGE_INFORMATION:
1068                 lcr_in_information(call, message_type, param);
1069                 break;
1070
1071                 case MESSAGE_NOTIFY:
1072                 lcr_in_notify(call, message_type, param);
1073                 break;
1074
1075                 case MESSAGE_FACILITY:
1076                 lcr_in_facility(call, message_type, param);
1077                 break;
1078
1079                 case MESSAGE_PATTERN: // audio available from LCR
1080                 break;
1081
1082                 case MESSAGE_NOPATTERN: // audio not available from LCR
1083                 break;
1084
1085                 case MESSAGE_AUDIOPATH: // if remote audio connected or hold
1086                 call->audiopath = param->audiopath;
1087                 break;
1088
1089                 default:
1090                 CDEBUG(call, call->ast, "Message %d from LCR unhandled.\n", message_type);
1091                 break;
1092         }
1093         return(0);
1094 }
1095
1096 /*
1097  * release all calls (due to broken socket)
1098  */
1099 static void release_all_calls(void)
1100 {
1101         struct chan_call *call;
1102
1103 again:
1104         call = call_first;
1105         while(call) {
1106                 /* no ast, so we may directly free call */
1107                 if (!call->ast) {
1108                         CDEBUG(call, NULL, "Freeing call, because no Asterisk channel is linked.\n");
1109                         free_call(call);
1110                         goto again;
1111                 }
1112                 /* already in release process */
1113                 if (call->state == CHAN_LCR_STATE_RELEASE) {
1114                         call = call->next;
1115                         continue;
1116                 }
1117                 /* release or queue release */
1118                 call->ref = 0;
1119                 call->state = CHAN_LCR_STATE_RELEASE;
1120                 if (!call->pbx_started) {
1121                         CDEBUG(call, call->ast, "Releasing call, because no Asterisk channel is not started.\n");
1122                         ast_hangup(call->ast); // call will be destroyed here
1123                         goto again;
1124                 }
1125                 CDEBUG(call, call->ast, "Queue call release, because Asterisk channel is running.\n");
1126                 ast_queue_hangup(call->ast);
1127                 call = call->next;
1128         }
1129
1130         /* release all bchannels */
1131         while(bchannel_first)
1132                 free_bchannel(bchannel_first);
1133 }
1134
1135
1136 /* asterisk handler
1137  * warning! not thread safe
1138  * returns -1 for socket error, 0 for no work, 1 for work
1139  */
1140 int handle_socket(void)
1141 {
1142         int work = 0;
1143         int len;
1144         struct admin_list *admin;
1145         struct admin_message msg;
1146
1147         /* read from socket */
1148         len = read(lcr_sock, &msg, sizeof(msg));
1149         if (len == 0)
1150         {
1151                 CERROR(NULL, NULL, "Socket closed.\n");
1152                 return(-1); // socket closed
1153         }
1154         if (len > 0)
1155         {
1156                 if (len != sizeof(msg))
1157                 {
1158                         CERROR(NULL, NULL, "Socket short read. (len %d)\n", len);
1159                         return(-1); // socket error
1160                 }
1161                 if (msg.message != ADMIN_MESSAGE)
1162                 {
1163                         CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message);
1164                         return(-1);
1165                 }
1166                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
1167                 work = 1;
1168         } else
1169         {
1170                 if (errno != EWOULDBLOCK)
1171                 {
1172                         CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1173                         return(-1);
1174                 }
1175         }
1176
1177         /* write to socket */
1178         if (!admin_first)
1179                 return(work);
1180         admin = admin_first;
1181         len = write(lcr_sock, &admin->msg, sizeof(msg));
1182         if (len == 0)
1183         {
1184                 CERROR(NULL, NULL, "Socket closed.\n");
1185                 return(-1); // socket closed
1186         }
1187         if (len > 0)
1188         {
1189                 if (len != sizeof(msg))
1190                 {
1191                         CERROR(NULL, NULL, "Socket short write. (len %d)\n", len);
1192                         return(-1); // socket error
1193                 }
1194                 /* free head */
1195                 admin_first = admin->next;
1196                 free(admin);
1197
1198                 work = 1;
1199         } else
1200         {
1201                 if (errno != EWOULDBLOCK)
1202                 {
1203                         CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1204                         return(-1);
1205                 }
1206         }
1207
1208         return(work);
1209 }
1210
1211 /*
1212  * open and close socket and thread
1213  */
1214 int open_socket(void)
1215 {
1216         int ret;
1217         char *socket_name = SOCKET_NAME;
1218         int conn;
1219         struct sockaddr_un sock_address;
1220         unsigned long on = 1;
1221         union parameter param;
1222
1223         /* open socket */
1224         if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1225         {
1226                 CERROR(NULL, NULL, "Failed to create socket.\n");
1227                 return(lcr_sock);
1228         }
1229
1230         /* set socket address and name */
1231         memset(&sock_address, 0, sizeof(sock_address));
1232         sock_address.sun_family = PF_UNIX;
1233         strcpy(sock_address.sun_path, socket_name);
1234
1235         /* connect socket */
1236         if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
1237         {
1238                 close(lcr_sock);
1239                 lcr_sock = -1;
1240                 CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
1241                 return(conn);
1242         }
1243
1244         /* set non-blocking io */
1245         if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0)
1246         {
1247                 close(lcr_sock);
1248                 lcr_sock = -1;
1249                 CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n");
1250                 return(ret);
1251         }
1252
1253         /* enque hello message */
1254         memset(&param, 0, sizeof(param));
1255         strcpy(param.hello.application, "asterisk");
1256         send_message(MESSAGE_HELLO, 0, &param);
1257
1258         return(lcr_sock);
1259 }
1260
1261 void close_socket(void)
1262 {
1263         struct admin_list *admin, *temp;
1264         
1265         /* flush pending messages */
1266         admin = admin_first;
1267         while(admin) {
1268                 temp = admin;
1269                 admin = admin->next;
1270                 free(temp);
1271         }
1272         admin_first = NULL;
1273
1274         /* close socket */
1275         if (lcr_sock >= 0)      
1276                 close(lcr_sock);
1277         lcr_sock = -1;
1278 }
1279
1280 void sighandler(int sigset)
1281 {
1282 }
1283
1284 static void *chan_thread(void *arg)
1285 {
1286         int work;
1287         int ret;
1288         union parameter param;
1289         time_t retry = 0, now;
1290
1291         bchannel_pid = getpid();
1292
1293 //      signal(SIGPIPE, sighandler);
1294         
1295         memset(&param, 0, sizeof(union parameter));
1296         if (lcr_sock < 0)
1297                 time(&retry);
1298
1299         ast_mutex_lock(&chan_lock);
1300
1301         while(!quit) {
1302                 work = 0;
1303
1304                 if (lcr_sock > 0) {
1305                         /* handle socket */
1306                         ret = handle_socket();
1307                         if (ret < 0) {
1308                                 CERROR(NULL, NULL, "Handling of socket failed - closing for some seconds.\n");
1309                                 close_socket();
1310                                 release_all_calls();
1311                                 time(&retry);
1312                         }
1313                         if (ret)
1314                                 work = 1;
1315                 } else {
1316                         time(&now);
1317                         if (retry && now-retry > 5) {
1318                                 CDEBUG(NULL, NULL, "Retry to open socket.\n");
1319                                 retry = 0;
1320                                 if (open_socket() < 0) {
1321                                         time(&retry);
1322                                 }
1323                                 work = 1;
1324                         }
1325                                         
1326                 }
1327
1328                 /* handle mISDN */
1329                 ret = bchannel_handle();
1330                 if (ret)
1331                         work = 1;
1332                 
1333                 if (!work) {
1334                         ast_mutex_unlock(&chan_lock);
1335                         usleep(30000);
1336                         ast_mutex_lock(&chan_lock);
1337                 }
1338         }
1339
1340         close_socket();
1341
1342         CERROR(NULL, NULL, "Thread exit.\n");
1343         
1344         ast_mutex_unlock(&chan_lock);
1345
1346 //      signal(SIGPIPE, SIG_DFL);
1347
1348         return NULL;
1349 }
1350
1351 /*
1352  * new asterisk instance
1353  */
1354 static
1355 struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1356 {
1357         char exten[256], *dial, *interface, *opt;
1358         struct ast_channel *ast;
1359         struct chan_call *call;
1360
1361         ast_mutex_lock(&chan_lock);
1362
1363         CDEBUG(NULL, NULL, "Received request from Asterisk. data=%s\n", (char *)data);
1364
1365         /* if socket is closed */
1366         if (lcr_sock < 0)
1367         {
1368                 CERROR(NULL, NULL, "Rejecting call from Asterisk, because LCR not running.\n");
1369                 return NULL;
1370         }
1371
1372         /* create call instance */
1373         call = alloc_call();
1374         if (!call)
1375         {
1376                 /* failed to create instance */
1377                 return NULL;
1378         }
1379
1380         /* create asterisk channel instrance */
1381         ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1382         if (!ast)
1383         {
1384                 CERROR(NULL, NULL, "Failed to create Asterisk channel.\n");
1385                 free_call(call);
1386                 /* failed to create instance */
1387                 return NULL;
1388         }
1389         ast->tech = &lcr_tech;
1390         ast->tech_pvt = (void *)1L; // set pointer or asterisk will not call
1391         /* configure channel */
1392         ast->nativeformats = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
1393         ast->readformat = ast->rawreadformat = ast->nativeformats;
1394         ast->writeformat = ast->rawwriteformat =  ast->nativeformats;
1395         ast->priority = 1;
1396         ast->hangupcause = 0;
1397
1398         /* link together */
1399         call->ast = ast;
1400         ast->tech_pvt = call;
1401         ast->fds[0] = call->pipe[0];
1402         ast_mutex_unlock(&chan_lock);
1403         call->pbx_started = 0;
1404         /* set state */
1405         call->state = CHAN_LCR_STATE_OUT_PREPARE;
1406
1407         /*
1408          * Extract interface, dialstring, options from data.
1409          * Formats can be:
1410          *      <dialstring>
1411          *      <interface>/<dialstring>
1412          *      <interface>/<dialstring>/options
1413          */
1414         strncpy(exten, (char *)data, sizeof(exten)-1);
1415         exten[sizeof(exten)-1] = '\0';
1416         if ((dial = strchr(exten, '/'))) {
1417                 *dial++ = '\0';
1418                 interface = exten;
1419                 if ((opt = strchr(dial, '/')))
1420                         *opt++ = '\0';
1421                 else
1422                         opt = "";
1423         } else {
1424                 dial = exten;
1425                 interface = "";
1426                 opt = "";
1427         }
1428         strncpy(call->interface, interface, sizeof(call->interface)-1);
1429         strncpy(call->dialstring, dial, sizeof(call->dialstring)-1);
1430
1431 #warning todo: parse options
1432
1433         return ast;
1434 }
1435
1436 /*
1437  * call from asterisk
1438  */
1439 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1440 {
1441         union parameter newparam;
1442         struct chan_call *call;
1443
1444         ast_mutex_lock(&chan_lock);
1445         call = ast->tech_pvt;
1446         if (!call) {
1447                 CERROR(NULL, ast, "Received call from Asterisk, but call instance does not exist.\n");
1448                 ast_mutex_unlock(&chan_lock);
1449                 return -1;
1450         }
1451
1452         CDEBUG(NULL, ast, "Received call from Asterisk.\n");
1453
1454         /* pbx process is started */
1455         call->pbx_started = 1;
1456         /* send MESSAGE_NEWREF */
1457         memset(&newparam, 0, sizeof(union parameter));
1458         newparam.direction = 0; /* request from app */
1459         send_message(MESSAGE_NEWREF, 0, &newparam);
1460
1461         ast_mutex_unlock(&chan_lock);
1462         return 0; 
1463 }
1464
1465 static int lcr_digit(struct ast_channel *ast, char digit)
1466 {
1467         struct chan_call *call;
1468         union parameter newparam;
1469         char buf[]="x";
1470
1471         /* only pass IA5 number space */
1472         if (digit > 126 || digit < 32)
1473                 return 0;
1474
1475         ast_mutex_lock(&chan_lock);
1476         call = ast->tech_pvt;
1477         if (!call) {
1478                 CERROR(NULL, ast, "Received digit from Asterisk, but no call instance exists.\n");
1479                 ast_mutex_unlock(&chan_lock);
1480                 return -1;
1481         }
1482
1483         CDEBUG(call, ast, "Received digit '%c' from Asterisk.\n", digit);
1484
1485         /* send information or queue them */
1486         if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1487         {
1488                 CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
1489                 memset(&newparam, 0, sizeof(union parameter));
1490                 newparam.information.id[0] = digit;
1491                 newparam.information.id[1] = '\0';
1492                 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1493         } else
1494         if (!call->ref
1495          && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP))
1496         {
1497                 CDEBUG(call, ast, "Queue digits, because we are in setup/dialing state and have no ref yet.\n");
1498                 *buf = digit;
1499                 strncat(call->dialque, buf, strlen(call->dialque)-1);
1500         }
1501
1502         ast_mutex_unlock(&chan_lock);
1503         
1504         return(0);
1505 }
1506
1507 static int lcr_answer(struct ast_channel *ast)
1508 {
1509         union parameter newparam;
1510         struct chan_call *call;
1511
1512         ast_mutex_lock(&chan_lock);
1513         call = ast->tech_pvt;
1514         if (!call) {
1515                 CERROR(NULL, ast, "Received answer from Asterisk, but no call instance exists.\n");
1516                 ast_mutex_unlock(&chan_lock);
1517                 return -1;
1518         }
1519         
1520         CDEBUG(call, ast, "Received answer from Asterisk.\n");
1521                 
1522         /* copy connectinfo, if bridged */
1523         if (call->bridge_call)
1524                 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1525         /* send connect message to lcr */
1526         memset(&newparam, 0, sizeof(union parameter));
1527         memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1528         send_message(MESSAGE_CONNECT, call->ref, &newparam);
1529         /* change state */
1530         call->state = CHAN_LCR_STATE_CONNECT;
1531         /* request bchannel */
1532         if (!call->bchannel) {
1533                 CDEBUG(call, ast, "Requesting B-channel.\n");
1534                 memset(&newparam, 0, sizeof(union parameter));
1535                 newparam.bchannel.type = BCHANNEL_REQUEST;
1536                 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
1537         }
1538         /* enable keypad */
1539 //      memset(&newparam, 0, sizeof(union parameter));
1540 //      send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam);
1541         call->dtmf = 1;
1542         
1543         ast_mutex_unlock(&chan_lock);
1544         return 0;
1545 }
1546
1547 static int lcr_hangup(struct ast_channel *ast)
1548 {
1549         struct chan_call *call;
1550         pthread_t tid = pthread_self();
1551
1552         if (!pthread_equal(tid, chan_tid))
1553                 ast_mutex_lock(&chan_lock);
1554         call = ast->tech_pvt;
1555         if (!call) {
1556                 CERROR(NULL, ast, "Received hangup from Asterisk, but no call instance exists.\n");
1557                 if (!pthread_equal(tid, chan_tid))
1558                         ast_mutex_unlock(&chan_lock);
1559                 return -1;
1560         }
1561
1562         if (!pthread_equal(tid, chan_tid))
1563                 CDEBUG(call, ast, "Received hangup from Asterisk thread.\n");
1564         else
1565                 CDEBUG(call, ast, "Received hangup from LCR thread.\n");
1566
1567         /* disconnect asterisk, maybe not required */
1568         ast->tech_pvt = NULL;
1569         ast->fds[0] = -1;
1570         if (call->ref)
1571         {
1572                 /* release */
1573                 CDEBUG(call, ast, "Releasing ref and freeing call instance.\n");
1574                 if (ast->hangupcause > 0)
1575                         send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL);
1576                 else
1577                         send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
1578                 /* remove call */
1579                 free_call(call);
1580                 if (!pthread_equal(tid, chan_tid))
1581                         ast_mutex_unlock(&chan_lock);
1582                 return 0;
1583         } else
1584         {
1585                 /* ref is not set, due to prepare setup or release */
1586                 if (call->state == CHAN_LCR_STATE_RELEASE)
1587                 {
1588                         /* we get the response to our release */
1589                         CDEBUG(call, ast, "Freeing call instance, because we have no ref AND we are requesting no ref.\n");
1590                         free_call(call);
1591                 } else
1592                 {
1593                         /* during prepare, we change to release state */
1594                         CDEBUG(call, ast, "We must wait until we received our ref, until we can free call instance.\n");
1595                         call->state = CHAN_LCR_STATE_RELEASE;
1596                 }
1597         } 
1598         if (!pthread_equal(tid, chan_tid))
1599                 ast_mutex_unlock(&chan_lock);
1600         return 0;
1601 }
1602
1603 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1604 {
1605         struct chan_call *call;
1606
1607         if (!f->subclass)
1608                 CDEBUG(NULL, ast, "No subclass\n");
1609         if (!(f->subclass & ast->nativeformats))
1610                 CDEBUG(NULL, ast, "Unexpected format.\n");
1611         
1612         ast_mutex_lock(&chan_lock);
1613         call = ast->tech_pvt;
1614         if (!call) {
1615                 ast_mutex_unlock(&chan_lock);
1616                 return -1;
1617         }
1618         if (call->bchannel && f->samples)
1619                 bchannel_transmit(call->bchannel, f->data, f->samples);
1620         ast_mutex_unlock(&chan_lock);
1621         return 0;
1622 }
1623
1624
1625 static struct ast_frame *lcr_read(struct ast_channel *ast)
1626 {
1627         struct chan_call *call;
1628         int i, len;
1629         unsigned char *p;
1630
1631         ast_mutex_lock(&chan_lock);
1632         call = ast->tech_pvt;
1633         if (!call) {
1634                 ast_mutex_unlock(&chan_lock);
1635                 return NULL;
1636         }
1637         if (call->pipe[0] > -1) {
1638                 len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff));
1639                 if (len <= 0) {
1640                         close(call->pipe[0]);
1641                         call->pipe[0] = -1;
1642                         return NULL;
1643                 }
1644         }
1645
1646         p = call->read_buff;
1647         for (i = 0; i < len; i++) {
1648                 *p = flip_bits[*p];
1649                 p++;
1650         }
1651
1652         call->read_fr.frametype = AST_FRAME_VOICE;
1653         call->read_fr.subclass = ast->nativeformats;
1654         call->read_fr.datalen = len;
1655         call->read_fr.samples = len;
1656         call->read_fr.delivery = ast_tv(0,0);
1657         call->read_fr.data = call->read_buff;
1658         ast_mutex_unlock(&chan_lock);
1659
1660         return &call->read_fr;
1661 }
1662
1663 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1664 {
1665         union parameter newparam;
1666         int res = 0;
1667         struct chan_call *call;
1668
1669         ast_mutex_lock(&chan_lock);
1670         call = ast->tech_pvt;
1671         if (!call) {
1672                 CERROR(NULL, ast, "Received indicate from Asterisk, but no call instance exists.\n");
1673                 ast_mutex_unlock(&chan_lock);
1674                 return -1;
1675         }
1676
1677         switch (cond) {
1678                 case AST_CONTROL_BUSY:
1679                         CDEBUG(call, ast, "Received indicate AST_CONTROL_BUSY from Asterisk.\n");
1680                         ast_setstate(ast, AST_STATE_BUSY);
1681                         if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1682                                 /* send message to lcr */
1683                                 memset(&newparam, 0, sizeof(union parameter));
1684                                 newparam.disconnectinfo.cause = 17;
1685                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1686                                 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1687                                 /* change state */
1688                                 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1689                         }
1690                         break;
1691                 case AST_CONTROL_CONGESTION:
1692                         CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk. (cause %d)\n", ast->hangupcause);
1693                         if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1694                                 /* send message to lcr */
1695                                 memset(&newparam, 0, sizeof(union parameter));
1696                                 newparam.disconnectinfo.cause = ast->hangupcause;
1697                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1698                                 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1699                                 /* change state */
1700                                 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1701                         }
1702                         break;
1703                 case AST_CONTROL_PROCEEDING:
1704                         CDEBUG(call, ast, "Received indicate AST_CONTROL_PROCEEDING from Asterisk.\n");
1705                         if (call->state == CHAN_LCR_STATE_IN_SETUP
1706                          || call->state == CHAN_LCR_STATE_IN_DIALING) {
1707                                 /* send message to lcr */
1708                                 memset(&newparam, 0, sizeof(union parameter));
1709                                 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
1710                                 /* change state */
1711                                 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
1712                         }
1713                         break;
1714                 case AST_CONTROL_RINGING:
1715                         CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n");
1716                         ast_setstate(ast, AST_STATE_RINGING);
1717                         if (call->state == CHAN_LCR_STATE_IN_SETUP
1718                          || call->state == CHAN_LCR_STATE_IN_DIALING
1719                          || call->state == CHAN_LCR_STATE_IN_PROCEEDING) {
1720                                 /* send message to lcr */
1721                                 memset(&newparam, 0, sizeof(union parameter));
1722                                 send_message(MESSAGE_ALERTING, call->ref, &newparam);
1723                                 /* change state */
1724                                 call->state = CHAN_LCR_STATE_IN_ALERTING;
1725                         }
1726                         break;
1727                 case -1:
1728                         CDEBUG(call, ast, "Received indicate -1.\n");
1729                         res = -1;
1730                         break;
1731
1732                 case AST_CONTROL_VIDUPDATE:
1733                         CDEBUG(call, ast, "Received indicate AST_CONTROL_VIDUPDATE.\n");
1734                         res = -1;
1735                         break;
1736                 case AST_CONTROL_HOLD:
1737                         CDEBUG(call, ast, "Received indicate AST_CONTROL_HOLD from Asterisk.\n");
1738                         /* send message to lcr */
1739                         memset(&newparam, 0, sizeof(union parameter));
1740                         newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1741                         send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1742                         
1743                         /*start music onhold*/
1744                         ast_moh_start(ast,data,ast->musicclass);
1745                         break;
1746                 case AST_CONTROL_UNHOLD:
1747                         CDEBUG(call, ast, "Received indicate AST_CONTROL_UNHOLD from Asterisk.\n");
1748                         /* send message to lcr */
1749                         memset(&newparam, 0, sizeof(union parameter));
1750                         newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1751                         send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1752
1753                         /*stop moh*/
1754                         ast_moh_stop(ast);
1755                         break;
1756
1757                 default:
1758                         CERROR(call, ast, "Received indicate from Asterisk with unknown condition %d.\n", cond);
1759                         res = -1;
1760                         break;
1761         }
1762
1763         /* return */
1764         ast_mutex_unlock(&chan_lock);
1765         return res;
1766 }
1767
1768 /*
1769  * fixup asterisk
1770  */
1771 static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *newast)
1772 {
1773         struct chan_call *call;
1774
1775         ast_mutex_lock(&chan_lock);
1776         call = oldast->tech_pvt;
1777         if (!call) {
1778                 CERROR(NULL, oldast, "Received fixup from Asterisk, but no call instance exists.\n");
1779                 ast_mutex_unlock(&chan_lock);
1780                 return -1;
1781         }
1782
1783         CDEBUG(call, oldast, "Received fixup from Asterisk.\n");
1784         call->ast = newast;
1785         ast_mutex_lock(&chan_lock);
1786         return 0;
1787 }
1788
1789 /*
1790  * send_text asterisk
1791  */
1792 static int lcr_send_text(struct ast_channel *ast, const char *text)
1793 {
1794         struct chan_call *call;
1795         union parameter newparam;
1796
1797         ast_mutex_lock(&chan_lock);
1798         call = ast->tech_pvt;
1799         if (!call) {
1800                 CERROR(NULL, ast, "Received send_text from Asterisk, but no call instance exists.\n");
1801                 ast_mutex_unlock(&chan_lock);
1802                 return -1;
1803         }
1804
1805         CDEBUG(call, ast, "Received send_text from Asterisk. (text=%s)\n", text);
1806         memset(&newparam, 0, sizeof(union parameter));
1807         strncpy(newparam.notifyinfo.display, text, sizeof(newparam.notifyinfo.display)-1);
1808         send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1809         ast_mutex_lock(&chan_lock);
1810         return 0;
1811 }
1812
1813 /*
1814  * bridge process
1815  */
1816 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1817                                   struct ast_channel *ast2, int flags,
1818                                   struct ast_frame **fo,
1819                                   struct ast_channel **rc, int timeoutms)
1820
1821 {
1822         struct chan_call        *call1, *call2;
1823         struct ast_channel      *carr[2], *who;
1824         int                     to;
1825         struct ast_frame        *f;
1826         int                     bridge_id;
1827
1828         CDEBUG(NULL, NULL, "Received briding request from Asterisk.\n");
1829
1830         carr[0] = ast1;
1831         carr[1] = ast2;
1832         
1833         /* join via dsp (if the channels are currently open) */
1834         ast_mutex_lock(&chan_lock);
1835         bridge_id = new_bridge_id();
1836         call1 = ast1->tech_pvt;
1837         call2 = ast2->tech_pvt;
1838         if (call1 && call2)
1839         {
1840                 call1->bridge_id = bridge_id;
1841                 if (call1->bchannel)
1842                         bchannel_join(call1->bchannel, bridge_id);
1843                 call1->bridge_call = call2;
1844         }
1845         if (call2)
1846         {
1847                 call2->bridge_id = bridge_id;
1848                 if (call2->bchannel)
1849                         bchannel_join(call2->bchannel, bridge_id);
1850                 call2->bridge_call = call1;
1851         }
1852         ast_mutex_unlock(&chan_lock);
1853         
1854         while(1) {
1855                 to = -1;
1856                 who = ast_waitfor_n(carr, 2, &to);
1857
1858                 if (!who) {
1859                         CDEBUG(NULL, NULL, "Empty read on bridge, breaking out.\n");
1860                         break;
1861                 }
1862                 f = ast_read(who);
1863     
1864                 if (!f || f->frametype == AST_FRAME_CONTROL) {
1865                         if (!f)
1866                                 CDEBUG(NULL, NULL, "Got hangup.\n");
1867                         else
1868                                 CDEBUG(NULL, NULL, "Got CONTROL.\n");
1869                         /* got hangup .. */
1870                         *fo=f;
1871                         *rc=who;
1872                         break;
1873                 }
1874                 
1875                 if ( f->frametype == AST_FRAME_DTMF ) {
1876                         CDEBUG(NULL, NULL, "Got DTMF.\n");
1877                         *fo=f;
1878                         *rc=who;
1879                         break;
1880                 }
1881         
1882
1883                 if (who == ast1) {
1884                         ast_write(ast2,f);
1885                 }
1886                 else {
1887                         ast_write(ast1,f);
1888                 }
1889     
1890         }
1891         
1892         CDEBUG(NULL, NULL, "Releasing bride.\n");
1893
1894         /* split channels */
1895         ast_mutex_lock(&chan_lock);
1896         call1 = ast1->tech_pvt;
1897         call2 = ast2->tech_pvt;
1898         if (call1)
1899         {
1900                 call1->bridge_id = 0;
1901                 if (call1->bchannel)
1902                         bchannel_join(call1->bchannel, 0);
1903                 if (call1->bridge_call)
1904                         call1->bridge_call->bridge_call = NULL;
1905                 call1->bridge_call = NULL;
1906         }
1907         if (call2)
1908         {
1909                 call2->bridge_id = 0;
1910                 if (call2->bchannel)
1911                         bchannel_join(call2->bchannel, 0);
1912                 if (call2->bridge_call)
1913                         call2->bridge_call->bridge_call = NULL;
1914                 call2->bridge_call = NULL;
1915         }
1916         ast_mutex_unlock(&chan_lock);
1917         
1918         
1919         return AST_BRIDGE_COMPLETE;
1920 }
1921 static struct ast_channel_tech lcr_tech = {
1922         .type="LCR",
1923         .description="Channel driver for connecting to Linux-Call-Router",
1924         .requester=lcr_request,
1925         .send_digit_begin=lcr_digit,
1926         .call=lcr_call,
1927         .bridge=lcr_bridge, 
1928         .hangup=lcr_hangup,
1929         .answer=lcr_answer,
1930         .read=lcr_read,
1931         .write=lcr_write,
1932         .indicate=lcr_indicate,
1933         .fixup=lcr_fixup,
1934         .send_text=lcr_send_text,
1935         .properties=0
1936 };
1937
1938
1939 /*
1940  * cli
1941  */
1942 #if 0
1943 static int lcr_show_lcr (int fd, int argc, char *argv[])
1944 {
1945         return 0;
1946 }
1947
1948 static int lcr_show_calls (int fd, int argc, char *argv[])
1949 {
1950         return 0;
1951 }
1952
1953 static int lcr_reload_routing (int fd, int argc, char *argv[])
1954 {
1955         return 0;
1956 }
1957
1958 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1959 {
1960         return 0;
1961 }
1962
1963 static int lcr_port_block (int fd, int argc, char *argv[])
1964 {
1965         return 0;
1966 }
1967
1968 static int lcr_port_unblock (int fd, int argc, char *argv[])
1969 {
1970         return 0;
1971 }
1972
1973 static int lcr_port_unload (int fd, int argc, char *argv[])
1974 {
1975         return 0;
1976 }
1977
1978 static struct ast_cli_entry cli_show_lcr =
1979 { {"lcr", "show", "lcr", NULL},
1980  lcr_show_lcr,
1981  "Shows current states of LCR core",
1982  "Usage: lcr show lcr\n",
1983 };
1984
1985 static struct ast_cli_entry cli_show_calls =
1986 { {"lcr", "show", "calls", NULL},
1987  lcr_show_calls,
1988  "Shows current calls made by LCR and Asterisk",
1989  "Usage: lcr show calls\n",
1990 };
1991
1992 static struct ast_cli_entry cli_reload_routing =
1993 { {"lcr", "reload", "routing", NULL},
1994  lcr_reload_routing,
1995  "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1996  "Usage: lcr reload routing\n",
1997 };
1998
1999 static struct ast_cli_entry cli_reload_interfaces =
2000 { {"lcr", "reload", "interfaces", NULL},
2001  lcr_reload_interfaces,
2002  "Reloads interfaces conf of LCR",
2003  "Usage: lcr reload interfaces\n",
2004 };
2005
2006 static struct ast_cli_entry cli_port_block =
2007 { {"lcr", "port", "block", NULL},
2008  lcr_port_block,
2009  "Blocks LCR port for further calls",
2010  "Usage: lcr port block \"<port>\"\n",
2011 };
2012
2013 static struct ast_cli_entry cli_port_unblock =
2014 { {"lcr", "port", "unblock", NULL},
2015  lcr_port_unblock,
2016  "Unblocks or loads LCR port, port is opened my mISDN",
2017  "Usage: lcr port unblock \"<port>\"\n",
2018 };
2019
2020 static struct ast_cli_entry cli_port_unload =
2021 { {"lcr", "port", "unload", NULL},
2022  lcr_port_unload,
2023  "Unloads LCR port, port is closes by mISDN",
2024  "Usage: lcr port unload \"<port>\"\n",
2025 };
2026 #endif
2027
2028
2029
2030 static int lcr_config_exec(struct ast_channel *chan, void *data)
2031 {
2032         //FIXME: add your aplication code here  
2033         // SEPERATOR ':'
2034         
2035         return 0;
2036 }
2037
2038 /*
2039  * module loading and destruction
2040  */
2041 int load_module(void)
2042 {
2043         u_short i;
2044
2045         for (i = 0; i < 256; i++) {
2046                 flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
2047                              | (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
2048         }
2049
2050         if (read_options() == 0) {
2051                 CERROR(NULL, NULL, "%s", options_error);
2052                 return AST_MODULE_LOAD_DECLINE;
2053         }
2054
2055         ast_mutex_init(&chan_lock);
2056         ast_mutex_init(&log_lock);
2057
2058         if (open_socket() < 0) {
2059                 /* continue with closed socket */
2060         }
2061
2062         if (bchannel_initialize()) {
2063                 CERROR(NULL, NULL, "Unable to open mISDN device\n");
2064                 close_socket();
2065                 return AST_MODULE_LOAD_DECLINE;
2066         }
2067         mISDN_created = 1;
2068
2069         lcr_tech.capabilities = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
2070         if (ast_channel_register(&lcr_tech)) {
2071                 CERROR(NULL, NULL, "Unable to register channel class\n");
2072                 bchannel_deinitialize();
2073                 close_socket();
2074                 return AST_MODULE_LOAD_DECLINE;
2075         }
2076
2077         ast_register_application("lcr_config", lcr_config_exec, "lcr_config",
2078                                  "lcr_config(:<opt><optarg>:<opt><optarg>..):\n"
2079                                  "Sets LCR opts. and optargs\n"
2080                                  "\n"
2081                                  "The available options are:\n"
2082                                  "    d - Send display text on called phone, text is the optparam\n"
2083                                  "    n - don't detect dtmf tones on called channel\n"
2084                                  "    h - make digital outgoing call\n" 
2085                                  "    c - make crypted outgoing call, param is keyindex\n"
2086                                  "    e - perform echo cancelation on this channel,\n"
2087                                  "        takes taps as arguments (32,64,128,256)\n"
2088                                  "    s - send Non Inband DTMF as inband\n"
2089                                  "   vr - rxgain control\n"
2090                                  "   vt - txgain control\n"
2091                 );
2092
2093  
2094 #if 0   
2095         ast_cli_register(&cli_show_lcr);
2096         ast_cli_register(&cli_show_calls);
2097
2098         ast_cli_register(&cli_reload_routing);
2099         ast_cli_register(&cli_reload_interfaces);
2100         ast_cli_register(&cli_port_block);
2101         ast_cli_register(&cli_port_unblock);
2102         ast_cli_register(&cli_port_unload);
2103   
2104         ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
2105                                  "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
2106                                  "Sets mISDN opts. and optargs\n"
2107                                  "\n"
2108                                  "The available options are:\n"
2109                                  "    d - Send display text on called phone, text is the optparam\n"
2110                                  "    n - don't detect dtmf tones on called channel\n"
2111                                  "    h - make digital outgoing call\n" 
2112                                  "    c - make crypted outgoing call, param is keyindex\n"
2113                                  "    e - perform echo cancelation on this channel,\n"
2114                                  "        takes taps as arguments (32,64,128,256)\n"
2115                                  "    s - send Non Inband DTMF as inband\n"
2116                                  "   vr - rxgain control\n"
2117                                  "   vt - txgain control\n"
2118                 );
2119
2120         
2121         lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2122
2123 =======
2124         //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2125 #endif
2126
2127         quit = 0;       
2128         if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
2129         {
2130                 /* failed to create thread */
2131                 bchannel_deinitialize();
2132                 close_socket();
2133                 ast_channel_unregister(&lcr_tech);
2134                 return AST_MODULE_LOAD_DECLINE;
2135         }
2136         return 0;
2137 }
2138
2139 int unload_module(void)
2140 {
2141         /* First, take us out of the channel loop */
2142         CDEBUG(NULL, NULL, "-- Unregistering mISDN Channel Driver --\n");
2143
2144         quit = 1;
2145         pthread_join(chan_tid, NULL);   
2146         
2147         ast_channel_unregister(&lcr_tech);
2148
2149         ast_unregister_application("lcr_config");
2150
2151
2152         if (mISDN_created) {
2153                 bchannel_deinitialize();
2154                 mISDN_created = 0;
2155         }
2156
2157         if (lcr_sock >= 0) {
2158                 close(lcr_sock);
2159                 lcr_sock = -1;
2160         }
2161
2162         return 0;
2163 }
2164
2165 int reload_module(void)
2166 {
2167 //      reload_config();
2168         return 0;
2169 }
2170
2171
2172 #define AST_MODULE "chan_lcr"
2173
2174 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for Linux-Call-Router Support (ISDN BRI/PRI)",
2175                 .load = load_module,
2176                 .unload = unload_module,
2177                 .reload = reload_module,
2178                );
2179