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