-
Notifications
You must be signed in to change notification settings - Fork 372
Expand file tree
/
Copy pathControlCommon.h
More file actions
executable file
·275 lines (216 loc) · 9.91 KB
/
ControlCommon.h
File metadata and controls
executable file
·275 lines (216 loc) · 9.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/**@file Declarations for common-use control-layer functions. */
/*
* Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011, 2014 Range Networks, Inc.
*
* This software is distributed under multiple licenses;
* see the COPYING file in the main directory for licensing
* information for this specific distribution.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef CONTROLCOMMON_H
#define CONTROLCOMMON_H
#include <stdio.h>
#include <list>
#include <Logger.h>
//#include <Interthread.h>
#include <Timeval.h>
//#include <GSML3CommonElements.h>
//#include <GSML3MMElements.h>
//#include <GSML3CCElements.h>
//#include <GSML3RRMessages.h>
//#include <SIPEngine.h>
//#include "TMSITable.h"
#include <ControlTransfer.h>
// These are macros for manufacturing states for state machines.
// Since we are using C++, they cannot be classes if we want to use switch().
// The pd selects an address space for each group of messages, whose mti must <256.
// The pd might be: L3CallControlPD, L3MobilityManagementPD, L3RadioResourcePD, etc.
// Note we overload pd==0 (Group Call Control) for naked states in the state machines, which is ok because
// we dont support Group Call and even if we did, the Group Call MTIs (GSM 04.68 9.3) will probably not collide.
// We use higher unused pds for our own purposes: 16 is for SIP Dialog messages, 17 for L3Frame primitives.
#define L3CASE_RAW(pd,mti) (((pd)<<8)|(mti))
#define L3CASE_CC(mti) L3CASE_RAW(L3CallControlPD,L3CCMessage::mti) // pd == 3
#define L3CASE_MM(mti) L3CASE_RAW(L3MobilityManagementPD,L3MMMessage::mti) // pd == 5
#define L3CASE_RR(mti) L3CASE_RAW(L3RadioResourcePD,L3RRMessage::mti) // pd == 6
#define L3CASE_SS(mti) L3CASE_RAW(L3NonCallSSPD,L3SupServMessage::mti) // pd == 6
#define L3CASE_SMS(mti) L3CASE_RAW(L3SMSPD,CPMessage::mti) // pd == 9
#define L3CASE_PRIMITIVE(prim) L3CASE_RAW(17,prim)
// L3CASE_DIALOG_STATE is for a raw dialog state number, and L3CASE_SIP is for a dialog state name.
#define L3CASE_DIALOG_STATE(sipDialogState) L3CASE_RAW(16,sipDialogState) // SIP messages use pd == 16, which is unused by GSM.
#define L3CASE_SIP(dialogStateName) L3CASE_DIALOG_STATE(SIP::DialogState::dialogStateName)
//unused: #define L3CASE_ERROR L3CASE_RAW(18,0)
// Enough forward refs to prevent "kitchen sink" includes and circularity.
namespace GSM {
class L3Message;
class SDCCHLogicalChannel;
class SACCHLogicalChannel;
class TCHFACCHLogicalChannel;
class L3CMServiceRequest;
};
/**@namespace Control This namepace is for use by the control layer. */
namespace Control {
class TranEntry;
class NewTransactionTable;
class MMContext;
class MMUser;
class L3LogicalChannel;
/**@name Call control time-out values (in ms) from ITU-T Q.931 Table 9-1 and GSM 04.08 Table 11.4. */
//@{
#ifndef RACETEST
const unsigned T301ms=60000; ///< recv ALERT --> recv CONN
const unsigned T302ms=12000; ///< send SETUP ACK --> any progress
const unsigned T303ms=30000; ///< send SETUP --> recv CALL CONF or REL COMP
const unsigned T304ms=20000; ///< recv SETUP ACK --> any progress
const unsigned T305ms=30000; ///< send DISC --> recv REL or DISC
const unsigned T308ms=30000; ///< send REL --> rev REL or REL COMP
const unsigned T310ms=30000; ///< recv CALL CONF --> recv ALERT, CONN, or DISC
const unsigned T313ms=30000; ///< send CONNECT --> recv CONNECT ACK
const unsigned T3270ms=12000; ///< send IdentityRequest -> recv IdentityResponse
const unsigned TR1Mms=40000; ///< MO-SMS timer. 3GPP 4.11 10.0 says: 35s < TR1M < 45s
const unsigned TR2Mms=15000; ///< MT-SMS timer. 3GPP 4.11 10.0 says: 12s < TR2M < 20s
#else
// These are reduced values to force testing of poor network behavior.
const unsigned T301ms=18000; ///< recv ALERT --> recv CONN
const unsigned T302ms=1200; ///< send SETUP ACK --> any progress
const unsigned T303ms=400; ///< send SETUP --> recv CALL CONF or REL COMP
const unsigned T304ms=2000; ///< recv SETUP ACK --> any progress
const unsigned T305ms=3000; ///< send DISC --> recv REL or DISC
const unsigned T308ms=3000; ///< send REL --> rev REL or REL COMP
const unsigned T310ms=3000; ///< recv CALL CONF --> recv ALERT, CONN, or DISC
const unsigned T313ms=3000; ///< send CONNECT --> recv CONNECT ACK
const unsigned T3270ms=12000; ///< send IdentityRequest -> recv IdentityResponse
const unsigned TR1Mms=40000; ///< MO-SMS timer. 3GPP 4.11 10.0 says: 35s < TR1M < 45s
const unsigned TR2Mms=15000; ///< MT-SMS timer. 3GPP 4.11 10.0 says: 12s < TR1M < 20s
#endif
//@}
// These enums are here because they need to be in a file included before others.
// Mobility Management Sublayer 4.08 4.1
// The primary purpose is to set between CM Call Management requests and RR channel allocation.
// There can be multiple simultaneous requests and MMLayer mediates them.
// The MM sublayer is not an exposed entity in the sense that nobody ever sees it or this state.
// The official Mobility Management states defined on the Network Side are 4.08 4.1.2.3.
//1. IDLE The MM sublayer is not active except possibly when the RR sublayer is in Group Receive mode.
//2. WAIT FOR RR CONNECTION aka paging.
//3. MM CONNECTION ACTIVE The MM sublayer has a RR connection to a mobile station. One or more MM connections are active, or no
// MM connection is active but an RRLP procedure is ongoing.
//4. IDENTIFICATION INITIATED The identification procedure has been started by the network. The timer T3270 is running.
//5. AUTHENTICATION INITIATED The authentication procedure has been started by the network. The timer T3260 is running.
//6. TMSI REALLOCATION INITIATED The TMSI reallocation procedure has been started by the network. The timer T3250 is running.
//7. CIPHERING MODE INITIATED The cipher mode setting procedure has been requested to the RR sublayer.
//8a. WAIT FOR MOBILE ORIGINATED MM CONNECTION A CM SERVICE REQUEST message is received and processed, and the MM sublayer
// awaits the "opening message" of the MM connection.
// 9. WAIT FOR REESTABLISHMENT The RR connection to a mobile station with one or more active MM connection has been lost.
// The network awaits a possible re-establishment request from the mobile station.
// We use our own MM states that are only vaguely related.
// The spec assumes that the MM entity and CM entity are separate, but we run all procedures on top of a TransactionEntry object,
// so we can combine some MM states.
enum MMState {
MMStateUndefined,
MMStatePaging, // aka "2. WAIT FOR CONNECTION"
MMStateActive, // aka "3. MM CONNECTION ACTIVE"
// In our case this means that we are not planning to change the channel either.
MMStateChannelChange, // We are busy changing the channel, eg, SDCCH to TCH, which blocks everything.
MMBlocked, // blocked for LUR, Identification or Authentication in progress, either on this IMSI (blocked for sure)
// or on this TMSI (speculatively blocked.) The outcome of the procedure may determine whether
// we keep or discard this MMUser and any pending CM requests.
};
// The MM reasons that may cause a call to end.
//enum MMCause {
// MMNormalEvent, // Means the MMLayer can try something else on this MS.
// MMCongestion,
// MMImsiDetach, // Means the MMLayer should terminate everything on this MS.
// MMFailure, // Authenticaion/id or other major failure. terminate everything
//};
/**@name Dispatch controllers for specific channel types. */
//@{
//void FACCHDispatcher(GSM::TCHFACCHLogicalChannel *TCHFACCH);
//void SDCCHDispatcher(GSM::SDCCHLogicalChannel *SDCCH);
void DCCHDispatcher(L3LogicalChannel *DCCH);
//@}
/**
SMSCB sender function
*/
void *SMSCBSender(void*);
/**@name Control-layer exceptions. */
//@{
/**
A control layer excpection includes a pointer to a transaction.
The transaction might require some clean-up action, depending on the exception.
*/
class ControlLayerException : public std::exception {
private:
unsigned mTransactionID;
public:
ControlLayerException(unsigned wTransactionID=0)
:mTransactionID(wTransactionID)
{
LOG(INFO) << "ControlLayerException";
}
unsigned transactionID() { return mTransactionID; }
};
/** Thrown when the control layer gets the wrong message */
class UnexpectedMessage : public ControlLayerException {
public:
UnexpectedMessage(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{
LOG(INFO) << "UnexpectedMessage Exception";
}
};
/** Thrown when recvL3 returns NULL */
class ChannelReadTimeout : public ControlLayerException {
public:
ChannelReadTimeout(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{}
};
/** Thrown when L3 can't parse an incoming message */
class UnsupportedMessage : public ControlLayerException {
public:
UnsupportedMessage(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{
LOG(INFO) << "UnsupportedMessage Exception";
}
};
/** Thrown when the control layer gets the wrong primitive */
class UnexpectedPrimitive : public ControlLayerException {
public:
UnexpectedPrimitive(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{
LOG(INFO) << "UnexpectedPrimitive Exception";
}
};
/** Thrown when a T3xx expires */
class Q931TimerExpired : public ControlLayerException {
public:
Q931TimerExpired(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{}
};
/** Thrown if we touch a removed transaction. */
class RemovedTransaction : public ControlLayerException {
public:
RemovedTransaction(unsigned wTransactionID=0)
:ControlLayerException(wTransactionID)
{
LOG(INFO) << "RemovedTransaction Exception";
}
};
//@}
} //Control
/**@addtogroup Globals */
//@{
/** A single global transaction table in the global namespace. */
extern Control::NewTransactionTable gNewTransactionTable;
//@}
#endif
// vim: ts=4 sw=4