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