aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmsc/smpp_openbsc.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2017-08-11 12:02:12 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2017-08-27 02:33:49 +0200
commit9a3ed85bcb9b04523ccc63860cba8db3f59e1ca7 (patch)
tree573b8ebad0d36c73f964b1fd9baeabfd3635375e /src/libmsc/smpp_openbsc.c
parentf113bcd67176ebfa4127eabbbc73ee5f9d161b6e (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/libmsc/smpp_openbsc.c')
-rw-r--r--src/libmsc/smpp_openbsc.c70
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;
}