added option to change the connected party number dialplan (ton)
[asterisk/asterisk.git] / channels / misdn / isdn_msg_parser.c
1 /*
2  * Chan_Misdn -- Channel Driver for Asterisk
3  *
4  * Interface to mISDN
5  *
6  * Copyright (C) 2004, Christian Richter
7  *
8  * Christian Richter <crich@beronet.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14
15 #include "isdn_lib_intern.h"
16
17
18 #include "isdn_lib.h"
19
20 #include "ie.c"
21
22 #include "fac.h"
23
24
25 void set_channel(struct misdn_bchannel *bc, int channel) {
26
27         cb_log(3,bc->port,"set_channel: bc->channel:%d channel:%d\n", bc->channel, channel);
28         
29         
30         if (channel==0xff) {
31                 /* any channel */
32                 channel=-1;
33         }
34         
35         /*  ALERT: is that everytime true ?  */
36         if (channel > 0 && bc->nt ) {
37                 
38                 if (bc->channel && ( bc->channel != 0xff) ) {
39                         cb_log(0,bc->port,"We already have a channel (%d)\n", bc->channel);
40                 } else {
41                         bc->channel = channel;
42                 }
43         }
44         
45         if (channel > 0 && !bc->nt ) 
46                 bc->channel = channel;
47 }
48
49 void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
50 {
51         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
52         CALL_PROCEEDING_t *proceeding=(CALL_PROCEEDING_t*)((unsigned long)msg->data+ HEADER_LEN);
53         //struct misdn_stack *stack=get_stack_by_bc(bc);
54         
55         {
56                 int  exclusive, channel;
57                 dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)proceeding, &exclusive, &channel, nt,bc);
58
59                 set_channel(bc,channel);
60                 
61         }
62         
63         dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
64         
65         
66 #if DEBUG 
67         printf("Parsing PROCEEDING Msg\n"); 
68 #endif
69 }
70 msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
71 {
72         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
73         CALL_PROCEEDING_t *proceeding;
74         msg_t *msg =(msg_t*)create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING,  bc?bc->l3_id:-1, sizeof(CALL_PROCEEDING_t) ,nt); 
75   
76         proceeding=(CALL_PROCEEDING_t*)((msg->data+HEADER_LEN));
77
78         enc_ie_channel_id(&proceeding->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
79   
80         if (nt) 
81                 enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
82   
83
84 #if DEBUG 
85         printf("Building PROCEEDING Msg\n"); 
86 #endif
87         return msg; 
88 }
89
90 void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
91 {
92         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN; 
93         ALERTING_t *alerting=(ALERTING_t*)((unsigned long)(msg->data+HEADER_LEN));
94         //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
95         
96         dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
97         
98 #if DEBUG 
99         printf("Parsing ALERTING Msg\n"); 
100 #endif
101
102  
103 }
104 msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
105 {
106         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
107         ALERTING_t *alerting;
108         msg_t *msg =(msg_t*)create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING,  bc?bc->l3_id:-1, sizeof(ALERTING_t) ,nt); 
109   
110         alerting=(ALERTING_t*)((msg->data+HEADER_LEN)); 
111   
112         enc_ie_channel_id(&alerting->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
113         
114         if (nt) 
115                 enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
116 #if DEBUG 
117         printf("Building ALERTING Msg\n"); 
118 #endif
119         return msg; 
120 }
121
122
123 void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
124 {
125         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
126         PROGRESS_t *progress=(PROGRESS_t*)((unsigned long)(msg->data+HEADER_LEN)); 
127         //Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);  
128         
129         dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
130         
131 #if DEBUG 
132         printf("Parsing PROGRESS Msg\n"); 
133 #endif
134 }
135
136 msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
137 {
138         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
139         PROGRESS_t *progress;
140         msg_t *msg =(msg_t*)create_l3msg(CC_PROGRESS | REQUEST, MT_PROGRESS,  bc?bc->l3_id:-1, sizeof(PROGRESS_t) ,nt); 
141  
142         progress=(PROGRESS_t*)((msg->data+HEADER_LEN)); 
143
144 #if DEBUG 
145         printf("Building PROGRESS Msg\n"); 
146 #endif
147         return msg; 
148 }
149
150 void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
151
152         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
153         SETUP_t *setup= (SETUP_t*)((unsigned long)msg->data+HEADER_LEN);
154         Q931_info_t *qi=(Q931_info_t*)((unsigned long)msg->data+HEADER_LEN);
155
156 #if DEBUG 
157         printf("Parsing SETUP Msg\n"); 
158 #endif
159         {
160                 int type,plan,present, screen;
161                 char id[32];
162                 dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, (unsigned char *)id, sizeof(id), nt,bc);
163
164                 bc->onumplan=type; 
165                 strcpy(bc->oad, id);
166                 switch (present) {
167                 case 0:
168                         bc->pres=0; /* screened */
169                         break;
170                 case 1:
171                         bc->pres=1; /* not screened */
172                         break;
173                 default:
174                         bc->pres=0;
175                 }
176                 switch (screen) {
177                 case 0:
178                         break;
179                 default:
180                         ;
181                 } 
182         }
183         {
184                 int  type, plan;
185                 char number[32]; 
186                 dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *)setup, &type, &plan, (unsigned char *)number, sizeof(number), nt,bc);
187                 strcpy(bc->dad, number);
188                 bc->dnumplan=type; 
189         }
190         {
191                 char keypad[32];
192                 dec_ie_keypad(setup->KEYPAD, (Q931_info_t *)setup, (unsigned char *)keypad, sizeof(keypad), nt,bc);
193                 strcpy(bc->keypad, keypad);
194         }
195
196         {
197                 int  sending_complete;
198                 dec_ie_complete(setup->COMPLETE, (Q931_info_t *)setup, &sending_complete, nt,bc);
199         }
200   
201         {
202                 int  type, plan, present, screen, reason;
203                 char id[32]; 
204                 dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *)setup, &type, &plan, &present, &screen, &reason, (unsigned char *)id, sizeof(id), nt,bc);
205     
206                 strcpy(bc->rad, id);
207                 bc->rnumplan=type; 
208         }
209         {
210                 int  coding, capability, mode, rate, multi, user, async, urate, stopbits, dbits, parity;
211                 dec_ie_bearer(setup->BEARER, (Q931_info_t *)setup, &coding, &capability, &mode, &rate, &multi, &user, &async, &urate, &stopbits, &dbits, &parity, nt,bc);
212                 switch (capability) {
213                 case -1: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED; 
214                         break;
215                 case 0: bc->capability=INFO_CAPABILITY_SPEECH;
216                         break;
217                 case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
218                         bc->user1 = user;
219                         bc->urate = urate;
220                         
221                         bc->rate = rate;
222                         bc->mode = mode;
223                         break;
224                 case 9: bc->capability=INFO_CAPABILITY_DIGITAL_RESTRICTED;
225                         break;
226                 default:
227                         break;
228                 }
229                 
230                 switch(user) {
231                 case 2:
232                         bc->law=INFO_CODEC_ULAW;
233                         break;
234                 case 3:
235                         bc->law=INFO_CODEC_ALAW;
236                         break;
237                 default:
238                         bc->law=INFO_CODEC_ALAW;
239                         
240                 }
241                 
242                 bc->capability=capability; 
243         }
244         {
245                 int  exclusive, channel;
246                 dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)setup, &exclusive, &channel, nt,bc);
247                 
248                 set_channel(bc,channel);
249         }
250         
251         dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
252         
253 }
254
255 #define ANY_CHANNEL 0xff /* IE attribut for 'any channel' */
256 msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
257 {
258         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
259         SETUP_t *setup;
260         msg_t *msg =(msg_t*)create_l3msg(CC_SETUP | REQUEST, MT_SETUP,  bc?bc->l3_id:-1, sizeof(SETUP_t) ,nt); 
261   
262         setup=(SETUP_t*)((msg->data+HEADER_LEN)); 
263   
264         if (bc->channel == 0 || bc->channel == ANY_CHANNEL || bc->channel==-1)
265                 enc_ie_channel_id(&setup->CHANNEL_ID, msg, 0, bc->channel, nt,bc);
266         else 
267                 enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
268         
269         
270         {
271                 int type=bc->onumplan,plan=1,present=bc->pres,screen=bc->screen;
272                 enc_ie_calling_pn(&setup->CALLING_PN, msg, type, plan, present,
273                                   screen, bc->oad, nt, bc);
274         }
275   
276         {
277                 if (bc->dad[0])
278                         enc_ie_called_pn(&setup->CALLED_PN, msg, bc->dnumplan, 1, bc->dad, nt,bc);
279         }
280
281         {
282                 if (bc->rad[0])
283                         enc_ie_redir_nr(&setup->REDIR_NR, msg, 1, 1,  bc->pres, bc->screen, 0, bc->rad, nt,bc);
284         }
285
286         
287   
288         if (*bc->display) {
289                 enc_ie_display(&setup->DISPLAY, msg, bc->display, nt,bc);
290         }
291   
292         {
293                 int coding=0, capability, mode=0 /*  2 for packet ! */
294                         ,user, rate=0x10;
295
296                 switch (bc->law) {
297                 case INFO_CODEC_ULAW: user=2;
298                         break;
299                 case INFO_CODEC_ALAW: user=3;
300                         break;
301                 default:
302                         user=3;
303                 }
304                 
305                 switch (bc->capability) {
306                 case INFO_CAPABILITY_SPEECH: capability = 0;
307                         break;
308                 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
309                         user=-1;
310                         mode=bc->mode;
311                         rate=bc->rate;
312                         break;
313                 case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
314                         user=-1;
315                         break;
316                 default:
317                         capability=bc->capability; 
318                 }
319                 
320                 
321     
322                 enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
323         }
324   
325 #if DEBUG 
326         printf("Building SETUP Msg\n"); 
327 #endif
328         return msg; 
329 }
330
331 void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
332 {
333         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
334         CONNECT_t *connect=(CONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
335   
336         bc->ces = connect->ces;
337         bc->ces = connect->ces;
338
339         dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
340         
341 #if DEBUG 
342         printf("Parsing CONNECT Msg\n"); 
343 #endif
344 }
345 msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
346 {
347         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
348         CONNECT_t *connect;
349         msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt); 
350         
351         cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
352
353         connect=(CONNECT_t*)((msg->data+HEADER_LEN)); 
354
355         if (nt) {
356                 time_t now;
357                 time(&now);
358                 enc_ie_date(&connect->DATE, msg, now, nt,bc);
359         }
360   
361         {
362                 int type=bc->cpnnumplan, plan=1, present=2, screen=0;
363                 enc_ie_connected_pn(&connect->CONNECT_PN, msg, type,plan, present, screen, (unsigned char*) bc->dad , nt , bc);
364         }
365
366 #if DEBUG 
367         printf("Building CONNECT Msg\n"); 
368 #endif
369         return msg; 
370 }
371
372 void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
373 {
374         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
375         SETUP_ACKNOWLEDGE_t *setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((unsigned long)(msg->data+HEADER_LEN));
376
377         {
378                 int  exclusive, channel;
379                 dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
380
381
382                 set_channel(bc, channel);
383         }
384         
385         dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
386 #if DEBUG 
387         printf("Parsing SETUP_ACKNOWLEDGE Msg\n"); 
388 #endif
389
390  
391 }
392 msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
393 {
394         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
395         SETUP_ACKNOWLEDGE_t *setup_acknowledge;
396         msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt); 
397  
398         setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
399   
400         enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
401   
402         if (nt) 
403                 enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
404   
405 #if DEBUG 
406         printf("Building SETUP_ACKNOWLEDGE Msg\n"); 
407 #endif
408         return msg; 
409 }
410
411 void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
412 {
413 #if DEBUG 
414         printf("Parsing CONNECT_ACKNOWLEDGE Msg\n"); 
415 #endif
416
417  
418 }
419 msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
420 {
421         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
422         CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
423         msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt); 
424  
425         connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
426   
427         enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
428   
429 #if DEBUG 
430         printf("Building CONNECT_ACKNOWLEDGE Msg\n"); 
431 #endif
432         return msg; 
433 }
434
435 void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
436 {
437 #if DEBUG 
438         printf("Parsing USER_INFORMATION Msg\n"); 
439 #endif
440
441  
442 }
443 msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
444 {
445         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
446         USER_INFORMATION_t *user_information;
447         msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION,  bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt); 
448  
449         user_information=(USER_INFORMATION_t*)((msg->data+HEADER_LEN)); 
450
451 #if DEBUG 
452         printf("Building USER_INFORMATION Msg\n"); 
453 #endif
454         return msg; 
455 }
456
457 void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
458 {
459 #if DEBUG 
460         printf("Parsing SUSPEND_REJECT Msg\n"); 
461 #endif
462
463  
464 }
465 msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
466 {
467         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
468         SUSPEND_REJECT_t *suspend_reject;
469         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT,  bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt); 
470  
471         suspend_reject=(SUSPEND_REJECT_t*)((msg->data+HEADER_LEN)); 
472
473 #if DEBUG 
474         printf("Building SUSPEND_REJECT Msg\n"); 
475 #endif
476         return msg; 
477 }
478
479 void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
480 {
481 #if DEBUG 
482         printf("Parsing RESUME_REJECT Msg\n"); 
483 #endif
484
485  
486 }
487 msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
488 {
489         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
490         RESUME_REJECT_t *resume_reject;
491         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT,  bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt); 
492  
493         resume_reject=(RESUME_REJECT_t*)((msg->data+HEADER_LEN)); 
494
495 #if DEBUG 
496         printf("Building RESUME_REJECT Msg\n"); 
497 #endif
498         return msg; 
499 }
500
501 void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
502 {
503 #if DEBUG 
504         printf("Parsing HOLD Msg\n"); 
505 #endif
506
507  
508 }
509 msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
510 {
511         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
512         HOLD_t *hold;
513         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD,  bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt); 
514  
515         hold=(HOLD_t*)((msg->data+HEADER_LEN)); 
516
517 #if DEBUG 
518         printf("Building HOLD Msg\n"); 
519 #endif
520         return msg; 
521 }
522
523 void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
524 {
525 #if DEBUG 
526         printf("Parsing SUSPEND Msg\n"); 
527 #endif
528
529  
530 }
531 msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
532 {
533         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
534         SUSPEND_t *suspend;
535         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND,  bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt); 
536  
537         suspend=(SUSPEND_t*)((msg->data+HEADER_LEN)); 
538
539 #if DEBUG 
540         printf("Building SUSPEND Msg\n"); 
541 #endif
542         return msg; 
543 }
544
545 void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
546 {
547 #if DEBUG 
548         printf("Parsing RESUME Msg\n"); 
549 #endif
550
551  
552 }
553 msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
554 {
555         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
556         RESUME_t *resume;
557         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME,  bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt); 
558  
559         resume=(RESUME_t*)((msg->data+HEADER_LEN)); 
560
561 #if DEBUG 
562         printf("Building RESUME Msg\n"); 
563 #endif
564         return msg; 
565 }
566
567 void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
568 {
569 #if DEBUG 
570         printf("Parsing HOLD_ACKNOWLEDGE Msg\n"); 
571 #endif
572
573  
574 }
575 msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
576 {
577         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
578         HOLD_ACKNOWLEDGE_t *hold_acknowledge;
579         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt); 
580  
581         hold_acknowledge=(HOLD_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
582
583 #if DEBUG 
584         printf("Building HOLD_ACKNOWLEDGE Msg\n"); 
585 #endif
586         return msg; 
587 }
588
589 void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
590 {
591 #if DEBUG 
592         printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n"); 
593 #endif
594
595  
596 }
597 msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
598 {
599         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
600         SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
601         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt); 
602  
603         suspend_acknowledge=(SUSPEND_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
604
605 #if DEBUG 
606         printf("Building SUSPEND_ACKNOWLEDGE Msg\n"); 
607 #endif
608         return msg; 
609 }
610
611 void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
612 {
613 #if DEBUG 
614         printf("Parsing RESUME_ACKNOWLEDGE Msg\n"); 
615 #endif
616
617  
618 }
619 msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
620 {
621         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
622         RESUME_ACKNOWLEDGE_t *resume_acknowledge;
623         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt); 
624  
625         resume_acknowledge=(RESUME_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
626
627 #if DEBUG 
628         printf("Building RESUME_ACKNOWLEDGE Msg\n"); 
629 #endif
630         return msg; 
631 }
632
633 void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
634 {
635 #if DEBUG 
636         printf("Parsing HOLD_REJECT Msg\n"); 
637 #endif
638
639  
640 }
641 msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
642 {
643         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
644         HOLD_REJECT_t *hold_reject;
645         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT,  bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt); 
646  
647         hold_reject=(HOLD_REJECT_t*)((msg->data+HEADER_LEN)); 
648
649 #if DEBUG 
650         printf("Building HOLD_REJECT Msg\n"); 
651 #endif
652         return msg; 
653 }
654
655 void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
656 {
657 #if DEBUG 
658         printf("Parsing RETRIEVE Msg\n"); 
659 #endif
660
661  
662 }
663 msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
664 {
665         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
666         RETRIEVE_t *retrieve;
667         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt); 
668  
669         retrieve=(RETRIEVE_t*)((msg->data+HEADER_LEN)); 
670
671 #if DEBUG 
672         printf("Building RETRIEVE Msg\n"); 
673 #endif
674         return msg; 
675 }
676
677 void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
678 {
679 #if DEBUG 
680         printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n"); 
681 #endif
682
683  
684 }
685 msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
686 {
687         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
688         RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
689         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt); 
690  
691         retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
692
693         enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
694 #if DEBUG 
695         printf("Building RETRIEVE_ACKNOWLEDGE Msg\n"); 
696 #endif
697         return msg; 
698 }
699
700 void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
701 {
702 #if DEBUG 
703         printf("Parsing RETRIEVE_REJECT Msg\n"); 
704 #endif
705
706  
707 }
708 msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
709 {
710         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
711         RETRIEVE_REJECT_t *retrieve_reject;
712         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT,  bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt); 
713  
714         retrieve_reject=(RETRIEVE_REJECT_t*)((msg->data+HEADER_LEN)); 
715
716 #if DEBUG 
717         printf("Building RETRIEVE_REJECT Msg\n"); 
718 #endif
719         return msg; 
720 }
721
722 void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
723 {
724         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
725         DISCONNECT_t *disconnect=(DISCONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
726         int location;
727   
728         dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &bc->cause, nt,bc);
729
730         dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
731 #if DEBUG 
732         printf("Parsing DISCONNECT Msg\n"); 
733 #endif
734
735  
736 }
737 msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
738 {
739         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
740         DISCONNECT_t *disconnect;
741         msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT,  bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt); 
742         
743         disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN)); 
744         
745         enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
746         if (nt) enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt?1:5, 8 ,nt,bc);
747   
748 #if DEBUG 
749         printf("Building DISCONNECT Msg\n"); 
750 #endif
751         return msg; 
752 }
753
754 void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
755 {
756         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
757         RESTART_t *restart=(RESTART_t*)((unsigned long)(msg->data+HEADER_LEN));
758
759         struct misdn_stack *stack=get_stack_by_bc(bc);
760         
761 #if DEBUG 
762         printf("Parsing RESTART Msg\n");
763 #endif
764   
765         {
766                 int  exclusive, channel;
767                 dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &channel, nt,bc);
768                 if (channel==0xff) /* any channel */
769                         channel=-1;
770                 cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n");
771         }
772   
773  
774 }
775 msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
776 {
777         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
778         RESTART_t *restart;
779         msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART,  bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt); 
780  
781         restart=(RESTART_t*)((msg->data+HEADER_LEN)); 
782
783 #if DEBUG 
784         printf("Building RESTART Msg\n"); 
785 #endif
786         return msg; 
787 }
788
789 void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
790 {
791         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
792         RELEASE_t *release=(RELEASE_t*)((unsigned long)(msg->data+HEADER_LEN));
793         int location;
794   
795         dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &bc->cause, nt,bc);
796 #if DEBUG 
797         printf("Parsing RELEASE Msg\n"); 
798 #endif
799
800  
801 }
802 msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
803 {
804         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
805         RELEASE_t *release;
806         msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE,  bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt); 
807  
808         release=(RELEASE_t*)((msg->data+HEADER_LEN)); 
809   
810         if (bc->out_cause>= 0)
811                 enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
812   
813 #if DEBUG 
814         printf("Building RELEASE Msg\n"); 
815 #endif
816         return msg; 
817 }
818
819 void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
820 {
821         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
822         RELEASE_COMPLETE_t *release_complete=(RELEASE_COMPLETE_t*)((unsigned long)(msg->data+HEADER_LEN));
823         int location;
824         iframe_t *frm = (iframe_t*) msg->data;
825
826         struct misdn_stack *stack=get_stack_by_bc(bc);
827         mISDNuser_head_t *hh;
828         hh=(mISDNuser_head_t*)msg->data;
829
830         /*hh=(mISDN_head_t*)msg->data;
831         mISDN_head_t *hh;*/
832
833         if (nt) {
834                 if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
835                         cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
836                         return;
837                 }
838         } else {
839                 if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
840                         cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
841                         return;
842                 }
843         }
844         dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &bc->cause, nt,bc);
845
846 #if DEBUG 
847         printf("Parsing RELEASE_COMPLETE Msg\n"); 
848 #endif
849 }
850
851 msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
852 {
853         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
854         RELEASE_COMPLETE_t *release_complete;
855         msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE,  bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt); 
856  
857         release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN)); 
858         
859         enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
860   
861 #if DEBUG 
862         printf("Building RELEASE_COMPLETE Msg\n"); 
863 #endif
864         return msg; 
865 }
866
867 void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
868 {
869         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
870         FACILITY_t *facility=(FACILITY_t*)((unsigned long)(msg->data+HEADER_LEN)); 
871         Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);  
872
873 #if DEBUG 
874         printf("Parsing FACILITY Msg\n"); 
875 #endif
876
877         {
878                 fac_dec(facility->FACILITY, qi, &bc->fac_type, &bc->fac, bc);
879         }
880 }
881
882 msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
883 {
884         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
885         FACILITY_t *facility;
886         msg_t *msg =(msg_t*)create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY,  bc?bc->l3_id:-1, sizeof(FACILITY_t) ,nt); 
887  
888         facility=(FACILITY_t*)((msg->data+HEADER_LEN)); 
889
890         {
891                 if (*bc->display) {
892                         printf("Sending %s as Display\n", bc->display);
893                         enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
894                 }
895                 
896                 
897                 fac_enc(&facility->FACILITY, msg, bc->out_fac_type, bc->out_fac,  bc);
898                 
899         }
900         
901 #if DEBUG 
902         printf("Building FACILITY Msg\n"); 
903 #endif
904         return msg; 
905 }
906
907 void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
908 {
909 #if DEBUG 
910         printf("Parsing NOTIFY Msg\n"); 
911 #endif
912 }
913
914 msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
915 {
916         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
917         NOTIFY_t *notify;
918         msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY,  bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt); 
919  
920         notify=(NOTIFY_t*)((msg->data+HEADER_LEN)); 
921
922 #if DEBUG 
923         printf("Building NOTIFY Msg\n"); 
924 #endif
925         return msg; 
926 }
927
928 void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
929 {
930 #if DEBUG 
931         printf("Parsing STATUS_ENQUIRY Msg\n"); 
932 #endif
933 }
934
935 msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
936 {
937         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
938         STATUS_ENQUIRY_t *status_enquiry;
939         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY,  bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt); 
940  
941         status_enquiry=(STATUS_ENQUIRY_t*)((msg->data+HEADER_LEN)); 
942
943 #if DEBUG 
944         printf("Building STATUS_ENQUIRY Msg\n"); 
945 #endif
946         return msg; 
947 }
948
949 void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
950 {
951         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
952         INFORMATION_t *information=(INFORMATION_t*)((unsigned long)(msg->data+HEADER_LEN));
953         {
954                 int  type, plan;
955                 char number[32];
956                 char keypad[32];
957                 dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)information, &type, &plan, (unsigned char *)number, sizeof(number), nt, bc);
958                 dec_ie_keypad(information->KEYPAD, (Q931_info_t *)information, (unsigned char *)keypad, sizeof(keypad), nt, bc);
959                 strcpy(bc->info_dad, number);
960                 strcpy(bc->keypad,keypad);
961         }
962 #if DEBUG 
963         printf("Parsing INFORMATION Msg\n"); 
964 #endif
965 }
966
967 msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
968 {
969         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
970         INFORMATION_t *information;
971         msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION,  bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt); 
972  
973         information=(INFORMATION_t*)((msg->data+HEADER_LEN)); 
974   
975         {
976                 enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
977         }
978
979         {
980                 if (*bc->display) {
981                         printf("Sending %s as Display\n", bc->display);
982                         enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
983                 }
984         }
985   
986 #if DEBUG 
987         printf("Building INFORMATION Msg\n"); 
988 #endif
989         return msg; 
990 }
991
992 void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
993 {
994         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
995         STATUS_t *status=(STATUS_t*)((unsigned long)(msg->data+HEADER_LEN));
996         int location;
997   
998         dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &bc->cause, nt,bc);
999         ;
1000
1001 #if DEBUG 
1002         printf("Parsing STATUS Msg\n"); 
1003 #endif
1004 }
1005
1006 msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
1007 {
1008         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1009         STATUS_t *status;
1010         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt); 
1011  
1012         status=(STATUS_t*)((msg->data+HEADER_LEN)); 
1013
1014 #if DEBUG 
1015         printf("Building STATUS Msg\n"); 
1016 #endif
1017         return msg; 
1018 }
1019
1020 void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
1021 {
1022 #if DEBUG 
1023         printf("Parsing STATUS Msg\n"); 
1024 #endif 
1025 }
1026
1027 msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
1028 {
1029         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1030         STATUS_t *status;
1031         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt); 
1032  
1033         status=(STATUS_t*)((msg->data+HEADER_LEN)); 
1034
1035 #if DEBUG 
1036         printf("Building STATUS Msg\n"); 
1037 #endif
1038         return msg; 
1039 }
1040
1041
1042 /************************************/
1043
1044
1045
1046
1047 /** Msg Array **/
1048
1049 struct isdn_msg msgs_g[] = {
1050         {CC_PROCEEDING,L3,EVENT_PROCEEDING,
1051          parse_proceeding,build_proceeding,
1052          "PROCEEDING"},
1053         {CC_ALERTING,L3,EVENT_ALERTING,
1054          parse_alerting,build_alerting,
1055          "ALERTING"},
1056         {CC_PROGRESS,L3,EVENT_PROGRESS,
1057          parse_progress,build_progress,
1058          "PROGRESS"},
1059         {CC_SETUP,L3,EVENT_SETUP,
1060          parse_setup,build_setup,
1061          "SETUP"},
1062         {CC_CONNECT,L3,EVENT_CONNECT,
1063          parse_connect,build_connect,
1064          "CONNECT"},
1065         {CC_SETUP_ACKNOWLEDGE,L3,EVENT_SETUP_ACKNOWLEDGE,
1066          parse_setup_acknowledge,build_setup_acknowledge,
1067          "SETUP_ACKNOWLEDGE"},
1068         {CC_CONNECT_ACKNOWLEDGE ,L3,EVENT_CONNECT_ACKNOWLEDGE ,
1069          parse_connect_acknowledge ,build_connect_acknowledge,
1070          "CONNECT_ACKNOWLEDGE "},
1071         {CC_USER_INFORMATION,L3,EVENT_USER_INFORMATION,
1072          parse_user_information,build_user_information,
1073          "USER_INFORMATION"},
1074         {CC_SUSPEND_REJECT,L3,EVENT_SUSPEND_REJECT,
1075          parse_suspend_reject,build_suspend_reject,
1076          "SUSPEND_REJECT"},
1077         {CC_RESUME_REJECT,L3,EVENT_RESUME_REJECT,
1078          parse_resume_reject,build_resume_reject,
1079          "RESUME_REJECT"},
1080         {CC_HOLD,L3,EVENT_HOLD,
1081          parse_hold,build_hold,
1082          "HOLD"},
1083         {CC_SUSPEND,L3,EVENT_SUSPEND,
1084          parse_suspend,build_suspend,
1085          "SUSPEND"},
1086         {CC_RESUME,L3,EVENT_RESUME,
1087          parse_resume,build_resume,
1088          "RESUME"},
1089         {CC_HOLD_ACKNOWLEDGE,L3,EVENT_HOLD_ACKNOWLEDGE,
1090          parse_hold_acknowledge,build_hold_acknowledge,
1091          "HOLD_ACKNOWLEDGE"},
1092         {CC_SUSPEND_ACKNOWLEDGE,L3,EVENT_SUSPEND_ACKNOWLEDGE,
1093          parse_suspend_acknowledge,build_suspend_acknowledge,
1094          "SUSPEND_ACKNOWLEDGE"},
1095         {CC_RESUME_ACKNOWLEDGE,L3,EVENT_RESUME_ACKNOWLEDGE,
1096          parse_resume_acknowledge,build_resume_acknowledge,
1097          "RESUME_ACKNOWLEDGE"},
1098         {CC_HOLD_REJECT,L3,EVENT_HOLD_REJECT,
1099          parse_hold_reject,build_hold_reject,
1100          "HOLD_REJECT"},
1101         {CC_RETRIEVE,L3,EVENT_RETRIEVE,
1102          parse_retrieve,build_retrieve,
1103          "RETRIEVE"},
1104         {CC_RETRIEVE_ACKNOWLEDGE,L3,EVENT_RETRIEVE_ACKNOWLEDGE,
1105          parse_retrieve_acknowledge,build_retrieve_acknowledge,
1106          "RETRIEVE_ACKNOWLEDGE"},
1107         {CC_RETRIEVE_REJECT,L3,EVENT_RETRIEVE_REJECT,
1108          parse_retrieve_reject,build_retrieve_reject,
1109          "RETRIEVE_REJECT"},
1110         {CC_DISCONNECT,L3,EVENT_DISCONNECT,
1111          parse_disconnect,build_disconnect,
1112          "DISCONNECT"},
1113         {CC_RESTART,L3,EVENT_RESTART,
1114          parse_restart,build_restart,
1115          "RESTART"},
1116         {CC_RELEASE,L3,EVENT_RELEASE,
1117          parse_release,build_release,
1118          "RELEASE"},
1119         {CC_RELEASE_COMPLETE,L3,EVENT_RELEASE_COMPLETE,
1120          parse_release_complete,build_release_complete,
1121          "RELEASE_COMPLETE"},
1122         {CC_FACILITY,L3,EVENT_FACILITY,
1123          parse_facility,build_facility,
1124          "FACILITY"},
1125         {CC_NOTIFY,L3,EVENT_NOTIFY,
1126          parse_notify,build_notify,
1127          "NOTIFY"},
1128         {CC_STATUS_ENQUIRY,L3,EVENT_STATUS_ENQUIRY,
1129          parse_status_enquiry,build_status_enquiry,
1130          "STATUS_ENQUIRY"},
1131         {CC_INFORMATION,L3,EVENT_INFORMATION,
1132          parse_information,build_information,
1133          "INFORMATION"},
1134         {CC_STATUS,L3,EVENT_STATUS,
1135          parse_status,build_status,
1136          "STATUS"},
1137         {CC_TIMEOUT,L3,EVENT_TIMEOUT,
1138          parse_timeout,build_timeout,
1139          "TIMEOUT"},
1140         {0,0,0,NULL,NULL,NULL}
1141 };
1142
1143 #define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
1144
1145 /** INTERFACE FCTS ***/
1146 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
1147 {
1148         int i;
1149
1150         if (nt){
1151                 mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
1152                 
1153                 for (i=0; i< msgs_max -1; i++) {
1154                         if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
1155                 }
1156                 
1157         } else {
1158                 iframe_t *frm = (iframe_t*)msg->data;
1159     
1160                 for (i=0; i< msgs_max -1; i++) 
1161                         if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
1162         }
1163
1164         return -1;
1165 }
1166
1167 int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
1168 {
1169         int i;
1170         for (i=0; i< msgs_max; i++) 
1171                 if ( event == msgs[i].event) return i;
1172
1173         cb_log(10,0, "get_index: event not found!\n");
1174         
1175         return -1;
1176 }
1177
1178 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
1179 {
1180         int i=isdn_msg_get_index(msgs, msg, nt);
1181         if(i>=0) return msgs[i].event;
1182         return EVENT_UNKNOWN;
1183 }
1184
1185 char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
1186 {
1187         int i=isdn_msg_get_index(msgs, msg, nt);
1188         if(i>=0) return msgs[i].info;
1189         return NULL;
1190 }
1191
1192
1193 char EVENT_CLEAN_INFO[] = "CLEAN_UP";
1194 char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
1195 char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
1196 char EVENT_NEW_BC_INFO[] = "NEW_BC";
1197 char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
1198 char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
1199 char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
1200
1201 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
1202 {
1203         int i=isdn_msg_get_index_by_event(msgs, event, nt);
1204         
1205         if(i>=0) return msgs[i].info;
1206         
1207         if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
1208         if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
1209         if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
1210         if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
1211         if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
1212         if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
1213         if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
1214         
1215         return NULL;
1216 }
1217
1218 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
1219 {
1220         int i=isdn_msg_get_index(msgs, msg, nt);
1221         if(i<0) return -1;
1222
1223         msgs[i].msg_parser(msgs, msg, bc, nt);
1224         return 0;
1225 }
1226
1227 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
1228 {
1229         int i=isdn_msg_get_index_by_event(msgs, event, nt);
1230         if(i<0) return NULL;
1231   
1232         return  msgs[i].msg_builder(msgs, bc, nt);
1233 }
1234