libisdn
Q921priv.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   FileName:     Q921priv.h
00004 
00005   Description:  Private declarations
00006 
00007   Created:      08.Aug.2008/STKN
00008 
00009   License/Copyright:
00010 
00011   Copyright (c) 2007, Jan Vidar Berger, Case Labs, Ltd. All rights reserved.
00012   email:janvb@caselaboratories.com
00013 
00014   Copyright (c) 2008, Stefan Knoblich, axsentis GmbH. All rights reserved.
00015   email:s.knoblich@axsentis.de
00016 
00017   Redistribution and use in source and binary forms, with or without
00018   modification, are permitted provided that the following conditions are
00019   met:
00020 
00021     * Redistributions of source code must retain the above copyright notice,
00022           this list of conditions and the following disclaimer.
00023     * Redistributions in binary form must reproduce the above copyright notice,
00024           this list of conditions and the following disclaimer in the documentation
00025           and/or other materials provided with the distribution.
00026     * Neither the name of the Case Labs, Ltd nor the names of its contributors
00027           may be used to endorse or promote products derived from this software
00028           without specific prior written permission.
00029 
00030   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00031   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00034   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00035   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00036   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00037   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00038   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00039   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00040   POSSIBILITY OF SUCH DAMAGE.
00041 
00042 *****************************************************************************/
00043 #ifndef _Q921_PRIVATE_H_
00044 #define _Q921_PRIVATE_H_
00045 
00046 #include "Q9XXplatform.h"
00047 
00048 typedef enum                    /* Q.921 States */
00049 {
00050         Q921_STATE_STOPPED = 0,                 /* Trunk stopped */
00051         Q921_STATE_TEI_UNASSIGNED = 1,          /* TEI unassigned */
00052         Q921_STATE_TEI_AWAITING,                /* Assign awaiting TEI */
00053         Q921_STATE_TEI_ESTABLISH,               /* Establish awaiting TEI */
00054         Q921_STATE_TEI_ASSIGNED,                /* TEI assigned */
00055         Q921_STATE_AWAITING_ESTABLISHMENT,      /* Awaiting establishment */
00056         Q921_STATE_AWAITING_RELEASE,            /* Awaiting release */
00057         Q921_STATE_MULTIPLE_FRAME_ESTABLISHED,  /* Multiple frame established */
00058         Q921_STATE_TIMER_RECOVERY,              /* Timer recovery */
00059 
00060         Q921_STATE_MAX
00061 } Q921State_t;
00062 
00063 /*
00064  * Flags
00065  */
00066 enum Q921_Flags {
00067         Q921_FLAG_L3_INITIATED = (1 << 0),
00068 
00069         Q921_FLAG_UI_FRAME_QUEUED = (1 << 1),
00070         Q921_FLAG_I_FRAME_QUEUED  = (1 << 2),
00071 
00072         Q921_FLAG_ACK_PENDING = (1 << 3),
00073         Q921_FLAG_REJECT      = (1 << 4),
00074 
00075         Q921_FLAG_RECV_BUSY      = (1 << 5),
00076         Q921_FLAG_PEER_RECV_BUSY = (1 << 6)
00077 };
00078 
00079 #define Q921_SET_FLAG(x, f)     ((x)->flags |= f)
00080 #define Q921_CHECK_FLAG(x, f)   ((x)->flags & f)
00081 #define Q921_CLEAR_FLAG(x, f)   ((x)->flags &= ~f)
00082 
00083 
00084 /*
00085  * dynamic TEI handling
00086  */
00087 #define Q921_SAPI_TEI           63      /* SAPI for all TEI Messages */
00088 #define Q921_LAYER_ENT_ID_TEI   0x0f    /* UN Layer Management Entity ID for TEI Mgmt */
00089 #define Q921_LAYER_ENT_ID_Q931  0x08    /* Q.931 Layer Management Entity ID */
00090 
00091 
00092 typedef enum {
00093         Q921_TEI_ID_REQUEST = 1,
00094         Q921_TEI_ID_ASSIGNED,
00095         Q921_TEI_ID_DENIED,
00096         Q921_TEI_ID_CHECKREQ,
00097         Q921_TEI_ID_CHECKRESP,
00098         Q921_TEI_ID_REMOVE,
00099         Q921_TEI_ID_VERIFY
00100 } Q921TeiMessageType_t;
00101 
00102 #ifdef Q921_STATISTICS
00103 
00106 typedef struct Q921Stats
00107 {
00108         unsigned int counter[Q921_STATS_MAX];
00109 } Q921Stats_t;
00110 #endif
00111 
00115 struct Q921_Link {
00116         L2UCHAR tei;            
00118         L2UCHAR va;
00119         L2UCHAR vs;
00120         L2UCHAR vr;
00121 
00122         L2INT flags;
00123         Q921State_t state;
00124 
00125         L2ULONG N202;           
00126         L2ULONG N200;           
00128         L2ULONG TM01;           
00130         L2ULONG T200;
00131         L2ULONG T201;           
00132         L2ULONG T203;
00133 
00134         L2USHORT ri;            
00136 #ifdef Q921_STATISTICS
00137         /* Statistics */
00138         Q921Stats_t stats;      
00139 #endif
00140 
00141         /* I + UI Frame queue */
00142         L2UCHAR UIFrameQueue[Q921MAXHDLCSPACE];
00143         L2UCHAR  IFrameQueue[Q921MAXHDLCSPACE];
00144         L2UCHAR  IFrameResendQueue[Q921MAXHDLCSPACE];
00145 };
00146 
00147 
00148 #define Q921_LINK_CONTEXT(tr, tei) \
00149         (Q921_IS_PTMP_NT(tr) && tei != Q921_TEI_BCAST) ? ((struct Q921_Link *)&(tr)->context[tei]) : (tr)->context
00150 
00151 #define Q921_TRUNK_CONTEXT(tr) \
00152         (tr)->context
00153 
00154 #define Q921_LOGBUFSIZE         2000
00155 #define INITIALIZED_MAGIC       42
00156 
00157 /*
00158  * Helper macros
00159  */
00160 #define Q921_INC_COUNTER(x)             (x = (x + 1) % 128)
00161 #define Q921_DEC_COUNTER(x)             (x = (x) ? (x - 1) : 127)
00162 
00163 #define Q921_UFRAME_HEADER_SIZE         3
00164 #define Q921_UFRAME_DATA_OFFSET(tr)     ((tr)->Q921HeaderSpace + Q921_UFRAME_HEADER_SIZE)
00165 
00166 #define Q921_SFRAME_HEADER_SIZE         4
00167 #define Q921_SFRAME_DATA_OFFSET(tr)     ((tr)->Q921HeaderSpace + Q921_SFRAME_HEADER_SIZE)
00168 
00169 #define Q921_IFRAME_HEADER_SIZE         4
00170 #define Q921_IFRAME_DATA_OFFSET(tr)     ((tr)->Q921HeaderSpace + Q921_IFRAME_HEADER_SIZE)
00171 
00172 #define Q921_IS_TE(x)                   ((x)->NetUser == Q921_TE)
00173 #define Q921_IS_NT(x)                   ((x)->NetUser == Q921_NT)
00174 
00175 #define Q921_IS_STOPPED(tr)             ((tr)->state == Q921_STATE_STOPPED)
00176 
00177 /* TODO: rework this one */
00178 #define Q921_IS_READY(tr)               ((tr)->state >= Q921_STATE_TEI_ASSIGNED)
00179 
00180 #define Q921_IS_PTMP(x)                 ((x)->NetType == Q921_PTMP)
00181 #define Q921_IS_PTMP_TE(x)              ((x)->NetType == Q921_PTMP && (x)->NetUser == Q921_TE)
00182 #define Q921_IS_PTMP_NT(x)              ((x)->NetType == Q921_PTMP && (x)->NetUser == Q921_NT)
00183 
00184 #define Q921_IS_PTP(x)                  ((x)->NetType == Q921_PTP)
00185 #define Q921_IS_PTP_TE(x)               ((x)->NetType == Q921_PTP && (x)->NetUser == Q921_TE)
00186 #define Q921_IS_PTP_NT(x)               ((x)->NetType == Q921_PTP && (x)->NetUser == Q921_NT)
00187 
00188 /* Make life a little easier */
00189 #define Q921_COMMAND(x)                 ((x)->NetUser == Q921_TE ? 0 : 1)
00190 #define Q921_RESPONSE(x)                ((x)->NetUser == Q921_TE ? 1 : 0)
00191 
00192 #define Q921_IS_COMMAND(tr, x)          ((x) == (Q921_IS_TE(tr) ? 1 : 0))
00193 #define Q921_IS_RESPONSE(tr, x)         ((x) == (Q921_IS_TE(tr) ? 0 : 1))
00194 
00195 
00196 /*******************************************************************************
00197  * Private functions
00198  *******************************************************************************/
00199 
00200 /*
00201  * L1 / L2 Interface
00202  */
00203 static int Q921Tx21Proc(L2TRUNK trunk, L2UCHAR *Msg, L2INT size);
00204 static int Q921Tx23Proc(L2TRUNK trunk, Q921DLMsg_t ind, L2UCHAR tei, L2UCHAR *Msg, L2INT size);
00205 
00206 
00207 /*
00208  * Timers
00209  */
00210 static L2ULONG Q921GetTime(void);
00211 
00212 static void Q921T200TimerStart(L2TRUNK trunk, L2UCHAR tei);
00213 static void Q921T200TimerStop(L2TRUNK trunk, L2UCHAR tei);
00214 static void Q921T200TimerReset(L2TRUNK trunk, L2UCHAR tei);
00215 static void Q921T200TimerExpire(L2TRUNK trunk, L2UCHAR tei);
00216 
00217 static void Q921T201TimerStart(L2TRUNK trunk, L2UCHAR tei);
00218 static void Q921T201TimerStop(L2TRUNK trunk, L2UCHAR tei);
00219 /* static void Q921T201TimerReset(L2TRUNK trunk, L2UCHAR tei); - Unused for now */
00220 static void Q921T201TimerExpire(L2TRUNK trunk, L2UCHAR tei);
00221 
00222 static void Q921T202TimerStart(L2TRUNK trunk);
00223 static void Q921T202TimerStop(L2TRUNK trunk);
00224 static void Q921T202TimerReset(L2TRUNK trunk);
00225 static void Q921T202TimerExpire(L2TRUNK trunk);
00226 
00227 static void Q921T203TimerStart(L2TRUNK trunk, L2UCHAR tei);
00228 static void Q921T203TimerStop(L2TRUNK trunk, L2UCHAR tei);
00229 static void Q921T203TimerReset(L2TRUNK trunk, L2UCHAR tei);
00230 static void Q921T203TimerExpire(L2TRUNK trunk, L2UCHAR tei);
00231 
00232 static void Q921TM01TimerStart(L2TRUNK trunk, L2UCHAR tei);
00233 /* static void Q921TM01TimerStop(L2TRUNK trunk, L2UCHAR tei); - Unused for now */
00234 static void Q921TM01TimerReset(L2TRUNK trunk, L2UCHAR tei);
00235 /* static void Q921TM01TimerExpire(L2TRUNK trunk, L2UCHAR tei); - Unused for now */
00236 
00237 /*
00238  * Frame encoding
00239  */
00240 static int Q921SendS(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR sv, L2UCHAR *mes, L2INT size);
00241 static int Q921SendU(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR m, L2UCHAR *mes, L2INT size);
00242 
00243 static int Q921SendRNR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00244 static int Q921SendREJ(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00245 static int Q921SendSABME(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00246 static int Q921SendDM(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00247 static int Q921SendDISC(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00248 static int Q921SendUA(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00249 static int Q921SendUN(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf, L2UCHAR *mes, L2INT size);
00250 static int Q921SendRR(L2TRUNK trunk, int Sapi, int cr, int Tei, int pf);
00251 
00252 /*
00253  * Frame decoding
00254  */
00255 static int Q921ProcIFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00256 static int Q921ProcSFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00257 static int Q921ProcUFrame(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00258 
00259 static int Q921ProcSABME(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00260 static int Q921ProcDM(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00261 static int Q921ProcUA(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00262 static int Q921ProcDISC(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00263 static int Q921ProcRR(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00264 static int Q921ProcRNR(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00265 static int Q921ProcREJ(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00266 
00267 
00268 /*
00269  * (Common) procedures defined in the Q.921 SDL
00270  */
00271 static int Q921SendEnquiry(L2TRUNK trunk, L2UCHAR tei);
00272 static int Q921SendEnquiryResponse(L2TRUNK trunk, L2UCHAR tei);
00273 static void Q921ResetExceptionConditions(L2TRUNK trunk, L2UCHAR tei);
00274 static int Q921EstablishDataLink(L2TRUNK trunk, L2UCHAR tei);
00275 static int Q921NrErrorRecovery(L2TRUNK trunk, L2UCHAR tei);
00276 static int Q921InvokeRetransmission(L2TRUNK trunk, L2UCHAR tei, L2UCHAR nr);
00277 static int Q921AcknowledgePending(L2TRUNK trunk, L2UCHAR tei);
00278 /*
00279 static int Q921SetReceiverBusy(L2TRUNK trunk);
00280 static int Q921ClearReceiverBusy(L2TRUNK trunk);
00281 */
00282 
00283 /*
00284  * Queueing
00285  */
00286 static int Q921SendQueuedIFrame(L2TRUNK trunk, L2UCHAR tei);
00287 static int Q921EnqueueI(L2TRUNK trunk, L2UCHAR Sapi, char cr, L2UCHAR Tei, char pf, L2UCHAR *mes, L2INT size);
00288 
00289 /*
00290  * TEI management
00291  */
00292 static int Q921TeiSendAssignRequest(L2TRUNK trunk);
00293 static int Q921TeiProcAssignResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00294 static int Q921TeiSendVerifyRequest(L2TRUNK trunk);
00295 static int Q921TeiProcCheckRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00296 static int Q921TeiProcRemoveRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00297 static int Q921TeiProcAssignRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00298 static int Q921TeiProcCheckResponse(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00299 static int Q921TeiProcVerifyRequest(L2TRUNK trunk, L2UCHAR *mes, L2INT size);
00300 static int Q921TeiSendRemoveRequest(L2TRUNK trunk, L2UCHAR tei);
00301 static int Q921TeiSendDenyResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri);
00302 static int Q921TeiSendAssignedResponse(L2TRUNK trunk, L2UCHAR tei, L2USHORT ri);
00303 static int Q921TeiSendCheckRequest(L2TRUNK trunk, L2UCHAR tei);
00304 
00305 /*
00306  * Logging
00307  */
00308 static int Q921Log(L2TRUNK trunk, Q921LogLevel_t level, const char *fmt, ...);
00309 static int Q921LogMesg(L2TRUNK trunk, Q921LogLevel_t level, L2UCHAR received, L2UCHAR *mes, L2INT size, const char *fmt, ...);
00310 
00311 /*
00312  * State handling
00313  */
00314 static int Q921ChangeState(L2TRUNK trunk, Q921State_t state, L2UCHAR tei);
00315 
00316 #ifdef Q921_STATISTICS
00317 /*
00318  * Statistics
00319  */
00320 static void Q921StatsIncrementCounter(struct Q921_Link *link, const int counter);
00321 #endif
00322 
00323 #endif /* _Q921_PRIVATE_H_ */