[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));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.