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