diff options
-rw-r--r-- | include/cc.h | 3 | ||||
-rw-r--r-- | src/cc.c | 42 |
2 files changed, 41 insertions, 4 deletions
diff --git a/include/cc.h b/include/cc.h index 718c6f2..1dba655 100644 --- a/include/cc.h +++ b/include/cc.h @@ -326,6 +326,7 @@ enum dect_cc_states { * @overlap_sending_timer: overlap sending timer (<CC.01>) * @release_timer: call release timer (<CC.02>) * @setup_timer: call setup timer (<CC.03>) + * @completion_timer: call setup completion timer (<CC.04>) * @lu_sap: U-Plane file descriptor * @qstats_timer: LU1 queue statistics debugging timer * @priv: libdect user private storage @@ -338,6 +339,7 @@ struct dect_call { struct dect_timer *overlap_sending_timer; struct dect_timer *release_timer; struct dect_timer *setup_timer; + struct dect_timer *completion_timer; struct dect_fd *lu_sap; #ifdef DEBUG struct dect_timer *qstats_timer; @@ -348,6 +350,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_COMPLETION_TIMEOUT 100 /* <CC.04>: 100 seconds */ #define DECT_CC_QUEUE_STATS_TIMER 1 /* 1 second */ extern const struct dect_nwk_protocol dect_cc_protocol; @@ -506,6 +506,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); +static void dect_cc_completion_timer(struct dect_handle *dh, struct dect_timer *timer); /* All CC timers should be stopped upon starting the release timer, receiving * or sending a {RELEASE-COM} message or a data link failure indication from @@ -518,6 +519,8 @@ static void dect_cc_stop_timers(const struct dect_handle *dh, dect_timer_stop(dh, call->overlap_sending_timer); if (dect_timer_running(call->setup_timer)) dect_timer_stop(dh, call->setup_timer); + if (dect_timer_running(call->completion_timer)) + dect_timer_stop(dh, call->completion_timer); } struct dect_call *dect_call_alloc(const struct dect_handle *dh) @@ -543,9 +546,16 @@ struct dect_call *dect_call_alloc(const struct dect_handle *dh) goto err4; dect_timer_setup(call->setup_timer, dect_cc_setup_timer, call); + call->completion_timer = dect_timer_alloc(dh); + if (call->completion_timer == NULL) + goto err5; + dect_timer_setup(call->completion_timer, dect_cc_completion_timer, call); + call->state = DECT_CC_NULL; return call; +err5: + dect_timer_free(dh, call->setup_timer); err4: dect_timer_free(dh, call->release_timer); err3: @@ -567,6 +577,7 @@ static void dect_call_destroy(const struct dect_handle *dh, dect_timer_free(dh, call->overlap_sending_timer); dect_timer_free(dh, call->release_timer); dect_timer_free(dh, call->setup_timer); + dect_timer_free(dh, call->completion_timer); dect_free(dh, call); } @@ -659,6 +670,14 @@ static void dect_cc_setup_timer(struct dect_handle *dh, struct dect_timer *timer dect_call_destroy(dh, call); } +static void dect_cc_completion_timer(struct dect_handle *dh, struct dect_timer *timer) +{ + struct dect_call *call = timer->data; + + cc_debug(call, "<CC.04>: completion timer"); + dect_cc_timer_release(dh, call); +} + /** * MNCC_SETUP-req primitive * @@ -846,6 +865,7 @@ int dect_mncc_call_proc_req(struct dect_handle *dh, struct dect_call *call, .escape_to_proprietary = param->escape_to_proprietary, .codec_list = param->codec_list, }; + int err; cc_debug_entry(call, "MNCC_CALL_PROC-req"); @@ -854,8 +874,13 @@ int dect_mncc_call_proc_req(struct dect_handle *dh, struct dect_call *call, dect_timer_stop(dh, call->overlap_sending_timer); call->state = DECT_CC_CALL_PROCEEDING; - return dect_cc_send_msg(dh, call, &cc_call_proc_msg_desc, - &msg.common, DECT_CC_CALL_PROC); + err = dect_cc_send_msg(dh, call, &cc_call_proc_msg_desc, + &msg.common, DECT_CC_CALL_PROC); + if (err < 0) + return err; + + dect_timer_start(dh, call->completion_timer, DECT_CC_COMPLETION_TIMEOUT); + return 0; } EXPORT_SYMBOL(dect_mncc_call_proc_req); @@ -901,6 +926,7 @@ int dect_mncc_alert_req(struct dect_handle *dh, struct dect_call *call, } else call->state = DECT_CC_CALL_RECEIVED; + dect_timer_start(dh, call->completion_timer, DECT_CC_COMPLETION_TIMEOUT); return 0; } EXPORT_SYMBOL(dect_mncc_alert_req); @@ -945,9 +971,11 @@ int dect_mncc_connect_req(struct dect_handle *dh, struct dect_call *call, &msg.common, DECT_CC_CONNECT) < 0) goto err1; - if (dh->mode == DECT_MODE_FP) + if (dh->mode == DECT_MODE_FP) { + if (dect_timer_running(call->completion_timer)) + dect_timer_stop(dh, call->completion_timer); call->state = DECT_CC_ACTIVE; - else + } else call->state = DECT_CC_CONNECT_PENDING; return 0; @@ -1276,6 +1304,10 @@ static void dect_cc_rcv_alerting(struct dect_handle *dh, struct dect_call *call, if (dect_timer_running(call->setup_timer)) dect_timer_stop(dh, call->setup_timer); + if (dh->mode == DECT_MODE_FP) + dect_timer_start(dh, call->completion_timer, + DECT_CC_COMPLETION_TIMEOUT); + dect_mncc_alert_ind(dh, call, &msg); dect_msg_free(dh, &cc_alerting_msg_desc, &msg.common); @@ -1322,6 +1354,7 @@ static void dect_cc_rcv_call_proc(struct dect_handle *dh, struct dect_call *call if (dect_timer_running(call->setup_timer)) dect_timer_stop(dh, call->setup_timer); + dect_timer_start(dh, call->completion_timer, DECT_CC_COMPLETION_TIMEOUT); dect_mncc_call_proc_ind(dh, call, &msg); call->state = DECT_CC_CALL_PROCEEDING; @@ -1371,6 +1404,7 @@ static void dect_cc_rcv_connect(struct dect_handle *dh, struct dect_call *call, if (dect_timer_running(call->setup_timer)) dect_timer_stop(dh, call->setup_timer); + dect_timer_stop(dh, call->completion_timer); if (dh->mode == DECT_MODE_PP) call->state = DECT_CC_ACTIVE; |