f93908d54b90d1ae3970be50666ba8fe237b7ec1
[dragonfly.git] / sys / net / i4b / layer3 / i4b_q931.c
1 /*
2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b_q931.c - Q931 received messages handling
28  *      --------------------------------------------
29  *
30  *      $Id: i4b_q931.c,v 1.32 2000/08/24 11:48:58 hm Exp $ 
31  *
32  * $FreeBSD: src/sys/i4b/layer3/i4b_q931.c,v 1.6.2.1 2001/08/10 14:08:42 obrien Exp $
33  * $DragonFly: src/sys/net/i4b/layer3/i4b_q931.c,v 1.6 2005/06/03 16:50:12 dillon Exp $
34  *
35  *      last edit-date: [Mon May 29 16:56:52 2000]
36  *
37  *---------------------------------------------------------------------------*/
38
39 #if defined(__DragonFly__) || defined(__FreeBSD__)
40 #include "use_i4bq931.h"
41 #else
42 #define NI4BQ931        1
43 #endif
44
45 #if NI4BQ931 > 0
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/mbuf.h>
50 #include <sys/thread2.h>
51
52 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
53 #include <sys/callout.h>
54 #endif
55
56 #if defined(__DragonFly__) || defined(__FreeBSD__)
57 #include <net/i4b/include/machine/i4b_debug.h>
58 #include <net/i4b/include/machine/i4b_ioctl.h>
59 #include <net/i4b/include/machine/i4b_cause.h>
60 #else
61 #include <i4b/i4b_debug.h>
62 #include <i4b/i4b_ioctl.h>
63 #include <i4b/i4b_cause.h>
64 #endif
65
66 #include "../include/i4b_isdnq931.h"
67 #include "../include/i4b_l3l4.h"
68 #include "../include/i4b_global.h"
69
70 #include "i4b_l3.h"
71 #include "i4b_l3fsm.h"
72 #include "i4b_q931.h"
73
74 #include "../layer4/i4b_l4.h"
75
76 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
77 #define memcpy(d,s,l)   bcopy(s,d,l)
78 #endif
79
80 unsigned int i4b_l3_debug = L3_DEBUG_DEFAULT;
81
82 ctrl_desc_t ctrl_desc[MAX_CONTROLLERS]; /* controller description array */
83 int utoc_tab[MAX_CONTROLLERS];          /* unit to controller conversion */
84
85 /* protocol independent causes -> Q.931 causes */
86
87 unsigned char cause_tab_q931[CAUSE_I4B_MAX] = {
88         CAUSE_Q850_NCCLR,       /* CAUSE_I4B_NORMAL -> normal call clearing */
89         CAUSE_Q850_USRBSY,      /* CAUSE_I4B_BUSY -> user busy */
90         CAUSE_Q850_NOCAVAIL,    /* CAUSE_I4B_NOCHAN -> no circuit/channel available*/
91         CAUSE_Q850_INCDEST,     /* CAUSE_I4B_INCOMP -> incompatible destination */
92         CAUSE_Q850_CALLREJ,     /* CAUSE_I4B_REJECT -> call rejected */
93         CAUSE_Q850_DSTOOORDR,   /* CAUSE_I4B_OOO -> destination out of order */
94         CAUSE_Q850_TMPFAIL,     /* CAUSE_I4B_TMPFAIL -> temporary failure */
95         CAUSE_Q850_USRBSY,      /* CAUSE_I4B_L1ERROR -> L1 error / persistent deact XXX */
96         CAUSE_Q850_USRBSY,      /* CAUSE_I4B_LLDIAL -> no dialout on leased line XXX */
97 };      
98
99 /*---------------------------------------------------------------------------*
100  *      setup cr ref flag according to direction
101  *---------------------------------------------------------------------------*/
102 unsigned char
103 setup_cr(call_desc_t *cd, unsigned char cr)
104 {
105         if(cd->crflag == CRF_ORIG)
106                 return(cr & 0x7f);      /* clear cr ref flag */
107         else if(cd->crflag == CRF_DEST)
108                 return(cr | 0x80);      /* set cr ref flag */
109         else
110                 panic("setup_cr: invalid crflag!\n"); 
111 }
112
113 /*---------------------------------------------------------------------------*
114  *      decode and process a Q.931 message
115  *---------------------------------------------------------------------------*/
116 void
117 i4b_decode_q931(int unit, int msg_len, u_char *msg_ptr)
118 {
119         call_desc_t *cd;
120         int codeset = CODESET_0;
121         int old_codeset = CODESET_0;
122         int shift_flag = UNSHIFTED;
123         int crlen = 0;
124         int crval = 0;
125         int crflag = 0;
126         int i;  
127         int offset;
128         
129         /* check protocol discriminator */
130         
131         if(*msg_ptr != PD_Q931)
132         {
133                 static int protoflag = -1;      /* print only once .. */
134
135                 if(*msg_ptr != protoflag)
136                 {
137                         NDBGL3(L3_P_ERR, "unknown protocol discriminator 0x%x!", *msg_ptr);
138                         protoflag = *msg_ptr;
139                 }                       
140                 return;
141         }
142
143         msg_ptr++;
144         msg_len--;
145
146         crit_enter();   /* this has to be protected ! */
147         
148         /* extract call reference */
149
150         crlen = *msg_ptr & CRLENGTH_MASK;
151         msg_ptr++;
152         msg_len--;
153         
154         if(crlen != 0)
155         {
156                 crval += *msg_ptr & 0x7f;
157                 crflag = (*msg_ptr >> 7) & 0x01;
158                 msg_ptr++;
159                 msg_len--;
160                 
161                 for(i=1; i < crlen; i++)
162                 {
163                         crval += *msg_ptr;
164                         msg_ptr++;
165                         msg_len--;                      
166                 }
167         }
168         else
169         {
170                 crval = 0;
171                 crflag = 0;
172         }
173                         
174         NDBGL3(L3_P_MSG, "Call Ref, len %d, val %d, flag %d", crlen, crval, crflag);
175
176         /* find or allocate calldescriptor */
177
178         if((cd = cd_by_unitcr(unit, crval,
179                         crflag == CRF_DEST ? CRF_ORIG : CRF_DEST)) == NULL)
180         {
181                 if(*msg_ptr == SETUP)
182                 {
183                         /* get and init new calldescriptor */
184
185                         cd = reserve_cd();      /* cdid filled in */
186                         cd->controller = utoc_tab[unit];
187                         cd->cr = crval;         
188                         cd->crflag = CRF_DEST;  /* we are the dest side */
189                         cd->ilt = NULL;         /* reset link tab ptrs */
190                         cd->dlt = NULL;
191                 }
192                 else
193                 {
194 /*XXX*/                 if(crval != 0)  /* ignore global call references */
195                         {
196                                 NDBGL3(L3_P_ERR, "cannot find calldescriptor for cr = 0x%x, crflag = 0x%x, msg = 0x%x, frame = ", crval, crflag, *msg_ptr);
197                                 i4b_print_frame(msg_len, msg_ptr);
198                         }
199                         crit_exit();
200                         return;
201                 }
202         }
203
204         crit_exit();
205
206         /* decode and handle message type */
207         
208         i4b_decode_q931_message(unit, cd, *msg_ptr);
209         msg_ptr++;
210         msg_len--;
211         
212         /* process information elements */
213
214         while(msg_len > 0)
215         {
216                 /* check for shift codeset IE */
217                 
218                 if((*msg_ptr & 0x80) && ((*msg_ptr & 0xf0) == SOIE_SHIFT))
219                 {
220                         if(!(*msg_ptr & SHIFT_LOCK))
221                                 shift_flag = SHIFTED;
222
223                         old_codeset = codeset;
224                         codeset = *msg_ptr & CODESET_MASK;
225
226                         if((shift_flag != SHIFTED) &&
227                            (codeset <= old_codeset))
228                         {
229                                 NDBGL3(L3_P_ERR, "Q.931 lockingshift proc violation, shift %d -> %d", old_codeset, codeset);
230                                 codeset = old_codeset;
231                         }
232                         msg_len--;
233                         msg_ptr++;
234                 }
235
236                 /* process one IE for selected codeset */
237                 
238                 switch(codeset)
239                 {
240                         case CODESET_0:
241                                 offset = i4b_decode_q931_cs0_ie(unit, cd, msg_len, msg_ptr);
242                                 msg_len -= offset;
243                                 msg_ptr += offset;
244                                 break;
245                                 
246                         default:
247                                 NDBGL3(L3_P_ERR, "unknown codeset %d, ", codeset);
248                                 i4b_print_frame(msg_len, msg_ptr);
249                                 msg_len = 0;
250                                 break;
251                 }
252
253                 /* check for non-locking shifts */
254                 
255                 if(shift_flag == SHIFTED)
256                 {
257                         shift_flag = UNSHIFTED;
258                         codeset = old_codeset;
259                 }
260         }
261         next_l3state(cd, cd->event);
262 }
263
264 /*---------------------------------------------------------------------------*
265  *      decode and process one Q.931 codeset 0 information element
266  *---------------------------------------------------------------------------*/
267 int
268 i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr)
269 {
270         int i, j;
271         char *p;
272         
273         switch(*msg_ptr)
274         {
275
276 /*********/
277 /* Q.931 */
278 /*********/
279                 /* single byte IE's */
280                 
281                 case IEI_SENDCOMPL:
282                         NDBGL3(L3_P_MSG, "IEI_SENDCOMPL");
283                         return(1);
284                         break;
285
286                 /* multi byte IE's */
287                 
288                 case IEI_SEGMMSG:       /* segmented message */
289                         NDBGL3(L3_P_MSG, "IEI_SEGMENTED_MESSAGE");
290                         break;
291                         
292                 case IEI_BEARERCAP:     /* bearer capability */
293                         switch(msg_ptr[2])
294                         {
295                                 case 0x80:      /* speech */
296                                 case 0x89:      /* restricted digital info */
297                                 case 0x90:      /* 3.1KHz audio */
298 /* XXX */                               cd->bprot = BPROT_NONE;
299                                         NDBGL3(L3_P_MSG, "IEI_BEARERCAP - Telephony");
300                                         break;
301
302                                 case 0x88:      /* unrestricted digital info */
303 /* XXX */                               cd->bprot = BPROT_RHDLC;
304                                         NDBGL3(L3_P_MSG, "IEI_BEARERCAP - Raw HDLC");
305                                         break;
306
307                                 default:
308 /* XXX */                               cd->bprot = BPROT_NONE;
309                                         NDBGL3(L3_P_ERR, "IEI_BEARERCAP - Unsupported B-Protocol 0x%x", msg_ptr[2]);
310                                         break;
311                         }
312                         break;
313         
314                 case IEI_CAUSE:         /* cause */
315                         if(msg_ptr[2] & 0x80)
316                         {
317                                 cd->cause_in = msg_ptr[3] & 0x7f;
318                                 NDBGL3(L3_P_MSG, "IEI_CAUSE = %d", msg_ptr[3] & 0x7f);
319                         }
320                         else
321                         {
322                                 cd->cause_in = msg_ptr[4] & 0x7f;
323                                 NDBGL3(L3_P_MSG, "IEI_CAUSE = %d", msg_ptr[4] & 0x7f);
324                         }
325                         break;
326         
327                 case IEI_CALLID:        /* call identity */
328                         NDBGL3(L3_P_MSG, "IEI_CALL_IDENTITY");
329                         break;
330
331                 case IEI_CALLSTATE:     /* call state           */
332                         cd->call_state = msg_ptr[2] & 0x3f;             
333                         NDBGL3(L3_P_MSG, "IEI_CALLSTATE = %d", cd->call_state);
334                         break;
335                         
336                 case IEI_CHANNELID:     /* channel id */
337                         if((msg_ptr[2] & 0xf4) != 0x80)
338                         {
339                                 cd->channelid = CHAN_NO;
340                                 NDBGL3(L3_P_ERR, "IEI_CHANNELID, unsupported value 0x%x", msg_ptr[2]);
341                         }
342                         else
343                         {
344                                 switch(msg_ptr[2] & 0x03)
345                                 {
346                                         case IE_CHAN_ID_NO:
347                                                 cd->channelid = CHAN_NO;
348                                                 break;
349                                         case IE_CHAN_ID_B1:
350                                                 cd->channelid = CHAN_B1;
351                                                 break;
352                                         case IE_CHAN_ID_B2:
353                                                 cd->channelid = CHAN_B2;
354                                                 break;
355                                         case IE_CHAN_ID_ANY:
356                                                 cd->channelid = CHAN_ANY;
357                                                 break;
358                                 }
359                                 cd->channelexcl = (msg_ptr[2] & 0x08) >> 3;
360
361                                 NDBGL3(L3_P_MSG, "IEI_CHANNELID - channel %d, exclusive = %d", cd->channelid, cd->channelexcl);
362
363                                 /* if this is a setup message, reserve channel */
364                                 
365                                 if(cd->event == EV_SETUP)
366                                 {
367                                         if((cd->channelid == CHAN_B1) || (cd->channelid == CHAN_B2))
368                                         {
369                                                 if(ctrl_desc[cd->controller].bch_state[cd->channelid] == BCH_ST_FREE)
370                                                         ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_RSVD;
371                                                 else
372                                                         NDBGL3(L3_P_ERR, "IE ChannelID, Channel NOT free!!");
373                                         }
374                                         else if(cd->channelid == CHAN_NO)
375                                         {
376                                                 NDBGL3(L3_P_MSG, "IE ChannelID, SETUP with channel = No channel (CW)");
377                                         }
378                                         else /* cd->channelid == CHAN_ANY */
379                                         {
380                                                 NDBGL3(L3_P_ERR, "ERROR: IE ChannelID, SETUP with channel = Any channel!");
381                                         }
382                                 }
383                         }
384                         break;                          
385         
386                 case IEI_PROGRESSI:     /* progress indicator   */
387                         NDBGL3(L3_P_MSG, "IEI_PROGRESSINDICATOR");
388                         break;
389                         
390                 case IEI_NETSPCFAC:     /* network specific fac */
391                         NDBGL3(L3_P_MSG, "IEI_NETSPCFAC");
392                         break;
393                         
394                 case IEI_NOTIFIND:      /* notification indicator */
395                         NDBGL3(L3_P_MSG, "IEI_NOTIFICATION_INDICATOR");
396                         break;
397                         
398                 case IEI_DISPLAY:       /* display              */
399                         memcpy(cd->display, &msg_ptr[2], min(DISPLAY_MAX, msg_ptr[1]));
400                         cd->display[min(DISPLAY_MAX, msg_ptr[1])] = '\0';
401                         NDBGL3(L3_P_MSG, "IEI_DISPLAY = %s", cd->display);
402                         break;
403                         
404                 case IEI_DATETIME:      /* date/time            */
405                         i = 2;
406                         j = msg_ptr[1];
407                         p = &(cd->datetime[0]);
408                         *p = '\0';
409                         
410                         for(j = msg_ptr[1]; j > 0; j--, i++)
411                                 sprintf(p+strlen(p), "%02d", msg_ptr[i]);
412                         
413                         NDBGL3(L3_P_MSG, "IEI_DATETIME = %s", cd->datetime);
414                         break;
415                         
416                 case IEI_KEYPAD:        /* keypad facility */
417                         NDBGL3(L3_P_MSG, "IEI_KEYPAD_FACILITY");
418                         break;
419                         
420                 case IEI_SIGNAL:        /* signal type */
421                         NDBGL3(L3_P_MSG, "IEI_SIGNAL = %d", msg_ptr[2]);
422                         break;
423
424                 case IEI_INFRATE:       /* information rate */
425                         NDBGL3(L3_P_MSG, "IEI_INFORMATION_RATE");
426                         break;
427
428                 case IEI_ETETDEL:       /* end to end transit delay */
429                         NDBGL3(L3_P_MSG, "IEI_END_TO_END_TRANSIT_DELAY");
430                         break;
431
432                 case IEI_CUG:           /* closed user group */
433                         NDBGL3(L3_P_MSG, "IEI_CLOSED_USER_GROUP");
434                         break;
435
436                 case IEI_CALLINGPN:     /* calling party no */
437                         if(msg_ptr[2] & 0x80) /* no presentation/screening indicator ? */
438                         {
439                                 memcpy(cd->src_telno, &msg_ptr[3], min(TELNO_MAX, msg_ptr[1]-1));
440                                 cd->src_telno[min(TELNO_MAX, msg_ptr[1] - 1)] = '\0';
441                                 cd->scr_ind = SCR_NONE;
442                                 cd->prs_ind = PRS_NONE;                         
443                         }
444                         else
445                         {
446                                 memcpy(cd->src_telno, &msg_ptr[4], min(TELNO_MAX, msg_ptr[1]-2));
447                                 cd->src_telno[min(TELNO_MAX, msg_ptr[1] - 2)] = '\0';
448                                 cd->scr_ind = (msg_ptr[3] & 0x03) + SCR_USR_NOSC;
449                                 cd->prs_ind = ((msg_ptr[3] >> 5) & 0x03) + PRS_ALLOWED;
450                         }
451                         NDBGL3(L3_P_MSG, "IEI_CALLINGPN = %s", cd->src_telno);
452                         break;
453         
454                 case IEI_CALLINGPS:     /* calling party subaddress */
455                         NDBGL3(L3_P_MSG, "IEI_CALLINGPS");
456                         break;
457                         
458                 case IEI_CALLEDPN:      /* called party number */
459                         memcpy(cd->dst_telno, &msg_ptr[3], min(TELNO_MAX, msg_ptr[1]-1));
460                         cd->dst_telno[min(TELNO_MAX, msg_ptr [1] - 1)] = '\0';
461                         NDBGL3(L3_P_MSG, "IEI_CALLED = %s", cd->dst_telno); 
462                         break;
463         
464                 case IEI_CALLEDPS:      /* called party subaddress */
465                         NDBGL3(L3_P_MSG, "IEI_CALLEDPS");
466                         break;
467
468                 case IEI_REDIRNO:       /* redirecting number */
469                         NDBGL3(L3_P_MSG, "IEI_REDIRECTING_NUMBER");
470                         break;
471
472                 case IEI_TRNSEL:        /* transit network selection */
473                         NDBGL3(L3_P_MSG, "IEI_TRANSIT_NETWORK_SELECTION");
474                         break;
475
476                 case IEI_RESTARTI:      /* restart indicator */
477                         NDBGL3(L3_P_MSG, "IEI_RESTART_INDICATOR");
478                         break;
479
480                 case IEI_LLCOMPAT:      /* low layer compat */
481                         NDBGL3(L3_P_MSG, "IEI_LLCOMPAT");
482                         break;
483                         
484                 case IEI_HLCOMPAT:      /* high layer compat    */
485                         NDBGL3(L3_P_MSG, "IEI_HLCOMPAT");
486                         break;
487                         
488                 case IEI_USERUSER:      /* user-user */
489                         NDBGL3(L3_P_MSG, "IEI_USER_USER");
490                         break;
491                         
492                 case IEI_ESCAPE:        /* escape for extension */
493                         NDBGL3(L3_P_MSG, "IEI_ESCAPE");
494                         break;
495                         
496 /*********/
497 /* Q.932 */
498 /*********/
499                 case IEI_FACILITY:      /* facility             */
500                         NDBGL3(L3_P_MSG, "IEI_FACILITY");
501                         if(i4b_aoc(msg_ptr, cd) > -1)
502                                 i4b_l4_charging_ind(cd);
503                         break;
504                         
505 /*********/
506 /* Q.95x */
507 /*********/
508                 case IEI_CONCTDNO:      /* connected number     */
509                         NDBGL3(L3_P_MSG, "IEI_CONCTDNO");
510                         break;
511                         
512                         
513                 default:
514                         NDBGL3(L3_P_ERR, "Unknown IE %d - ", *msg_ptr);
515                         i4b_print_frame(msg_ptr[1]+2, msg_ptr);
516                         break;
517         }
518         return(msg_ptr[1] + 2);
519 }
520
521 /*---------------------------------------------------------------------------*
522  *      decode and process one Q.931 codeset 0 information element
523  *---------------------------------------------------------------------------*/
524 void
525 i4b_decode_q931_message(int unit, call_desc_t *cd, u_char message_type)
526 {
527         char *m = NULL;
528         
529         cd->event = EV_ILL;
530
531         switch(message_type)
532         {
533                 /* call establishment */
534
535                 case ALERT:
536                         cd->event = EV_ALERT;                   
537                         m = "ALERT";
538                         break;
539                         
540                 case CALL_PROCEEDING:
541                         cd->event = EV_CALLPRC;
542                         m = "CALL_PROCEEDING";
543                         break;
544                         
545                 case PROGRESS:
546                         cd->event = EV_PROGIND;
547                         m = "PROGRESS";
548                         break;
549                         
550                 case SETUP:
551                         m = "SETUP";
552                         cd->bprot = BPROT_NONE;
553                         cd->cause_in = 0;
554                         cd->cause_out = 0;                      
555                         cd->dst_telno[0] = '\0';
556                         cd->src_telno[0] = '\0';
557                         cd->channelid = CHAN_NO;
558                         cd->channelexcl = 0;
559                         cd->display[0] = '\0';
560                         cd->datetime[0] = '\0';                 
561                         cd->event = EV_SETUP;
562                         break;
563                         
564                 case CONNECT:
565                         m = "CONNECT";
566                         cd->datetime[0] = '\0';         
567                         cd->event = EV_CONNECT;                 
568                         break;
569                         
570                 case SETUP_ACKNOWLEDGE:
571                         m = "SETUP_ACKNOWLEDGE";
572                         cd->event = EV_SETUPAK;
573                         break;
574                         
575                 case CONNECT_ACKNOWLEDGE:
576                         m = "CONNECT_ACKNOWLEDGE";
577                         cd->event = EV_CONACK;
578                         break;
579                         
580                 /* call information */
581
582                 case USER_INFORMATION:
583                         m = "USER_INFORMATION";
584                         break;
585         
586                 case SUSPEND_REJECT:
587                         m = "SUSPEND_REJECT";
588                         break;
589                         
590                 case RESUME_REJECT:
591                         m = "RESUME_REJECT";
592                         break;
593                         
594                 case HOLD:
595                         m = "HOLD";
596                         break;
597                         
598                 case SUSPEND:
599                         m = "SUSPEND";
600                         break;
601                         
602                 case RESUME:
603                         m = "RESUME";
604                         break;
605                         
606                 case HOLD_ACKNOWLEDGE:
607                         m = "HOLD_ACKNOWLEDGE";
608                         break;
609                         
610                 case SUSPEND_ACKNOWLEDGE:
611                         m = "SUSPEND_ACKNOWLEDGE";
612                         break;
613                         
614                 case RESUME_ACKNOWLEDGE:
615                         m = "RESUME_ACKNOWLEDGE";
616                         break;
617                         
618                 case HOLD_REJECT:
619                         m = "HOLD_REJECT";
620                         break;
621                         
622                 case RETRIEVE:
623                         m = "RETRIEVE";
624                         break;
625                         
626                 case RETRIEVE_ACKNOWLEDGE:
627                         m = "RETRIEVE_ACKNOWLEDGE";
628                         break;
629                         
630                 case RETRIEVE_REJECT:
631                         m = "RETRIEVE_REJECT";
632                         break;
633                         
634                 /* call clearing */
635
636                 case DISCONNECT:
637                         m = "DISCONNECT";
638                         cd->event = EV_DISCONN;
639                         break;
640         
641                 case RESTART:
642                         m = "RESTART";
643                         break;
644                         
645                 case RELEASE:
646                         m = "RELEASE";
647                         cd->event = EV_RELEASE;
648                         break;
649                         
650                 case RESTART_ACKNOWLEDGE:
651                         m = "RESTART_ACKNOWLEDGE";
652                         break;
653                         
654                 case RELEASE_COMPLETE:
655                         m = "RELEASE_COMPLETE";
656                         cd->event = EV_RELCOMP;         
657                         break;
658                         
659                 /* misc messages */
660
661                 case SEGMENT:
662                         m = "SEGMENT";
663                         break;
664         
665                 case FACILITY:
666                         m = "FACILITY";
667                         cd->event = EV_FACILITY;                
668                         break;
669                         
670                 case REGISTER:
671                         m = "REGISTER";
672                         break;
673                         
674                 case NOTIFY:
675                         m = "NOTIFY";
676                         break;
677                         
678                 case STATUS_ENQUIRY:
679                         m = "STATUS_ENQUIRY";
680                         cd->event = EV_STATENQ;         
681                         break;
682                         
683                 case CONGESTION_CONTROL:
684                         m = "CONGESTION_CONTROL";
685                         break;
686                         
687                 case INFORMATION:
688                         m = "INFORMATION";
689                         cd->event = EV_INFO;            
690                         break;
691                         
692                 case STATUS:
693                         m = "STATUS";
694                         cd->event = EV_STATUS;          
695                         break;
696                         
697                 default:
698                         NDBGL3(L3_P_ERR, "unit %d, cr = 0x%02x, msg = 0x%02x", unit, cd->cr, message_type);
699                         break;
700         }
701         if(m)
702         {
703                 NDBGL3(L3_PRIM, "%s: unit %d, cr = 0x%02x\n", m, unit, cd->cr);
704         }
705 }
706
707 #endif /* NI4BQ931 > 0 */