diff options
author | Patrick McHardy <kaber@trash.net> | 2010-09-14 23:04:58 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-09-17 17:42:26 +0200 |
commit | cb378b33339538f381b1d99e139db384c602ef65 (patch) | |
tree | 87fe866623ffb07055b90987372337d81cee6355 | |
parent | 03ee13dcb4d6ee436b8bf8374465b36151dcee16 (diff) |
cc: add release timer
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/cc.h | 3 | ||||
-rw-r--r-- | src/cc.c | 41 |
2 files changed, 41 insertions, 3 deletions
diff --git a/include/cc.h b/include/cc.h index a808691..718c6f2 100644 --- a/include/cc.h +++ b/include/cc.h @@ -324,6 +324,7 @@ enum dect_cc_states { * @pt_id: PT ID * @state: call state * @overlap_sending_timer: overlap sending timer (<CC.01>) + * @release_timer: call release timer (<CC.02>) * @setup_timer: call setup timer (<CC.03>) * @lu_sap: U-Plane file descriptor * @qstats_timer: LU1 queue statistics debugging timer @@ -335,6 +336,7 @@ struct dect_call { struct dect_ie_portable_identity *pt_id; enum dect_cc_states state; struct dect_timer *overlap_sending_timer; + struct dect_timer *release_timer; struct dect_timer *setup_timer; struct dect_fd *lu_sap; #ifdef DEBUG @@ -344,6 +346,7 @@ struct dect_call { }; #define DECT_CC_OVERLAP_SENDING_TIMEOUT 20 /* <CC.01>: 20 seconds */ +#define DECT_CC_RELEASE_TIMEOUT 36 /* <CC.02>: 36 seconds */ #define DECT_CC_SETUP_TIMEOUT 20 /* <CC.03>: 20 seconds */ #define DECT_CC_QUEUE_STATS_TIMER 1 /* 1 second */ @@ -504,6 +504,7 @@ static void dect_call_disconnect_uplane(const struct dect_handle *dh, } static void dect_cc_overlap_sending_timer(struct dect_handle *dh, struct dect_timer *timer); +static void dect_cc_release_timer(struct dect_handle *dh, struct dect_timer *timer); static void dect_cc_setup_timer(struct dect_handle *dh, struct dect_timer *timer); /* All CC timers should be stopped upon starting the release timer, receiving @@ -532,14 +533,21 @@ struct dect_call *dect_call_alloc(const struct dect_handle *dh) goto err2; dect_timer_setup(call->overlap_sending_timer, dect_cc_overlap_sending_timer, call); + call->release_timer = dect_timer_alloc(dh); + if (call->release_timer == NULL) + goto err3; + dect_timer_setup(call->release_timer, dect_cc_release_timer, call); + call->setup_timer = dect_timer_alloc(dh); if (call->setup_timer == NULL) - goto err3; + goto err4; dect_timer_setup(call->setup_timer, dect_cc_setup_timer, call); call->state = DECT_CC_NULL; return call; +err4: + dect_timer_free(dh, call->release_timer); err3: dect_timer_free(dh, call->overlap_sending_timer); err2: @@ -553,7 +561,11 @@ static void dect_call_destroy(const struct dect_handle *dh, struct dect_call *call) { dect_cc_stop_timers(dh, call); + if (dect_timer_running(call->release_timer)) + dect_timer_stop(dh, call->release_timer); + dect_timer_free(dh, call->overlap_sending_timer); + dect_timer_free(dh, call->release_timer); dect_timer_free(dh, call->setup_timer); dect_free(dh, call); } @@ -603,6 +615,8 @@ static void dect_cc_send_release(struct dect_handle *dh, struct dect_call *call, static void dect_cc_timer_release(struct dect_handle *dh, struct dect_call *call) { dect_cc_send_release(dh, call, DECT_RELEASE_TIMER_EXPIRY); + dect_cc_stop_timers(dh, call); + dect_timer_start(dh, call->release_timer, DECT_CC_RELEASE_TIMEOUT); call->state = DECT_CC_RELEASE_PENDING; cc_debug(call, "MNCC_REJECT-ind: cause: DECT_CAUSE_LOCAL_TIMER_EXPIRY"); @@ -617,6 +631,19 @@ static void dect_cc_overlap_sending_timer(struct dect_handle *dh, struct dect_ti dect_cc_timer_release(dh, call); } +static void dect_cc_release_timer(struct dect_handle *dh, struct dect_timer *timer) +{ + struct dect_call *call = timer->data; + + cc_debug(call, "<CC.02>: release timer"); + dect_cc_send_release_com(dh, &call->transaction, DECT_RELEASE_TIMER_EXPIRY); + + cc_debug(call, "MNCC_RELEASE-cfm"); + dh->ops->cc_ops->mncc_release_cfm(dh, call, DECT_CAUSE_LOCAL_TIMER_EXPIRY, NULL); + + dect_call_shutdown(dh, call); +} + static void dect_cc_setup_timer(struct dect_handle *dh, struct dect_timer *timer) { struct dect_call *call = timer->data; @@ -986,8 +1013,12 @@ int dect_mncc_release_req(struct dect_handle *dh, struct dect_call *call, }; cc_debug_entry(call, "MNCC_RELEASE-req"); - dect_cc_send_msg(dh, call, &cc_release_msg_desc, - &msg.common, DECT_CC_RELEASE); + if (dect_cc_send_msg(dh, call, &cc_release_msg_desc, + &msg.common, DECT_CC_RELEASE) < 0) + return -1; + + dect_cc_stop_timers(dh, call); + dect_timer_start(dh, call->release_timer, DECT_CC_RELEASE_TIMEOUT); call->state = DECT_CC_RELEASE_PENDING; @@ -1475,6 +1506,8 @@ static void dect_cc_rcv_release(struct dect_handle *dh, struct dect_call *call, /* Release collision */ cc_debug(call, "MNCC_RELEASE-cfm"); dh->ops->cc_ops->mncc_release_cfm(dh, call, DECT_CAUSE_PEER_MESSAGE, param); + + dect_timer_stop(dh, call->release_timer); dect_call_shutdown(dh, call); } else { /* Normal call release */ @@ -1525,6 +1558,8 @@ static void dect_cc_rcv_release_com(struct dect_handle *dh, struct dect_call *ca if (call->state == DECT_CC_RELEASE_PENDING) { dect_mncc_release_cfm(dh, call, &msg); + + dect_timer_stop(dh, call->release_timer); dect_call_shutdown(dh, call); } else { struct dect_mncc_release_param *param; |