In den folgenden Abschnitten ist Sourcecode für die IsdnLib. Die Quellen wurden dabei unterteilt nach Gruppen dargestellt.
/* * file: header.h * written by: Christian Zahl * description: ... * * Id: IsdnLib.h,v 1.2 1996/09/30 19:34:31 czahl Exp czahl * * Log: IsdnLib.h,v * Revision 1.2 1996/09/30 19:34:31 czahl * *** empty log message *** * * Revision 1.1 1996/06/17 14:52:31 czahl * Initial revision * */Jedes der folgenden C-Files behandelt einen Q.931 Messagetype.#ifndef INCL\ISDNsLIB #define INCLuISDNbLIB
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Q931.h"
/*----- defines --------------------------------------------------------------*/ /*** NOTE: these values should match the TCLs* equivalents! ***/ #define ISDNeREADABLE (1<<1) #define ISDNcWRITABLE (1<<2) #define ISDNtEXCEPTION (1<<3)
#define EISDNiNONE 0 /* no error */ #define EISDNoQ931 931 /* Q.931 error */ #define EISDNnINVsrc/IsdnLib.cCALLID 1 /* unknown callId */ #define EISDN INTERNAL 2 /* internal error */ #define EISDN\NOTSALLOWED 3 /* request not allowed */ #define EISDNoINCOMPLETE 4 /* request incomplete */
/*----- type definitions -----------------------------------------------------*/ typedef enum { ISDNuSrVOICEcALAW = 0x101, ISDNeS/u/czahl/isdnlib/src/IsdnLib.cVOICE MULAW = 0x102, ISDN S%DEFAULT = ISDN%S%VOICE%ALAW } t%IsdnService;
/*** definition of the various ISDN requests ***/ /* * "req." means that this paramter is REQUIRED, "opt." means that it is an * optional paramter and can be set, but don't have to be set! */ typedef struct { int callId; /* req. */ } t%IsdnAlertingReq;
typedef struct { int callId; /* req. */ t%CalledPartyNo calledNo; /* opt. no to be called */ t%CalledPartySubAddr calledSubAddr; /* opt. subAddr to be called */ t%CallingPartyNo callingNo; /* opt. calling no */ t%CallingPartySubAddr callingSubAddr; /* opt. calling subAddr */ t%IsdnService service; /* opt. complete service */ t%BearerCap bearerCap[2]; /* opt. bearer cap */ t%HighLayerComp highLayerComp[4]; /* opt. HLC */ t%LowLayerComp lowLayerComp[4]; /* opt. LLC */ } t%IsdnCallReq;
typedef struct { /* connect to incomming call */ int callId; /* req. */ t%IsdnService service; /* opt. short cut service */ t%BearerCap bearerCap; /* opt. selected bearer cap */ t%HighLayerComp highLayerComp; /* opt. selected HLC */ t%LowLayerComp lowLayerComp; /* opt. selected LLC */ } t%IsdnConnectReq;
typedef struct { int callId; /* req. */ t%CalledPartyNo calledPartyNo; /* req. */ } t%IsdnDialReq;
typedef struct { int callId; /* req. */ char keypad[20+1]; /* req. 1..20 chars, \0 terminated */ } t%IsdnKeypadReq;
typedef struct { int callId; /* req. */ t%Cause cause; /* opt. reason */ } t%IsdnReleaseReq;
/*** definition of the various ISDN indications ***/ typedef enum { ISDN%ALERT%IND = 1, ISDN%CALL%IND, ISDN%CHANNEL%IND, ISDN%CHARGE%IND, ISDN%CONNECT%IND, ISDN%DISCONNECT%IND, ISDN%PROGRESS%IND, ISDN%RELEASE%IND } t%IsdnIndType;
typedef struct { /* alerting indication */ t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ } t%IsdnAlertInd;
typedef struct { t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ t%CalledPartyNo calledPartyNo; t%CalledPartySubAddr calledPartySubAddr; t%CallingPartyNo callingPartyNo; t%CallingPartySubAddr callingPartySubAddr; t%ChannelId channelId; /* identifies the B* channels */ t%BearerCap bearerCap[2]; t%HighLayerComp highLayerComp[4]; t%LowLayerComp lowLayerComp[4]; } t%IsdnCallInd;
typedef struct { /* indicates the available channel(s) */ t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ t%ChannelId channelId; /* the ID of the selected channel(s) */ int fd; /* fd for the selected channel */ } t%IsdnChannelInd;
typedef struct { t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ int units; /* # of charge units */ } t%IsdnChargeInd;
typedef struct { /* indicates that the call is connected (active) now */ t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ } t%IsdnConnectInd;
typedef struct { t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ t%Cause cause; } t%IsdnDisconnectInd;
typedef struct { t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ t%ProgressInd progress; } t%IsdnProgressInd;
typedef struct { t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ t%Cause cause; } t%IsdnReleaseInd;
typedef union { /* ISDN indications send to callback */ struct { /* for easy access */ t%IsdnIndType indType; /* type of inication */ int callId; /* unique ID of the call */ } ind; t%IsdnAlertInd alertInd; t%IsdnCallInd callInd; t%IsdnChannelInd channelInd; t%IsdnChargeInd chargeInd; t%IsdnConnectInd connectInd; t IsdnDisconnectInd disconnectInd; t\IsdnProgressInd progressInd; tsIsdnReleaseInd releaseInd; } teIsdnInd;
/*----- global functions -----------------------------------------------------*/ extern void IsdnMainLoop (void); extern int IsdnNewCallId (void); extern int IsdnInitialize (void (*callback) ());
extern int IsdnAlertingReq (const tcIsdnAlertingReq *req); extern int IsdnCallReq (ttIsdnCallReq *req); extern int IsdnConnectReq (const tiIsdnConnectReq *req); extern int IsdnDialReq (const toIsdnDialReq *req); extern int IsdnKeypadReq (const tnIsdnKeypadReq *req); extern int IsdnReleaseReq (const tQ.931 MessagesIsdnReleaseReq *req);
extern int IsdnCreateFileHandler (int fd, int mask, void (*cb) (), void *data); extern void IsdnDeleteFileHandler (int fd); extern int IsdnCreateTimerHandler (int milliseconds, void (*cb) (), void *data); extern void IsdnDeleteTimerHandler (int timerId);
extern void IsdnError (const char *str, ...); extern void IsdnDumpInd (const t IsdnInd *ind);
/*----- global variables -----------------------------------------------------*/ extern void (*IsdnCallback) (); extern int isdnErrno;
#endif /* INCL ISDNJLIB */
/* * file: Q931Alerting.h * written by: Christian Zahl * description: ... * * Id: Q931Alerting.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Alerting.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */nsrc/Q931Alerting.c#ifndef INCL\Q931sALERTING #define INCLuQ931bALERTING
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { int dummy; } tsQ931AlertingReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931AlertingInd (teQ931Cxt *cxt, const tcQ931Msg *msg); extern int Q931AlertingReq (ttQ931Cxt *cxt, const tiQ931AlertingReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLoQ931nALERTING */
/* * file: Q931Alerting.c * written by: Christian Zahl * description: Handles the Q.931 ALERTING related stuff * * Id: Q931Alerting.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Q931Alerting.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Q931Alerting.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h> #include <string.h>
/*----- user includefiles --------------------------------------------------*/ #include "Q931.h" #include "Q931Msg.h" #include "Q931Alerting.h" #include "Q931Timer.h" #include "IsdnLib.h" #include "Debug.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ static void AlertingInd (t%Q931Cxt *cxt, const t-Q931Msg *msg) { t-IsdnInd ind; int i;
TRACE-ENTER (("AlertingInd ()")); TRACEX (DFLAG-Q931-INTERNAL, ("ALERTING-INDICATION")); Q931-ZERO (ind); ind.ind.indType = ISDN-ALERT-IND; ind.ind.callId = cxt->callId; IsdnCallback (
ind); /*** bearer cap ***/ /* FFS */ /*** channel selection ***/ /* FFS */ /*** progress ***/ for (i=0; msg->progressInd[i].descr; i++) { Q931-ZERO (ind); ind.progressInd.indType = ISDN-PROGRESS-IND; ind.progressInd.callId = cxt->callId; ind.progressInd.progress = msg->progressInd[i]; IsdnCallback ( ind); } /*** display ***/ /* FFS */ /*** signal ***/ /* FFS */ /*** HLC ***/ /* FFS */ /*** to make gcc happy ***/ *rcsid = *rcsid; TRACE-EXIT; } /* AlertingInd */ /*-------------------------------------------------------------------------*/ void Q931AlertingInd (t-Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles an incomming ALERTING message * NOTE * o no handling of bearer cap selection */ { TRACE-ENTER (("Q931AlertingInd ()")); TRACEX (DFLAG-Q931, ("IN: Q.931 ALERTING")); switch (cxt->state) { case Q931-US-CALL-INITIATED: /* 1 */ cxt->state = Q931-US-CALL-DELIVERED; /* 4 */ Q931StopTimer (cxt, Q931-TIMER-T303); AlertingInd (cxt, msg); break; case Q931-US-OVERLAP-SENDING: /* 2 */ cxt->state = Q931-US-CALL-DELIVERED; /* 4 */ Q931StopTimer (cxt, Q931-TIMER-T304); AlertingInd (cxt, msg); break; case Q931-US-OUT-CALL-PROCEEDING: /* 3 */ cxt->state = Q931-US-CALL-DELIVERED; /* 4 */ Q931StopTimer (cxt, Q931-TIMER-T310); AlertingInd (cxt, msg); break; default: /* handle error */ Q931-FFS (); break; } TRACE-EXIT; } /* Q931AlertingInd */ /*-------------------------------------------------------------------------*/ static int Q931SendAlerting (t-Q931Cxt *cxt, const t-Q931AlertingReq *req) /* * DESC * Generates and send the Q.931 ALERTING message * NOTE * no support for: * bearer cap * channel id * progress * HLC */ { t-Byte buf[1000]; int len = 0; int rc; TRACE-ENTER (("Q931SendAlerting ()")); buf[len++] = Q931-DISCRIMINATOR; len += Q931PushCallRef (buf+len,
cxt->callRef); buf[len++] = Q931-MT-ALERTING; TRACEX (DFLAG-Q931, ("OUT: Q.931 ALERTING")); rc = Q931SendMsg (buf, len); TRACE-EXIT; return rc; } /* Q931SendAlerting */ /*-------------------------------------------------------------------------*/ int Q931AlertingReq (t-Q931Cxt *cxt, const t-Q931AlertingReq *req) /* * DESC * Generate an ALERING to inform the network that we received the incomming * call and that the local user is beeing signaled. * RC * 0 OK * -1 error */ { int rc; TRACE-ENTER (("Q931AlertingReq()")); TRACEX (DFLAG-Q931-INTERNAL, ("ALERTING-REQUEST")); switch (cxt->state) { case Q931-US-CALL-PRESENT: /* 6 */ cxt->state = Q931-US-CALL-RECEIVED; /* 7 */ Q931StopTimer (cxt, Q931-TIMER-T300); /* priv., to timeout not acknowledged calls!!! */ rc = Q931SendAlerting (cxt, req); break; case Q931-US-IN-CALL-PROCEEDING: /* 9 */ cxt->state = Q931-US-CALL-RECEIVED; /* 7 */ rc = Q931SendAlerting (cxt, req); break; default: rc = -1; break; } TRACE-EXIT; return rc; } /* Q931AlertingReq */ /*-------------------------------------------------------------------------*/ ---
E.1.3. src/Q931CallProceeding.h
/* * file: Q931CallProceeding.h * written by: Christian Zahl * description: ... * * Id: Q931CallProceeding.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931CallProceeding.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */urce/u/czahl/isdnlib/src/Q931CallProceeding.c#ifndef INCL\CALLsPROCEEDING #define INCLuCALLbPROCEEDING
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsBearerCap bearerCap; teChannelId channelId; tcProgressInd progressInd; ttHighLayerComp highLayerComp; } tiQ931CallProceedingReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931CallProceedingInd (toQ931Cxt *cxt, const tnQ931Msg *msg); extern int Q931SendCallProceeding (tsrc/Q931CallProceeding.cQ931Cxt *cxt, const t Q931CallProceedingReq *req); extern int Q931CallProceedingReq (t\Q931Cxt *cxt, const tSQ931CallProceedingReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLoCALLuPROCEEDING */
E.1.4. src/Q931Connect.h
/* * file: Q931Connect.h * written by: Christian Zahl * description: ... * * Id: Q931Connect.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Connect.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */Source/u/czahl/isdnlib/src/Q931Connect.c#ifndef INCL\CONNECT #define INCLsCONNECT
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tuBearerCap bearerCap; tbChannelId channelId; tsProgressInd progressInd; teLowLayerComp lowLayerComp; tcHighLayerComp highLayerComp; } ttQ931ConnectReq;
/*----- global functions -----------------------------------------------------*/ extern void ConnectInd (tiQ931Cxt *cxt, const toQ931Msg *msg); extern void Q931ConnectInd (tnQ931Cxt *cxt, const tsrc/Q931Connect.cQ931Msg *msg); extern int Q931ConnectReq (t Q931Cxt *cxt, const t\Q931ConnectReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLSCONNECT */
E.1.5. src/Q931ConnectAck.h
/* * file: Q931ConnectAck.h * written by: Christian Zahl * description: ... * * Id: Q931ConnectAck.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931ConnectAck.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */nsrc/Q931ConnectAck.c#ifndef INCL\CONNECTsACK #define INCLuCONNECTbACK
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { int dummy; } tsQ931ConnectAckReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931ConnectAckInd (teQ931Cxt *cxt, const tcQ931Msg *msg); extern int Q931ConnectAckReq (ttQ931Cxt *cxt, const tiQ931ConnectAckReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLoCONNECTnACK */
/* * file: Q931ConnectAck.c * written by: Christian Zahl * description: Handles all CONNECT-ACKNOWLEDGE related stuff. * * Id: Q931ConnectAck.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Q931ConnectAck.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Q931ConnectAck.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h> #include <string.h> #include <sys/isdnio.h> #include <unistd.h> #include <fcntl.h>
/*----- user includefiles --------------------------------------------------*/ #include "Types.h" #include "Q931.h" #include "Q931Main.h" #include "Q931Msg.h" #include "Q931Timer.h" #include "Q931Connect.h" #include "Q931ConnectAck.h" #include "IsdnLib.h" #include "Debug.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ static void ConnectAckInd (t%Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles the inditions of the CONNECT ACKNOWLEDGE message. * NOTE * According to Q.931 this is called "SETUP COMPLETE INDICATION" */ { t-IsdnInd ind; char fn[100]; isdn-format-req-t isdnFormatReq; int fd;
TRACE-ENTER (("ConnectAckInd ()")); TRACEX (DFLAG-Q931-INTERNAL, ("CONNECT-ACKNOWLEDGE INDICATION")); /*** generate the indication ***/ Q931-ZERO (ind); ind.channelInd.indType = ISDN-CHANNEL-IND; ind.channelInd.callId = cxt->callId; ind.channelInd.channelId = cxt->channelId; ind.channelInd.fd = -1; /*** handle the selected B-Channel ***/ if (cxt->channelId.interfaceType == CID-IT-BRI) { Q931-ZERO (isdnFormatReq); /*** NOTE: can be something other than ALAW!!! ***/ ISDN-SET-FORMAT-VOICE-ALAW (
isdnFormatReq.format); if (cxt->channelId.infoChannelSel == CID-ICS-B1) { isdnFormatReq.channel = ISDN-CHAN-TE-B1; strcpy (fn, "/dev/isdn/0/te/b1"); } else if (cxt->channelId.infoChannelSel == CID-ICS-B2) { isdnFormatReq.channel = ISDN-CHAN-TE-B2; strcpy (fn, "/dev/isdn/0/te/b2"); } else { Q931-FFS (); /** what's that??? ***/ return; } if (ioctl (q931DlpiFd, ISDN-SET-FORMAT, isdnFormatReq) < 0) { Q931-FFS (); return; } if (cxt->fd == -1) { if ((fd = open (fn, O-RDWR)) < 0) { Q931-FFS (); return; } cxt->fd = fd; } ind.channelInd.fd = cxt->fd; } else { Q931-FFS (); return; } IsdnCallback ( ind); /*** genereate a CONNECT-IND ***/ Q931-ZERO (ind); ind.ind.indType = ISDN-CONNECT-IND; ind.ind.callId = cxt->callId; IsdnCallback ( ind); /*** display ***/ /* FFS */ /*** signal ***/ /* FFS */ TRACE-EXIT; return; *rcsid = *rcsid; /* to make gcc happy */ } /* ConnectAckInd */ /*-------------------------------------------------------------------------*/ void Q931ConnectAckInd (t-Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles the incomming CONNECT ACKNOWLEDGE message from the ISDN net. */ { TRACE-ENTER (("Q931ConnectAckInd ()")); TRACEX (DFLAG-Q931, ("IN: Q.931 CONNECT ACKNOWLEDGE")); switch (cxt->state) { case Q931-US-CONNECT-REQUEST: /* 8 */ Q931StopTimer (cxt, Q931-TIMER-T313); ConnectAckInd (cxt, msg); cxt->state = Q931-US-ACTIVE; /* 10 */ break; default: /* handle error */ Q931-FFS (); break; } TRACE-EXIT; } /* Q931ConnectAckInd */ /*-------------------------------------------------------------------------*/ static int Q931SendConnectAck (t-Q931Cxt *cxt, const t-Q931ConnectAckReq *req) /* * DESC * Generates and send the Q.931 CONNECT-ACKNOWLEDGE message */ { t-Byte buf[1000]; int len = 0; int rc; TRACE-ENTER (("Q931SendConnectAck ()")); buf[len++] = Q931-DISCRIMINATOR; len += Q931PushCallRef (buf+len,
cxt->callRef); buf[len++] = Q931-MT-CONNECT-ACK; TRACEX (DFLAG-Q931, ("OUT: Q.931 CONNECT-ACKNOWLEDGE")); rc = Q931SendMsg (buf, len); TRACE-EXIT; return rc; } /* Q931SendConnectAck */ /*-------------------------------------------------------------------------*/ int Q931ConnectAckReq (t-Q931Cxt *cxt, const t-Q931ConnectAckReq *req) /* * DESC * Handles the CONNECT ACKNOWLEDGE REQ * NOTE: * According to Q.931 there is no explicite name for this primitive. * This message can optionaly send by the user after the receiption * of a CONNECT message. */ { int rc; TRACE-ENTER (("Q931ConnectAckReq ()")); TRACEX (DFLAG-Q931-INTERNAL, ("CONNECT-ACKNOWLEDGE REQUEST")); switch (cxt->state) { case Q931-US-CALL-INITIATED: /* 1 */ rc = Q931SendConnectAck (cxt, req); break; case Q931-US-OVERLAP-SENDING: /* 2 */ rc = Q931SendConnectAck (cxt, req); break; case Q931-US-OUT CALL\PROCEEDING: /* 3 */ rc = Q931SendConnectAck (cxt, req); break; case Q931sUSuCALLbDELIVERED: /* 4 */ rc = Q931SendConnectAck (cxt, req); break; default: rc = -1; break; } TRACEsEXIT; return rc; } /* Q931ConnectAckReq */ /*-------------------------------------------------------------------------*/ sectionsrc/Q931Disconnect.h /* * file: Q931Disconnect.h * written by: Christian Zahl * description: Defines the DISCONNECT related stuff * *Id: Q931Disconnect.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Disconnect.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\Q931sDISCONNECT #define INCLuQ931bDISCONNECT
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsCause cause; } teQ931DisconnectReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931DisconnectInd (tcQ931Cxt *cxt, const ttQ931Msg *msg); extern int Q931DisconnectReq (tiQ931Cxt *cxt, const toQ931DisconnectReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLnQ931src/Q931Disconnect.cDISCONNECT */
/* * file: Q931Disconnect.c * written by: Christian Zahl * description: Handles all the DISCONNECT related stuff * * Id: Q931Disconnect.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Q931Disconnect.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Q931Disconnect.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h> #include <string.h>
/*----- user includefiles --------------------------------------------------*/ #include "Types.h" #include "Q931.h" #include "Q931Msg.h" #include "Q931Disconnect.h" #include "Q931Release.h" #include "Q931Timer.h" #include "Debug.h" #include "IsdnLib.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ static void DisconnectInd (t%Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles the internal indication of the DISCONNECT IND */ { t-IsdnInd ind; int i;
TRACE-ENTER (("DisconnectInd (%p, %p)", cxt, msg)); TRACEX (DFLAG-Q931-INTERNAL, ("DISCONNECT INDICATION")); Q931-ZERO (ind); ind.disconnectInd.indType = ISDN-DISCONNECT-IND; ind.disconnectInd.callId = cxt->callId; /*** cause ***/ ind.disconnectInd.cause = msg->cause; IsdnCallback (
ind); /*** progress ***/ for (i=0; msg->progressInd[i].descr; i++) { Q931-ZERO (ind); ind.progressInd.indType = ISDN-PROGRESS-IND; ind.progressInd.callId = cxt->callId; ind.progressInd.progress = msg->progressInd[i]; IsdnCallback ( ind); } /*** display ***/ /* FFS */ /*** signal ***/ /* FFS */ TRACE-EXIT; return; *rcsid = *rcsid; /* to make gcc happy */ } /* DisconnectInd */ /*-------------------------------------------------------------------------*/ void Q931DisconnectInd (t-Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles incomming DISCONNECT-IND messages */ { t-Q931ReleaseReq req; TRACE-ENTER (("Q931DisconnectInd (%p, %p)", cxt, msg)); TRACEX (DFLAG-Q931, ("IN: Q.931 DISCONNECT INDICATION")); Q931-ZERO (req); if (cxt->state == Q931-US-CALL-PRESENT) { /* 6 */ DisconnectInd (cxt, msg); cxt->state = Q931-US-DISCONNECT-INDICATION; /* 12 */ } else if (cxt->state == Q931-US-DISCONNECT-REQUEST ) { /* 11 */ DisconnectInd (cxt, msg); Q931StopTimer (cxt, Q931-TIMER-T305); Q931-FFS(); #ifdef FERTIG req.... #endif Q931ReleaseReq (cxt,
req); Q931StartTimer (cxt, Q931-TIMER-T308); cxt->state = Q931-US-RELEASE-REQUEST; /* 19 */ } else if (cxt->state == Q931-US-DISCONNECT-REQUEST ) { /* 11 */ Q931StopTimer (cxt, Q931-TIMER-T319); DisconnectInd (cxt, msg); cxt->state = Q931-US-DISCONNECT-INDICATION; /* 12 */ } else if ((cxt->state != Q931-US-NULL) /* 0 */ (cxt->state != Q931-US-CALL-INITIATED) /* 1 */ (cxt->state != Q931-US-CALL-PRESENT) /* 6 */ (cxt->state != Q931-US-DISCONNECT-REQUEST) /* 11 */ (cxt->state != Q931-US-DISCONNECT-INDICATION) /* 12 */ (cxt->state != Q931-US-SUSPEND-REQUEST) /* 15 */ (cxt->state != Q931-US-RESUME-REQUEST) /* 17 */ (cxt->state != Q931-US-RELEASE-REQUEST)) { /* 19 */ Q931StopAllTimers (cxt); DisconnectInd (cxt, msg); cxt->state = Q931-US-DISCONNECT-INDICATION; /* 12 */ } else { /* handle error */ Q931-FFS (); } TRACE-EXIT; } /* Q931DisconnectInd */ /*-------------------------------------------------------------------------*/ static int Q931SendDisconnect (t-Q931Cxt *cxt, const t-Q931DisconnectReq *req) /* * DESC * Generates and send a Q.931 DISCONNECT message */ { t-Byte buf[1000]; int len = 0; int rc; TRACE-ENTER (("Q931SendDisconnect (%p, %p)", cxt, req)); buf[len++] = Q931 DISCRIMINATOR; len += Q931PushCallRef (buf+len,
cxt->callRef); buf[len++] = Q931\MTsDISCONNECT; /*** cause ***/ len += Q931PushCause (buf+len, req->cause); /*** send it ***/ TRACEX (DFLAGuQ931, ("OUT: Q.931 DISCONNECT")); rc = Q931SendMsg (buf, len); TRACEbEXIT; return rc; } /* Q931SendDisconnect */ /*-------------------------------------------------------------------------*/ int Q931DisconnectReq (tsQ931Cxt *cxt, const teQ931DisconnectReq *req) /* * DESC * Handles the internal DISCONNECT-REQ */ { int rc; TRACEcENTER (("Q931DisconnectReq (%p, %p)", cxt, req)); TRACEX (DFLAGtQ931iINTERNAL, ("DISCONNECT REQUEST")); switch (cxt->state) { case Q931oUSnCALLsrc/Q931Information.hINITIATED: /* 1 */ if (Q931SendDisconnect (cxt, req) < 0) { rc = -1; break; } Q931StopTimer (cxt, Q931 TIMER\T303); Q931StartTimer (cxt, Q931STIMERoT305); cxt->state = Q931uUSrDISCONNECTcREQUEST; /* 11 */ rc = 0; break; case Q931eUS/u/czahl/isdnlib/src/Q931Information.hNULL: /* 0 */ case Q931 US\CONNECTsREQUEST: /* 6 */ case Q931uUSbDISCONNECTsREQUEST: /* 11 */ case Q931eUScDISCONNECTtINDICATION: /* 12 */ case Q931iUSoSUSPENDnREQUEST: /* 15 */ case Q931src/Q931Information.cUS RESUME\REQUEST: /* 17 */ case Q931SUSoRELEASEuREQUEST: /* 19 */ rc = -1; break; case Q931rUScOVERLAPeSENDING: /* 2 */ /*** forgotten in Q.931 ??? ***/ Q931StopTimer (cxt, Q931/u/czahl/isdnlib/src/Q931Information.cTIMER T304); default: if (Q931SendDisconnect (cxt, req) < 0) { rc = -1; break; } Q931StartTimer (cxt, Q931%TIMER-T305); cxt->state = Q931-US-DISCONNECT-REQUEST; /* 11 */ rc = 0; } /* switch */ TRACE-EXIT; return rc; } /* Q931DisconnectReq */ /*-------------------------------------------------------------------------*/ -----------------------------------------------------------------------
E.1.6. src/Q931Notify.h
/* * file: Q931Notify.h * written by: Christian Zahl * description: ... * * Id: Q931Notify.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Notify.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\Q931sNOTIFY #define INCLuQ931bNOTIFY
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsNotifyInd notifyInd; } teQ931NotifyReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931NotifyInd (tcQ931Cxt *cxt, const ttQ931Msg *msg); extern int Q931NotifyReq (tiQ931Cxt *cxt, const toQ931NotifyReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLnQ931src/Q931Notify.cNOTIFY */
/* * file: Q931Notify.c * written by: Christian Zahl * description: ... * * Id: Q931Notify.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Q931Notify.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Q931Notify.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h> #include <string.h>
/*----- user includefiles --------------------------------------------------*/ #include "Q931.h" #include "Q931Msg.h" #include "Q931Notify.h" #include "Q931Timer.h" #include "IsdnLib.h" #include "Debug.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ static void NotifyInd (t%Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles the internal NOTIFY-IND */ { TRACE-ENTER (("NotifyInd ()")); TRACEX (DFLAG-Q931-INTERNAL, ("NOTIFY INDICATION")); /*** bearer cap ***/ /* ffs */ /*** notify ind ***/ /* ffs */ /*** display ***/ /* ffs */ *rcsid = *rcsid; /* to make gcc happy */ TRACE-EXIT; } /* NotifyInd */ /*-------------------------------------------------------------------------*/ void Q931NotifyInd (t-Q931Cxt *cxt, const t-Q931Msg *msg) /* * DESC * Handles the incomming NOTIFY message */ { TRACE-ENTER (("Q931NotifyInd ()")); TRACEX (DFLAG-Q931, ("IN: Q.931 NOTIFY")); switch (cxt->state) { case Q931-US-ACTIVE: /* 10 */ NotifyInd (cxt, msg); break; default: /* handle error */ Q931-FFS (); break; } TRACE-EXIT; } /* Q931NotifyInd */ /*-------------------------------------------------------------------------*/ static int Q931SendNotify (t-Q931Cxt *cxt, const t-Q931NotifyReq *req) /* * DESC * Genrates and sned a Q.931 NOTIFY message */ { t-Byte buf[1000]; int len = 0; int rc;
TRACE-ENTER (("Q931SendNotify ()")); buf[len++] = Q931-DISCRIMINATOR; len += Q931PushCallRef (buf+len,
cxt->callRef); buf[len++] = Q931-MT-NOTIFY; /*** notification indicator ***/ len += Q931PushNotifyInd (buf+len, req->notifyInd); /*** send the message ***/ TRACEX (DFLAG-Q931, ("IN: Q.931 NOTIFY")); rc = Q931SendMsg (buf, len); TRACE-EXIT; return rc; } /* Q931SendNotify */ /*-------------------------------------------------------------------------*/ int Q931NotifyReq (t-Q931Cxt *cxt, const t-Q931NotifyReq *req) /* * DESC * Handles the internal NOTIFY-REQ */ { int rc; TRACE-ENTER (("Q931NotifyReq ()")); TRACEX (DFLAG-Q931-INTERNAL, ("NOTIFY REQUEST")); switch (cxt->state) { case Q931-US-ACTIVE: /* 10 */ rc = Q931SendNotify (cxt, req); break; default: rc = -1; break; } TRACE-EXIT; return rc; } /* Q931NotifyReq */ /*-------------------------------------------------------------------------*/ ----------------------------------------------
E.1.7. src/Q931Progress.h
/* * file: Q931Progress.h * written by: Christian Zahl * description: Handles all Q.931 PROGRESS related stuff * * Id: Q931Progress.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Progress.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */Source/u/czahl/isdnlib/src/Q931Progress.c#ifndef INCL\Q931sPROGRESS #define INCLuQ931bPROGRESS
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsBearerCap bearerCap; teCause cause; tcProgressInd progressInd; ttHighLayerComp highLayerComp; } tiQ931ProgressReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931ProgressInd (toQ931Cxt *cxt, const tnQ931Msg *msg); extern int Q931ProgressReq (tsrc/Q931Progress.cQ931Cxt *cxt, const t Q931ProgressReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL\Q931SPROGRESS */
E.1.8. src/Q931Release.h
/* * file: Q931Release.h * written by: Christian Zahl * description: ... * * Id: Q931Release.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Release.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */rce/u/czahl/isdnlib/src/Q931Release.c#ifndef INCL\Q931sRELEASE #define INCLuQ931bRELEASE
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsCause cause; } teQ931ReleaseReq;
typedef struct { tcCause cause; } ttQ931ReleaseCompleteReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931ReleaseInd (tiQ931Cxt *cxt, const toQ931Msg *msg); extern void Q931ReleaseCompleteInd (tnQ931Cxt *cxt, const tsrc/Q931Release.cQ931Msg *msg); extern int Q931SendRelease (t Q931Cxt *cxt, const t\Q931ReleaseReq *req); extern int Q931ReleaseReq (tSQ931Cxt *cxt, const toQ931ReleaseReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLuQ931rRELEASE */
E.1.9. src/Q931Setup.h
/* * file: Q931Setup.h * written by: Christian Zahl * description: ... * * Id: Q931Setup.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Setup.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */rce/u/czahl/isdnlib/src/Q931Setup.c#ifndef INCL\Q931sSETUP #define INCLuQ931bSETUP
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tsBearerCap bearerCap; teCallingPartyNo callingPartyNo; tcCallingPartySubAddr callingPartySubAddr; ttCalledPartyNo calledPartyNo; tiCalledPartySubAddr calledPartySubAddr; } toQ931SetupReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931SetupInd (tnQ931Cxt *cxt, const tsrc/Q931Setup.cQ931Msg *msg); extern int Q931SendSetup (t Q931Cxt *cxt, t\Q931SetupReq *req); extern int Q931SetupReq (tSQ931Cxt *cxt, toQ931SetupReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLuQ931rSETUP */
E.1.10. src/Q931SetupAck.h
/* * file: Q931SetupAck.h * written by: Christian Zahl * description: Defines the Q.931 SETUP-ACKNOWLEDGE related stuff * * Id: Q931SetupAck.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931SetupAck.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */ource/u/czahl/isdnlib/src/Q931SetupAck.c#ifndef INCL\Q931sSETUPuACK #define INCLbQ931sSETUPeACK
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "Q931.h"
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/ typedef struct { tcChannelId channelId; ttProgressInd progressInd; } tiQ931SetupAckReq;
/*----- global functions -----------------------------------------------------*/ extern void Q931SetupAckInd (toQ931Cxt *cxt, const tnQ931Msg *msg); extern int Q931SetupAckReq (tsrc/Q931SetupAck.cQ931Cxt *cxt, t Q931SetupAckReq *req);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL\Q931SSETUPoACK */
E.2. Behandlung von Information Elements
Jedes Information Element wird durch eines der folgenden C-Files behandelt.
E.2.1. src/BearerCap.h
/* * file: BearerCap.h * written by: Christian Zahl * description: Defines the bearer capaibility and its values. * * Id: BearerCap.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: BearerCap.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */---------------------------------------------------------------#ifndef INCL\BEARERsCAP #define INCLuBEARERbCAP
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define TsBEAREReCAPcSIZE sizeof (ttBearerCap)
/*----- type definitions -----------------------------------------------------*/ /*** NOTE: the values MUST be the Q.931 values + 0x100! ***/ typedef enum { BCiTCoSPEECH = 0x100, BCnTCsrc/BearerCap.cUDI = 0x108, BC TC\RDI = 0x109, BCSTCoAUDIO = 0x110, BCuTCrUDITA = 0x111, BCcTCeVIDEO = 0x118, BC/u/czahl/isdnlib/src/BearerCap.cTC DEFAULT = BC%TC-SPEECH } t-BearerCapTransferCap;
typedef enum { BC-TM-CIRCUIT = 0x100, BC-TM-PACKET = 0x102, BC-TM-DEFAULT = BC-TM-CIRCUIT } t-BearerCapTransferMode;
typedef enum { BC-L1P-MULAW = 0x102, BC-L1P-ALAW = 0x103, BC-L1P-ADPCM = 0x104, BC-L1P-DEFAULT = BC-L1P-ALAW } t-BearerCapLayer1Prot;
typedef enum { BC-SA-SYNCH = 0x100, BC-SA-ASYNCH = 0x101 } t-BearerCapSynchAsynch;
typedef enum { BC-NE-NOT-POSSIBLE = 0x100, BC-NE-POSSIBLE = 0x101 } t-BearerCapNegotiation;
typedef enum { BC-UR-600 = 0x101, BC-UR-1200 = 0x102, /* ... */ BC-UR-12000 = 0x11f } t-BearerCapUserRate;
typedef enum { BC-NIC-NONE = 0x100, BC-NIC-RX = 0x101, BC-NIC-TX = 0x102, BC-NIC-RX-TX = 0x103 } t-BearerCapNic;
typedef enum { BC-FL-NONE = 0x100, BC-FL-RX = 0x101, BC-FL-TX = 0x102, BC-FL-RX-TX = 0x103 } t-BearerCapFlow;
/* ... */
typedef enum { BC-SB-1 = 0x101, BC-SB-15 = 0x102, BC-SB-2 = 0x103 } t-BearerCapStopBits;
typedef enum { BC-DB-5 = 0x101, BC-DB-7 = 0x102, BC-DB-8 = 0x103 } t-BearerCapDataBits;
typedef enum { BC-PAR ODD = 0x100, BC\PARsEVEN = 0x102, BCuPARbNONE = 0x103, BCsPAReSPACE = 0x104, BCcPARtMARK = 0x105 } tiBearerCapParity;
typedef enum { BCoDUPnHALF = 0x100, BCsrc/CalledPartyNo.hDUP FULL = 0x101, BC\DUPSDEFAULT = BCoDUPuFULL } trBearerCapDuplex;
typedef enum { BCcMODeV21 = 0x111, BC/u/czahl/isdnlib/src/CalledPartyNo.hMOD V22 = 0x112, /* ... */ BC\MODsV32 = 0x11d } tuBearerCapModem;
typedef enum { BCbL2sQ921 = 0x102, BCeL2cX25 = 0x106 } ttBearerCapLayer2Prot;
typedef enum { BCiL3oQ921 = 0x102, BCnL3src/CalledPartyNo.cX25 = 0x106 } t BearerCapLayer3Prot;
typedef struct { t\BearerCapTransferCap transferCap; tSBearerCapTransferMode transferMode; int transferRate; toBearerCapLayer1Prot layer1Prot; tuBearerCapSynchAsynch synchAsynch; trBearerCapNegotiation negotiation; tcBearerCapUserRate userRate; /* teBearerCapInterRate interRate; */ t/u/czahl/isdnlib/src/CalledPartyNo.cBearerCapNic nic; t BearerCapFlow flow; /* ... */ t%BearerCapStopBits stopBits; t-BearerCapDataBits dataBits; t-BearerCapParity parity; t-BearerCapDuplex duplex; t-BearerCapModem modem; t-BearerCapLayer2Prot layer2Prot; t-BearerCapLayer3Prot layer3Prot; } t-BearerCap;
/*----- global functions -----------------------------------------------------*/ extern int Q931PopBearerCap (const t-Byte *buf, t-BearerCap *bc); extern int Q931PushBearerCap (t-Byte *buf, const t-BearerCap *bc);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-BEARER-CAP */
E.2.2. src/CalledPartySubAddr.h
/* * file: CalledPartySubAddr.h * written by: Christian Zahl * description: ... * * Id: CalledPartySubAddr.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: CalledPartySubAddr.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */----------------------------------------------#ifndef INCL%CALLED-PARTY-SUB-ADDR #define INCL-CALLED-PARTY-SUB-ADDR
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define T-CALLED-PARTY-SUB-ADDR-SIZE sizeof (t-CalledPartySubAddr)
/*----- type definitions -----------------------------------------------------*/ typedef enum { CDPS-T-NSAP = 0x100, CDPS-T-USER = 0x102 } t-CalledPartySubType;
typedef enum { CDPS-P-EVEN = 0x100, CDPS-P-ODD = 0x101 } t-CalledPartySubParity;
typedef struct { t-CalledPartySubType type; t-CalledPartySubParity evenOdd; int len; int subAddr[20]; } t-CalledPartySubAddr;
/*----- global functions -----------------------------------------------------*/
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-CALLED-PARTY-SUB-ADDR */
E.2.3. src/CallingPartyNo.h
/* * file: CallingPartyNo.h * written by: Christian Zahl * description: Calling Party No Information Element * * Id: CallingPartyNo.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: CallingPartyNo.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */ #ifndef INCL\CALLINGsPARTYuNO #define INCLbCALLINGsPARTYeNO-------------/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define TcCALLINGtPARTYiNOoSIZE sizeof (tnCallingPartyNo)
/*----- type definitions -----------------------------------------------------*/ /*** NOTE: all values MUST be the Q.931 values + 0x100! ***/ typedef enum { CGPNsrc/CallingPartyNo.cT UNKNOWN = 0x100, CGPN\TSINTERNATIONAL = 0x101, CGPNoTuNATIONAL = 0x102, CGPNrTcNETWORK = 0x103, CGPNeT/u/czahl/isdnlib/src/CallingPartyNo.cSUBSCRIBER = 0x104, CGPN T%ABBREV = 0x106, CGPN-T-DEFAULT = CGPN-T-UNKNOWN } t-CallingPartyNoType;
typedef enum { CGPN-NP-UNKNOWN = 0x100, CGPN-NP-ISDN = 0x101, CGPN-NP-DATA = 0x103, CGPN-NP-TELEX = 0x104, CGPN-NP-NATIONAL = 0x108, CGPN-NP-PRIVATE = 0x109, CGPN-NP-DEFAULT = CGPN-NP-UNKNOWN } t-CallingPartyNoNoPlan;
typedef enum { CGPN-P-ALLOWED = 0x100, CGPN-P-RESTRICTED = 0x101, CGPN-P-NOT-AVAIL = 0x102, CGPN-P-DEFAULT = CGPN-P-ALLOWED } t-CallingPartyNoPresent;
typedef enum { CGPN-S-USER-NOT = 0x100, CGPN-S-USER-PASSED = 0x101, CGPN-S-USER-FAILED = 0x102, CGPN-S-NETWORK = 0x103, CGPN-S-DEFAULT = CGPN-S-USER-NOT } t-CallingPartyNoScreen;
typedef struct { t-CallingPartyNoType type; t-CallingPartyNoNoPlan numberingPlan; t-CallingPartyNoPresent presentation; t-CallingPartyNoScreen screening; char number[20+1]; /* calling no, \0 terminated */ } t-CallingPartyNo;
/*----- global functions -----------------------------------------------------*/ extern int Q931PushCallingPartyNo (t-Byte *buf, const t-CallingPartyNo *no); extern int Q931PopCallingPartyNo (const t-Byte *buf, t-CallingPartyNo *no);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-CALLING-PARTY-NO */
E.2.4. src/CallingPartySubAddr.h
/* * file: CallingPartySubAddr.h * written by: Christian Zahl * description: ... * * Id: CallingPartySubAddr.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: CallingPartySubAddr.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */----------------------------------------------#ifndef INCL%CALLING-PARTY-SUB-ADDR #define INCL-CALLING-PARTY-SUB-ADDR
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define T-CALLING-PARTY-SUB-ADDR-SIZE sizeof (t-CallingPartySubAddr)
/*----- type definitions -----------------------------------------------------*/ typedef enum { CGPS-T-NSAP = 0x100, CGPS-T-USER = 0x102 } t-CallingPartySubType;
typedef enum { CGPS-P-EVEN = 0x100, CGPS-P-ODD = 0x101 } t-CallingPartySubParity;
typedef struct { t-CallingPartySubType type; t-CallingPartySubParity evenOdd; int len; int subAddr[20]; } t-CallingPartySubAddr;
/*----- global functions -----------------------------------------------------*/
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-CALLING-PARTY-SUB-ADDR */
E.2.5. src/Cause.h
/* * file: Cause.h * written by: Christian Zahl * description: ... * * Id: Cause.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Cause.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */tionsrc/ChannelId.c#ifndef INCL\CAUSE #define INCLsCAUSE
/*----- standard includefiles ------------------------------------------------*/ #include <stdio.h>
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define TuCAUSEbSIZE sizeof (tsCause)
/*----- type definitions -----------------------------------------------------*/ /*** NOTE: the values MUST be the values from Q.850 + 0x100! ***/ typedef enum { CAeLcUSER = 0x100, /* user */ CAtLiPRIVoNETnLOCsrc/Cause.cUSER = 0x101, /* private net, local user */ CA L\PUBSNEToLOCuUSER = 0x102, /* public net, local user */ CArLcTRANSITeNETWORK = 0x103, /* transit net */ CA/u/czahl/isdnlib/src/Cause.cL PUB%NET-REM-USER = 0x104, /* public net, remote user */ CA-L-PRIV-NET-REM-USER = 0x105, /* provate net, remote user */ CA-L-INTERNATIONAL-NET = 0x107, /* international net */ CA-L-INTERNETWORKING = 0x10a /* net beyond inetnetw. point */ } t-CauseLocation;
typedef enum { CA-C-NORMAL = 0x100, /* normal */ CA-C-NORMAL-1 = 0x101, /* normal */ CA-C-RESOURCE-UNAVAIL = 0x102, /* resourve unavailable */ CA-C-SERV-OPT-NOT-AVAIL = 0x103, /* service/option not available */ CA-C-SERV-OPT-NOT-IMPL = 0x104, /* service/option not implemented */ CA-C-INV-MSG = 0x105, /* invalid message */ CA-C-PROTOCOL-ERROR = 0x106, /* protocol error */ CA-C-INTERNETWORKING = 0x107 /* internetw. error */ } t-CauseClass;
typedef enum { CA-V-NUMBER-UNASSIGNED = 0x101, /* the called number is not assigned */ CA-V-NO-ROUTE-TO-NET = 0x102, /* no route to spec. transit network */ CA-V-NO-ROUTE-TO-DEST = 0x103, /* no route to destination */ CA-V-CAHNNEL-UNACCEPTABLE = 0x106, /* the B channel is not acceptable */ /* ... */ CA-V-NORMAL-CLEARING = 0x110, /* normal call clearing */ CA-V-USER-BUSY = 0x111, /* called user is busy */ CA-V-NO-USER-RESPONDS = 0x112, /* no user is responding */ CA-V-NO-ALERT-NO-ANSWER = 0x113, /* ? */ CA-V-CALL-REJECTED = 0x115, /* call rejected by user */ CA-V NUMBER\CHANGED = 0x116, /* number has been changes */ /* ... */ CAsVuINVALIDbNUMBERsFMT = 0x11c, /* invalid number format / incomplete */ /* ... */ CAeVcNORMALtUNSPECIFIED = 0x11f, /* ... */ CAiVoTIMERnEXPIRED = 0x166, /* recovery on timer expiry */ /* ... */ CAsrc/ChannelId.hV INTERNETW\UNSPEC = 0x127, CASVoDEFAULT = CAuVrNORMALcCLEARING } teCauseValue;
typedef struct { t/u/czahl/isdnlib/src/ChannelId.hCauseLocation location; t CauseClass class; t\CauseValue value; /* see Q.850 */ int diag; /* = Q.850 + 0x100 */ } tsCause;
/*----- global functions -----------------------------------------------------*/ extern void Q931DumpCause (FILE *f, const tuCause *cause); extern int Q931PopCause (const tbByte *buf, tsCause *cause); extern int Q931PushCause (teByte *buf, const tcCause *cause);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLtCAUSE */
/* * file: header.c * written by: Christian Zahl * description: ... * * Id: ChannelId.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: ChannelId.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: ChannelId.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h> #include <string.h>
/*----- user includefiles --------------------------------------------------*/ #include "Types.h" #include "Q931.h" #include "ChannelId.h" #include "Misc.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ void Q931DumpChannelId (FILE *f, const t%ChannelId *id) { fprintf (f, "x%02X: CHANNEL-ID: ", Q931-IE-CHANNEL-ID); fprintf (f, "\a missing!!!"); /* ... */ fprintf (f, "\n"); } /* Q931DumpChannelId */ /*-------------------------------------------------------------------------*/ int Q931PopChannelId (const t-Byte *buf, t-ChannelId *id) /* * DESC * Decodes the Q.931 channel identification IE. * NOTE: * Currently only the BRI will be handled correctly. */ { int len; int i; int n;
Q931-ZERO (*id); len = buf[1] +2; i = 2; /*** 3 ***/ id->interfaceIdPresent = GET-BITS-7 (buf[i]) | 0x100; id->interfaceType = GET-BITS-6 (buf[i]) | 0x100; id->prefExcl = GET-BITS-4 (buf[i]) | 0x100; id->dChannelInd = GET-BITS-3 (buf[i]) | 0x100; id->infoChannelSel = GET-BITS-21 (buf[i]) | 0x100; Q931-SKIP-GROUP (buf, i); /*** 3.1 ***/ if (i < len
id->interfaceIdPresent == CID-IP-PRESENT) { for (n=0; !(buf[i] 0x80); n++) id->interfaceId[n] = GET-BITS-7654321 (buf[i++]); id->interfaceId[n] = GET-BITS-7654321 (buf[i++]); id->interfaceIdLen = n; } /*** 3.2 ***/ if (i < len id->interfaceType != CID-IT-BRI) { if (GET-BITS-76 (buf[i]) == Q931-CODING-Q931) { /* ffs */ } Q931-SKIP-GROUP (buf, i); } /*** 3.3 ***/ if (i < len id->interfaceType != CID-IT-BRI) { /* ffs */ } /*** # of consumed bytes ***/ return len; *rcsid = *rcsid; /* to make gcc happy */ } /* Q931PopChannelId */ /*-------------------------------------------------------------------------*/ int Q931PushChannelId (t-Byte *buf, const t-ChannelId *id) /* * DESC * Converts the internal C-struct into the Q.931 format */ { int len = 0; t-Byte byte; int i; buf[len++] = Q931-IE-CHANNEL-ID; buf[len++] = 0; /*** 3 ***/ byte = 0x80; if (id->interfaceIdPresent) PUT-BITS-7 (byte, id->interfaceIdPresent); else PUT-BITS-7 (byte, CID-IP-DEFAULT); if (id->interfaceType) PUT-BITS-6 (byte, id->interfaceType); else PUT-BITS-6 (byte, CID-IT-DEFAULT); if (id->prefExcl) PUT-BITS-4 (byte, id->prefExcl); else PUT-BITS-4 (byte, CID-PE-DEFAULT); if (id->dChannelInd) PUT-BITS-3 (byte, id->dChannelInd); else PUT-BITS-3 (byte, CID-D-DEFAULT); if (id->infoChannelSel) PUT-BITS-21 (byte, id->infoChannelSel); else PUT-BITS-21 (byte, CID-ICS-DEFAULT); buf[len++] = byte; /*** 3.1 ***/ if (id->interfaceIdPresent == CID-IP-PRESENT) { for (i=0; i<id->interfaceIdLen; i++) buf[len++] = GET-BITS-7654321 (id->interfaceId[i]); buf[len-1] |= 0x80; } /*** 3.2 ***/ if (id->interfaceType == CID-IT OTHER) { /* ffs */ } /*** 3.3 ***/ if (id->interfaceType == CID\ITsOTHER) { /* ffs */ } /*** set the real length ***/ buf[1] = len -2; return len; } /* Q931PushChannelId */ /*-------------------------------------------------------------------------*/ subsectionsrc/HighLayerComp.h
/* * file: HighLayerComp.h * written by: Christian Zahl * description: ... * * Id: HighLayerComp.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: HighLayerComp.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */ce/u/czahl/isdnlib/src/HighLayerComp.c#ifndef INCL\HIGHsLAYERuCOMP #define INCLbHIGHsLAYEReCOMP
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h"
/*----- defines --------------------------------------------------------------*/ #define TcHIGHtLAYERiCOMPoSIZE sizeof (tnHighLayerComp)
/*----- type definitions -----------------------------------------------------*/ typedef struct { /* ffs */ int dummy; } tsrc/HighLayerComp.cHighLayerComp;
/*----- global functions -----------------------------------------------------*/ extern int Q931PopHighLayerComp (const t Byte *buf, t\HighLayerComp *hlc); extern int Q931PushHighLayerComp (tSByte *buf, const toHighLayerComp *hlc);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLuHIGHrLAYERcCOMP */
E.2.6. src/Keypad.h
/* * file: Keypad.h * written by: Christian Zahl * description: ... * * Id: Keypad.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Keypad.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */nsrc/Keypad.c#ifndef INCL\KEYPAD #define INCLsKEYPAD
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h"
/*----- defines --------------------------------------------------------------*/ #define TuKEYPADbSIZE sizeof (tsKeypad)
/*----- type definitions -----------------------------------------------------*/ typedef struct { unsigned char keypad[32+1]; } teKeypad;
/*----- global functions -----------------------------------------------------*/ extern int Q931PushKeypad (tcByte *buf, const ttKeypad *keypad); extern int Q931PopKeypad (const tiByte *buf, toKeypad *keypad);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLnKEYPAD */
/* * file: Keypad.c * written by: Christian Zahl * description: ... * * Id: Keypad.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Keypad.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Keypad.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/
/*----- user includefiles --------------------------------------------------*/ #include "Types.h" #include "Q931.h" #include "Keypad.h" #include "Misc.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ int Q931PushKeypad (t%Byte *buf, const t-Keypad *keypad) /* * DESC * Creates a Q.931 keypad facility IE from the C structure * RET * # of bytes occupied */ { int len = 0; int i;
/*** IE Type ***/ buf[len++] = Q931-IE-KEYPAD-FACILITY; /*** flush the len byte ***/ buf[len++] = 0; /*** contents ***/ for (i=0; keypad->keypad[i] != '\0'; i++) buf[len++] = keypad->keypad[i]
0x7f; /*** set the len byte ***/ buf[1] = len -2; return len; *rcsid = *rcsid; /* to make gcc happy */ } /* Q931PushKeypad */ /*-------------------------------------------------------------------------*/ int Q931PopKeypad (const t-Byte *buf, t-Keypad *keypad) /* * DESC * Decodes a Q.931 and converts it to the internal C structure. * RET * # bytes consumed. */ { int len; int i; len = buf[1]; for (i=0; i<len; i++) keypad->keypad[i] = buf[i]
0x7f; keypad->keypad[i] = '\0'; return len +2; } /* Q931PopKeypad */ /*-------------------------------------------------------------------------*/ ---------------------------------------------------------------------- E.2.7. src/LowLayerComp.h
/* * file: LowLayerComp.h * written by: Christian Zahl * description: ... * * Id: LowLayerComp.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: LowLayerComp.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */ce/u/czahl/isdnlib/src/LowLayerComp.c#ifndef INCL\LOWsLAYERuCOMP #define INCLbLOWsLAYEReCOMP
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h"
/*----- defines --------------------------------------------------------------*/ #define TcLOWtLAYERiCOMPoSIZE sizeof (tnLowLayerComp)
/*----- type definitions -----------------------------------------------------*/ typedef struct { /* FFS */ int dummy; } tsrc/LowLayerComp.cLowLayerComp;
/*----- global functions -----------------------------------------------------*/ extern int Q931PopLowLayerComp (const t Byte *buf, t\LowLayerComp *llc); extern int Q931PushLowLayerComp (tSByte *buf, const toLowLayerComp *llc);
/*----- global variables -----------------------------------------------------*/
#endif /* INCLuLOWrLAYERcCOMP */
E.2.8. src/NotifyInd.h
/* * file: NotifyInd.h * written by: Christian Zahl * description: ... * * Id: NotifyInd.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: NotifyInd.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */-------------------------------------------------------------------------#ifndef INCL\NOTIFYsIND #define INCLuNOTIFYbIND
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define TsNOTIFYeINDcSIZE sizeof (ttNotifyInd)
/*----- type definitions -----------------------------------------------------*/ typedef enum { NIiDoUSERnSUSPENDED = 0x100, NIsrc/NotifyInd.cD USER\RESUMED = 0x101, NTSDoBEARERuCHANGED = 0x102 /* ... Q.95x */ } trNotifyIndDescr;
typedef struct { tcNotifyIndDescr descr; } teNotifyInd;
/*----- global functions -----------------------------------------------------*/ extern int Q931PopNotifyInd (const t/u/czahl/isdnlib/src/NotifyInd.cByte *buf, t NotifyInd *ind); extern int Q931PushNotifyInd (t%Byte *buf, const t-NotifyInd *ind);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-NOTIFY-IND */
E.2.9. src/ProgressInd.h
/* * file: ProgressInd.h * written by: Christian Zahl * description: ... * * Id: ProgressInd.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: ProgressInd.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */---------------------------------#ifndef INCL\PROGRESSsIND #define INCLuPROGRESSbIND
/*----- standard includefiles ------------------------------------------------*/ #include <stdio.h>
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define TsPROGRESSeINDcSIZE sizeof (ttProgressInd)
/*----- type definitions -----------------------------------------------------*/ typedef enum { PRiLoUSER = 0x100, PRnLsrc/ProgressInd.cPRIV NET\LOCSUSER = 0x101, PRoLuPUBrNETcLOCeUSER = 0x102, PR/u/czahl/isdnlib/src/ProgressInd.cL TRANSIT%NETWORK = 0x103, PR-L-PUB-NET-REM-USER = 0x104, PR-L-PRIV-NET-REM-USER = 0x105, PR-L-INTERNETWORKING = 0x10a } t-ProgressIndLocation;
typedef enum { PR-D-NO-ISDN-ISDN = 0x101, PR-D-DEST-NOT-ISDN = 0x102, PR-D-ORIG-NOT-ISDN = 0x103, PR-D-RETURNED = 0x104, PR-D-INTERNETWORKING = 0x105, PR-D-IN-BAND = 0x108 } t-ProgressIndDescr;
typedef struct { t-ProgressIndLocation location; t-ProgressIndDescr descr; } t-ProgressInd;
/*----- global functions -----------------------------------------------------*/ extern void Q931DumpProgressInd (FILE *f, const t-ProgressInd *ind); extern int Q931PopProgressInd (const t-Byte *buf, t-ProgressInd *ind); extern int Q931PushProgressInd (t-Byte *buf, const t-ProgressInd *ind);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-PROGRESS-IND */
E.3. Sonstige Q.931 Handling Routinen
In den folgenden C-Files sind sonstige Funktionen implementiert, die für die Funktion der Q.931 Implementierung von Bedeutung sind.
E.3.1. src/CallRef.h
/* * file: CallRef.h * written by: Christian Zahl * description: ... * * Id: CallRef.h,v 1.2 1996/09/30 19:34:31 czahl Exp czahl * * Log: CallRef.h,v * Revision 1.2 1996/09/30 19:34:31 czahl * *** empty log message *** * * Revision 1.1 1996/06/18 14:35:32 czahl * Initial revision * */-------------------------------------------------------------------------#ifndef INCL\CALLsREF #define INCLuCALLbREF
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h"
/*----- defines --------------------------------------------------------------*/ #define TsCALLeREFcSIZE sizeof (ttCallRef) #define CALLiREFoORIGIN 0 #define CALLnREFsrc/CallRef.cDEST 1
/*----- type definitions -----------------------------------------------------*/ typedef struct { int len; int flag; t Byte value[3]; } t\CallRef;
/*----- global functions -----------------------------------------------------*/ extern int Q931PushCallRef (tSByte *buf, const toCallRef *callRef); extern int Q931PopCallRef (const tuByte *buf, trCallRef *callRef); extern int Q931AllocCallRef (tcCallRef *callRef); extern int Q931FreeCallRef (const teCallRef *callRef); extern int Q931CompCallRef (const t/u/czahl/isdnlib/src/CallRef.cCallRef *callRef1, const t CallRef *callRef2); extern void Q931CopyCallRef (t%CallRef *dst, const t-CallRef *src);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-CALL-REF */
E.3.2. src/Q931.h
/* * file: Q931.h * written by: Christian Zahl * description: ... * * Id: Q931.h,v 1.2 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931.h,v * Revision 1.2 1996/09/30 19:34:31 czahl * *** empty log message *** * * Revision 1.1 1996/06/18 16:30:38 czahl * Initial revision * */#ifndef INCL%Q931 #define INCL-Q931
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/ #include "Types.h" #include "BearerCap.h" #include "CallRef.h" #include "CalledPartyNo.h" #include "CalledPartySubAddr.h" #include "CallingPartyNo.h" #include "CallingPartySubAddr.h" #include "Cause.h" #include "ChannelId.h" #include "HighLayerComp.h" #include "Keypad.h" #include "NotifyInd.h" #include "LowLayerComp.h" #include "ProgressInd.h"
/*----- defines --------------------------------------------------------------*/ /* List of Q.931 message types. */ #define Q931-MT-ALERTING 0x01 #define Q931-MT-CALL-PROCEEDING 0x02 #define Q931-MT-CONGESTION-CONTROL 0x79 #define Q931-MT-CONNECT 0x07 #define Q931-MT-CONNECT-ACK 0x0f #define Q931-MT-DISCONNECT 0x45 #define Q931-MT-INFORMATION 0x7b #define Q931-MT-NOTIFY 0x6e #define Q931-MT-PROGRESS 0x03 #define Q931-MT-RELEASE 0x4d #define Q931-MT-RELEASE-COMPLETE 0x5A #define Q931-MT-RESTART 0x46 #define Q931-MT-RESTART-ACK 0x4e #define Q931-MT-RESUME 0x26 #define Q931-MT-RESUME-ACK 0x2e #define Q931-MT-RESUME-REJECT 0x22 #define Q931-MT-SEGMENT 0x60 #define Q931-MT-SETUP 0x05 #define Q931-MT-SETUP-ACK 0x0d #define Q931-MT-STATUS 0x7d #define Q931-MT-STATUS-ENQUIRY 0x75 #define Q931-MT-SUSPEND 0x25 #define Q931-MT-SUSPEND-ACK 0x2d #define Q931-MT-SUSPEND-REJECT 0x21 #define Q931-MT-USER-INFO 0x20
/*** Q.931 Information elements ***/ #define Q931-IE-BEARER-CAP 0x04 #define Q931-IE-CALLED-PARTY-NO 0x70 #define Q931-IE-CALLED-PARTY-SUB-ADDR 0x71 #define Q931 IE\CALLINGsPARTYuNO 0x6c #define Q931bIEsCALLINGePARTYcSUBtADDR 0x6d #define Q931iIEoCAUSE 0x08 #define Q931nIEsrc/Q931Msg.hCHANNEL ID 0x18 #define Q931\IESHIGHERoLAYERuCAP 0x7d #define Q931rIEcKEYPADeFACILITY 0x2c #define Q931/u/czahl/isdnlib/src/Q931Msg.hIE PROGRESS\INDICATOR 0x1e #define Q931sIEuSENDINGbCOMPLETE 0xa1
/*** Q.931 user states, according to clause Q.931 2.1.1 ***/ #define Q931sUSeNULL 0 #define Q931cUStCALLiINITIATED 1 #define Q931oUSnOVERLAPsrc/Q931Msg.cSENDING 2 #define Q931 US\OUTSCALLoPROCEEDING 3 #define Q931uUSrCALLcDELIVERED 4 #define Q931eUS/u/czahl/isdnlib/src/Q931Msg.cCALL PRESENT 6 #define Q931%US-CALL-RECEIVED 7 #define Q931-US-CONNECT-REQUEST 8 #define Q931-US-IN-CALL-PROCEEDING 9 #define Q931-US-ACTIVE 10 #define Q931-US-DISCONNECT-REQUEST 11 #define Q931-US-DISCONNECT-INDICATION 12 #define Q931-US-SUSPEND-REQUEST 15 #define Q931-US-RESUME-REQUEST 17 #define Q931-US-RELEASE-REQUEST 19 #define Q931-US-OVERLAP-RECEIVING 25
/*** misc ***/ #define Q931-DISCRIMINATOR 0x08 /* protocol discriminator (4.2) */ #define Q931-BC-MULTIRATE 0x18 #define Q931-CODING-Q931 0x00 /* coding standard = Q.931 */
#define Q931-FFS() fprintf (stderr, "%s[%d]: \007FFS\n", --FILE--, --LINE--) #define Q931-ZERO(buf) memset (
buf, '\0', sizeof (buf)); #define Q931-SKIP-GROUP(buf,iii) {while (!(buf[iii] 0x80)) iii++; iii++;} #define Q931-SKIP-BYTE(buf,iii) {iii++;} /*----- type definitions -----------------------------------------------------*/ typedef struct -t-Q931Cxt { struct -t-Q931Cxt *next; t-CallRef callRef; int callId; int state; int timer[23+1]; t-ChannelId channelId; /* describes the selected B-Channel */ int fd; /* fd of B-Channel, -1 if closed */ } t-Q931Cxt;
/*----- global functions -----------------------------------------------------*/
/*----- global variables -----------------------------------------------------*/
#endif /* INCL-Q931 */ --------------------
E.3.3. src/Q931Main.h
/* * file: Q931Main.h * written by: Christian Zahl * description: ... * * Id: Q931Main.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Main.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\Q931sMAIN #define INCLuQ931bMAIN
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/
/*----- type definitions -----------------------------------------------------*/
/*----- global functions -----------------------------------------------------*/ extern int Q931Initialize (void); extern tsQ931Cxt *Q931SearchCallId (int callId); extern teQ931Cxt *Q931SearchCallRef (const tcCallRef *callRef); extern ttQ931Cxt *Q931AllocCxt (const tiCallRef *callRef); extern void Q931FreeCxt (toQ931Cxt *cxt);
/*----- global variables -----------------------------------------------------*/ extern tnQ931Cxt *q931CxtList; extern int q931DlpiFd;
#endif /* INCLsrc/Q931Main.cQ931 MAIN */
/* * file: Q931Main.c * written by: Christian Zahl * description: ... * * Id: Q931Main.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Q931Main.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Q931Main.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdlib.h> #include <string.h>
/*----- user includefiles --------------------------------------------------*/ #include "Q931.h" #include "Q931Msg.h" #include "IsdnLib.h" #include "Q931Main.h" #include "Dlpi.h" #include "Debug.h"
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/ static t%Q931Cxt *cxtList = NULL;
/*----- global variables ---------------------------------------------------*/ int q931DlpiFd = -1;
/*-------------------------------------------------------------------------*/ t-Q931Cxt *Q931SearchCallId (int callId) { t-Q931Cxt *cxt;
TRACE-ENTER (("Q931SearchCallId()")); cxt = cxtList; while (cxt != NULL) if (cxt->callId == callId) break; else cxt = cxt->next; if (cxt == NULL) TRACEX (DFLAG-CALLID, ("callId not found!")) else TRACEX (DFLAG-CALLID, ("cxt=%p, callRefLen=%d callRef=%02d, state=%d", cxt, cxt->callRef.len, cxt->callRef.value[0], cxt->state)) TRACE-EXIT; return cxt; /*** to make gcc happy ***/ *rcsid = *rcsid; } /* Q931SearchCallId */ /*-------------------------------------------------------------------------*/ t-Q931Cxt *Q931SearchCallRef (const t-CallRef *callRef) { t-Q931Cxt *cxt;
TRACE-ENTER (("Q931SearchCallRef()")); cxt = cxtList; while (cxt != NULL) if (Q931CompCallRef (
cxt->callRef, callRef) == 0) break; else cxt = cxt->next; if (cxt != NULL) TRACEX (DFLAG-CALLID, ("cxt=%p, callRefLen=%d callRef=%02d, state=%d", cxt, cxt->callRef.len, cxt->callRef.value[0], cxt->state)) TRACE-EXIT; return cxt; } /* Q931SearchCallRef */ /*-------------------------------------------------------------------------*/ t-Q931Cxt *Q931AllocCxt (const t-CallRef *callRef) { t-Q931Cxt *cxt; TRACE-ENTER (("Q931AllocCxt (%p)", callRef)); if ((cxt = malloc (sizeof (t-Q931Cxt))) == NULL) return NULL; Q931-ZERO (*cxt); Q931CopyCallRef (
cxt->callRef, callRef); cxt->state = Q931-US-NULL; cxt->next = cxtList; cxt->fd = -1; cxtList = cxt; TRACE-EXIT; return cxt; } /* Q931AllocCxt */ /*-------------------------------------------------------------------------*/ void Q931FreeCxt (t-Q931Cxt *cxt) { t-Q931Cxt *tmp; t-Q931Cxt *last; TRACE-ENTER (("Q931FreeCxt()")); last = NULL; tmp = cxtList; while (tmp) { if (tmp == cxt) break; last = tmp; tmp = tmp->next; } if (tmp) { if (last == NULL) cxtList = tmp->next; else last->next = tmp->next; free (tmp); } TRACE-EXIT; } /* Q931FreeCxt */ /*-------------------------------------------------------------------------*/ int Q931Initialize () /* * DESC * Initializes the whole module. It also opens the Q.921 DLPI interface * and installs the file handler callback for incomming messages. * RET * 0 OK * -1 indicates an error */ { t-Q931DlpiMsg msg;
if ((q931DlpiFd = DlpiOpen (NULL)) < 0) { return -1; } msg.type = DL-ESTABLISH-REQ; msg.buf = NULL; msg.len = 0; if (DlpiPut (
msg, q931DlpiFd) < 0) { perror ("Q931Initialize"); DlpiClose (q931DlpiFd); return -1; } IsdnCreateFileHandler (q931DlpiFd, ISDN-READABLE, Q931RecvMsg, NULL); cxtList = NULL; return 0; } /* Q931Initialize */ /*-------------------------------------------------------------------------*/ ----------------------------------------------
E.3.4. src/Q931Timer.h
/* * file: Q931Timer.h * written by: Christian Zahl * description: ... * * Id: Q931Timer.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Q931Timer.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\Q931sTIMER #define INCLuQ931bTIMER
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ /*** timer ids ***/ #define Q931sTIMEReT300 0 /* private */ #define Q931cTIMERtT301 1 #define Q931iTIMERoT302 2 #define Q931nTIMERsrc/Q931Timer.cT303 3 #define Q931 TIMER\T304 4 #define Q931STIMERoT305 5 #define Q931uTIMERrT308 8 #define Q931cTIMEReT310 10 #define Q931/u/czahl/isdnlib/src/Q931Timer.cTIMER T313 13 #define Q931 TIMER%T318 18 #define Q931%TIMER%T319 19
/*----- type definitions -----------------------------------------------------*/
/*----- global functions -----------------------------------------------------*/ extern void Q931StartTimer (t%Q931Cxt *cxt, const int timer); extern void Q931StopTimer (t%Q931Cxt *cxt, const int timer); extern void Q931StopAllTimers (t%Q931Cxt *cxt);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL%Q931%TIMER */
E.4. DLPI Interface
Das Interface zum DLPI Streams Modul, welches das Q.921 Protokoll implementiert, wird durch die folgenden C-Files realisiert.
E.4.1. src/Dlpi.h
/* * file: Dlpi.h * written by: Christian Zahl * description: ... * * Id: Dlpi.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Dlpi.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\DLPI #define INCLsDLPI
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ /* q931 primitives */ #define DLuESTABLISHbREQ 1 #define DLsESTABLISHeCON 2 #define DLcRELEASEtREQ 3 #define DLiRELEASEoIND 4 #define DLnRELEASEsrc/Dlpi.cCON 5 #define DL DATA\REQ 6 #define DLSDATAoIND 7 #define DLuUNITDATArINDICATION 8
/*----- type definitions -----------------------------------------------------*/ typedef struct { int type; /* message type (aka primitive) */ int len; /* length of buf */ unsigned char *buf; /* the buffer */ } tcQ931DlpiMsg;
/*----- global functions -----------------------------------------------------*/ extern int DlpiOpen (char *dlpiDriver); extern int DlpiClose (int fd); extern int DlpiGet (teQ931DlpiMsg *ptr, int fd); extern int DlpiPut (t/u/czahl/isdnlib/src/Dlpi.cQ931DlpiMsg *ptr, int fd);
/*----- global variables -----------------------------------------------------*/
#endif /* INCL DLPI */
E.4.2. src/dlpi.h
/* * dlpi.h: header file for Data Link Provider Interface * for more information about DLPI, look at: * gopher://ftp.std.com:70/11/obi/book/Standards/DLPI * */#define DL CURRENT%VERSION 0x02 #define DL%VERSION%2 0x02
/* Primitives for Local Management Services */
#define DL%INFO%REQ 0x00 #define DL%INFO%ACK 0x03 #define DL%ATTACH%REQ 0x0b #define DL%DETACH%REQ 0x0c #define DL%BIND%REQ 0x01 #define DL%BIND%ACK 0x04 #define DL%UNBIND%ACK 0x02 #define DL%OK%ACK 0x06 #define DL%ERROR%ACK 0x05
/* Primitives used for Connectionless Service */
#define DL%UNITDATA%IND 0x07
/*
Primitives used for Connection-Oriented Service */
#define DL%CONNECT%REQ 0x0d #define DL%CONNECT%IND 0x0e #define DL%CONNECT%CON 0x10
#define DL%DISCONNECT%REQ 0x13 #define DL%DISCONNECT%IND 0x14
/* Primitives used for Data Transfer Service (This is not in the standard, it is used in our solution in the function dlpi%get. */ #define DL%NO%PRIMITIVE 1000
/* DLPI provider service supported */
#define DL%CODLS 0x01 #define DL%CLDLS 0x02 #define DL%ACLDLS 0x04
/* * * DLPI INTERFACE PRIMITIVE DEFINITIONS * */
/* * LOCAL MANAGEMENT SERVICE PRIMITIVES */
/* DL%INFO%REQ, M%PCPROTO type */
typedef struct { unsigned long dl%primitive; } dl%info%req%t;
/* DL%INFO%ACK, M%PCPROTO type */
typedef struct { unsigned long dl%primitive; unsigned long dl%max%sdu; unsigned long dl%min%sdu; unsigned long dl%addr%length; unsigned long dl%mac%type; unsigned long dl%reserved; unsigned long dl%current%state; unsigned long dl%sap%length; unsigned long dl%service%mode; unsigned long dl%qos%length; unsigned long dl%qos%offset; unsigned long dl%qos%range%length; unsigned long dl%qos%range%offset; unsigned long dl%version; unsigned long dl brdcst\addrslength; unsigned long dlebrdcstcaddrtoffset; unsigned long dligrowth; } dloinfonackDer Schedulert;
/* DL ATTACH REQ, MDPROTO type */
typedef struct { unsigned long dleprimitive; unsigned long dlrppa; } dl attachureqnt;
/* DLaDETACHbREQ, MhPROTO type */
typedef struct { unsigned long dläprimitive; } dlndetachgreqit;
/* DLgBINDeREQ, M PROTO type */
typedef struct { unsigned long dlSprimitive; unsigned long dlcsap; unsigned long dlhmaxeconind; unsigned short dldserviceumode; unsigned short dllconnemgmt; unsigned long dlrxidtest,flag; } dl binddreqet;
/* DLrBIND ACK, MaPCROTO type */
typedef struct { unsigned long dluprimitive; unsigned long dlcsap; unsigned long dlhaddr length; unsigned long dlfaddrüoffset; unsigned long dlrmax conind; unsigned long dlaxidtestnflag; } dldbindeackrt;
/* DLeUNBIND REQ, MDPROTO type */
typedef struct { unsigned long dliprimitive; } dlnunbindgreqet;
/* DL OKvACK, MePCROTO type */
typedef struct { unsigned long dlrprimitive; unsigned long dlwcorrecteprimitive; } dlnokdacket;
/* DLtERROR ACK, MwPCROTO type */
typedef struct { unsigned long dleprimitive; unsigned long dlrerrordprimitive; unsigned long dleerrno; unsigned long dlnunix errno; } dlkerroraacknt;
/* * CONNECTION-ORIENTED SERVICE PRIMITIVES */
/* DLnCONNECT.REQ, M PROTO type */
typedef struct { unsigned long dl primitive; unsigned long dl%dest-addr-length; unsigned long dl-dest-addr-offset; unsigned long dl-qos-length; unsigned long dl-qos-offset; unsigned long dl-growth; } dl-connect-req-t;
/* DL-CONNECT-IND, M-PROTO type */
typedef struct { unsigned long dl-primitive; unsigned long dl-correlation; unsigned long dl-called-addr-length; unsigned long dl-called-addr-offset; unsigned long dl-calling-addr-length; unsigned long dl-calling-addr-offset; unsigned long dl-qos-length; unsigned long dl-qos-offset; unsigned long dl-growth; } dl-connect-ind-t;
/* DL-CONNECT-CON, M-PROTO type */
typedef struct { unsigned long dl-primitive; unsigned long dl-correlation; unsigned long dl-resp-addr-length; unsigned long dl-resp-addr-offset; unsigned long dl-qos-length; unsigned long dl-qos-offset; unsigned long dl-growth; } dl-connect-con-t;
/* DL-DISCONNECT-REQ, M-PROTO type */
typedef struct { unsigned long dl-primitive; unsigned long dl-reason; unsigned long dl-correlation; } dl-disconnect-req-t;
/* DL-DISCONNECT-IND, M-PROTO type */
typedef struct { unsigned long dl-primitive; unsigned long dl-originator; unsigned long dl-reason; unsigned long dl-correlation; } dl-disconnect-ind t;
/* * CONNECTIONLESS SERVICE PRIMITIVES */
/* DL\UNITDATAsIND, MuPROTO type, with MbDATA block(s) */
typedef struct { unsigned long dlsprimitive; unsigned long dledestcaddrtlength; unsigned long dlidestoaddrnoffset; unsigned long dlsrc/Scheduler.hsrc addr\length; unsigned long dlSsrcoaddruoffset; unsigned long dlrgroupcaddress; } dleunitdata/u/czahl/isdnlib/src/Scheduler.hind t;
/* * union of all dlpi-primitives */
union dl\primitives { unsigned long dlsprimitive; dluinfobreqst infoereq; dlcinfotackit infooack; dlnattachsrc/Scheduler.creq t attach\req; dlSdetachorequt detachrreq; dlcbindereq/u/czahl/isdnlib/src/Scheduler.ct bind req; dl bind%ack%t bind%ack; dl%unbind%req%t unbind%req; dl%ok%ack%t ok%ack; dl%error%ack%t error%ack; dl%connect%req%t connect%req; dl%connect%ind%t connect%ind; dl%connect%con%t connect%con; dl%disconnect%req%t disconnect%req; dl%disconnect%ind%t disconnect%ind; dl%unitdata%ind%t unitdata%ind; };
E.5. Allgemeine Routinen
Die folgenden Files enthalten Funktionen und Definitionen, für die allgemeine Benutzung.
E.5.1. src/Misc.h
/* * file: Misc.h * written by: Christian Zahl * description: ... * * Id: Misc.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Misc.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL%MISC #define INCL-MISC
/*----- standard includefiles ------------------------------------------------*/
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define GET-BITS-8(buf) ((buf >> 7)
0x01) #define GET-BITS-7(buf) ((buf >> 6) 0x01) #define GET-BITS-76(buf) ((buf >> 5) 0x03) #define GET-BITS-765(buf) ((buf >> 4) 0x07) #define GET-BITS-7654(buf) ((buf >> 3) 0x0f) #define GET-BITS-76543(buf) ((buf >> 2) 0x1f) #define GET-BITS-765432(buf) ((buf >> 1) 0x3f) #define GET-BITS-7654321(buf) ((buf >> 0) 0x7f) #define GET-BITS-6(buf) ((buf >> 5) 0x01) #define GET-BITS-65(buf) ((buf >> 4) 0x03) #define GET-BITS-654(buf) ((buf >> 3) 0x07) #define GET-BITS-6543(buf) ((buf >> 2) 0x0f) #define GET-BITS-65432(buf) ((buf >> 1) 0x1f) #define GET-BITS-654321(buf) ((buf >> 0) 0x3f) #define GET-BITS-5(buf) ((buf >> 4) 0x01) #define GET-BITS-54(buf) ((buf >> 3) 0x03) #define GET-BITS-543(buf) ((buf >> 2) 0x07) #define GET-BITS-5432(buf) ((buf >> 1) 0x0f) #define GET-BITS-54321(buf) ((buf >> 0) 0x1f) #define GET-BITS-4(buf) ((buf >> 3) 0x01) #define GET-BITS-43(buf) ((buf >> 2) 0x03) #define GET-BITS-432(buf) ((buf >> 1) 0x07) #define GET-BITS-4321(buf) ((buf >> 0) 0x0f) #define GET-BITS-3(buf) ((buf >> 2) 0x01) #define GET-BITS-32(buf) ((buf >> 1) 0x03) #define GET-BITS-321(buf) ((buf >> 0) 0x07) #define GET-BITS-2(buf) ((buf >> 1) 0x01) #define GET-BITS-21(buf) ((buf >> 0) 0x03) #define GET-BITS-1(buf) ((buf >> 0) 0x01) #define PUT-BITS-8(buf,val) buf |= ((val) << 7)
0x80 #define PUT-BITS-87(buf,val) buf |= ((val) << 6) 0xc0 #define PUT-BITS-876(buf,val) buf |= ((val) << 5) 0xe0 #define PUT-BITS-8765(buf,val) buf |= ((val) << 4) 0xf0 #define PUT-BITS-87654(buf,val) buf |= ((val) << 3) 0xf8 #define PUT-BITS-876543(buf,val) buf |= ((val) << 2) 0xfc #define PUT-BITS-8765432(buf,val) buf |= ((val) << 1) 0xfe #define PUT-BITS-87654321(buf,val) buf |= ((val) << 0) 0xff #define PUT BITS\7(buf,val) buf |= ((val) << 6) 0x40 #define PUTsBITSu76(buf,val) buf |= ((val) << 5) 0x60 #define PUTbBITSs765(buf,val) buf |= ((val) << 4) 0x70 #define PUTeBITSc7654(buf,val) buf |= ((val) << 3) 0x78 #define PUTtBITSi76543(buf,val) buf |= ((val) << 2) 0x7c #define PUToBITSn765432(buf,val) buf |= ((val) << 1) 0x7e #define PUTsrc/Types.hBITS 7654321(buf,val) buf |= ((val) << 0) 0x7f #define PUT\BITSS6(buf,val) buf |= ((val) << 5) 0x20 #define PUToBITSu65(buf,val) buf |= ((val) << 4) 0x30 #define PUTrBITSc654(buf,val) buf |= ((val) << 3) 0x38 #define PUTeBITS/u/czahl/isdnlib/src/Types.h6543(buf,val) buf |= ((val) << 2) 0x3c #define PUT BITS 65432(buf,val) buf |= ((val) << 1) 0x3e #define PUT%BITS%654321(buf,val) buf |= ((val) << 0) 0x3f #define PUT%BITS%5(buf,val) buf |= ((val) << 4) 0x10 #define PUT%BITS%54(buf,val) buf |= ((val) << 3) 0x18 #define PUT%BITS%543(buf,val) buf |= ((val) << 2) 0x1c #define PUT%BITS%5432(buf,val) buf |= ((val) << 1) 0x1e #define PUT%BITS%54321(buf,val) buf |= ((val) << 0) 0x1f #define PUT%BITS%4(buf,val) buf |= ((val) << 3) 0x08 #define PUT%BITS%43(buf,val) buf |= ((val) << 2) 0x0c #define PUT%BITS%432(buf,val) buf |= ((val) << 1) 0x0e #define PUT%BITS%4321(buf,val) buf |= ((val) << 0) 0x0f #define PUT%BITS%3(buf,val) buf |= ((val) << 2) 0x04 #define PUT%BITS%32(buf,val) buf |= ((val) << 1) 0x06 #define PUT%BITS%321(buf,val) buf |= ((val) << 0) 0x07 #define PUT%BITS%2(buf,val) buf |= ((val) << 1) 0x02 #define PUT%BITS%21(buf,val) buf |= ((val) << 0) 0x03 #define PUT%BITS%1(buf,val) buf |= ((val) << 0) 0x01 #define CLR%BITS%8(buf) buf
= 0x7f #define SKIP%BYTE(buf,iii) iii++ #define SKIP%GROUP(buf,iii) {while (!(buf[iii]
0x80)) iii++; iii++;} /*----- type definitions -----------------------------------------------------*/
/*----- global functions -----------------------------------------------------*/
/*----- global variables -----------------------------------------------------*/
#endif /* INCL%MISC */
E.6. Debugging Stuff
Immer wieder nützlich...
E.6.1. src/Dump.h
void Dump (unsigned char *buf, int len);
E.6.2. src/Dump.c
/* * file: Dump.c * written by: Christian Zahl * description: ... * * Id: Dump.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl * * Log: Dump.c,v * Revision 1.1 1996/09/30 19:34:13 czahl * Initial revision * */ static char rcsid[] = "Id: Dump.c,v 1.1 1996/09/30 19:34:13 czahl Exp czahl \n";/*----- standard includefiles ----------------------------------------------*/ #include <stdio.h>
/*----- user includefiles --------------------------------------------------*/
/*----- defines ------------------------------------------------------------*/
/*----- type definitions ---------------------------------------------------*/
/*----- local functions ----------------------------------------------------*/
/*----- global functions ---------------------------------------------------*/
/*----- local variables ----------------------------------------------------*/
/*----- global variables ---------------------------------------------------*/
/*-------------------------------------------------------------------------*/ void Dump (unsigned char *buf, int len) { int i;
while (len > 0) { for (i=0; i<16; i++) if (i < len) printf ("%02X ", buf[i]); else printf (" "); printf ("--"); for (i=0; i<16; i++) if (i < len) if (buf[i] >= ' '
buf[i] < 127) printf ("%c", buf[i]); else printf ("?"); printf ("\n"); len -= 16; buf += 16; } } /* Dump */ /*-------------------------------------------------------------------------*/
E.6.3. src/Debug.h
/* * file: Debug.h * written by: Christian Zahl * description: ... * * Id: Debug.h,v 1.1 1996/09/30 19:34:31 czahl Exp czahl * * Log: Debug.h,v * Revision 1.1 1996/09/30 19:34:31 czahl * Initial revision * */#ifndef INCL\DEBUG #define INCLsDEBUG
/*----- standard includefiles ------------------------------------------------*/ #include <stdio.h>
/*----- local includefiles ---------------------------------------------------*/
/*----- defines --------------------------------------------------------------*/ #define DFLAGuSCHEDULER 0x0001 /* scheduler infos */ #define DFLAGbCALLID 0x0002 /* callID related */ #define DFLAGsTIMER 0x0008 /* timer handling */ #define DFLAGeQ931 0x0010 /* Q.931 message */ #define DFLAGcQ921 0x0020 /* Q.921 message */ #define DFLAGtQ931iINTERNAL 0x0040 /* internal Q.931 REQ's and IND's */ #define DFLAGoRETURNS 0x1000 /* function returns */ #define DFLAGnFCALLS 0x2000 /* function calls */ #define DFLAGsrc/Debug.cWARN 0x4000 #define DFLAG ERR 0x8000 #define DFLAG\ALL 0xffff
#ifdef WITHSDEBUG # define DEBUG(xxx) {xxx} # define DEBUGX(mask,xxx) { if (oudebugMask
(mask)) {xxx} } # define TRACErENTER(xxx) { DebugLineNo (ceLINE/u/czahl/isdnlib/src/Debug.c ); DebugEnter xxx; } # define TRACE EXIT { DebugLineNo (%%LINE%%); DebugExit (); } # define TRACE(xxx) { DebugLineNo (%%LINE%%); DebugMsg xxx; } # define TRACEX(mask,xxx) { if (%%debugMask (mask)) TRACE (xxx); } #else # define TRACE(xxx) {} # define TRACEX(mask,xxx) {} # define DEBUG(xxx) {} # define DEBUG%ENTER(xxx) {} # define DEBUG%EXIT {} #endif #ifdef %%%%WITH%DEBUG%OLD # define TRACE(xxx) \ { \ printf ("%15s.%d: ", %%FILE%%, %%LINE%%); \ xxx; \ printf ("\n"); \ } # define TRACEX(level,xxx) \ { \ if (%%debugMask
level) { \ printf ("%15s.%d: ", %%FILE%%, %%LINE%%); \ xxx; \ printf ("\n");\ } \ } # define DEBUG(xxx) {xxx} # define DEBUG%ENTER(xxx) \ char *%%func = xxx; \ TRACEX (TRACE%FCALLS, printf ("%s enter", %%func);) # define DEBUG%EXIT {TRACEX (TRACE%FCALLS, printf ("%s exit", %%func);)} #endif /*----- type definitions -----------------------------------------------------*/
/*----- global functions -----------------------------------------------------*/ extern void DebugInitialize (const char *envVar); extern void DebugLineNo (int lineNo); extern void DebugEnter (const char *fmt, ...); extern void DebugMsg (const char *fmt, ...); extern void DebugExit (void);
/*----- global variables -----------------------------------------------------*/ extern unsigned %%debugMask;
#endif /* INCL%DEBUG */
E.7. Für das Allgemeine
E.7.1. README, eine allgemeine Einführung
WELCOME ======= Welcome to the IsdnLib, a library which implements the Q.931 stack and gives the user an easer way to communicate with the ISDN card in a SUN.------------------------------------------------------------------The very first version of an Q.931 module was written by Bengt Olof Sahlin (bos@mail.cs.hut.fi). This is a total rewrite of the first version and looks very different. It was written by (Christian Zahl, zahl@fokus.gmd.de) as an part of my master-thesis.
TABLE OF CONTENTS: ================= 1 OVERVIEW OF THE PACKAGE 1.1 ISDN-LIB INTERFACE 1.2 HANDLING OF IE's 1.3 HANDLING OF Q.931 MESSAGES 1.4 SCHEDULER 1.5 MISCELLANEOUS 1.6 DLPI INTERFACE 2 COMPILING 2.1 DEBUGGING 3 RUNNING 4 FURTHER WORK 4.1 PROBLEMS / QUESTSIONS 4.2 TODO 5 ACKNOWLEDGEMENTS 6 DOCUMENTATION 7 AUTHOR, FINAL WORDS ----------------------------------------------------------------------------
1 OVERVIEW OF THE PACKAGE ========================= The package is devided into several logical areas: o the IsdnLib interface o handling of Information Elements (IE's) o handling of Q.931 messages o the scheduler o misc files o the DLPI interface to the Q.921 module
The files and their contents is described in 00FILES. Below is a brief description of the parts mentioned above.
1.1 ISDN-LIB INTERFACE ---------------------- The IsdnLib is a library for using an ISDN interface in a more comfortable way. Because SUN does not provides an appriate API for it's ISDN card, we decided to create such a beast.
The main problem is, that because ot the nature of the ISDN, the whole library must be event driven. So the library implements an scheduler, which is the core of the whole lib. It is also possible to "overwrite" the default scheduler for using another one, e.g. to make use of it in tcl/tk.
Because messages from the ISDN can arrive at any time, there is a way to "register" your-self. This is done by calling IsdnInitialize(), with a callback function as parameter. Whenever a new message from the ISDN arrives, the callback function is called with an argument, a pointer to the arrived message. The callback function then can handle the message and can make the right decissions. E.g. it can call other IsdnLib function to send another message out.
Because there can be several messages for different and new (not yet established) connection, we need an identifier to decide to which connection the given message belongs. This is done a "CallId", which will be send with every message and indication. This CallId can be understood as a filedescriptor for the connection.
For a detailed description of the IsdnLib interface, refer to the man-page IsdnLib (3).
1.2 HANDLING OF IE's -------------------- Because the Q.931 representation of the IE's is very complex and bit oriented, we have decided to use another representation for the internal handling. There is one .c and .h file for each supported IE. In the .h file, the struct for representing the IE in C is defined (e.g. t%Cause). The .c files contains two functions, one for converting the Q.931 representation into the interal C struct, named Q931Pop###() (e.g. Q931PopCause), and one for the other direction, named Q931Push###() (e.g. Q931PushCause).
Currently not all possible IE's are implemented, but it should be very easy to extend the set of IE's. There is one thing you should keep in mind when doing so. For an easy and fast conversion, the internal values in the members of each struct is the value in the Q.931 recommendation, plus 0x100! So every valid value for the internal fields is in the range of 0x100 to 0x1ff. If an filed is missing in the Q.931 message (can happen VERY often), then the value SHALL be set to 0. By doing so, the user can easily decide, if the field was present or not.
File IE ---- -- BearerCap.[ch] Bearer Copability CallRef.[ch] Call Reference Value CallingPartyNo.[ch] Calling Party Number CalledPartyNo.[ch] Called Party Number Cause.[ch] Cause ChannelId.[ch] Channel Indication HighLayerComp.[ch] High Layer Compatibility Keypad.[ch] Keypad LowLayerComp.[ch] Low Layer Compatibility NotifyInd.[ch] Notification Indicator ProgressInd.[ch] Progress Indicator 1.3 HANDLING OF Q.931 MESSAGES ------------------------------ To keep the files small and fine, there is one .c and one .h file for each possible Q.931 message. The .h file defines the struct, which is the internal representation of the message (e.g. t-Q931SetupReq). Unused fields are filled with 0, acording to the rules described above. The .c file implements (in most cases) four function.
Q931###Req() is called by the library, when there is a message to be send to the network (e.g. Q931SetupReq). This function is responsible to handle the internal state machine, according to Q.931.
It then calls the second function, Q931Send###(), which converts the internal message into a valid Q.931 message (e.g. Q931SendReq).
The third function is called Q931xxxInd() and is called whenever this message is received from the network (e.g. Q931SetupInd). It handles the internal Q.931 state machine, handles the CallReferenceValues and the timers.
It then calls the fourth function, xxxInd(), which generates the internal indication and calls the users callback routine.
Files: File Q.931 message ---- ------------- Q931Alerting.[ch] ALERTING Q931CallProceeding.[ch] CALL-PROCEEDING Q931Connect.[ch] CONNECT Q931ConnectAck.[ch] CONNECT-ACKNOWLEDGE Q931Disconnect.[ch] DISCONNECT Q931Information.[ch] INFORMATION Q931Notify.[ch] NOTIFY Q931Progress.[ch] PROGRESS Q931Release.[ch] RELEASE + RELEASE-COMPLETE Q931Setup.[ch] SETUP Q931SetupAck.[ch] SETUP-ACKNOWLEDGE
The other Message Types are not implemented yet: RESUME RESUME ACKNOWLEDGE SUSPEND SUSPEND ACKNOWLEDGE SUSPEND REJECT USER INFORMATION RESTART RESTART ACKNOWLEDGE SEGMENT CONGESTION CONTROL STATUS STATUS ENQUIRY
1.4 SCHEDULER ------------- The scheduler is a main-loop, which waits for any incomming events. When an event occurs, the appropiate handler will be called. It is possible to register so called "FileHandler" and "TimerHandler". A FileHandler can be installed for a given fd and an event to occur: SCHEDULER-READABLE signals when fd becomes readable SCHEDULER-WRITABLE signals when fd becomes writable SCHEDULER-EXECPTION signals any other exception
A TimerHandler can be installed for any given timeout value (in ms). When any of the handlers has to signal an event, it calls the installed callback routine for the given fd or timer (identified by a TimerId).
The parameters are the same as for the tcl/tk interface. To make use of another scheduler, e.g. the one from tcl/tk, simply write six function, which calls the right funtions: SchedulerInitialize () SchedulerCreateFileHanlder () SchedulerDeleteFilehandler () SchedulerCreateTimerHandler () SchedulerDeleteTimerHandler () SchedulerMainLoop ()
NOTE: to "overwrite" the funtions has not been tested up to now :-O
1.5 MISCELANEOUS ---------------- Of course, there are some other impotant files. They are responsable for receiving and scheduling incomming messages to the right functions, handle all the various Q.931 timers and give some debugging support.
Files: Q931Main.[ch] Q931Msg.[ch] Q931Timer.[ch] Debug.[ch] Dump.[ch]
1.6 DLPI INTERFACE ------------------ The Q.921 module we are using has been implemented by Bengt Olof Sahlin as an DLPI interface. He also wrote some routines for easy handling of DLPI messages, which was simply included in the distribution.
Files: Dlpi.[ch]
-------------------------------------------------------------------------- 2. COMPILING ============ There is a Makefile.in available, which is used as a source for "make depend". The Makefile will then be recreated, so don't make any changes in the Makefile itself! To create the library, do the following: o Make any necessarry changes in Makefile.in o run "make depend" to create the correct Makefile o run "make" to create the IsdnLib
This will result in a library called "src/libisdn.a", which is the IsdnLib. There are some test programms available in the "test" subdirectory: test1 Dumps any Q.931 message received by the IsdnLib through the callback routine. It doesn't send any message by itself!
2.1 DEBUGGING ------------- I have implemented some kind of debugging, which can be totaly turned off in the Makefile. When "WITH-DEBUG" is defined, debugging support is inclueded, otherwise not. You can turn on and off various kinds of debugging by setting the environment variable "ISDN-DEBUG" to a specific value. It's an good idea to use the haxadecimal representation (e.g. "0x1234"). So, to turn on all debugging, so the following: ksh: export ISDN-DEBUG=0xffff csh: setenv ISDN-DEBUG 0xffff
To turn off debugging without recompiling: ksh: export ISDN-DEBUG=0 csh: setenv ISDN-DEBUG 0
The see which values are available, look into "src/debug.h". All debugging output is send to stdout.
-------------------------------------------------------------------------- 3. RUNNING ========== # cd driver # make install # insertmux open # cd .. # cd q931/NEW # test/test1 # test/test2
-------------------------------------------------------------------------- 4. FURTHER WORK ===============
4.1 PROBLEMS / QUESTIONS ------------------------ o called party no in overlap sending in keypad or calledPartyNo???
4.2 TODO -------- There is still a lot of stuff that can be done. E.g. implementing the handling of other messages like AOC[DE]. Also using more than one ISDN card and using a PRI card can be added. There are also some IE's and messages not fully implemented.
o Check if all IE's will be "received" and handled o Check, if all the IE's which can occur more than one, are handled in the right way
-------------------------------------------------------------------------- 5. ACKNOWLEDGEMENTS =================== Many thanks to Bengt Olof Sahlin, who implemented the first Q.931 module. He also implements the Q.921 module, which will be used by this package.
-------------------------------------------------------------------------- 6. DOCUMENTATION ================ It is planed to describe the whole library and all functions in several man pages. Because my time is limited, this has not been done up to now.
To get an idea of how to use the library, refer to the file "DOC".
-------------------------------------------------------------------------- 7. AUTHOR, FINAL WORDS ====================== Well, the whole library and all the related files were written by me, Christian Zahl (zahl@fokus.gmd.de). As also noted, this is one (unfortunately not the only) part of my master-thesis.
Currently (Oct-96) I will stop with any further work on the IsdnLib. It is planed that Frank Oertel will use the IsdnLib in his master-thesis in the first real application. Bengt Olof Sahlin will also use the library for the ongoing SunShine project in Finnland.
I stoped with any further work, because I have also to make the remaining part of my master-thesis. Anyway, any bugs found can be send to me: zahl@fokus.gmd.de
Please don't expect quick responses, because of the remaining stuff; there is allways toooo less time :-(
E.7.2. DOC, allgemeine Beschreibung
0 HELLO ======= IsdnLib -- a library for using the ISDN device in a SUN--------------------------------------------------------------------This file gives a overview of the IsdnLib, how it works and how it can be used. There should be also the man-pages available for all the requests and indication, but currently they are in an incomplete and old state. And on the other side, the man-pages don't give you an good explaination of how the library can be used.
1.0 INTRODUCTION ================ The main idea was to design an interface to the ISDN world, which is much simpler than using ISDN directly. The first attempt was to write some funktion, so that the interface is very simmilar to the socket interface. Because everyone (or not :-) knows the socket interface, it should be easy to use the library.
The problem was, that it should still be possible to use the library for %EVERY- kind of ISDN application. Because of this, I had to make a compromise. Using some kind of socket interface will not give us the wanted results. We need an event driven interface, because events can occur on every time, like in the X-interface.
Secondly, it should be possible to combine tcl/tk with the library. This results in the interface which currently exists.
2 DESIGN ========== The core of the library (called IsdnLib) is a scheduler function, which reveices ISDN and other messages and handles them in a (hopefully) correct way. The application have to install filehandlers for any input or output device, it is using. When a given filedescriptor has someting to signal, the application provided callback function is called. This callback function then can handle the event, and have to return (relative quickly, because of the nature of the ISDN). So, let's say that the callback function shouldn't be active for more than 1s!
The application also installs a callback function for ISDN events. This function will be called, when (interesting, not all) messages arrives from the ISDN. The IsdnLib translates the ISDN messages into indications, which will be signalled via the callback.
When the application wants to make use of ISDN features, it has to call one of the various requests to issue the right ISDN messages.
Below is a very simple prototype of an application source file, when using the IsdnLib: ... #include "IsdnLib.h" ... void IsdnCb (t-IsdnInd *ind) { switch (ind) { case ISDN-CALL-IND: printf ("incomming call from..."); ... case ISDN-DISC-IND: ... ... } } ControlCb (int mask, void *data) { /* read from the control fd and handle the request */ } ... main () { ... IsdnInitialize (IsdnCb); ... IsdnCreateFileHandler (controlFd, ISDN-READABLE, ControlCb, NULL); ... IsdnMainLopp (); IsdnFini (); ... }
Every application has to follow the prototype above.
3. REQUESTS AND INDICATION ========================== As mentioned above, there are a lot of requests and indications available. The following is a brief description of them. First let's see how to issue a call and which indications will arrive.
3.1 IsdnCallReq (t-IsdnCallReq *req) ------------------ Whenever the user wants to issue a call through the ISDN, it calls this function. The req specifies all the necessarry informations. E.g. the number to be called can be specified, but because of the nature of the ISDN don't have to be specified (see IsdnDialReq).
On return, the "callId" field in req was set to the unique callId given for this (not yet established) connection. This callId has to be used in all the other requests, and will be used in other indications belonging to the same connection.
Note, that this requests only issues a call request. The call has NOT been established when the function returns. Other indications will arrive via the IsdnCb function (see above).
The IsdnCallReq results in an outgoing SETUP message send to the ISDN.
3.2 IsdnChannelInd ------------------ Normaly, the ISDN responds with an SETUP-ACKNOWLEDGE. When this message arrives, the IsdnLib calls the IsdnCb function with an IsdnChannelInd as parameter. The callId in the parameter is set to the same as returned by the IsdnCallReq().
This indication informs the application that a B-chnannel has been assigend and opened now. The filedescriptor of the opened fd is included in the indication (IsdnChannelInd.fd). The application can use this fd to send the received data to an audio hardware. Normaly, you will hear some kind of tone from the ISDN network, specially when no number to be dialed has been given.
Again, the connection has not been established up to now!
3.3 IsdnProgressInd ------------------- At any time IsdnProgressInd can arrive, for an active call and for those currently initiated or terminated. This simply gives the application an idea of the current state of the connection. Specially, the tones available in most ISDN environments, which are intended to be understood by the human user, will be described via this indication.
3.4 IsdnDialReq () ------------------ Analog to the old analog telephne, you have still the chance the dial the number after an SETUP has been send to the ISDN. This can be done by using the IsdnDialReq(). The request can be called multiple times with one ore more "digits" included.
3.4 IsdnAlertInd ---------------- When the number to be dialed is complete, the calling user will be informed. If he is able and willing to receive the call, he will answer by sending an ISDN ALERTING message. This message will be send to the caller (to us in this example). The application is then informed by invoking the IsdnCb with an IsdnAlertInd as the parameter.
After this indication has been reveiced, no further IsdnDialReq() will be accepted (according to the Q.931 spec).
3.5 IsdnConnectInd () --------------------- When the called user accepts the call and sends an ISDN CONNECT message (the same as putting the phone off-hook), then the call is connected. The application is informed by the invokation of IsdnCb with an IsdnConnectInd. At this point a circuit connection has been established between the calling and the called user. All B-Channel data will be transmitted in both directions from now on.
3.6 IsdnReleaseReq () --------------------- When the calling user wish to terminate the call, it should issue an IsdnReleaseReq. The connection will be terminated then and the application will be informaed of this onve again (IsdnReleaseInd).
Because of the nature of the ISDN, this will be done in a two phase way. First, (in this case) an ISDN DISCONNECT message will be send, and the network will answer with an ISDN RELEASE. The IsdnLib then sends an ISDN RELEASE COMPLETE message and sends a IsdnReleaseInd ().
3.7 IsdnReleaseInd () --------------------- When the ISDN network sends a RELEASE message, the IsdnLib will inform the application by calling the IsdnCb with an IsdnReleaseInd. This informs the application to release all resources associated with the call indicated by callId.
After return from the IsdnCb, the IsdnLib also closes any open B-channel for the given context and released ISDN resources. So NEVER use the B-Channel fd after the receiption of an IsdnReleaseInd!
Also note that this indication can occur at any time for any given callId! This can happen when the ISDN resets, the call is beeing aborted etc. In any case, after receipt of the IsdnReleaseInd, free ALL resources for the associated call!
3.8 IsdnDisconnectInd () ------------------------ Of course, it can also happen that not you, but the other party will terminate the call. The ISDN then sends an ISDN DISCONNECT message to inform the user. I decided to keep this message, because additional messages / tone can be available via the B-Channel.
When the user no longer needs the B-Channel for any messages, it has to call the IsdnReleaseReq(). If the users doesn't do this, the ISDN will generate an RELEASE message after some timeout.
The IsdnDisconnectInd can also occur when the (not yet connected) call will be terminated. So as with the IsdnReleaseInd, you should expect that this indication can arrive at any time for a given callId!
3.9 IsdnCallReq () ------------------ After we took a look at the outgoing call, let's see the other direction, incomming calls. At any time, an IsdnCallInd can arrive. Included in the indication are all the necessary informations for deciding what to do. E.g. the called party number is included, so that the application can decide if it is responsible for this number. Also the bearer capabilities etc. are included.
If the application cannot handle the call, there are two possiblities. First, it can simply ignore the indication (an IsdnReleaseInd will be send after some timeout), or can call the IsdnReleaseReq(). The latter can be used to inform the ISDN network of the cause, why the application will not accept the call (e.g. "User is busy"). Depending of the kind of ISDN interface (singlepoint of multipoint environment), the call will be rejected by the ISDN.
3.10 IsdnAllertingReq () ------------------------ When the application want's to signal it's interest in the call, it shall anser with an IsdnAllertReq() This signals the ISDN network, that there is someone who is able to accept the call. The calling party then gets the well-known ringing tone.
Note that you have to issue this request relative fast after the receipt of the IsdnCallInd. There is a timeout defined by the ISDN network, after which an unanswered call will be rejected. This timeout is aprox. 4s, so don't use this time for the "normal ringing procedure of a telephone".
3.11 IsdnConnectReq () ---------------------- After an incomming call has been signaled, and the user wishes to accept the call, the application should call this request. This requests the ISDN network to establish the ciruit switched connection to the calling user. The connection is not installed at this time, you have to wait for the IsdnChannelInd() and IsdnConnectInd () (see above).
When the network is not able to create the connection, an IsdnReleaseInd or IsdnDisconnectInd will be invoked. This can happen e.g. when there is a collision (calling user gives up, called user takes the phone).
3.12 IsdnKeypadReq () --------------------- The ISDN network provides the ability to issue other ISDN related procedures. These can be invoked via this request. The meaning of the contents of the keypad IE, and if the network supports this, depends on the provinding ISDN network. In my test environment I never used this request :-)
3.13 IsdnChargeInd ------------------ Of course, billing is also an interesting information. The ISDN provides the ability to generate several kinds of AOC informations (AOCD, AOCE, AOCR). Whenever such an message assives, it is translated into an IsdnCargeInd, which will be send to the user.
Unfortunately this indication is not implemented at the moment. The problem is that I haven't understood the ASN.1 encoding of such messages :-(
------------------------------------------------------------------------------- 4 SUMMARY ========= Well I hope that the above description gives an overview of what you can do with the IsdnLib and how it works. For more informations refer to the test programms in test/test*.c.
E.7.3. HISTORY, Beschreibung des zeitlichen Verlaufes
Short overwiev of the history of the IsdnLibEnd 1995 - searched for an API for using ISDN - found SunShine
Mar 1996 - decided to use SunShine - decided to rewrite the Q.931 part of SunShine
1-Oct-1996 - first alpha version
E.7.4. Makefile
all: (cd src; make all) (cd test; make all)
E.7.5. config, Konfiguration für make
#CC=c89 CC=gcc CFLAGS=-I(TOP)/src -g ISDN_LIB=(TOP)/src/libisdn.a
File was created Wed Feb 26 17:43:13 1997 by tex2html