4935deefac50213d0abd9bb2953adeea6929b155
[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         if (*bc->display) {
282                 enc_ie_display(&setup->DISPLAY, msg, bc->display, nt,bc);
283         }
284   
285         {
286                 int coding=0, capability, mode=0 /*  2 for packet ! */
287                         ,user, rate=0x10;
288
289                 switch (bc->law) {
290                 case INFO_CODEC_ULAW: user=2;
291                         break;
292                 case INFO_CODEC_ALAW: user=3;
293                         break;
294                 default:
295                         user=3;
296                 }
297                 
298                 switch (bc->capability) {
299                 case INFO_CAPABILITY_SPEECH: capability = 0;
300                         break;
301                 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
302                         user=-1;
303                         mode=bc->mode;
304                         rate=bc->rate;
305                         break;
306                 case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
307                         user=-1;
308                         break;
309                 default:
310                         capability=bc->capability; 
311                 }
312                 
313                 
314     
315                 enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
316         }
317   
318 #if DEBUG 
319         printf("Building SETUP Msg\n"); 
320 #endif
321         return msg; 
322 }
323
324 void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
325 {
326         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
327         CONNECT_t *connect=(CONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
328   
329         bc->ces = connect->ces;
330         bc->ces = connect->ces;
331
332         dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
333         
334 #if DEBUG 
335         printf("Parsing CONNECT Msg\n"); 
336 #endif
337 }
338 msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
339 {
340         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
341         CONNECT_t *connect;
342         msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt); 
343         
344         cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
345
346         connect=(CONNECT_t*)((msg->data+HEADER_LEN)); 
347
348         if (nt) {
349                 time_t now;
350                 time(&now);
351                 enc_ie_date(&connect->DATE, msg, now, nt,bc);
352         }
353   
354         {
355                 int type=0, plan=1, present=2, screen=0;
356                 enc_ie_connected_pn(&connect->CONNECT_PN, msg, type,plan, present, screen, (unsigned char*) bc->dad , nt , bc);
357         }
358
359 #if DEBUG 
360         printf("Building CONNECT Msg\n"); 
361 #endif
362         return msg; 
363 }
364
365 void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
366 {
367         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
368         SETUP_ACKNOWLEDGE_t *setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((unsigned long)(msg->data+HEADER_LEN));
369
370         {
371                 int  exclusive, channel;
372                 dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
373
374
375                 set_channel(bc, channel);
376         }
377         
378         dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
379 #if DEBUG 
380         printf("Parsing SETUP_ACKNOWLEDGE Msg\n"); 
381 #endif
382
383  
384 }
385 msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
386 {
387         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
388         SETUP_ACKNOWLEDGE_t *setup_acknowledge;
389         msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt); 
390  
391         setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
392   
393         enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
394   
395         if (nt) 
396                 enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
397   
398 #if DEBUG 
399         printf("Building SETUP_ACKNOWLEDGE Msg\n"); 
400 #endif
401         return msg; 
402 }
403
404 void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
405 {
406 #if DEBUG 
407         printf("Parsing CONNECT_ACKNOWLEDGE Msg\n"); 
408 #endif
409
410  
411 }
412 msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
413 {
414         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
415         CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
416         msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT,  bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt); 
417  
418         connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
419   
420         enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
421   
422 #if DEBUG 
423         printf("Building CONNECT_ACKNOWLEDGE Msg\n"); 
424 #endif
425         return msg; 
426 }
427
428 void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
429 {
430 #if DEBUG 
431         printf("Parsing USER_INFORMATION Msg\n"); 
432 #endif
433
434  
435 }
436 msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
437 {
438         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
439         USER_INFORMATION_t *user_information;
440         msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION,  bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt); 
441  
442         user_information=(USER_INFORMATION_t*)((msg->data+HEADER_LEN)); 
443
444 #if DEBUG 
445         printf("Building USER_INFORMATION Msg\n"); 
446 #endif
447         return msg; 
448 }
449
450 void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
451 {
452 #if DEBUG 
453         printf("Parsing SUSPEND_REJECT Msg\n"); 
454 #endif
455
456  
457 }
458 msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
459 {
460         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
461         SUSPEND_REJECT_t *suspend_reject;
462         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT,  bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt); 
463  
464         suspend_reject=(SUSPEND_REJECT_t*)((msg->data+HEADER_LEN)); 
465
466 #if DEBUG 
467         printf("Building SUSPEND_REJECT Msg\n"); 
468 #endif
469         return msg; 
470 }
471
472 void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
473 {
474 #if DEBUG 
475         printf("Parsing RESUME_REJECT Msg\n"); 
476 #endif
477
478  
479 }
480 msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
481 {
482         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
483         RESUME_REJECT_t *resume_reject;
484         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT,  bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt); 
485  
486         resume_reject=(RESUME_REJECT_t*)((msg->data+HEADER_LEN)); 
487
488 #if DEBUG 
489         printf("Building RESUME_REJECT Msg\n"); 
490 #endif
491         return msg; 
492 }
493
494 void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
495 {
496 #if DEBUG 
497         printf("Parsing HOLD Msg\n"); 
498 #endif
499
500  
501 }
502 msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
503 {
504         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
505         HOLD_t *hold;
506         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD,  bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt); 
507  
508         hold=(HOLD_t*)((msg->data+HEADER_LEN)); 
509
510 #if DEBUG 
511         printf("Building HOLD Msg\n"); 
512 #endif
513         return msg; 
514 }
515
516 void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
517 {
518 #if DEBUG 
519         printf("Parsing SUSPEND Msg\n"); 
520 #endif
521
522  
523 }
524 msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
525 {
526         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
527         SUSPEND_t *suspend;
528         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND,  bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt); 
529  
530         suspend=(SUSPEND_t*)((msg->data+HEADER_LEN)); 
531
532 #if DEBUG 
533         printf("Building SUSPEND Msg\n"); 
534 #endif
535         return msg; 
536 }
537
538 void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
539 {
540 #if DEBUG 
541         printf("Parsing RESUME Msg\n"); 
542 #endif
543
544  
545 }
546 msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
547 {
548         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
549         RESUME_t *resume;
550         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME,  bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt); 
551  
552         resume=(RESUME_t*)((msg->data+HEADER_LEN)); 
553
554 #if DEBUG 
555         printf("Building RESUME Msg\n"); 
556 #endif
557         return msg; 
558 }
559
560 void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
561 {
562 #if DEBUG 
563         printf("Parsing HOLD_ACKNOWLEDGE Msg\n"); 
564 #endif
565
566  
567 }
568 msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
569 {
570         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
571         HOLD_ACKNOWLEDGE_t *hold_acknowledge;
572         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt); 
573  
574         hold_acknowledge=(HOLD_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
575
576 #if DEBUG 
577         printf("Building HOLD_ACKNOWLEDGE Msg\n"); 
578 #endif
579         return msg; 
580 }
581
582 void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
583 {
584 #if DEBUG 
585         printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n"); 
586 #endif
587
588  
589 }
590 msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
591 {
592         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
593         SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
594         msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt); 
595  
596         suspend_acknowledge=(SUSPEND_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
597
598 #if DEBUG 
599         printf("Building SUSPEND_ACKNOWLEDGE Msg\n"); 
600 #endif
601         return msg; 
602 }
603
604 void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
605 {
606 #if DEBUG 
607         printf("Parsing RESUME_ACKNOWLEDGE Msg\n"); 
608 #endif
609
610  
611 }
612 msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
613 {
614         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
615         RESUME_ACKNOWLEDGE_t *resume_acknowledge;
616         msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt); 
617  
618         resume_acknowledge=(RESUME_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
619
620 #if DEBUG 
621         printf("Building RESUME_ACKNOWLEDGE Msg\n"); 
622 #endif
623         return msg; 
624 }
625
626 void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
627 {
628 #if DEBUG 
629         printf("Parsing HOLD_REJECT Msg\n"); 
630 #endif
631
632  
633 }
634 msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
635 {
636         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
637         HOLD_REJECT_t *hold_reject;
638         msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT,  bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt); 
639  
640         hold_reject=(HOLD_REJECT_t*)((msg->data+HEADER_LEN)); 
641
642 #if DEBUG 
643         printf("Building HOLD_REJECT Msg\n"); 
644 #endif
645         return msg; 
646 }
647
648 void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
649 {
650 #if DEBUG 
651         printf("Parsing RETRIEVE Msg\n"); 
652 #endif
653
654  
655 }
656 msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
657 {
658         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
659         RETRIEVE_t *retrieve;
660         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt); 
661  
662         retrieve=(RETRIEVE_t*)((msg->data+HEADER_LEN)); 
663
664 #if DEBUG 
665         printf("Building RETRIEVE Msg\n"); 
666 #endif
667         return msg; 
668 }
669
670 void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
671 {
672 #if DEBUG 
673         printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n"); 
674 #endif
675
676  
677 }
678 msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
679 {
680         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
681         RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
682         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE,  bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt); 
683  
684         retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN)); 
685
686         enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
687 #if DEBUG 
688         printf("Building RETRIEVE_ACKNOWLEDGE Msg\n"); 
689 #endif
690         return msg; 
691 }
692
693 void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
694 {
695 #if DEBUG 
696         printf("Parsing RETRIEVE_REJECT Msg\n"); 
697 #endif
698
699  
700 }
701 msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
702 {
703         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
704         RETRIEVE_REJECT_t *retrieve_reject;
705         msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT,  bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt); 
706  
707         retrieve_reject=(RETRIEVE_REJECT_t*)((msg->data+HEADER_LEN)); 
708
709 #if DEBUG 
710         printf("Building RETRIEVE_REJECT Msg\n"); 
711 #endif
712         return msg; 
713 }
714
715 void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
716 {
717         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
718         DISCONNECT_t *disconnect=(DISCONNECT_t*)((unsigned long)(msg->data+HEADER_LEN));
719         int location;
720   
721         dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &bc->cause, nt,bc);
722
723         dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
724 #if DEBUG 
725         printf("Parsing DISCONNECT Msg\n"); 
726 #endif
727
728  
729 }
730 msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
731 {
732         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
733         DISCONNECT_t *disconnect;
734         msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT,  bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt); 
735         
736         disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN)); 
737         
738         enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
739         if (nt) enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt?1:5, 8 ,nt,bc);
740   
741 #if DEBUG 
742         printf("Building DISCONNECT Msg\n"); 
743 #endif
744         return msg; 
745 }
746
747 void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
748 {
749         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
750         RESTART_t *restart=(RESTART_t*)((unsigned long)(msg->data+HEADER_LEN));
751
752         struct misdn_stack *stack=get_stack_by_bc(bc);
753         
754 #if DEBUG 
755         printf("Parsing RESTART Msg\n");
756 #endif
757   
758         {
759                 int  exclusive, channel;
760                 dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &channel, nt,bc);
761                 if (channel==0xff) /* any channel */
762                         channel=-1;
763                 cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n");
764         }
765   
766  
767 }
768 msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
769 {
770         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
771         RESTART_t *restart;
772         msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART,  bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt); 
773  
774         restart=(RESTART_t*)((msg->data+HEADER_LEN)); 
775
776 #if DEBUG 
777         printf("Building RESTART Msg\n"); 
778 #endif
779         return msg; 
780 }
781
782 void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
783 {
784         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
785         RELEASE_t *release=(RELEASE_t*)((unsigned long)(msg->data+HEADER_LEN));
786         int location;
787   
788         dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &bc->cause, nt,bc);
789 #if DEBUG 
790         printf("Parsing RELEASE Msg\n"); 
791 #endif
792
793  
794 }
795 msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
796 {
797         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
798         RELEASE_t *release;
799         msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE,  bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt); 
800  
801         release=(RELEASE_t*)((msg->data+HEADER_LEN)); 
802   
803         if (bc->out_cause>= 0)
804                 enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
805   
806 #if DEBUG 
807         printf("Building RELEASE Msg\n"); 
808 #endif
809         return msg; 
810 }
811
812 void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
813 {
814         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
815         RELEASE_COMPLETE_t *release_complete=(RELEASE_COMPLETE_t*)((unsigned long)(msg->data+HEADER_LEN));
816         int location;
817         iframe_t *frm = (iframe_t*) msg->data;
818
819         struct misdn_stack *stack=get_stack_by_bc(bc);
820         mISDNuser_head_t *hh;
821         hh=(mISDNuser_head_t*)msg->data;
822
823         /*hh=(mISDN_head_t*)msg->data;
824         mISDN_head_t *hh;*/
825
826         if (nt) {
827                 if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
828                         cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
829                         return;
830                 }
831         } else {
832                 if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
833                         cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
834                         return;
835                 }
836         }
837         dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &bc->cause, nt,bc);
838
839 #if DEBUG 
840         printf("Parsing RELEASE_COMPLETE Msg\n"); 
841 #endif
842 }
843
844 msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
845 {
846         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
847         RELEASE_COMPLETE_t *release_complete;
848         msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE,  bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt); 
849  
850         release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN)); 
851         
852         enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
853   
854 #if DEBUG 
855         printf("Building RELEASE_COMPLETE Msg\n"); 
856 #endif
857         return msg; 
858 }
859
860 void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
861 {
862         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
863         FACILITY_t *facility=(FACILITY_t*)((unsigned long)(msg->data+HEADER_LEN)); 
864         Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);  
865
866 #if DEBUG 
867         printf("Parsing FACILITY Msg\n"); 
868 #endif
869
870         {
871                 fac_dec(facility->FACILITY, qi, &bc->fac_type, &bc->fac, bc);
872         }
873 }
874
875 msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
876 {
877         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
878         FACILITY_t *facility;
879         msg_t *msg =(msg_t*)create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY,  bc?bc->l3_id:-1, sizeof(FACILITY_t) ,nt); 
880  
881         facility=(FACILITY_t*)((msg->data+HEADER_LEN)); 
882
883         {
884                 if (*bc->display) {
885                         printf("Sending %s as Display\n", bc->display);
886                         enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
887                 }
888                 
889                 
890                 fac_enc(&facility->FACILITY, msg, bc->out_fac_type, bc->out_fac,  bc);
891                 
892         }
893         
894 #if DEBUG 
895         printf("Building FACILITY Msg\n"); 
896 #endif
897         return msg; 
898 }
899
900 void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
901 {
902 #if DEBUG 
903         printf("Parsing NOTIFY Msg\n"); 
904 #endif
905 }
906
907 msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
908 {
909         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
910         NOTIFY_t *notify;
911         msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY,  bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt); 
912  
913         notify=(NOTIFY_t*)((msg->data+HEADER_LEN)); 
914
915 #if DEBUG 
916         printf("Building NOTIFY Msg\n"); 
917 #endif
918         return msg; 
919 }
920
921 void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
922 {
923 #if DEBUG 
924         printf("Parsing STATUS_ENQUIRY Msg\n"); 
925 #endif
926 }
927
928 msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
929 {
930         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
931         STATUS_ENQUIRY_t *status_enquiry;
932         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY,  bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt); 
933  
934         status_enquiry=(STATUS_ENQUIRY_t*)((msg->data+HEADER_LEN)); 
935
936 #if DEBUG 
937         printf("Building STATUS_ENQUIRY Msg\n"); 
938 #endif
939         return msg; 
940 }
941
942 void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
943 {
944         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
945         INFORMATION_t *information=(INFORMATION_t*)((unsigned long)(msg->data+HEADER_LEN));
946         {
947                 int  type, plan;
948                 char number[32];
949                 char keypad[32];
950                 dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *)information, &type, &plan, (unsigned char *)number, sizeof(number), nt, bc);
951                 dec_ie_keypad(information->KEYPAD, (Q931_info_t *)information, (unsigned char *)keypad, sizeof(keypad), nt, bc);
952                 strcpy(bc->info_dad, number);
953                 strcpy(bc->keypad,keypad);
954         }
955 #if DEBUG 
956         printf("Parsing INFORMATION Msg\n"); 
957 #endif
958 }
959
960 msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
961 {
962         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
963         INFORMATION_t *information;
964         msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION,  bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt); 
965  
966         information=(INFORMATION_t*)((msg->data+HEADER_LEN)); 
967   
968         {
969                 enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
970         }
971
972         {
973                 if (*bc->display) {
974                         printf("Sending %s as Display\n", bc->display);
975                         enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
976                 }
977         }
978   
979 #if DEBUG 
980         printf("Building INFORMATION Msg\n"); 
981 #endif
982         return msg; 
983 }
984
985 void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
986 {
987         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
988         STATUS_t *status=(STATUS_t*)((unsigned long)(msg->data+HEADER_LEN));
989         int location;
990   
991         dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &bc->cause, nt,bc);
992         ;
993
994 #if DEBUG 
995         printf("Parsing STATUS Msg\n"); 
996 #endif
997 }
998
999 msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
1000 {
1001         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1002         STATUS_t *status;
1003         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt); 
1004  
1005         status=(STATUS_t*)((msg->data+HEADER_LEN)); 
1006
1007 #if DEBUG 
1008         printf("Building STATUS Msg\n"); 
1009 #endif
1010         return msg; 
1011 }
1012
1013 void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt) 
1014 {
1015 #if DEBUG 
1016         printf("Parsing STATUS Msg\n"); 
1017 #endif 
1018 }
1019
1020 msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt) 
1021 {
1022         int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
1023         STATUS_t *status;
1024         msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS,  bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt); 
1025  
1026         status=(STATUS_t*)((msg->data+HEADER_LEN)); 
1027
1028 #if DEBUG 
1029         printf("Building STATUS Msg\n"); 
1030 #endif
1031         return msg; 
1032 }
1033
1034
1035 /************************************/
1036
1037
1038
1039
1040 /** Msg Array **/
1041
1042 struct isdn_msg msgs_g[] = {
1043         {CC_PROCEEDING,L3,EVENT_PROCEEDING,
1044          parse_proceeding,build_proceeding,
1045          "PROCEEDING"},
1046         {CC_ALERTING,L3,EVENT_ALERTING,
1047          parse_alerting,build_alerting,
1048          "ALERTING"},
1049         {CC_PROGRESS,L3,EVENT_PROGRESS,
1050          parse_progress,build_progress,
1051          "PROGRESS"},
1052         {CC_SETUP,L3,EVENT_SETUP,
1053          parse_setup,build_setup,
1054          "SETUP"},
1055         {CC_CONNECT,L3,EVENT_CONNECT,
1056          parse_connect,build_connect,
1057          "CONNECT"},
1058         {CC_SETUP_ACKNOWLEDGE,L3,EVENT_SETUP_ACKNOWLEDGE,
1059          parse_setup_acknowledge,build_setup_acknowledge,
1060          "SETUP_ACKNOWLEDGE"},
1061         {CC_CONNECT_ACKNOWLEDGE ,L3,EVENT_CONNECT_ACKNOWLEDGE ,
1062          parse_connect_acknowledge ,build_connect_acknowledge,
1063          "CONNECT_ACKNOWLEDGE "},
1064         {CC_USER_INFORMATION,L3,EVENT_USER_INFORMATION,
1065          parse_user_information,build_user_information,
1066          "USER_INFORMATION"},
1067         {CC_SUSPEND_REJECT,L3,EVENT_SUSPEND_REJECT,
1068          parse_suspend_reject,build_suspend_reject,
1069          "SUSPEND_REJECT"},
1070         {CC_RESUME_REJECT,L3,EVENT_RESUME_REJECT,
1071          parse_resume_reject,build_resume_reject,
1072          "RESUME_REJECT"},
1073         {CC_HOLD,L3,EVENT_HOLD,
1074          parse_hold,build_hold,
1075          "HOLD"},
1076         {CC_SUSPEND,L3,EVENT_SUSPEND,
1077          parse_suspend,build_suspend,
1078          "SUSPEND"},
1079         {CC_RESUME,L3,EVENT_RESUME,
1080          parse_resume,build_resume,
1081          "RESUME"},
1082         {CC_HOLD_ACKNOWLEDGE,L3,EVENT_HOLD_ACKNOWLEDGE,
1083          parse_hold_acknowledge,build_hold_acknowledge,
1084          "HOLD_ACKNOWLEDGE"},
1085         {CC_SUSPEND_ACKNOWLEDGE,L3,EVENT_SUSPEND_ACKNOWLEDGE,
1086          parse_suspend_acknowledge,build_suspend_acknowledge,
1087          "SUSPEND_ACKNOWLEDGE"},
1088         {CC_RESUME_ACKNOWLEDGE,L3,EVENT_RESUME_ACKNOWLEDGE,
1089          parse_resume_acknowledge,build_resume_acknowledge,
1090          "RESUME_ACKNOWLEDGE"},
1091         {CC_HOLD_REJECT,L3,EVENT_HOLD_REJECT,
1092          parse_hold_reject,build_hold_reject,
1093          "HOLD_REJECT"},
1094         {CC_RETRIEVE,L3,EVENT_RETRIEVE,
1095          parse_retrieve,build_retrieve,
1096          "RETRIEVE"},
1097         {CC_RETRIEVE_ACKNOWLEDGE,L3,EVENT_RETRIEVE_ACKNOWLEDGE,
1098          parse_retrieve_acknowledge,build_retrieve_acknowledge,
1099          "RETRIEVE_ACKNOWLEDGE"},
1100         {CC_RETRIEVE_REJECT,L3,EVENT_RETRIEVE_REJECT,
1101          parse_retrieve_reject,build_retrieve_reject,
1102          "RETRIEVE_REJECT"},
1103         {CC_DISCONNECT,L3,EVENT_DISCONNECT,
1104          parse_disconnect,build_disconnect,
1105          "DISCONNECT"},
1106         {CC_RESTART,L3,EVENT_RESTART,
1107          parse_restart,build_restart,
1108          "RESTART"},
1109         {CC_RELEASE,L3,EVENT_RELEASE,
1110          parse_release,build_release,
1111          "RELEASE"},
1112         {CC_RELEASE_COMPLETE,L3,EVENT_RELEASE_COMPLETE,
1113          parse_release_complete,build_release_complete,
1114          "RELEASE_COMPLETE"},
1115         {CC_FACILITY,L3,EVENT_FACILITY,
1116          parse_facility,build_facility,
1117          "FACILITY"},
1118         {CC_NOTIFY,L3,EVENT_NOTIFY,
1119          parse_notify,build_notify,
1120          "NOTIFY"},
1121         {CC_STATUS_ENQUIRY,L3,EVENT_STATUS_ENQUIRY,
1122          parse_status_enquiry,build_status_enquiry,
1123          "STATUS_ENQUIRY"},
1124         {CC_INFORMATION,L3,EVENT_INFORMATION,
1125          parse_information,build_information,
1126          "INFORMATION"},
1127         {CC_STATUS,L3,EVENT_STATUS,
1128          parse_status,build_status,
1129          "STATUS"},
1130         {CC_TIMEOUT,L3,EVENT_TIMEOUT,
1131          parse_timeout,build_timeout,
1132          "TIMEOUT"},
1133         {0,0,0,NULL,NULL,NULL}
1134 };
1135
1136 #define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
1137
1138 /** INTERFACE FCTS ***/
1139 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
1140 {
1141         int i;
1142
1143         if (nt){
1144                 mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
1145                 
1146                 for (i=0; i< msgs_max -1; i++) {
1147                         if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
1148                 }
1149                 
1150         } else {
1151                 iframe_t *frm = (iframe_t*)msg->data;
1152     
1153                 for (i=0; i< msgs_max -1; i++) 
1154                         if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
1155         }
1156
1157         return -1;
1158 }
1159
1160 int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
1161 {
1162         int i;
1163         for (i=0; i< msgs_max; i++) 
1164                 if ( event == msgs[i].event) return i;
1165
1166         cb_log(10,0, "get_index: event not found!\n");
1167         
1168         return -1;
1169 }
1170
1171 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
1172 {
1173         int i=isdn_msg_get_index(msgs, msg, nt);
1174         if(i>=0) return msgs[i].event;
1175         return EVENT_UNKNOWN;
1176 }
1177
1178 char * isdn_msg_get_info(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].info;
1182         return NULL;
1183 }
1184
1185
1186 char EVENT_CLEAN_INFO[] = "CLEAN_UP";
1187 char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
1188 char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
1189 char EVENT_NEW_BC_INFO[] = "NEW_BC";
1190 char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
1191 char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
1192 char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
1193
1194 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
1195 {
1196         int i=isdn_msg_get_index_by_event(msgs, event, nt);
1197         
1198         if(i>=0) return msgs[i].info;
1199         
1200         if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
1201         if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
1202         if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
1203         if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
1204         if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
1205         if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
1206         if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
1207         
1208         return NULL;
1209 }
1210
1211 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
1212 {
1213         int i=isdn_msg_get_index(msgs, msg, nt);
1214         if(i<0) return -1;
1215
1216         msgs[i].msg_parser(msgs, msg, bc, nt);
1217         return 0;
1218 }
1219
1220 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
1221 {
1222         int i=isdn_msg_get_index_by_event(msgs, event, nt);
1223         if(i<0) return NULL;
1224   
1225         return  msgs[i].msg_builder(msgs, bc, nt);
1226 }
1227