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