diff options
Diffstat (limited to 'src/host/layer23/src/mobile/gsm48_cc.c')
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_cc.c | 99 |
1 files changed, 72 insertions, 27 deletions
diff --git a/src/host/layer23/src/mobile/gsm48_cc.c b/src/host/layer23/src/mobile/gsm48_cc.c index 4e267137..c3ec94b3 100644 --- a/src/host/layer23/src/mobile/gsm48_cc.c +++ b/src/host/layer23/src/mobile/gsm48_cc.c @@ -623,10 +623,14 @@ static int gsm48_cc_rx_progress(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received PROGRESS\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, + GSM48_IE_PROGR_IND, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + memset(&progress, 0, sizeof(struct gsm_mncc)); progress.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, - GSM48_IE_PROGR_IND, 0); /* progress */ if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) { progress.fields |= MNCC_F_PROGRESS; @@ -654,13 +658,17 @@ static int gsm48_cc_rx_call_proceeding(struct gsm_trans *trans, struct tlv_parsed tp; struct gsm_mncc call_proc; - LOGP(DCC, LOGL_INFO, "sending CALL PROCEEDING\n"); + LOGP(DCC, LOGL_INFO, "received CALL PROCEEDING\n"); + + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } gsm48_stop_cc_timer(trans); memset(&call_proc, 0, sizeof(struct gsm_mncc)); call_proc.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); #if 0 /* repeat */ if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR)) @@ -712,12 +720,16 @@ static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received ALERTING\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); /* no T301 in MS call control */ memset(&alerting, 0, sizeof(struct gsm_mncc)); alerting.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* facility */ if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { alerting.fields |= MNCC_F_FACILITY; @@ -753,11 +765,15 @@ static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received CONNECT\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); memset(&connect, 0, sizeof(struct gsm_mncc)); connect.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* facility */ if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) { connect.fields |= MNCC_F_FACILITY; @@ -823,10 +839,13 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received SETUP\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + memset(&setup, 0, sizeof(struct gsm_mncc)); setup.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); - /* bearer capability */ if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { setup.fields |= MNCC_F_BEARER_CAP; @@ -1076,9 +1095,13 @@ static int gsm48_cc_rx_start_dtmf_ack(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received START DTMF ACKNOWLEDGE\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + memset(&dtmf, 0, sizeof(struct gsm_mncc)); dtmf.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* keypad facility */ if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) { dtmf.fields |= MNCC_F_KEYPAD; @@ -1139,9 +1162,13 @@ static int gsm48_cc_rx_stop_dtmf_ack(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received STOP DTMF ACKNOWLEDGE\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + memset(&dtmf, 0, sizeof(struct gsm_mncc)); dtmf.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); return mncc_recvmsg(trans->ms, trans, MNCC_STOP_DTMF_RSP, &dtmf); } @@ -1335,15 +1362,18 @@ static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received USERINFO\n"); - memset(&user, 0, sizeof(struct gsm_mncc)); - user.callref = trans->callref; if (payload_len < 1) { - LOGP(DCC, LOGL_NOTICE, "Short read of userinfo message " - "error.\n"); + LOGP(DCC, LOGL_NOTICE, "Short read of USERINFO message\n"); return -EINVAL; } - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, - GSM48_IE_USER_USER, 0); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, + GSM48_IE_USER_USER, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + + memset(&user, 0, sizeof(struct gsm_mncc)); + user.callref = trans->callref; /* user-user */ gsm48_decode_useruser(&user.useruser, TLVP_VAL(&tp, GSM48_IE_USER_USER)-1); @@ -1417,17 +1447,20 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received MODIFY REJECT\n"); + if (payload_len < 1) { + LOGP(DCC, LOGL_NOTICE, "Short read of MODIFY REJECT message\n"); + return -EINVAL; + } + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, + GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); memset(&modify, 0, sizeof(struct gsm_mncc)); modify.callref = trans->callref; - if (payload_len < 1) { - LOGP(DCC, LOGL_NOTICE, "Short read of modify reject message " - "error.\n"); - return -EINVAL; - } - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, - GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE); /* bearer capability */ if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) { modify.fields |= MNCC_F_BEARER_CAP; @@ -1675,14 +1708,18 @@ static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received DISCONNECT\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, + GSM48_IE_CAUSE, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND); memset(&disc, 0, sizeof(struct gsm_mncc)); disc.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, - GSM48_IE_CAUSE, 0); /* cause */ if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { disc.fields |= MNCC_F_CAUSE; @@ -1724,11 +1761,15 @@ static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received RELEASE\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); memset(&rel, 0, sizeof(struct gsm_mncc)); rel.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* cause */ if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { rel.fields |= MNCC_F_CAUSE; @@ -1793,11 +1834,15 @@ static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg) LOGP(DCC, LOGL_INFO, "received RELEASE COMPLETE\n"); + if (tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0) < 0) { + LOGP(DCC, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -EINVAL; + } + gsm48_stop_cc_timer(trans); memset(&rel, 0, sizeof(struct gsm_mncc)); rel.callref = trans->callref; - tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0); /* cause */ if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) { rel.fields |= MNCC_F_CAUSE; |