diff options
author | Pablo Neira Ayuso <pablo@gnumonks.org> | 2017-08-11 12:02:12 +0200 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2017-08-27 02:33:49 +0200 |
commit | 9a3ed85bcb9b04523ccc63860cba8db3f59e1ca7 (patch) | |
tree | 573b8ebad0d36c73f964b1fd9baeabfd3635375e /src | |
parent | f113bcd67176ebfa4127eabbbc73ee5f9d161b6e (diff) |
libmsc: use smpp34_tlv_for_each() to avoid suboptimal TLV handling
submit_to_sms() now handles two TLVs, so find_tlv() is suboptiomal and
it can be removed, since it would result in two passes on the TLV list.
Use new smpp34_tlv_for_each() helper to iterate over the list of TLVs
that is available since I446929feed049d0411e1629ca263e2bc41f714cc.
Change-Id: I53a65164a6cc4abc6bf57d9a8dc275cf21c90222
Diffstat (limited to 'src')
-rw-r--r-- | src/libmsc/smpp_openbsc.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/src/libmsc/smpp_openbsc.c b/src/libmsc/smpp_openbsc.c index 09012d013..1ffb0cd87 100644 --- a/src/libmsc/smpp_openbsc.c +++ b/src/libmsc/smpp_openbsc.c @@ -73,26 +73,31 @@ static struct vlr_subscr *subscr_by_dst(struct gsm_network *net, return vsub; } -/*! \brief find a TLV with given tag in list of libsmpp34 TLVs */ -static struct tlv_t *find_tlv(struct tlv_t *head, uint16_t tag) +static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t, + const struct submit_sm_t *submit, + const uint8_t **sms_msg, + unsigned int *sms_msg_len) { - struct tlv_t *t; - - for (t = head; t != NULL; t = t->next) { - if (t->tag == tag) - return t; + if (submit->sm_length) { + LOGP(DLSMS, LOGL_ERROR, + "SMPP cannot have payload in TLV _and_ in the header\n"); + return -1; } - return NULL; + *sms_msg = t->value.octet; + *sms_msg_len = t->length; + + return 0; } /*! \brief convert from submit_sm_t to gsm_sms */ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, const struct submit_sm_t *submit) { + const uint8_t *sms_msg = NULL; struct vlr_subscr *dest; + uint16_t msg_ref = 0; struct gsm_sms *sms; struct tlv_t *t; - const uint8_t *sms_msg; unsigned int sms_msg_len; int mode; @@ -106,31 +111,40 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, return ESME_RINVDSTADR; } - t = find_tlv(submit->tlv, TLVID_message_payload); - if (t) { - if (submit->sm_length) { - /* ERROR: we cannot have both! */ - LOGP(DLSMS, LOGL_ERROR, "SMPP Cannot have payload in " - "TLV _and_ in the header\n"); + smpp34_tlv_for_each(t, submit->tlv) { + switch (t->tag) { + case TLVID_message_payload: + if (smpp34_submit_tlv_msg_payload(t, submit, &sms_msg, + &sms_msg_len) < 0) { + vlr_subscr_put(dest); + return ESME_ROPTPARNOTALLWD; + } + break; + case TLVID_user_message_reference: + msg_ref = ntohs(t->value.val16); + break; + default: + break; + } + } + + if (!sms_msg) { + if (submit->sm_length > 0 && submit->sm_length < 255) { + sms_msg = submit->short_message; + sms_msg_len = submit->sm_length; + } else { + LOGP(DLSMS, LOGL_ERROR, + "SMPP neither message payload nor valid sm_length.\n"); vlr_subscr_put(dest); - return ESME_ROPTPARNOTALLWD; + return ESME_RINVPARLEN; } - sms_msg = t->value.octet; - sms_msg_len = t->length; - } else if (submit->sm_length > 0 && submit->sm_length < 255) { - sms_msg = submit->short_message; - sms_msg_len = submit->sm_length; - } else { - LOGP(DLSMS, LOGL_ERROR, - "SMPP neither message payload nor valid sm_length.\n"); - vlr_subscr_put(dest); - return ESME_RINVPARLEN; } sms = sms_alloc(); sms->source = SMS_SOURCE_SMPP; sms->smpp.sequence_nr = submit->sequence_number; sms->status_rep_req = submit->registered_delivery; + sms->msg_ref = msg_ref; /* fill in the destination address */ sms->receiver = dest; @@ -205,10 +219,6 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, sms->user_data_len = sms_msg_len; } - t = find_tlv(submit->tlv, TLVID_user_message_reference); - if (t) - sms->msg_ref = ntohs(t->value.val16); - *psms = sms; return ESME_ROK; } |