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