[PATCH] Kannel SMPP v5.0 support
Stipe Tolj <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Organization | Kannel Software Foundation (KSF) |
| Message-ID | <[email protected]> |
Hi list,
please find attached a patchset that adds all the relevant new PDUs and
optional TLVs as defined in SMPP v5.0. The diff is against current SVN
trunk.
Some facts about the patch:
- We add the missing PDUs as defined in SMPP v5.0, even while we're
currently not handling them. (This is more or less the same case already
for the submit_multi PDU that is supported in SMPP v3.4)
- We add the missing optional TLVs that are now added to various known
PDUs. From those we currently use only 'billing_idenfitication' in the
submit_sm and data_sm PDU. The field carries according to the SMPP v5.0
spec an arbitrary billing information, so we're mapping this into/from
our msg->sms.binfo field.
- The patch is not intrusive, meaning it doesn't change any current
behavior.
- To allow a v5.0 connection to a SMSC, the 'interface-version = 50' can
be configured in the 'group = smsc' scope.
Please review, any comments are welcome.
Stipe
--
-------------------------------------------------------------------
Kölner Landstrasse 419
40589 DÃŒsseldorf, NRW, Germany
tolj.org system architecture Kannel Software Foundation (KSF)
http://www.tolj.org/ http://www.kannel.org/
mailto:st_{at}_tolj.org mailto:stolj_{at}_kannel.org
-------------------------------------------------------------------
gateway-smpp-v5.diff
(text/plain, 24.5 KB)
Index: gw/smsc/smpp_pdu.def =================================================================== --- gw/smsc/smpp_pdu.def (revision 4992) +++ gw/smsc/smpp_pdu.def (working copy) @@ -62,6 +62,8 @@ * Initial optional parameters implementation. * Alexander Malysh <[email protected]>: * Extended optional parameters implementation. + * Stipe Tolj <stolj at kannel.org>: + * Adding SMPP v5.0 PDUs */ @@ -118,6 +120,9 @@ INTEGER(command_status, 4) \ INTEGER(sequence_number, 4) +/* + * PDUs defined in SMPP v3.4 + */ PDU(bind_transmitter, 0x00000002, HEADER @@ -225,10 +230,11 @@ INTEGER(sm_length, 1) OCTETS(short_message, sm_length) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ TLV_INTEGER(user_message_reference, 2) TLV_INTEGER(source_port, 2) TLV_INTEGER(source_addr_subunit, 1) - TLV_INTEGER(destination_port, 2) + TLV_INTEGER(destination_port, 2) /* renamed to 'dest_port' in SMPP v5.0 ?? */ TLV_INTEGER(dest_addr_subunit, 1) TLV_INTEGER(sar_msg_ref_num, 2) TLV_INTEGER(sar_total_segments, 1) @@ -253,6 +259,23 @@ TLV_INTEGER(its_reply_type, 1) TLV_OCTETS(its_session_info, 2, 2) TLV_OCTETS(ussd_service_op, 1, 1) + /* added in SMPP v5.0 */ + TLV_OCTETS(billing_identification, 1, 1024) + TLV_INTEGER(dest_addr_np_country, 5) + TLV_OCTETS(dest_addr_np_information, 10, 10) + TLV_INTEGER(dest_addr_np_resolution, 1) + TLV_INTEGER(dest_bearer_type, 1) + TLV_NULTERMINATED(dest_network_id, 65) + TLV_INTEGER(dest_network_type, 1) + TLV_OCTETS(dest_node_id, 6, 6) + TLV_INTEGER(dest_telematics_id, 2) + TLV_INTEGER(qos_time_to_live, 4) + TLV_INTEGER(set_dpf, 1) + TLV_INTEGER(source_bearer_type, 1) + TLV_NULTERMINATED(source_network_id, 65) + TLV_INTEGER(source_network_type, 1) + TLV_OCTETS(source_node_id, 6, 6) + TLV_INTEGER(source_telematics_id, 1) OPTIONAL_END ) @@ -260,6 +283,13 @@ 0x80000004, HEADER NULTERMINATED(message_id, 65) + OPTIONAL_BEGIN + /* added in SMPP v5.0 */ + TLV_NULTERMINATED(additional_status_info_text, 256) + TLV_INTEGER(delivery_failure_reason, 1) + TLV_INTEGER(dpf_result, 1) + TLV_OCTETS(network_error_code, 3, 3) + OPTIONAL_END ) PDU(submit_multi, @@ -283,6 +313,7 @@ INTEGER(sm_length, 1) OCTETS(short_message, sm_length) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ TLV_INTEGER(user_message_reference, 2) TLV_INTEGER(source_port, 2) TLV_INTEGER(source_addr_subunit, 1) @@ -305,6 +336,28 @@ TLV_INTEGER(ms_msg_wait_facilities, 1) TLV_INTEGER(alert_on_message_delivery, 0) TLV_INTEGER(language_indicator, 1) + /* added in SMPP v5.0 */ + TLV_OCTETS(billing_identification, 1, 1024) + TLV_INTEGER(dest_addr_np_country, 5) + TLV_OCTETS(dest_addr_np_information, 10, 10) + TLV_INTEGER(dest_addr_np_resolution, 1) + TLV_INTEGER(dest_bearer_type, 1) + TLV_NULTERMINATED(dest_network_id, 65) + TLV_INTEGER(dest_network_type, 1) + TLV_OCTETS(dest_node_id, 6, 6) + TLV_INTEGER(dest_telematics_id, 2) + TLV_INTEGER(its_reply_type, 1) + TLV_OCTETS(its_session_info, 2, 2) + TLV_INTEGER(more_messages_to_send, 1) + TLV_INTEGER(number_of_messages, 1) + TLV_INTEGER(qos_time_to_live, 4) + TLV_INTEGER(set_dpf, 1) + TLV_INTEGER(source_bearer_type, 1) + TLV_NULTERMINATED(source_network_id, 65) + TLV_INTEGER(source_network_type, 1) + TLV_OCTETS(source_node_id, 6, 6) + TLV_INTEGER(source_telematics_id, 1) + TLV_INTEGER(user_response_code, 1) OPTIONAL_END ) @@ -313,6 +366,15 @@ HEADER NULTERMINATED(message_id, 65) INTEGER(no_unsuccess, 1) + //VAR_OCTETS(unsuccess_sme, 6, 27) + //OCTETS(unsuccess_sme, 27) + OPTIONAL_BEGIN + /* added in SMPP v5.0 */ + TLV_NULTERMINATED(additional_status_info_text, 256) + TLV_INTEGER(delivery_failure_reason, 1) + TLV_INTEGER(dpf_result, 1) + TLV_OCTETS(network_error_code, 3, 3) + OPTIONAL_END ) PDU(deliver_sm, @@ -337,9 +399,10 @@ INTEGER(sm_length, 1) OCTETS(short_message, sm_length) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ TLV_INTEGER(user_message_reference, 2) TLV_INTEGER(source_port, 2) - TLV_INTEGER(destination_port, 2) + TLV_INTEGER(destination_port, 2) /* renamed to 'dest_port' in SMPP v5.0 ?? */ TLV_INTEGER(sar_msg_ref_num, 2) TLV_INTEGER(sar_total_segments, 1) TLV_INTEGER(sar_segment_seqnum, 1) @@ -355,6 +418,20 @@ TLV_OCTETS(network_error_code, 3, 3) TLV_INTEGER(message_state, 1) TLV_NULTERMINATED(receipted_message_id, 65) + /* added in SMPP v5.0 */ + TLV_OCTETS(callback_num_atag, 0, 65) + TLV_INTEGER(callback_num_pres_ind, 1) + TLV_INTEGER(dest_addr_np_country, 5) + TLV_OCTETS(dest_addr_np_information, 10, 10) + TLV_INTEGER(dest_addr_np_resolution, 1) + TLV_INTEGER(dest_addr_subunit, 1) + TLV_NULTERMINATED(dest_network_id, 65) + TLV_INTEGER(dpf_result, 1) + TLV_INTEGER(its_reply_type, 1) + TLV_INTEGER(source_addr_subunit, 1) + TLV_NULTERMINATED(source_network_id, 65) + TLV_OCTETS(source_node_id, 6, 6) + TLV_OCTETS(ussd_service_op, 1, 1) OPTIONAL_END ) @@ -362,6 +439,12 @@ 0x80000005, HEADER NULTERMINATED(message_id, 1) + OPTIONAL_BEGIN + /* added in SMPP v5.0 */ + TLV_NULTERMINATED(additional_status_info_text, 256) + TLV_INTEGER(delivery_failure_reason, 1) + TLV_OCTETS(network_error_code, 3, 3) + OPTIONAL_END ) PDU(data_sm, @@ -378,6 +461,7 @@ INTEGER(registered_delivery, 1) INTEGER(data_coding, 1) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ TLV_INTEGER(source_port, 2) TLV_INTEGER(source_addr_subunit, 1) TLV_INTEGER(source_network_type, 1) @@ -416,6 +500,16 @@ TLV_INTEGER(language_indicator, 1) TLV_INTEGER(its_reply_type, 1) TLV_OCTETS(its_session_info, 2, 2) + /* added in SMPP v5.0 */ + TLV_OCTETS(billing_identification, 1, 1024) + TLV_INTEGER(dest_addr_np_country, 5) + TLV_OCTETS(dest_addr_np_information, 10, 10) + TLV_INTEGER(dest_addr_np_resolution, 1) + TLV_NULTERMINATED(dest_network_id, 65) + TLV_OCTETS(dest_node_id, 6, 6) + TLV_NULTERMINATED(source_network_id, 65) + TLV_OCTETS(source_node_id, 6, 6) + TLV_OCTETS(ussd_service_op, 1, 1) OPTIONAL_END ) @@ -424,10 +518,11 @@ HEADER NULTERMINATED(message_id, 65) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ + TLV_NULTERMINATED(additional_status_info_text, 256) TLV_INTEGER(delivery_failure_reason, 1) + TLV_INTEGER(dpf_result, 1) TLV_OCTETS(network_error_code, 3, 3) - TLV_NULTERMINATED(additional_status_info_text, 256) - TLV_INTEGER(dpf_result, 1) OPTIONAL_END ) @@ -481,6 +576,10 @@ INTEGER(sm_default_msg_id, 1) INTEGER(sm_length, 1) OCTETS(short_message, sm_length) + OPTIONAL_BEGIN + /* added in SMPP v5.0 */ + TLV_OCTETS(message_payload, 0, 65536) + OPTIONAL_END ) PDU(replace_sm_resp, @@ -508,10 +607,115 @@ INTEGER(esme_addr_npi, 1) NULTERMINATED(esme_addr, 65) OPTIONAL_BEGIN + /* defined in SMPP v3.4 */ TLV_INTEGER(ms_availability_status, 1) OPTIONAL_END ) +/* + * PDUs defined in SMPP v5.0 + */ +PDU(broadcast_sm, + 0x00000111, + HEADER + NULTERMINATED(service_type, 6) + INTEGER(source_addr_ton, 1) + INTEGER(source_addr_npi, 1) + NULTERMINATED(source_addr, 21) + NULTERMINATED(message_id, 65) + INTEGER(priority_flag, 1) + NULTERMINATED(schedule_delivery_time, 17) + NULTERMINATED(validity_period, 17) + INTEGER(registered_delivery, 1) + INTEGER(replace_if_present_flag, 1) + INTEGER(data_coding, 1) + INTEGER(sm_default_msg_id, 1) + OPTIONAL_BEGIN + TLV_OCTETS(broadcast_area_identifier, 1, 101) + TLV_OCTETS(broadcast_content_type, 3, 3) + TLV_OCTETS(broadcast_rep_num, 3, 3) + TLV_OCTETS(broadcast_frequency_interval, 3, 3) + //OPTIONAL_BEGIN + TLV_INTEGER(alert_on_message_delivery, 0) + TLV_INTEGER(broadcast_channel_indicator, 1) + TLV_OCTETS(broadcast_content_type_info, 1, 254) + TLV_INTEGER(broadcast_message_class, 1) + TLV_OCTETS(broadcast_service_group, 1, 254) + TLV_OCTETS(callback_num, 4, 19) + TLV_OCTETS(callback_num_atag, 0, 65) + TLV_INTEGER(callback_num_pres_ind, 1) + TLV_INTEGER(dest_addr_subunit, 1) + TLV_OCTETS(dest_subaddress, 2, 23) + TLV_INTEGER(destination_port, 2) /* called 'dest_port' in SMPP v5.0 spec?? */ + TLV_INTEGER(display_time, 1) + TLV_INTEGER(language_indicator, 1) + TLV_OCTETS(message_payload, 0, 65536) + TLV_INTEGER(ms_validity, 1) + TLV_INTEGER(payload_type, 1) + TLV_INTEGER(privacy_indicator, 1) + TLV_INTEGER(sms_signal, 2) + TLV_INTEGER(source_addr_subunit, 1) + TLV_INTEGER(source_port, 2) + TLV_OCTETS(source_subaddress, 2, 23) + TLV_INTEGER(user_message_reference, 2) + OPTIONAL_END +) + +PDU(broadcast_sm_resp, + 0x80000111, + HEADER + NULTERMINATED(message_id, 65) + OPTIONAL_BEGIN + TLV_INTEGER(broadcast_error_status, 4) + TLV_OCTETS(failed_broadcast_area_identifier, 1, 101) + OPTIONAL_END +) + +PDU(query_broadcast_sm, + 0x00000112, + HEADER + NULTERMINATED(message_id, 65) + INTEGER(source_addr_ton, 1) + INTEGER(source_addr_npi, 1) + NULTERMINATED(source_addr, 21) + OPTIONAL_BEGIN + TLV_INTEGER(user_message_reference, 2) + OPTIONAL_END +) + +PDU(query_broadcast_sm_resp, + 0x80000112, + HEADER + NULTERMINATED(message_id, 65) + OPTIONAL_BEGIN + TLV_INTEGER(message_state, 1) + TLV_OCTETS(broadcast_area_identifier, 1, 101) + TLV_INTEGER(broadcast_area_success, 1) + //OPTIONAL_BEGIN + TLV_NULTERMINATED(broadcast_end_time, 16) + TLV_INTEGER(user_message_reference, 2) + OPTIONAL_END +) + +PDU(cancel_broadcast_sm, + 0x00000113, + HEADER + NULTERMINATED(service_type, 6) + NULTERMINATED(message_id, 65) + INTEGER(source_addr_ton, 1) + INTEGER(source_addr_npi, 1) + NULTERMINATED(source_addr, 21) + OPTIONAL_BEGIN + TLV_OCTETS(broadcast_content_type, 3, 3) + TLV_INTEGER(user_message_reference, 2) + OPTIONAL_END +) + +PDU(cancel_broadcast_sm_resp, + 0x80000113, + HEADER +) + #undef PDU #undef INTEGER #undef NULTERMINATED Index: gw/smsc/smpp_pdu.h =================================================================== --- gw/smsc/smpp_pdu.h (revision 4992) +++ gw/smsc/smpp_pdu.h (working copy) @@ -106,7 +106,7 @@ /****************************************************************************** -* Numering Plan Indicator and Type of Number codes from +* Numbering Plan Indicator and Type of Number codes from * GSM 03.40 Version 5.3.0 Section 9.1.2.5. * http://www.etsi.org/ */ @@ -126,7 +126,9 @@ #define GSM_ADDR_NPI_NATIONAL 0x00000008 #define GSM_ADDR_NPI_PRIVATE 0x00000009 #define GSM_ADDR_NPI_ERMES 0x0000000A /* ETSI DE/PS 3 01-3 */ +#define GSM_ADDR_NPI_INTERNET 0x0000000E /* SMPP v5.0, sec. 4.7.2, page 113 */ #define GSM_ADDR_NPI_EXTENSION 0x0000000F /* Reserved */ +#define GSM_ADDR_NPI_WAP_CLIENT_ID 0x00000012 /* SMPP v5.0, sec. 4.7.2, page 113 */ /****************************************************************************** * esm_class parameters for both submit_sm and deliver_sm PDUs Index: gw/smsc/smpp_pdu_opt.def =================================================================== --- gw/smsc/smpp_pdu_opt.def (revision 4992) +++ gw/smsc/smpp_pdu_opt.def (working copy) @@ -55,56 +55,82 @@ */ /* - * Taken from SMPP Spec v3.4 + * The SMPP supported TLVs and their associated Tag Values. + * + * Reference: + * SMPP v5.0 Specification, section 4.8 'PDU TLV Definitions', page 135. */ #ifndef SMPP_PDU_OPT #define SMPP_PDU_OPT -#define SMPP_dest_addr_subunit 0x0005 -#define SMPP_dest_network_type 0x0006 -#define SMPP_dest_bearer_type 0x0007 -#define SMPP_dest_telematics_id 0x0008 -#define SMPP_source_addr_subunit 0x000D -#define SMPP_source_network_type 0x000E -#define SMPP_source_bearer_type 0x000F -#define SMPP_source_telematics_id 0x0010 -#define SMPP_qos_time_to_live 0x0017 -#define SMPP_payload_type 0x0019 -#define SMPP_additional_status_info_text 0x001D -#define SMPP_receipted_message_id 0x001E -#define SMPP_ms_msg_wait_facilities 0x0030 -#define SMPP_privacy_indicator 0x0201 -#define SMPP_source_subaddress 0x0202 -#define SMPP_dest_subaddress 0x0203 -#define SMPP_user_message_reference 0x0204 -#define SMPP_user_response_code 0x0205 -#define SMPP_source_port 0x020A -#define SMPP_destination_port 0x020B -#define SMPP_sar_msg_ref_num 0x020C -#define SMPP_language_indicator 0x020D -#define SMPP_sar_total_segments 0x020E -#define SMPP_sar_segment_seqnum 0x020F -#define SMPP_sc_interface_version 0x0210 -#define SMPP_callback_num_pres_ind 0x0302 -#define SMPP_callback_num_atag 0x0303 -#define SMPP_number_of_messages 0x0304 -#define SMPP_callback_num 0x0381 -#define SMPP_dpf_result 0x0420 -#define SMPP_set_dpf 0x0421 -#define SMPP_ms_availability_status 0x0422 -#define SMPP_network_error_code 0x0423 -#define SMPP_message_payload 0x0424 -#define SMPP_delivery_failure_reason 0x0425 -#define SMPP_more_messages_to_send 0x0426 -#define SMPP_message_state 0x0427 -#define SMPP_ussd_service_op 0x0501 -#define SMPP_display_time 0x1201 -#define SMPP_sms_signal 0x1203 -#define SMPP_ms_validity 0x1204 -#define SMPP_alert_on_message_delivery 0x130C -#define SMPP_its_reply_type 0x1380 -#define SMPP_its_session_info 0x1383 +/* defined in SMP v3.4 */ +#define SMPP_dest_addr_subunit 0x0005 +#define SMPP_dest_network_type 0x0006 +#define SMPP_dest_bearer_type 0x0007 +#define SMPP_dest_telematics_id 0x0008 +#define SMPP_source_addr_subunit 0x000D +#define SMPP_source_network_type 0x000E +#define SMPP_source_bearer_type 0x000F +#define SMPP_source_telematics_id 0x0010 +#define SMPP_qos_time_to_live 0x0017 +#define SMPP_payload_type 0x0019 +#define SMPP_additional_status_info_text 0x001D +#define SMPP_receipted_message_id 0x001E +#define SMPP_ms_msg_wait_facilities 0x0030 +#define SMPP_privacy_indicator 0x0201 +#define SMPP_source_subaddress 0x0202 +#define SMPP_dest_subaddress 0x0203 +#define SMPP_user_message_reference 0x0204 +#define SMPP_user_response_code 0x0205 +#define SMPP_source_port 0x020A +#define SMPP_destination_port 0x020B +#define SMPP_sar_msg_ref_num 0x020C +#define SMPP_language_indicator 0x020D +#define SMPP_sar_total_segments 0x020E +#define SMPP_sar_segment_seqnum 0x020F +#define SMPP_sc_interface_version 0x0210 +#define SMPP_callback_num_pres_ind 0x0302 +#define SMPP_callback_num_atag 0x0303 +#define SMPP_number_of_messages 0x0304 +#define SMPP_callback_num 0x0381 +#define SMPP_dpf_result 0x0420 +#define SMPP_set_dpf 0x0421 +#define SMPP_ms_availability_status 0x0422 +#define SMPP_network_error_code 0x0423 +#define SMPP_message_payload 0x0424 +#define SMPP_delivery_failure_reason 0x0425 +#define SMPP_more_messages_to_send 0x0426 +#define SMPP_message_state 0x0427 +#define SMPP_congestion_state 0x0428 /* defined in SMPP v5.0 */ +#define SMPP_ussd_service_op 0x0501 /* defined in SMPP v3.4 */ +/* block 0x06xx defined in SMPP v5.0 */ +#define SMPP_broadcast_channel_indicator 0x0600 +#define SMPP_broadcast_content_type 0x0601 +#define SMPP_broadcast_content_type_info 0x0602 +#define SMPP_broadcast_message_class 0x0603 +#define SMPP_broadcast_rep_num 0x0604 +#define SMPP_broadcast_frequency_interval 0x0605 +#define SMPP_broadcast_area_identifier 0x0606 +#define SMPP_failed_broadcast_area_identifier 0x0606 /* see 4.8.4.4, page 138 */ +#define SMPP_broadcast_error_status 0x0607 +#define SMPP_broadcast_area_success 0x0608 +#define SMPP_broadcast_end_time 0x0609 +#define SMPP_broadcast_service_group 0x060A +#define SMPP_billing_identification 0x060B +#define SMPP_source_network_id 0x060D +#define SMPP_dest_network_id 0x060E +#define SMPP_source_node_id 0x060F +#define SMPP_dest_node_id 0x0610 +#define SMPP_dest_addr_np_resolution 0x0611 +#define SMPP_dest_addr_np_information 0x0612 +#define SMPP_dest_addr_np_country 0x0613 +/* defined in SMPP v3.4 */ +#define SMPP_display_time 0x1201 +#define SMPP_sms_signal 0x1203 +#define SMPP_ms_validity 0x1204 +#define SMPP_alert_on_message_delivery 0x130C +#define SMPP_its_reply_type 0x1380 +#define SMPP_its_session_info 0x1383 #endif - Index: gw/smsc/smsc_smpp.c =================================================================== --- gw/smsc/smsc_smpp.c (revision 4997) +++ gw/smsc/smsc_smpp.c (working copy) @@ -367,19 +367,19 @@ /* We consider this as a "non-hard" condition, since there "may" * be international numbers routable that are < 7 digits. Think * of 2 digit country code + 3 digit emergency code. */ - warning(0, "SMPP[%s]: Mallformed addr `%s', generally expected at least 7 digits. ", + warning(0, "SMPP[%s]: Malformed addr `%s', generally expected at least 7 digits. ", octstr_get_cstr(id), octstr_get_cstr(addr)); } else if (octstr_get_char(addr, 0) == '+' && !octstr_check_range(addr, 1, 256, gw_isdigit)) { - error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ", + error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ", octstr_get_cstr(id), octstr_get_cstr(addr)); reason = SMPP_ESME_RINVSRCADR; goto error; } else if (octstr_get_char(addr, 0) != '+' && !octstr_check_range(addr, 0, 256, gw_isdigit)) { - error(0, "SMPP[%s]: Mallformed addr `%s', expected all digits. ", + error(0, "SMPP[%s]: Malformed addr `%s', expected all digits. ", octstr_get_cstr(id), octstr_get_cstr(addr)); reason = SMPP_ESME_RINVSRCADR; @@ -397,7 +397,7 @@ case GSM_ADDR_TON_ALPHANUMERIC: if (octstr_len(addr) > 11) { /* alphanum sender, max. allowed length is 11 (according to GSM specs) */ - error(0, "SMPP[%s]: Mallformed addr `%s', alphanum length greater 11 chars. ", + error(0, "SMPP[%s]: Malformed addr `%s', alphanumeric length greater 11 chars. ", octstr_get_cstr(id), octstr_get_cstr(addr)); reason = SMPP_ESME_RINVSRCADR; @@ -456,7 +456,7 @@ * it's not allowed to have destination_addr NULL */ if (pdu->u.deliver_sm.destination_addr == NULL) { - error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. " + error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. " "Discarding MO message.", octstr_get_cstr(smpp->conn->id), octstr_get_cstr(pdu->u.deliver_sm.destination_addr)); *reason = SMPP_ESME_RINVDSTADR; @@ -472,7 +472,9 @@ msg->sms.receiver = pdu->u.deliver_sm.destination_addr; pdu->u.deliver_sm.destination_addr = NULL; - /* SMSCs use service_type for billing information */ + /* SMSCs use service_type for billing information + * According to SMPP v5.0 there is no 'billing_identification' + * TLV in the deliver_sm PDU optional TLVs. */ msg->sms.binfo = pdu->u.deliver_sm.service_type; pdu->u.deliver_sm.service_type = NULL; @@ -506,7 +508,7 @@ debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d", octstr_get_cstr(smpp->conn->id), udhl); if (udhl > octstr_len(msg->sms.msgdata)) { - error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length " + error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length " "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id), udhl, octstr_len(msg->sms.msgdata)); *reason = SMPP_ESME_RINVESMCLASS; @@ -629,7 +631,7 @@ * it's not allowed to have destination_addr NULL */ if (pdu->u.data_sm.destination_addr == NULL) { - error(0, "SMPP[%s]: Mallformed destination_addr `%s', may not be empty. " + error(0, "SMPP[%s]: Malformed destination_addr `%s', may not be empty. " "Discarding MO message.", octstr_get_cstr(smpp->conn->id), octstr_get_cstr(pdu->u.data_sm.destination_addr)); *reason = SMPP_ESME_RINVDSTADR; @@ -646,8 +648,13 @@ pdu->u.data_sm.destination_addr = NULL; /* SMSCs use service_type for billing information */ - msg->sms.binfo = pdu->u.data_sm.service_type; - pdu->u.data_sm.service_type = NULL; + if (smpp->version == 0x50 && pdu->u.data_sm.billing_identification) { + msg->sms.binfo = pdu->u.data_sm.billing_identification; + pdu->u.data_sm.billing_identification = NULL; + } else { + msg->sms.binfo = pdu->u.data_sm.service_type; + pdu->u.data_sm.service_type = NULL; + } /* Foreign ID on MO */ msg->sms.foreign_id = pdu->u.data_sm.receipted_message_id; @@ -669,7 +676,7 @@ debug("bb.sms.smpp",0,"SMPP[%s]: UDH length read as %d", octstr_get_cstr(smpp->conn->id), udhl); if (udhl > octstr_len(msg->sms.msgdata)) { - error(0, "SMPP[%s]: Mallformed UDH length indicator 0x%03x while message length " + error(0, "SMPP[%s]: Malformed UDH length indicator 0x%03x while message length " "0x%03lx. Discarding MO message.", octstr_get_cstr(smpp->conn->id), udhl, octstr_len(msg->sms.msgdata)); *reason = SMPP_ESME_RINVESMCLASS; @@ -781,11 +788,19 @@ /* Set the service type of the outgoing message. We'll use the config * directive as default and 'binfo' as specific parameter. */ - pdu->u.submit_sm.service_type = octstr_len(msg->sms.binfo) ? - octstr_duplicate(msg->sms.binfo) : octstr_duplicate(smpp->service_type); + if (octstr_len(msg->sms.binfo)) { + /* SMPP v5.0 has an own TLV for billing information */ + if (smpp->version == 0x50) { + pdu->u.submit_sm.billing_identification = octstr_duplicate(msg->sms.binfo); + } else { + pdu->u.submit_sm.service_type = octstr_duplicate(msg->sms.binfo); + } + } else { + pdu->u.submit_sm.service_type = octstr_duplicate(smpp->service_type); + } /* Check for manual override of source ton and npi values */ - if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) { + if (smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) { pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton; pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi; debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d", @@ -879,7 +894,7 @@ msg->sms.alt_dcs : smpp->conn->alt_dcs)); /* set protocol id */ - if(msg->sms.pid != SMS_PARAM_UNDEFINED) + if (msg->sms.pid != SMS_PARAM_UNDEFINED) pdu->u.submit_sm.protocol_id = msg->sms.pid; /* @@ -1293,6 +1308,10 @@ if (smpp->version > 0x33 && receipted_message_id) { msgid = octstr_duplicate(receipted_message_id); switch(message_state) { + case 0: /* SCHEDULED, defined in SMPP v5.0, sec. 4.7.15, page 127 */ + if (smpp->version == 0x50) /* being very pedantic here */ + dlrstat = DLR_BUFFERED; + break; case 1: /* ENROUTE */ case 6: /* ACCEPTED */ dlrstat = DLR_BUFFERED; @@ -1307,6 +1326,10 @@ case 8: /* REJECTED */ dlrstat = DLR_FAIL; break; + case 9: /* SKIPPED, defined in SMPP v5.0, sec. 4.7.15, page 127 */ + if (smpp->version == 0x50) + dlrstat = DLR_FAIL; + break; case -1: /* message state is not present, partial SMPP v3.4 */ debug("bb.sms.smpp", 0, "SMPP[%s]: Partial SMPP v3.4, receipted_message_id present but not message_state.", octstr_get_cstr(smpp->conn->id));