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