From c75ed6d593ddfa29fd86b19c842eadf5410d8181 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 May 2013 20:58:02 +0200 Subject: SMPP: Add new 'dcs_transparent' ESME setting If an ESME has the dcs_transparent config flag, then the TP-DCS of MO-SMS is transparently passed to SMPP and not converted to SMPP specific data_coding values. This is needed in cases where ESMEs actually care about the exact TP-DCS, as the conversion from TP-DCS to SMPP data_coding is not bijective. --- openbsc/src/libmsc/smpp_openbsc.c | 39 ++++++++++++++++++++++++++++++--------- openbsc/src/libmsc/smpp_smsc.h | 1 + openbsc/src/libmsc/smpp_vty.c | 27 +++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index fdef90eee..887f0ebee 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -172,7 +172,7 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, return ESME_RUNKNOWNERR; } - if (mode == MODE_7BIT) { + if (mode == MODE_7BIT) { uint8_t ud_len = 0, padbits = 0; sms->data_coding_scheme = GSM338_DCS_1111_7BIT; if (sms->ud_hdr_ind) { @@ -429,6 +429,7 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, { struct deliver_sm_t deliver; uint8_t dcs; + int mode; memset(&deliver, 0, sizeof(deliver)); deliver.command_length = 0; @@ -465,14 +466,38 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, deliver.priority_flag = 0; deliver.registered_delivery = 0; + /* Figure out SMPP DCS from TP-DCS */ dcs = sms->data_coding_scheme; - if (dcs == GSM338_DCS_1111_7BIT || - ((dcs & 0xE0000000) == 0 && (dcs & 0xC) == 0)) { + if ((dcs & 0xFC) == GSM338_DCS_1111_7BIT) { + deliver.data_coding = 0x01; + mode = MODE_7BIT; + } else if ((dcs & 0xE0) == 0 && (dcs & 0xC) == 0) { + deliver.data_coding = 0x01; + mode = MODE_7BIT; + } else if ((dcs & 0xFC) == GSM338_DCS_1111_8BIT_DATA) { + deliver.data_coding = 0x02; + mode = MODE_8BIT; + } else if ((dcs & 0xE0) == 0 && (dcs & 0xC) == 4) { + deliver.data_coding = 0x02; + mode = MODE_8BIT; + } else if ((dcs & 0xE0) == 0 && (dcs & 0xC) == 8) { + deliver.data_coding = 0x08; /* UCS-2 */ + mode = MODE_8BIT; + } else { + LOGP(DLSMS, LOGL_ERROR, "SMPP MO Unknown Data Coding 0x%02x\n", + dcs); + return -1; + } + + /* Transparently pass on DCS via SMPP if requested */ + if (esme->acl->dcs_transparent) + deliver.data_coding = dcs; + + if (mode == MODE_7BIT) { uint8_t *dst = deliver.short_message; /* SMPP has this strange notion of putting 7bit SMS in * an octet-aligned mode */ - deliver.data_coding = 0x01; if (sms->ud_hdr_ind) { /* length (bytes) of UDH inside UD */ uint8_t udh_len = sms->user_data[0] + 1; @@ -484,13 +509,9 @@ static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms, } /* add decoded text */ deliver.sm_length += gsm_7bit_expand((char *)dst, sms->user_data, sms->user_data_len, sms->ud_hdr_ind); - } else if (dcs == GSM338_DCS_1111_8BIT_DATA || - ((dcs & 0xE0000000) == 0 && (dcs & 0xC) == 4)) { - deliver.data_coding = 0x02; + } else { deliver.sm_length = sms->user_data_len; memcpy(deliver.short_message, sms->user_data, deliver.sm_length); - } else if ((dcs & 0xE0000000) == 0 && (dcs & 0xC) == 8) { - deliver.data_coding = 0x08; /* UCS-2 */ deliver.sm_length = sms->user_data_len; memcpy(deliver.short_message, sms->user_data, deliver.sm_length); } diff --git a/openbsc/src/libmsc/smpp_smsc.h b/openbsc/src/libmsc/smpp_smsc.h index e72f81fef..86fbeb5f0 100644 --- a/openbsc/src/libmsc/smpp_smsc.h +++ b/openbsc/src/libmsc/smpp_smsc.h @@ -61,6 +61,7 @@ struct osmo_smpp_acl { int default_route; int deliver_src_imsi; int osmocom_ext; + int dcs_transparent; struct llist_head route_list; }; diff --git a/openbsc/src/libmsc/smpp_vty.c b/openbsc/src/libmsc/smpp_vty.c index 4c64a3cf1..adea9590e 100644 --- a/openbsc/src/libmsc/smpp_vty.c +++ b/openbsc/src/libmsc/smpp_vty.c @@ -361,6 +361,29 @@ DEFUN(cfg_esme_no_osmo_ext, cfg_esme_no_osmo_ext_cmd, return CMD_SUCCESS; } +DEFUN(cfg_esme_dcs_transp, cfg_esme_dcs_transp_cmd, + "dcs-transparent", + "Enable the transparent pass-through of TP-DCS to SMPP DataCoding") +{ + struct osmo_smpp_acl *acl = vty->index; + + acl->dcs_transparent = 1; + + return CMD_SUCCESS; +} + +DEFUN(cfg_esme_no_dcs_transp, cfg_esme_no_dcs_transp_cmd, + "no dcs-transparent", NO_STR + "Disable the transparent pass-through of TP-DCS to SMPP DataCoding") +{ + struct osmo_smpp_acl *acl = vty->index; + + acl->dcs_transparent = 0; + + return CMD_SUCCESS; +} + + static void dump_one_esme(struct vty *vty, struct osmo_esme *esme) { char host[128], serv[128]; @@ -419,6 +442,8 @@ static void config_write_esme_single(struct vty *vty, struct osmo_smpp_acl *acl) vty_out(vty, " deliver-src-imsi%s", VTY_NEWLINE); if (acl->osmocom_ext) vty_out(vty, " osmocom-extensions%s", VTY_NEWLINE); + if (acl->dcs_transparent) + vty_out(vty, " dcs-transparent%s", VTY_NEWLINE); llist_for_each_entry(r, &acl->route_list, list) write_esme_route_single(vty, r); @@ -457,6 +482,8 @@ int smpp_vty_init(void) install_element(SMPP_ESME_NODE, &cfg_esme_no_defaultroute_cmd); install_element(SMPP_ESME_NODE, &cfg_esme_osmo_ext_cmd); install_element(SMPP_ESME_NODE, &cfg_esme_no_osmo_ext_cmd); + install_element(SMPP_ESME_NODE, &cfg_esme_dcs_transp_cmd); + install_element(SMPP_ESME_NODE, &cfg_esme_no_dcs_transp_cmd); install_element(SMPP_ESME_NODE, &ournode_exit_cmd); install_element_ve(&show_esme_cmd); -- cgit v1.2.3