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 #include <assert.h>
00040
00041 #define Q931PRIVATE
00042 #include "Q931.h"
00043 #include "memory.h"
00044
00045
00046
00047
00048 void Q931CallSetState(struct Q931_Call *call, const L3INT state)
00049 {
00050 assert(call);
00051
00052 if (Q931CallIsGlobal(call))
00053 return;
00054
00055 Q931Log(Q931CallGetTrunk(call), Q931_LOG_DEBUG, "Call going from state %d -> %d\n",
00056 (call->State & 0xff), (state & 0xff));
00057
00058 call->State = state;
00059 }
00060
00061 L3INT Q931CallGetState(const struct Q931_Call *call)
00062 {
00063 assert(call);
00064
00065 return call->State;
00066 }
00067
00068
00069
00070
00071
00072 static struct Q931_Call *Q931FindFreeCall(const Q931_TrunkInfo_t *trunk)
00073 {
00074 struct Q931_Call *call = NULL;
00075 L3INT i;
00076
00077
00078 for (i = 1; i < Q931MAXCALLPERTRUNK; i++) {
00079 if (!trunk->call[i].InUse) {
00080 call = (struct Q931_Call *)&trunk->call[i];
00081 break;
00082 }
00083 }
00084 return call;
00085 }
00086
00097 struct Q931_Call *Q931CallNew(Q931_TrunkInfo_t *trunk)
00098 {
00099 struct Q931_Call *call = NULL;
00100 L3INT crv = 0;
00101
00102
00103 call = Q931FindFreeCall(trunk);
00104 if (!call) {
00105
00106 return NULL;
00107 }
00108 call->InUse = 1;
00109
00110 Q931Log(trunk, Q931_LOG_INFO, "Found a free call, trying to find a new CRV\n");
00111
00112
00113 crv = Q931GetUniqueCRV(trunk);
00114 if (!crv) {
00115 goto crverror;
00116 }
00117
00118 Q931Log(trunk, Q931_LOG_INFO, "Using crv %d for new call\n", crv);
00119
00120
00121 call->Direction = Q931_DIRECTION_OUTBOUND;
00122 call->CRV = crv;
00123 call->Trunk = trunk;
00124
00125 Q931CallSetState(call, (trunk->NetUser == Q931_NT) ? Q931_N0 : Q931_U0);
00126
00127 return call;
00128
00129 crverror:
00130 call->InUse = 0;
00131 return NULL;
00132 }
00133
00134 struct Q931_Call *Q931CallNewIncoming(Q931_TrunkInfo_t *trunk, const L3INT crv)
00135 {
00136 struct Q931_Call *call = NULL;
00137
00138
00139 call = Q931FindFreeCall(trunk);
00140 if (!call) {
00141
00142 return NULL;
00143 }
00144 call->InUse = 1;
00145
00146
00147 call->Direction = Q931_DIRECTION_INBOUND;
00148 call->CRV = crv;
00149 call->Trunk = trunk;
00150
00151 Q931CallSetState(call, (trunk->NetUser == Q931_NT) ? Q931_N0 : Q931_U0);
00152
00153 return call;
00154 }
00155
00156
00165 L3INT Q931CallRelease(struct Q931_Call *call)
00166 {
00167 L3INT state;
00168
00169 assert(call);
00170
00171 if (Q931CallIsGlobal(call))
00172 return 0;
00173
00174
00175 state = Q931CallGetState(call);
00176
00177 if (state != Q931_U0 || state != Q931_N0) {
00178
00179 return -1;
00180 }
00181
00182
00183 memset(call, 0, sizeof(struct Q931_Call));
00184
00185 return 0;
00186 }
00187
00188
00189
00190
00191
00192 void Q931CallSetPrivate(struct Q931_Call *call, const void *priv)
00193 {
00194 assert(call);
00195
00196 call->pvt = (void *)priv;
00197 }
00198
00199 void *Q931CallGetPrivate(const struct Q931_Call *call)
00200 {
00201 assert(call);
00202
00203 return call->pvt;
00204 }
00205
00206 Q931_TrunkInfo_t *Q931CallGetTrunk(const struct Q931_Call *call)
00207 {
00208 assert(call);
00209 assert(call->Trunk);
00210
00211 return call->Trunk;
00212 }
00213
00214 L3INT Q931CallGetCRV(const struct Q931_Call *call)
00215 {
00216 assert(call);
00217
00218 return call->CRV;
00219 }
00220
00221 L3INT Q931CallGetDirection(const struct Q931_Call *call)
00222 {
00223 assert(call);
00224
00225 return call->Direction;
00226 }
00227
00228 L3BOOL Q931CallIsOutgoing(const struct Q931_Call *call)
00229 {
00230 assert(call);
00231
00232 return call->Direction == Q931_DIRECTION_OUTBOUND;
00233 }
00234
00235
00236
00237
00238
00239 struct Q931CallStateName
00240 {
00241 L3INT id;
00242 const L3CHAR *name;
00243
00244 } Q931CallStateNames[] = {
00245 { Q931_U0, "Null" },
00246 { Q931_U1, "Call initiated" },
00247 { Q931_U2, "Overlap sending" },
00248 { Q931_U3, "Outgoing call proceeding" },
00249 { Q931_U4, "Call delivered" },
00250 { Q931_U6, "Call present" },
00251 { Q931_U7, "Call received" },
00252 { Q931_U8, "Connect request" },
00253 { Q931_U9, "Incoming call proceeding" },
00254 { Q931_U10, "Active" },
00255 { Q931_U11, "Disconnect request" },
00256 { Q931_U12, "Disconnect indication" },
00257 { Q931_U15, "Suspend request" },
00258 { Q931_U17, "Resume request" },
00259 { Q931_U19, "Release request" },
00260 { Q931_U25, "Overlap receiving" },
00261
00262 { Q931_N0, "Null" },
00263 { Q931_N1, "Call initiated" },
00264 { Q931_N2, "Overlap sending" },
00265 { Q931_N3, "Outgoing call proceeding" },
00266 { Q931_N4, "Call delivered" },
00267 { Q931_N6, "Call present" },
00268 { Q931_N7, "Call received" },
00269 { Q931_N8, "Connect request" },
00270 { Q931_N9, "Incoming call proceeding" },
00271 { Q931_N10, "Active" },
00272 { Q931_N11, "Disconnect request" },
00273 { Q931_N12, "Disconnect indication" },
00274 { Q931_N15, "Suspend request" },
00275 { Q931_N17, "Resume request" },
00276 { Q931_N19, "Release request" },
00277 { Q931_N22, "N22" },
00278 { Q931_N25, "Overlap receiving" },
00279
00280 { 0, NULL }
00281 };
00282
00283 const char *Q931CallGetStateName(const struct Q931_Call *call)
00284 {
00285 struct Q931CallStateName *ptr = Q931CallStateNames;
00286 L3INT state;
00287
00288 assert(call);
00289
00290 state = Q931CallGetState(call);
00291
00292 while (ptr->name) {
00293 if (ptr->id == state) {
00294 return ptr->name;
00295 }
00296 ptr++;
00297 }
00298 return "Unknown/Invalid";
00299 }
00300
00301 struct Q931CallEventName
00302 {
00303 L3INT id;
00304 const L3CHAR *name;
00305
00306 } Q931CallEventNames[] = {
00307 { Q931_EVENT_SETUP_INDICATION, "Setup indication" },
00308 { Q931_EVENT_SETUP_CONFIRM, "Setup confirm" },
00309 { Q931_EVENT_SETUP_COMPLETE_INDICATION, "Setup complete indication" },
00310 { Q931_EVENT_MORE_INFO_INDICATION, "More information indication" },
00311 { Q931_EVENT_REJECT_INDICATION, "Reject indication" },
00312 { Q931_EVENT_PROCEEDING_INDICATION, "Proceeding indication" },
00313 { Q931_EVENT_ALERTING_INDICATION, "Alerting indication" },
00314 { Q931_EVENT_PROGRESS_INDICATION, "Progress indication" },
00315 { Q931_EVENT_NOTIFY_INDICATION, "Notify indication" },
00316 { Q931_EVENT_RELEASE_INDICATION, "Release indication" },
00317 { Q931_EVENT_SUSPEND_CONFIRM, "Suspend confirm" },
00318 { Q931_EVENT_RESUME_CONFIRM, "Resume confirm" },
00319 { Q931_EVENT_DISCONNECT_INDICATION, "Disconnect indication" },
00320 { Q931_EVENT_INFORMATION_INDICATION, "Information indication" },
00321 { Q931_EVENT_STATUS_INDICATION, "Status indication" },
00322 { Q931_EVENT_RESTART_CONFIRM, "Restart confirm" },
00323
00324
00325 { Q931_EVENT_SETUP_RESPONSE, "Setup response" },
00326 { Q931_EVENT_REJECT_REQUEST, "Reject request" },
00327 { Q931_EVENT_INFORMATION_REQUEST, "Information request" },
00328 { Q931_EVENT_ALERTING_REQUEST, "Alerting request" },
00329 { Q931_EVENT_PROGRESS_REQUEST, "Progress request" },
00330 { Q931_EVENT_PROCEEDING_REQUEST, "Proceeding request" },
00331 { Q931_EVENT_NOTIFY_REQUEST, "Notify request" },
00332 { Q931_EVENT_SUSPEND_REQUEST, "Suspend request" },
00333 { Q931_EVENT_DISCONNECT_REQUEST, "Disconnect request" },
00334 { Q931_EVENT_RESTART_REQUEST, "Restart request" },
00335
00336
00337 { Q931_EVENT_TIMEOUT_INDICATION, "Timeout indication" },
00338 { Q931_EVENT_DL_FAILURE_INDICATION, "Datalink Layer failure indication" },
00339
00340 { 0, NULL },
00341 };
00342
00343 const char *Q931CallGetEventName(const L3INT event)
00344 {
00345 struct Q931CallEventName *ptr = Q931CallEventNames;
00346
00347 while (ptr->name) {
00348 if (ptr->id == event) {
00349 return ptr->name;
00350 }
00351 ptr++;
00352 }
00353 return "Unknown";
00354 }
00355
00356 struct Q931CallTimerName
00357 {
00358 L3INT id;
00359 const L3CHAR *name;
00360
00361 } Q931CallTimerNames[] = {
00362 { Q931_TIMER_T300, "T300" },
00363 { Q931_TIMER_T301, "T301" },
00364 { Q931_TIMER_T302, "T302" },
00365 { Q931_TIMER_T303, "T303" },
00366 { Q931_TIMER_T304, "T304" },
00367 { Q931_TIMER_T305, "T305" },
00368 { Q931_TIMER_T306, "T306" },
00369 { Q931_TIMER_T307, "T307" },
00370 { Q931_TIMER_T308, "T308" },
00371 { Q931_TIMER_T309, "T309" },
00372 { Q931_TIMER_T310, "T310" },
00373 { Q931_TIMER_T311, "T311" },
00374 { Q931_TIMER_T312, "T312" },
00375 { Q931_TIMER_T313, "T313" },
00376 { Q931_TIMER_T314, "T314" },
00377 { Q931_TIMER_T315, "T315" },
00378 { Q931_TIMER_T316, "T316" },
00379 { Q931_TIMER_T317, "T317" },
00380 { Q931_TIMER_T318, "T318" },
00381 { Q931_TIMER_T319, "T319" },
00382 { Q931_TIMER_T320, "T320" },
00383 { Q931_TIMER_T321, "T321" },
00384 { Q931_TIMER_T322, "T322" },
00385
00386 { 0, NULL }
00387 };
00388
00389 const char *Q931CallGetTimerName(const L3USHORT timer)
00390 {
00391 struct Q931CallTimerName *ptr = Q931CallTimerNames;
00392
00393 while (ptr->name) {
00394 if (ptr->id == timer) {
00395 return ptr->name;
00396 }
00397 ptr++;
00398 }
00399 return "Unknown";
00400 }
00401
00402
00403
00404 struct Q931_Call *Q931GetCallByCRV(const Q931_TrunkInfo_t *trunk, const L3INT crv)
00405 {
00406 struct Q931_Call *call = NULL;
00407 int i = 0;
00408
00409 assert(trunk);
00410
00411 if (!crv) {
00412
00413 return (struct Q931_Call *)&trunk->call[0];
00414 }
00415
00416
00417 for (i = 1; i < Q931MAXCALLPERTRUNK; i++) {
00418 call = (struct Q931_Call *)&trunk->call[i];
00419
00420 if (call->InUse && call->CRV == crv) {
00421 return call;
00422 }
00423 }
00424 return NULL;
00425 }
00426
00427 struct Q931_Call *Q931GetCallByIndex(const Q931_TrunkInfo_t *trunk, const L3INT idx)
00428 {
00429 struct Q931_Call *call = NULL;
00430
00431 assert(trunk);
00432
00433 call = (struct Q931_Call *)&trunk->call[idx];
00434 if (call->InUse) {
00435 return call;
00436 }
00437
00438 return NULL;
00439 }
00440
00441 struct Q931_Call *Q931GetGlobalCall(const Q931_TrunkInfo_t *trunk)
00442 {
00443 return (struct Q931_Call *)&trunk->call[0];
00444 }
00445
00446 L3BOOL Q931CallIsGlobal(const struct Q931_Call *call)
00447 {
00448 return (call->CRV == 0);
00449 }
00450
00457 void Q931CallDump(const struct Q931_Call *call)
00458 {
00459 assert(call);
00460 assert(call->InUse);
00461
00462
00463 Q931Log(Q931CallGetTrunk(call), Q931_LOG_DEBUG,
00464 "Call %#x, direction: %s, state: %d (\"%s\")\n\tTimer active: %s",
00465 call->CRV,
00466 (call->Direction) ? "Outbound" : "Inbound",
00467 Q931CallGetState(call),
00468 Q931CallGetStateName(call),
00469 (call->TimerID) ? Q931CallGetTimerName(call->TimerID) : "None");
00470 }
00471
00472
00479 void Q931CallStartTimer(struct Q931_Call *call, L3USHORT timer)
00480 {
00481 Q931_TrunkInfo_t *trunk = NULL;
00482 L3ULONG duration;
00483
00484 assert(call);
00485
00486 trunk = Q931CallGetTrunk(call);
00487 assert(trunk);
00488
00489 duration = Q931DialectGetTimeout(trunk->Dialect, timer);
00490
00491 if (duration) {
00492 call->Timer = Q931GetTime() + duration;
00493 call->TimerID = timer;
00494 call->TimerCnt = 0;
00495
00496 Q931Log(Q931CallGetTrunk(call), Q931_LOG_NOTICE, "Starting timer %d (timeout: %d ms) for call %d [0x%x]\n", timer, duration, Q931CallGetCRV(call), Q931CallGetCRV(call));
00497 }
00498 }
00499
00507 void Q931CallRestartTimer(struct Q931_Call *call, L3USHORT timer)
00508 {
00509 Q931_TrunkInfo_t *trunk = NULL;
00510 L3ULONG duration;
00511
00512 assert(call);
00513
00514 trunk = Q931CallGetTrunk(call);
00515 assert(trunk);
00516
00517 duration = Q931DialectGetTimeout(trunk->Dialect, timer);
00518
00519 if (duration) {
00520 call->Timer = Q931GetTime() + duration;
00521 call->TimerID = timer;
00522
00523 Q931Log(Q931CallGetTrunk(call), Q931_LOG_NOTICE, "Restarting timer %d (timeout: %d ms) for call %d [0x%x]\n", timer, duration, Q931CallGetCRV(call), Q931CallGetCRV(call));
00524 }
00525 }
00526
00533 void Q931CallStopTimer(struct Q931_Call *call, L3USHORT timer)
00534 {
00535 assert(call);
00536
00537 if (call->TimerID == timer) {
00538 call->TimerID = Q931_TIMER_NONE;
00539
00540 Q931Log(Q931CallGetTrunk(call), Q931_LOG_NOTICE, "Stopping timer %d for call %d [0x%x]\n", timer, Q931CallGetCRV(call), Q931CallGetCRV(call));
00541 }
00542 }
00543
00549 void Q931CallStopAllTimers(struct Q931_Call *call)
00550 {
00551 assert(call);
00552
00553 call->TimerID = Q931_TIMER_NONE;
00554
00555 Q931Log(Q931CallGetTrunk(call), Q931_LOG_NOTICE, "Stopped all timers for call %d [0x%x]\n", Q931CallGetCRV(call), Q931CallGetCRV(call));
00556 }
00557
00564 L3USHORT Q931CallGetTimerID(const struct Q931_Call *call)
00565 {
00566 return call->TimerID;
00567 }
00568
00577 L3UCHAR Q931CallGetTimerExpireCount(const struct Q931_Call *call)
00578 {
00579 return call->TimerCnt;
00580 }
00581
00582
00589 void Q931CallIncrementTimerExpireCount(struct Q931_Call *call)
00590 {
00591 call->TimerCnt++;
00592 }
00593
00594
00595
00596
00597
00604 void Q931SetCallEventCB(Q931_TrunkInfo_t *trunk, const Q931CallEventCB_t cb, const void *priv)
00605 {
00606 assert(trunk);
00607 assert(cb);
00608
00609 trunk->CallEventCBProc = (Q931CallEventCB_t)cb;
00610 trunk->PrivateDataCallEventCB = (void *)priv;
00611 }
00612
00618 void Q931CallSendEvent(const struct Q931_Call *call, const struct Q931_CallEvent *event)
00619 {
00620 Q931_TrunkInfo_t *trunk = Q931CallGetTrunk(call);
00621
00622 assert(trunk);
00623 assert(event);
00624
00625 if (!event || event->id == Q931_EVENT_NONE || event->type == Q931_EVENT_TYPE_NONE)
00626 return;
00627
00628 if (trunk->CallEventCBProc) {
00629 Q931Log(trunk, Q931_LOG_DEBUG, "Sending call event to Layer4 [call: %d, id: %d, type: %d]\n", Q931CallGetCRV(call), event->id, event->type);
00630
00631 trunk->CallEventCBProc((struct Q931_Call *)call, (struct Q931_CallEvent *)event, trunk->PrivateDataCallEventCB);
00632 }
00633 }
00634
00638 void Q931CallInitEvent(struct Q931_CallEvent *event)
00639 {
00640 memset(event, 0, sizeof(struct Q931_CallEvent));
00641 }
00642
00643
00644
00645
00646
00650 struct Q931_CallEvent *Q931CallNewEvent(struct Q931_Call *call)
00651 {
00652 assert(call);
00653
00654 if (call->numevents == Q931_CALL_MAX_EVENTS)
00655 return NULL;
00656
00657 return &call->events[call->numevents];
00658 }
00659
00664 void Q931CallQueueEvent(struct Q931_Call *call, struct Q931_CallEvent *event)
00665 {
00666 assert(call);
00667
00668 call->numevents++;
00669 }
00670
00674 void Q931CallFlushEvents(struct Q931_Call *call)
00675 {
00676 assert(call);
00677
00678 memset(call->events, 0, Q931_CALL_MAX_EVENTS * sizeof(struct Q931_CallEvent));
00679 call->numevents = 0;
00680 }
00681
00685 void Q931CallSendQueuedEvents(struct Q931_Call *call)
00686 {
00687 int i;
00688
00689 assert(call);
00690
00691 for (i = 0; i < call->numevents; i++) {
00692 Q931CallSendEvent(call, &call->events[i]);
00693 }
00694
00695 Q931CallFlushEvents(call);
00696 }
00697
00701 L3INT Q931CallEventGetType(const struct Q931_CallEvent *event)
00702 {
00703 return event->type;
00704 }
00705
00709 L3INT Q931CallEventGetId(const struct Q931_CallEvent *event)
00710 {
00711 return event->id;
00712 }
00713
00718 void *Q931CallEventGetData(const struct Q931_CallEvent *event)
00719 {
00720 switch (event->type) {
00721 case Q931_EVENT_TYPE_TIMER:
00722 return (void *)&event->timer;
00723
00724 case Q931_EVENT_TYPE_MESSAGE:
00725 return (void *)&event->message;
00726
00727 default:
00728 return NULL;
00729 }
00730 }