00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <assert.h>
00045
00046 #define Q931PRIVATE
00047 #include "Q931.h"
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 struct Q931MessageIE Q931MessageIEs[] = {
00060
00061
00062
00063
00064
00065 { Q931mes_ALERTING, 8, {
00066 { Q931ie_BEARER_CAPABILITY, 4, 12, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00067 { Q931ie_CHANNEL_IDENTIFICATION, 2, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00068 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00069 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00070 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00071 { Q931ie_HIGH_LAYER_COMPATIBILITY, 2, 5, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00072
00073 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00074 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00075
00076 { 0, 0, 0, 0 },
00077 }},
00078
00079
00080 { Q931mes_CALL_PROCEEDING, 8, {
00081 { Q931ie_BEARER_CAPABILITY, 4, 12, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00082 { Q931ie_CHANNEL_IDENTIFICATION, 2, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00083 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00084 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00085 { Q931ie_HIGH_LAYER_COMPATIBILITY, 2, 5, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00086
00087 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00088 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00089
00090 { 0, 0, 0, 0 },
00091 }},
00092
00093
00094 { Q931mes_CONNECT, 8, {
00095 { Q931ie_BEARER_CAPABILITY, 4, 12, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00096 { Q931ie_CHANNEL_IDENTIFICATION, 2, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00097 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00098 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00099 { Q931ie_DATETIME, 8, 8, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00100 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00101 { Q931ie_LOW_LAYER_COMPATIBILITY, 2, 18, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00102 { Q931ie_HIGH_LAYER_COMPATIBILITY, 2, 5, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00103
00104 { Q931ie_CONNECTED_NUMBER, 4, 24, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00105 { Q931ie_CONNECTED_SUBADDRESS, 2, 23, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00106
00107 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00108 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00109
00110 { 0, 0, 0, 0 },
00111 }},
00112
00113
00114 { Q931mes_CONNECT_ACKNOWLEDGE, 8, {
00115 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00116 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00117
00118 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00119 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00120
00121 { 0, 0, 0, 0 },
00122 }},
00123
00124
00125 { Q931mes_DISCONNECT, 8, {
00126 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00127 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00128 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00129 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00130
00131 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00132 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00133
00134 { 0, 0, 0, 0 },
00135 }},
00136
00137
00138 { Q931mes_INFORMATION, 8, {
00139 { Q931ie_SENDING_COMPLETE, 1, 1, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00140 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00141 { Q931ie_KEYPAD_FACILITY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00142 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00143 { Q931ie_CALLED_PARTY_NUMBER, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00144 { 0, 0, 0, 0 },
00145 }},
00146
00147
00148 { Q931mes_NOTIFY, 8, {
00149 { Q931ie_BEARER_CAPABILITY, 2, 12, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00150 { Q931ie_NOTIFICATION_INDICATOR, 3, 3, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00151 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00152 { 0, 0, 0, 0 },
00153 }},
00154
00155
00156 { Q931mes_PROGRESS, 8, {
00157 { Q931ie_BEARER_CAPABILITY, 4, 12, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00158 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00159 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00160 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00161 { Q931ie_HIGH_LAYER_COMPATIBILITY, 2, 5, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00162
00163 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00164 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00165
00166 { 0, 0, 0, 0 },
00167 }},
00168
00169
00170 { Q931mes_RELEASE, 8, {
00171 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00172 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00173 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00174
00175 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00176 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00177
00178 { 0, 0, 0, 0 },
00179 }},
00180
00181
00182 { Q931mes_RELEASE_COMPLETE, 8, {
00183 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00184 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00185 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00186
00187 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00188 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00189
00190 { 0, 0, 0, 0 },
00191 }},
00192
00193
00194 { Q931mes_RESUME, 8, {
00195 { Q931ie_CALL_IDENTITY, 2, 10, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00196 { 0, 0, 0, 0 },
00197 }},
00198
00199
00200 { Q931mes_RESUME_ACKNOWLEDGE, 8, {
00201 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_USER | Q931_IEF_MANDATORY },
00202 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00203 { 0, 0, 0, 0 },
00204 }},
00205
00206
00207 { Q931mes_RESUME_REJECT, 8, {
00208 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_USER | Q931_IEF_MANDATORY },
00209 { Q931ie_DISPLAY, 4, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00210 { 0, 0, 0, 0 },
00211 }},
00212
00213
00214 { Q931mes_SETUP, 8, {
00215 { Q931ie_SENDING_COMPLETE, 1, 1, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00216 { Q931ie_REPEAT_INDICATOR, 1, 1, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00217 { Q931ie_BEARER_CAPABILITY, 4, 12, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00218 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00219 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00220 { Q931ie_NETWORK_SPECIFIC_FACILITIES, 2, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00221 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00222 { Q931ie_DATETIME, 8, 8, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00223 { Q931ie_KEYPAD_FACILITY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00224 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00225 { Q931ie_CALLING_PARTY_NUMBER, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00226 { Q931ie_CALLING_PARTY_SUBADDRESS, 2, 23, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00227 { Q931ie_CALLED_PARTY_NUMBER, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00228 { Q931ie_CALLED_PARTY_SUBADDRESS, 2, 23, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00229 { Q931ie_TRANSIT_NETWORK_SELECTION, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00230 { Q931ie_LOW_LAYER_COMPATIBILITY, 2, 18, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00231 { Q931ie_HIGH_LAYER_COMPATIBILITY, 2, 5, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00232
00233 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00234 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00235
00236 { 0, 0, 0, 0 },
00237 }},
00238
00239
00240 { Q931mes_SETUP_ACKNOWLEDGE, 8, {
00241 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00242 { Q931ie_PROGRESS_INDICATOR, 2, 4, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00243 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00244 { Q931ie_SIGNAL, 2, 3, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00245
00246 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00247 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00248
00249 { 0, 0, 0, 0 },
00250 }},
00251
00252
00253 { Q931mes_STATUS, 8, {
00254 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00255 { Q931ie_CALL_STATE, 3, 3, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00256 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00257 { 0, 0, 0, 0 },
00258 }},
00259
00260
00261 { Q931mes_STATUS_ENQUIRY, 8, {
00262 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00263 { 0, 0, 0, 0 },
00264 }},
00265
00266
00267 { Q931mes_SUSPEND, 8, {
00268 { Q931ie_CALL_IDENTITY, 2, 10, Q931_IE_CODESET_0, Q931_IEF_TO_NET },
00269 { 0, 0, 0, 0 },
00270 }},
00271
00272
00273 { Q931mes_SUSPEND_ACKNOWLEDGE, 8, {
00274 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00275 { 0, 0, 0, 0 },
00276 }},
00277
00278
00279 { Q931mes_SUSPEND_REJECT, 8, {
00280 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_USER | Q931_IEF_MANDATORY },
00281 { Q931ie_DISPLAY, 4, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00282 { 0, 0, 0, 0 },
00283 }},
00284
00285
00286 { Q931mes_RESTART, 8, {
00287 { Q931ie_RESTART_INDICATOR, 3, 3, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00288 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00289 { Q931ie_DISPLAY, 4, 34, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00290 { 0, 0, 0, 0 },
00291 }},
00292
00293
00294 { Q931mes_RESTART_ACKNOWLEDGE, 8, {
00295 { Q931ie_RESTART_INDICATOR, 3, 3, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00296 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00297 { Q931ie_DISPLAY, 4, 34, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00298 { 0, 0, 0, 0 },
00299 }},
00300
00301
00302
00303
00304
00305
00306
00307 { Q932mes_HOLD, 8, {
00308 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00309
00310 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00311 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00312 { 0, 0, 0, 0 },
00313 }},
00314
00315
00316 { Q932mes_HOLD_ACKNOWLEDGE, 8, {
00317 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00318
00319 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00320 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00321 { 0, 0, 0, 0 },
00322 }},
00323
00324
00325 { Q932mes_HOLD_REJECT, 8, {
00326 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00327 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00328
00329 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00330 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00331 { 0, 0, 0, 0 },
00332 }},
00333
00334
00335 { Q932mes_REGISTER, 8, {
00336 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00337 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00338 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00339
00340 { 0, 0, 0, 0 },
00341 }},
00342
00343
00344 { Q932mes_RETRIEVE, 8, {
00345 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00346 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00347
00348 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00349 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00350 { 0, 0, 0, 0 },
00351 }},
00352
00353
00354 { Q932mes_RETRIEVE_ACKNOWLEDGE, 8, {
00355 { Q931ie_CHANNEL_IDENTIFICATION, 3, 0, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00356 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00357
00358 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00359 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00360 { 0, 0, 0, 0 },
00361 }},
00362
00363
00364 { Q932mes_RETRIEVE_REJECT, 8, {
00365 { Q931ie_CAUSE, 4, 32, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00366 { Q931ie_DISPLAY, 2, 34, Q931_IE_CODESET_0, Q931_IEF_TO_USER },
00367
00368 { Q932ie_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00369 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00370 { 0, 0, 0, 0 },
00371 }},
00372
00373
00374 { Q932mes_FACILITY, 8, {
00375 { Q932ie_FACILITY, 8, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH | Q931_IEF_MANDATORY },
00376 { Q932ie_EXTENDED_FACILITY, 2, 99, Q931_IE_CODESET_0, Q931_IEF_TO_BOTH },
00377 { 0, 0, 0, 0 },
00378 }},
00379
00380
00381
00382 { 0, 0, {{ 0, 0, 0, 0 }}},
00383 };
00384
00394 static struct Q931MessageIEEntry *Q931MesgIEsGetEntry(struct Q931Dialect *dialect, L3INT MesType, L3UCHAR ProtDisc, L3UCHAR id, L3UCHAR *index)
00395 {
00396 struct Q931MessageIE *mes = NULL;
00397 struct Q931MessageIE *map = NULL;
00398 struct Q931MessageIEEntry *ie;
00399 int i, offset = 0;
00400
00401 assert(dialect);
00402
00403 map = Q931DialectGetMesIEMap(dialect);
00404 if (!map) {
00405 return NULL;
00406 }
00407
00408 if (index) {
00409 offset = *index;
00410 }
00411
00412 for (i = offset; map[i].id; i++) {
00413 if(map[i].id == MesType && map[i].protdisc == ProtDisc) {
00414 mes = &map[i];
00415 break;
00416 }
00417 }
00418 if (!mes) {
00419
00420 return NULL;
00421 }
00422
00423 if (index) {
00424 *index = i;
00425 }
00426
00427 ie = mes->ies;
00428 while (ie->id) {
00429 if (ie->id == id) {
00430 return ie;
00431 }
00432 ie++;
00433 }
00434 return NULL;
00435 }
00436
00444 static struct Q931MessageIEEntry *Q931MesgIEsGetFirstEntry(struct Q931Dialect *dialect, L3INT MesType, L3UCHAR ProtDisc)
00445 {
00446 struct Q931MessageIE *map = NULL;
00447
00448 assert(dialect);
00449
00450 map = Q931DialectGetMesIEMap(dialect);
00451 if (!map) {
00452 return NULL;
00453 }
00454
00455 while (map->id) {
00456 if(map->id == MesType && map->protdisc == ProtDisc)
00457 break;
00458 map++;
00459 }
00460 if (!map->id) {
00461
00462 return NULL;
00463 }
00464 return map->ies;
00465 }
00466
00477 static L3INT Q931MesgIEsGetMandatory(struct Q931Dialect *dialect, L3INT MesType, L3UCHAR ProtDisc, L3UCHAR *list, L3INT size)
00478 {
00479 struct Q931MessageIE *map = NULL;
00480 struct Q931MessageIEEntry *ie;
00481 int i = 0;
00482
00483 assert(dialect);
00484
00485 map = Q931DialectGetMesIEMap(dialect);
00486 if (!map) {
00487 return -1;
00488 }
00489
00490 while (map->id) {
00491 if(map->id == MesType && map->protdisc == ProtDisc)
00492 break;
00493 map++;
00494 }
00495 if (!map->id) {
00496
00497 return -1;
00498 }
00499
00500 ie = map->ies;
00501 while (ie->id) {
00502 if (ie->flags & Q931_IEF_MANDATORY) {
00503 if (i >= size) {
00504 return -1;
00505 }
00506 list[i++] = ie->id;
00507 }
00508 ie++;
00509 }
00510 return i;
00511 }
00512
00520 static L3INT Q931MesgIEsMandatoryMissing(L3UCHAR *list, L3INT size)
00521 {
00522 int count = 0;
00523 int i;
00524
00525 for (i = 0; i < size; i++) {
00526 if (list[i]) {
00527 count++;
00528 }
00529 }
00530 return count;
00531 }
00532
00540 static void Q931MesgIEsMandatoryClear(L3UCHAR *list, L3INT size, L3UCHAR id)
00541 {
00542 int i;
00543
00544 for (i = 0; i < size; i++) {
00545 if (list[i] == id) {
00546 list[i] = 0;
00547 return;
00548 }
00549 }
00550 }
00551
00560 static L3BOOL Q931MesgIEIsDirectionValid(struct Q931MessageIEEntry *ie, L3INT mode, L3BOOL outgoing)
00561 {
00562 L3INT flags = Q931_IEF_NONE;
00563
00564 if (mode == Q931_NT) {
00565 flags |= (outgoing) ? Q931_IEF_TO_USER : Q931_IEF_TO_NET;
00566 } else {
00567 flags |= (outgoing) ? Q931_IEF_TO_NET : Q931_IEF_TO_USER;
00568 }
00569
00570 if (!(ie->flags & flags)) {
00571 return L3FALSE;
00572 }
00573 return L3TRUE;
00574 }
00575
00583 static L3BOOL Q931MesgIEIsCodesetValid(struct Q931MessageIEEntry *ie, L3INT codeset)
00584 {
00585 L3INT flags = Q931_IE_CODESET_0;
00586
00587
00588 if (ie->codeset & Q931_IE_CODESET_ALL) {
00589 flags <<= codeset;
00590
00591 if (!(ie->codeset & flags)) {
00592 return L3FALSE;
00593 }
00594 }
00595 return L3TRUE;
00596 }
00597
00604 static L3UCHAR Q931MesgIEGetCodeset(struct Q931MessageIEEntry *ie)
00605 {
00606 L3INT mask = Q931_IE_CODESET_0;
00607 L3UCHAR codeset = 0;
00608
00609 while (mask <= Q931_IE_CODESET_7) {
00610 if (ie->codeset & mask) {
00611 return codeset;
00612 }
00613
00614 mask <<= 1;
00615 codeset++;
00616 }
00617 return 0;
00618 }
00619
00627 static L3BOOL Q931MesgIEIsSizeValid(struct Q931MessageIEEntry *ie, L3UCHAR size)
00628 {
00629 if (ie->id & 0x80) {
00630 return (L3BOOL)(size == 1);
00631 }
00632
00633 return (L3BOOL)(ie->minsize <= size || ie->maxsize >= size);
00634 }
00635
00642 static L3BOOL Q931MesgIEIsMandatory(struct Q931MessageIEEntry *ie)
00643 {
00644 return (L3BOOL)((ie->flags & Q931_IEF_MANDATORY) != 0);
00645 }
00646
00651 L3INT Q931MesgHeader(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *mes, L3UCHAR *OBuf, L3INT Size, L3INT *IOff)
00652 {
00653 L3INT Octet = *IOff;
00654
00655 Q931Log(pTrunk, Q931_LOG_DEBUG, "Creating Q.931 Message Header:\n ProtDisc %d (%#x), CRV %d (%#x), CRVflag: %d (%#x), MesType: %d (%#x)\n",
00656 mes->ProtDisc, mes->ProtDisc, mes->CRV, mes->CRV, mes->CRVFlag, mes->CRVFlag, mes->MesType, mes->MesType);
00657
00658 OBuf[Octet++] = mes->ProtDisc;
00659 if (!Q931_IS_BRI(pTrunk)) {
00660 OBuf[Octet++] = 2;
00661 OBuf[Octet++] = (L3UCHAR)((mes->CRV >> 8) & 0x7f) | ((mes->CRVFlag << 7) & 0x80);
00662 OBuf[Octet++] = (L3UCHAR) (mes->CRV & 0xff);
00663 } else {
00664 OBuf[Octet++] = 1;
00665 OBuf[Octet++] = (L3UCHAR) (mes->CRV & 0x7f) | ((mes->CRVFlag << 7) & 0x80);
00666 }
00667 OBuf[Octet++] = mes->MesType;
00668
00669 *IOff = Octet;
00670 return 0;
00671 }
00672
00673
00674
00675
00676
00677
00678
00690 L3INT Q931Umes_Generic(Q931_TrunkInfo_t *pTrunk, L3UCHAR *IBuf, Q931mes_Generic *mes, L3INT IOff, L3INT Size)
00691 {
00692 L3INT ir = 0;
00693 L3INT OOff = 0;
00694 L3INT rc = Q931E_NO_ERROR;
00695 L3UCHAR last_codeset = 0, codeset = 0;
00696 L3UCHAR shift_nolock = 1;
00697 L3UCHAR mandatoryIEs[Q931MAXIE];
00698 L3UCHAR msgidx = 0;
00699 L3INT mandsize = 0, missing_count;
00700
00701 if (!mes->MesType) {
00702 Q931Log(pTrunk, Q931_LOG_ERROR, "Nationally specified message types not supported\n");
00703 return Q931E_UNEXPECTED_MESSAGE;
00704 }
00705
00706 memset(mandatoryIEs, 0, sizeof(mandatoryIEs));
00707
00708 mandsize = Q931MesgIEsGetMandatory(pTrunk->Dialect, mes->MesType, mes->ProtDisc, mandatoryIEs, sizeof(mandatoryIEs));
00709 if (mandsize < 0) {
00710 Q931Log(pTrunk, Q931_LOG_DEBUG, "Unable to load mandatory IEs for message\n");
00711 return Q931E_UNKNOWN_MESSAGE;
00712 }
00713
00714
00715
00716
00717 while (IOff < Size) {
00718 struct Q931MessageIEEntry *entry;
00719 L3UCHAR id, size;
00720
00721
00722 if ((IBuf[IOff] & 0xf0) == Q931ie_SHIFT) {
00723 shift_nolock = (IBuf[IOff] & 0x08);
00724 if (shift_nolock) {
00725 last_codeset = codeset;
00726 }
00727 codeset = (IBuf[IOff++] & 0x07);
00728 #ifdef __TODO__
00729
00730 if (!Q931MesgCodesetIsValid(pTrunk, codeset)) {
00731 Q931Log(pTrunk, Q931_LOG_ERROR, "Shift to invalid codeset %d\n", codeset);
00732 }
00733 #endif
00734 continue;
00735 }
00736
00737
00738 id = IBuf[IOff];
00739
00740 if (!(id & 0x80)) {
00741
00742 size = IBuf[IOff + 1] + 2;
00743 } else {
00744
00745 size = 1;
00746 }
00747
00748
00749 if (Q931UieIsNull(pTrunk, id)) {
00750
00751 Q931Log(pTrunk, Q931_LOG_DEBUG, "Unhandled IE %hhu (%#hhx)\n", id, id);
00752
00753 if (Q931TrunkIsSetFlag(pTrunk, Q931_TFLAG_IGNORE_UNKNOWN_IE)) {
00754 IOff += size;
00755 goto skip;
00756 } else
00757 return Q931E_UNKNOWN_IE;
00758 }
00759
00760
00761 entry = Q931MesgIEsGetEntry(pTrunk->Dialect, mes->MesType, mes->ProtDisc, id, &msgidx);
00762 if (!entry) {
00763
00764 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) not allowed for message type\n", id, id);
00765
00766 if (Q931TrunkIsSetFlag(pTrunk, Q931_TFLAG_IGNORE_ILLEGAL_IE)) {
00767 IOff += size;
00768 goto skip;
00769 } else
00770 return Q931E_ILLEGAL_IE;
00771 }
00772
00773 if (!Q931MesgIEIsDirectionValid(entry, pTrunk->NetUser, 0)) {
00774
00775 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) in wrong direction (flags: 0x%x, mode: %d, incoming)\n", id, id, entry->flags, pTrunk->NetUser);
00776 return Q931E_ILLEGAL_IE;
00777 }
00778
00779 if (!Q931MesgIEIsSizeValid(entry, size)) {
00780
00781 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) size error\n", id, id);
00782 return Q931E_ILLEGAL_IE;
00783 }
00784
00785 if (!Q931MesgIEIsCodesetValid(entry, codeset)) {
00786
00787 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) not allowed in codeset %d\n", id, id, codeset);
00788 return Q931E_ILLEGAL_IE;
00789 }
00790
00791 switch (id) {
00792 case Q931ie_REPEAT_INDICATOR:
00793 if (ir < 2) {
00794 rc = Q931Uie(pTrunk, id, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
00795 ir++;
00796 } else {
00797 return Q931E_ILLEGAL_IE;
00798 }
00799 break;
00800 default:
00801 rc = Q931Uie(pTrunk, id, mes, &IBuf[IOff], &mes->buf[OOff], &IOff, &OOff);
00802 if (rc != Q931E_NO_ERROR)
00803 return rc;
00804 break;
00805 }
00806
00807
00808 if (Q931MesgIEIsMandatory(entry)) {
00809 Q931MesgIEsMandatoryClear(mandatoryIEs, mandsize, id);
00810 }
00811
00812 skip:
00813
00814 if (shift_nolock) {
00815 codeset = last_codeset;
00816 }
00817 }
00818
00819 if ((missing_count = Q931MesgIEsMandatoryMissing(mandatoryIEs, mandsize)) > 0) {
00820
00821 Q931Log(pTrunk, Q931_LOG_ERROR, "%d Mandatory IEs missing in this incoming message\n", missing_count);
00822
00823 return Q931E_MANDATORY_IE_MISSING;
00824 }
00825
00826 mes->Size = sizeof(Q931mes_Generic) - 1 + OOff;
00827 return Q931E_NO_ERROR;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837 static Q931ie_Generic * Q931MesgGetIE(Q931_TrunkInfo_t *trunk, Q931mes_Generic *mes, L3UCHAR id)
00838 {
00839 ie ie = 0;
00840
00841 switch(id) {
00842 case Q931ie_SENDING_COMPLETE:
00843 ie = mes->SendComplete;
00844 break;
00845 case Q931ie_REPEAT_INDICATOR:
00846 ie = mes->RepeatInd;
00847 break;
00848 case Q931ie_BEARER_CAPABILITY:
00849 ie = mes->BearerCap;
00850 break;
00851 case Q931ie_CHANNEL_IDENTIFICATION:
00852 ie = mes->ChanID;
00853 break;
00854 case Q931ie_NETWORK_SPECIFIC_FACILITIES:
00855 ie = mes->NetFac;
00856 break;
00857 case Q931ie_DISPLAY:
00858 ie = mes->Display;
00859 break;
00860 case Q931ie_DATETIME:
00861 ie = mes->DateTime;
00862 break;
00863 case Q931ie_KEYPAD_FACILITY:
00864 ie = mes->KeypadFac;
00865 break;
00866 case Q931ie_SIGNAL:
00867 ie = mes->Signal;
00868 break;
00869 case Q931ie_CALLING_PARTY_NUMBER:
00870 ie = mes->CallingNum;
00871 break;
00872 case Q931ie_CALLING_PARTY_SUBADDRESS:
00873 ie = mes->CallingSub;
00874 break;
00875 case Q931ie_CALLED_PARTY_NUMBER:
00876 ie = mes->CalledNum;
00877 break;
00878 case Q931ie_CALLED_PARTY_SUBADDRESS:
00879 ie = mes->CalledSub;
00880 break;
00881 case Q931ie_TRANSIT_NETWORK_SELECTION:
00882 ie = mes->TransNetSel;
00883 break;
00884 case Q931ie_LOW_LAYER_COMPATIBILITY:
00885 ie = mes->LLComp;
00886 break;
00887 case Q931ie_HIGH_LAYER_COMPATIBILITY:
00888 ie = mes->HLComp;
00889 break;
00890 case Q931ie_PROGRESS_INDICATOR:
00891 ie = mes->ProgInd;
00892 break;
00893 case Q931ie_CAUSE:
00894 ie = mes->Cause;
00895 break;
00896 case Q931ie_CHANGE_STATUS:
00897 ie = mes->ChangeStatus;
00898 break;
00899 case Q931ie_RESTART_INDICATOR:
00900 ie = mes->RestartInd;
00901 break;
00902 case Q931ie_CALL_STATE:
00903 ie = mes->CallState;
00904 break;
00905 default:
00906 Q931Log(trunk, Q931_LOG_NOTICE, "Unable to get reference for IE %hhu (%#hhx)\n", id, id);
00907 return NULL;
00908 }
00909
00910 if(Q931IsIEPresent(ie)) {
00911 return Q931GetIEPtr(ie, mes->buf);
00912 }
00913
00914 return NULL;
00915 }
00916
00917 L3INT Q931Pmes_Generic(Q931_TrunkInfo_t *pTrunk, Q931mes_Generic *IBuf, L3INT ISize, L3UCHAR *OBuf, L3INT *OSize)
00918 {
00919 Q931mes_Generic *pMes = (Q931mes_Generic *)IBuf;
00920 struct Q931MessageIEEntry *entry;
00921 L3UCHAR mandatoryIEs[Q931MAXIE];
00922 L3UCHAR codeset = 0;
00923 L3INT rc = Q931E_NO_ERROR;
00924 L3INT Octet = 0;
00925 L3INT mandsize = 0, missing_count;
00926
00927 memset(mandatoryIEs, 0, sizeof(mandatoryIEs));
00928
00929
00930 Q931MesgHeader(pTrunk, pMes, OBuf, *OSize, &Octet);
00931
00932
00933 mandsize = Q931MesgIEsGetMandatory(pTrunk->Dialect, pMes->MesType, pMes->ProtDisc, mandatoryIEs, sizeof(mandatoryIEs));
00934 if (mandsize < 0) {
00935 Q931Log(pTrunk, Q931_LOG_DEBUG, "Unable to load mandatory IEs for message\n");
00936 return Q931E_UNKNOWN_MESSAGE;
00937 }
00938
00939
00940 entry = Q931MesgIEsGetFirstEntry(pTrunk->Dialect, pMes->MesType, pMes->ProtDisc);
00941
00942 while (entry && entry->id) {
00943 L3UCHAR ie_codeset = 0;
00944 Q931ie_Generic *pIE;
00945
00946 pIE = Q931MesgGetIE(pTrunk, pMes, entry->id);
00947
00948
00949 if (pIE) {
00950 L3UCHAR size = 1;
00951
00952 if (!(entry->id & 0x80)) {
00953 size = pIE->Size + 2;
00954 }
00955
00956
00957 if (!Q931MesgIEIsDirectionValid(entry, pTrunk->NetUser, 1)) {
00958
00959 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) in wrong direction\n", entry->id, entry->id);
00960 return Q931E_ILLEGAL_IE;
00961 }
00962
00963
00964 if (!Q931MesgIEIsSizeValid(entry, size)) {
00965
00966 Q931Log(pTrunk, Q931_LOG_DEBUG, "IE %hhu (%#hhx) size error\n", entry->id, entry->id);
00967 return Q931E_ILLEGAL_IE;
00968 }
00969
00970
00971 if (Q931PieIsNull(pTrunk, entry->id)) {
00972
00973 Q931Log(pTrunk, Q931_LOG_DEBUG, "Unhandled IE %hhu (%#hhx)\n", entry->id, entry->id);
00974 return Q931E_UNKNOWN_IE;
00975 }
00976
00977
00978 ie_codeset = Q931MesgIEGetCodeset(entry);
00979 if (ie_codeset != codeset) {
00980 #ifdef __TODO__
00981 if (dialect->flags & Q931_DIALECT_LOCKING_SHIFT_ONLY) {
00982
00983 codeset = rc;
00984 OBuf[Octet++] = Q931ie_SHIFT | (codeset & 0x07);
00985 } else {
00986 #endif
00987
00988 OBuf[Octet++] = Q931ie_SHIFT | 0x08 | (rc & 0x07);
00989 #ifdef __TODO__
00990 }
00991 #endif
00992 }
00993
00994
00995
00996 if ((rc = Q931Pie(pTrunk, entry->id, (L3UCHAR *)pIE, OBuf, &Octet)) != Q931E_NO_ERROR) {
00997 return rc;
00998 }
00999
01000
01001 if (Q931MesgIEIsMandatory(entry)) {
01002 Q931MesgIEsMandatoryClear(mandatoryIEs, mandsize, entry->id);
01003 }
01004 }
01005
01006 entry++;
01007 }
01008
01009 if ((missing_count = Q931MesgIEsMandatoryMissing(mandatoryIEs, mandsize)) > 0) {
01010
01011 Q931Log(pTrunk, Q931_LOG_ERROR, "%d Mandatory IEs missing in this outgoing message\n", missing_count);
01012
01013 return Q931E_MANDATORY_IE_MISSING;
01014 }
01015
01016 *OSize = Octet;
01017 return rc;
01018 }