[PATCH] smpp optional params
Alexander Malysh <[email protected]>
| Newsgroups | gmane.comp.mobile.kannel.devel |
|---|---|
| Organization | Centrium GmbH |
| Message-ID | <[email protected]> |
Hi, attached you can find patch with new version of optional params handling in smpp pdu. With this version Dict* is killed and all opt. params are treated the same as mandatory and could be easier accessed. Now pack/unpack for int values works too. Note: not available in pdu opt. params are initialized with '-1' for int, NULL for nulterminated/octet strings. Comments/votes are highly welcome! P.S. Patch wich adds handling of 'message_payload' and dlr handling with opt. params is available and will follow (please be patient;)... -- Best regards / Mit besten Grüßen aus Düsseldorf Dipl.-Ing. Alexander Malysh ___________________________________________ Centrium GmbH Vogelsanger Weg 80 40470 Düsseldorf Fon: +49 (0211) 74 84 51 80 Fax: +49 (0211) 277 49 109 email: [email protected] web: www.centrium.de msn: [email protected] icq: 98063111 ___________________________________________ Please avoid sending me Word, Excel or PowerPoint attachments. See http://www.fsf.org/philosophy/no-word-attachments.html
smpp-optional-params.patch
(text/x-diff, 27.1 KB)
Index: gw/smsc/smpp_pdu.def =================================================================== RCS file: /home/cvs/gateway/gw/smsc/smpp_pdu.def,v retrieving revision 1.7 diff -a -u -p -r1.7 smpp_pdu.def --- gw/smsc/smpp_pdu.def 22 Jan 2004 14:08:24 -0000 1.7 +++ gw/smsc/smpp_pdu.def 23 Mar 2004 13:55:22 -0000 @@ -58,29 +58,15 @@ * smpp_pdu.def - definitions of SMPP PDU structure * * Lars Wirzenius + * Daniel Lukic <[email protected]>: + * Initial optional parameters implementation. + * Alexander Malysh <[email protected]>: + * Extended optional parameters implementation. */ -/* - * Remarks by Daniel Lukic <[email protected]>: - * - * 1. submit_multi does not handle unsuccess_sme(s). A "MULTIPLE" macro would be - * needed. No time for that now. Maybe switch to some kind of reg-ex handling? - */ #include "smpp_pdu_opt.def" -/* - * XXX Implementation note: - * - * The PDUs bind_transmitter_resp, bind_receiver_resp, and submit_sm_resp - * contain a body part that is not optional, but on the other hand is only - * included if the command_status field is zero. The way this is handled at - * the moment is that the body is not included in the PDU description in - * this file, so it is always ignored. This is OK because it is not being - * used anyway. In the future the body will be needed, and so this will - * be implemented in a better way then. - */ - #ifndef PDU #error Macro PDU not defined. @@ -102,8 +88,16 @@ #error Macro OPTIONAL_BEGIN not defined. #endif -#ifndef TLV -#error Macro TLV not defined. +#ifndef TLV_INTEGER +#error Macro TLV_INTEGER not defined. +#endif + +#ifndef TLV_NULTERMINATED +#error Macro TLV_NULTERMINATED not defined. +#endif + +#ifndef TLV_OCTETS +#error Macro TLV_OCTETS not defined. #endif #ifndef OPTIONAL_END @@ -120,9 +114,9 @@ #error Macro HEADER was already defined. #endif #define HEADER \ - INTEGER(command_id, 4) \ - INTEGER(command_status, 4) \ - INTEGER(sequence_number, 4) + INTEGER(command_id, 4) \ + INTEGER(command_status, 4) \ + INTEGER(sequence_number, 4) PDU(bind_transmitter, 0x00000002, @@ -140,8 +134,8 @@ PDU(bind_transmitter_resp, 0x80000002, HEADER NULTERMINATED(system_id, 16) - OPTIONAL_BEGIN(1) - TLV(SMPP_SC_interface_version, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(sc_interface_version, 1) OPTIONAL_END ) @@ -161,8 +155,8 @@ PDU(bind_receiver_resp, 0x80000001, HEADER NULTERMINATED(system_id, 16) - OPTIONAL_BEGIN(1) - TLV(SMPP_SC_interface_version, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(sc_interface_version, 1) OPTIONAL_END ) @@ -182,8 +176,8 @@ PDU(bind_transceiver_resp, 0x80000009, HEADER NULTERMINATED(system_id, 16) - OPTIONAL_BEGIN(1) - TLV(SMPP_SC_interface_version, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(sc_interface_version, 1) OPTIONAL_END ) @@ -230,35 +224,35 @@ PDU(submit_sm, INTEGER(sm_default_msg_id, 1) INTEGER(sm_length, 1) OCTETS(short_message, sm_length) - OPTIONAL_BEGIN(28) - TLV(SMPP_user_message_reference, 2, 2) - TLV(SMPP_source_port, 2, 2) - TLV(SMPP_source_addr_subunit, 1, 1) - TLV(SMPP_destination_port, 2, 2) - TLV(SMPP_dest_addr_subunit, 1, 1) - TLV(SMPP_sar_msg_ref_num, 2, 2) - TLV(SMPP_sar_total_segments, 1, 1) - TLV(SMPP_sar_segment_seqnum, 1, 1) - TLV(SMPP_more_messages_to_send, 1, 1) - TLV(SMPP_payload_type, 1, 1) - TLV(SMPP_message_payload, 0, 65536) - TLV(SMPP_privacy_indicator, 1, 1) - TLV(SMPP_callback_num, 4, 19) - TLV(SMPP_callback_num_pres_ind, 1, 1) - TLV(SMPP_callback_num_atag, 0, 65) - TLV(SMPP_source_subaddress, 2, 23) - TLV(SMPP_dest_subaddress, 2, 23) - TLV(SMPP_user_response_code, 1, 1) - TLV(SMPP_display_time, 1, 1) - TLV(SMPP_sms_signal, 2, 2) - TLV(SMPP_ms_validity, 1, 1) - TLV(SMPP_ms_msg_wait_facilities, 1, 1) - TLV(SMPP_number_of_messages, 1, 1) - TLV(SMPP_alert_on_message_delivery, 0, 0) - TLV(SMPP_language_indicator, 1, 1) - TLV(SMPP_its_reply_type, 1, 1) - TLV(SMPP_its_session_info, 2, 2) - TLV(SMPP_ussd_service_op, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(user_message_reference, 2) + TLV_INTEGER(source_port, 2) + TLV_INTEGER(source_addr_subunit, 1) + TLV_INTEGER(destination_port, 2) + TLV_INTEGER(dest_addr_subunit, 1) + TLV_INTEGER(sar_msg_ref_num, 2) + TLV_INTEGER(sar_total_segments, 1) + TLV_INTEGER(sar_segment_seqnum, 1) + TLV_INTEGER(more_messages_to_send, 1) + TLV_INTEGER(payload_type, 1) + TLV_OCTETS(message_payload, 0, 65536) + TLV_INTEGER(privacy_indicator, 1) + TLV_OCTETS(callback_num, 4, 19) + TLV_INTEGER(callback_num_pres_ind, 1) + TLV_OCTETS(callback_num_atag, 0, 65) + TLV_OCTETS(source_subaddress, 2, 23) + TLV_OCTETS(dest_subaddress, 2, 23) + TLV_INTEGER(user_response_code, 1) + TLV_INTEGER(display_time, 1) + TLV_INTEGER(sms_signal, 2) + TLV_INTEGER(ms_validity, 1) + TLV_INTEGER(ms_msg_wait_facilities, 1) + TLV_INTEGER(number_of_messages, 1) + TLV_INTEGER(alert_on_message_delivery, 0) + TLV_INTEGER(language_indicator, 1) + TLV_INTEGER(its_reply_type, 1) + TLV_OCTETS(its_session_info, 2, 2) + TLV_OCTETS(ussd_service_op, 1, 1) OPTIONAL_END ) @@ -288,29 +282,29 @@ PDU(submit_multi, INTEGER(sm_default_msg_id, 1) INTEGER(sm_length, 1) OCTETS(short_message, sm_length) - OPTIONAL_BEGIN(22) - TLV(SMPP_user_message_reference, 2, 2) - TLV(SMPP_source_port, 2, 2) - TLV(SMPP_source_addr_subunit, 1, 1) - TLV(SMPP_destination_port, 2, 2) - TLV(SMPP_dest_addr_subunit, 1, 1) - TLV(SMPP_sar_msg_ref_num, 2, 2) - TLV(SMPP_sar_total_segments, 1, 1) - TLV(SMPP_sar_segment_seqnum, 1, 1) - TLV(SMPP_payload_type, 1, 1) - TLV(SMPP_message_payload, 0, 65536) - TLV(SMPP_privacy_indicator, 1, 1) - TLV(SMPP_callback_num, 4, 19) - TLV(SMPP_callback_num_pres_ind, 1, 1) - TLV(SMPP_callback_num_atag, 0, 65) - TLV(SMPP_source_subaddress, 2, 23) - TLV(SMPP_dest_subaddress, 2, 23) - TLV(SMPP_display_time, 1, 1) - TLV(SMPP_sms_signal, 2, 2) - TLV(SMPP_ms_validity, 1, 1) - TLV(SMPP_ms_msg_wait_facilities, 1, 1) - TLV(SMPP_alert_on_message_delivery, 0, 0) - TLV(SMPP_language_indicator, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(user_message_reference, 2) + TLV_INTEGER(source_port, 2) + TLV_INTEGER(source_addr_subunit, 1) + TLV_INTEGER(destination_port, 2) + TLV_INTEGER(dest_addr_subunit, 1) + TLV_INTEGER(sar_msg_ref_num, 2) + TLV_INTEGER(sar_total_segments, 1) + TLV_INTEGER(sar_segment_seqnum, 1) + TLV_INTEGER(payload_type, 1) + TLV_OCTETS(message_payload, 0, 65536) + TLV_INTEGER(privacy_indicator, 1) + TLV_OCTETS(callback_num, 4, 19) + TLV_INTEGER(callback_num_pres_ind, 1) + TLV_OCTETS(callback_num_atag, 0, 65) + TLV_OCTETS(source_subaddress, 2, 23) + TLV_OCTETS(dest_subaddress, 2, 23) + TLV_INTEGER(display_time, 1) + TLV_INTEGER(sms_signal, 2) + TLV_INTEGER(ms_validity, 1) + TLV_INTEGER(ms_msg_wait_facilities, 1) + TLV_INTEGER(alert_on_message_delivery, 0) + TLV_INTEGER(language_indicator, 1) OPTIONAL_END ) @@ -342,25 +336,25 @@ PDU(deliver_sm, INTEGER(sm_default_msg_id, 1) INTEGER(sm_length, 1) OCTETS(short_message, sm_length) - OPTIONAL_BEGIN(18) - TLV(SMPP_user_message_reference, 2, 2) - TLV(SMPP_source_port, 2, 2) - TLV(SMPP_destination_port, 2, 2) - TLV(SMPP_sar_msg_ref_num, 2, 2) - TLV(SMPP_sar_total_segments, 1, 1) - TLV(SMPP_sar_segment_seqnum, 1, 1) - TLV(SMPP_user_response_code, 1, 1) - TLV(SMPP_privacy_indicator, 1, 1) - TLV(SMPP_payload_type, 1, 1) - TLV(SMPP_message_payload, 0, 65536) - TLV(SMPP_callback_num, 4, 19) - TLV(SMPP_source_subaddress, 2, 23) - TLV(SMPP_dest_subaddress, 2, 23) - TLV(SMPP_language_indicator, 1, 1) - TLV(SMPP_its_session_info, 2, 2) - TLV(SMPP_network_error_code, 3, 3) - TLV(SMPP_message_state, 1, 1) - TLV(SMPP_receipted_message_id, 1, 65) + OPTIONAL_BEGIN + TLV_INTEGER(user_message_reference, 2) + TLV_INTEGER(source_port, 2) + TLV_INTEGER(destination_port, 2) + TLV_INTEGER(sar_msg_ref_num, 2) + TLV_INTEGER(sar_total_segments, 1) + TLV_INTEGER(sar_segment_seqnum, 1) + TLV_INTEGER(user_response_code, 1) + TLV_INTEGER(privacy_indicator, 1) + TLV_INTEGER(payload_type, 1) + TLV_OCTETS(message_payload, 0, 65536) + TLV_OCTETS(callback_num, 4, 19) + TLV_OCTETS(source_subaddress, 2, 23) + TLV_OCTETS(dest_subaddress, 2, 23) + TLV_INTEGER(language_indicator, 1) + TLV_OCTETS(its_session_info, 2, 2) + TLV_OCTETS(network_error_code, 3, 3) + TLV_INTEGER(message_state, 1) + TLV_NULTERMINATED(receipted_message_id, 65) OPTIONAL_END ) @@ -383,45 +377,45 @@ PDU(data_sm, INTEGER(esm_class, 1) INTEGER(registered_delivery, 1) INTEGER(data_coding, 1) - OPTIONAL_BEGIN(38) - TLV(SMPP_source_port, 2, 2) - TLV(SMPP_source_addr_subunit, 1, 1) - TLV(SMPP_source_network_type, 1, 1) - TLV(SMPP_source_bearer_type, 1, 1) - TLV(SMPP_source_telematics_id, 1, 1) - TLV(SMPP_destination_port, 2, 2) - TLV(SMPP_dest_addr_subunit, 1, 1) - TLV(SMPP_dest_network_type, 1, 1) - TLV(SMPP_dest_bearer_type, 1, 1) - TLV(SMPP_dest_telematics_id, 2, 2) - TLV(SMPP_sar_msg_ref_num, 2, 2) - TLV(SMPP_sar_total_segments, 1, 1) - TLV(SMPP_sar_segment_seqnum, 1, 1) - TLV(SMPP_more_messages_to_send, 1, 1) - TLV(SMPP_qos_time_to_live, 4, 4) - TLV(SMPP_payload_type, 1, 1) - TLV(SMPP_message_payload, 0, 65536) - TLV(SMPP_set_dpf, 1, 1) - TLV(SMPP_receipted_message_id, 1, 65) - TLV(SMPP_message_state, 1, 1) - TLV(SMPP_network_error_code, 3, 3) - TLV(SMPP_user_message_reference, 2, 2) - TLV(SMPP_privacy_indicator, 1, 1) - TLV(SMPP_callback_num, 4, 19) - TLV(SMPP_callback_num_pres_ind, 1, 1) - TLV(SMPP_callback_num_atag, 0, 65) - TLV(SMPP_source_subaddress, 2, 23) - TLV(SMPP_dest_subaddress, 2, 23) - TLV(SMPP_user_response_code, 1, 1) - TLV(SMPP_display_time, 1, 1) - TLV(SMPP_sms_signal, 2, 2) - TLV(SMPP_ms_validity, 1, 1) - TLV(SMPP_ms_msg_wait_facilities, 1, 1) - TLV(SMPP_number_of_messages, 1, 1) - TLV(SMPP_alert_on_message_delivery, 0, 0) - TLV(SMPP_language_indicator, 1, 1) - TLV(SMPP_its_reply_type, 1, 1) - TLV(SMPP_its_session_info, 2, 2) + OPTIONAL_BEGIN + TLV_INTEGER(source_port, 2) + TLV_INTEGER(source_addr_subunit, 1) + TLV_INTEGER(source_network_type, 1) + TLV_INTEGER(source_bearer_type, 1) + TLV_INTEGER(source_telematics_id, 1) + TLV_INTEGER(destination_port, 2) + TLV_INTEGER(dest_addr_subunit, 1) + TLV_INTEGER(dest_network_type, 1) + TLV_INTEGER(dest_bearer_type, 1) + TLV_INTEGER(dest_telematics_id, 2) + TLV_INTEGER(sar_msg_ref_num, 2) + TLV_INTEGER(sar_total_segments, 1) + TLV_INTEGER(sar_segment_seqnum, 1) + TLV_INTEGER(more_messages_to_send, 1) + TLV_INTEGER(qos_time_to_live, 4) + TLV_INTEGER(payload_type, 1) + TLV_OCTETS(message_payload, 0, 65536) + TLV_INTEGER(set_dpf, 1) + TLV_NULTERMINATED(receipted_message_id, 65) + TLV_INTEGER(message_state, 1) + TLV_OCTETS(network_error_code, 3, 3) + TLV_INTEGER(user_message_reference, 2) + TLV_INTEGER(privacy_indicator, 1) + TLV_OCTETS(callback_num, 4, 19) + TLV_INTEGER(callback_num_pres_ind, 1) + TLV_OCTETS(callback_num_atag, 0, 65) + TLV_OCTETS(source_subaddress, 2, 23) + TLV_OCTETS(dest_subaddress, 2, 23) + TLV_INTEGER(user_response_code, 1) + TLV_INTEGER(display_time, 1) + TLV_INTEGER(sms_signal, 2) + TLV_INTEGER(ms_validity, 1) + TLV_INTEGER(ms_msg_wait_facilities, 1) + TLV_INTEGER(number_of_messages, 1) + TLV_INTEGER(alert_on_message_delivery, 0) + TLV_INTEGER(language_indicator, 1) + TLV_INTEGER(its_reply_type, 1) + TLV_OCTETS(its_session_info, 2, 2) OPTIONAL_END ) @@ -429,11 +423,11 @@ PDU(data_sm_resp, 0x80000103, HEADER NULTERMINATED(message_id, 65) - OPTIONAL_BEGIN(28) - TLV(SMPP_delivery_failure_reason, 1, 1) - TLV(SMPP_network_error_code, 3, 3) - TLV(SMPP_additional_status_info_text, 1, 256) - TLV(SMPP_dpf_result, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(delivery_failure_reason, 1) + TLV_OCTETS(network_error_code, 3, 3) + TLV_NULTERMINATED(additional_status_info_text, 256) + TLV_INTEGER(dpf_result, 1) OPTIONAL_END ) @@ -513,8 +507,8 @@ PDU(alert_notification, INTEGER(esme_addr_ton, 1) INTEGER(esme_addr_npi, 1) NULTERMINATED(esme_addr, 65) - OPTIONAL_BEGIN(1) - TLV(SMPP_ms_availability_status, 1, 1) + OPTIONAL_BEGIN + TLV_INTEGER(ms_availability_status, 1) OPTIONAL_END ) @@ -524,6 +518,8 @@ PDU(alert_notification, #undef OCTETS #undef HEADER #undef OPTIONAL_BEGIN -#undef TLV +#undef TLV_INTEGER +#undef TLV_NULTERMINATED +#undef TLV_OCTETS #undef OPTIONAL_END Index: gw/smsc/smpp_pdu_opt.def =================================================================== RCS file: /home/cvs/gateway/gw/smsc/smpp_pdu_opt.def,v retrieving revision 1.3 diff -a -u -p -r1.3 smpp_pdu_opt.def --- gw/smsc/smpp_pdu_opt.def 22 Jan 2004 14:08:24 -0000 1.3 +++ gw/smsc/smpp_pdu_opt.def 23 Mar 2004 13:55:22 -0000 @@ -85,7 +85,7 @@ #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_sc_interface_version 0x0210 #define SMPP_callback_num_pres_ind 0x0302 #define SMPP_callback_num_atag 0x0303 #define SMPP_number_of_messages 0x0304 Index: gw/smsc/smpp_pdu.c =================================================================== RCS file: /home/cvs/gateway/gw/smsc/smpp_pdu.c,v retrieving revision 1.18 diff -a -u -p -r1.18 smpp_pdu.c --- gw/smsc/smpp_pdu.c 22 Jan 2004 14:08:24 -0000 1.18 +++ gw/smsc/smpp_pdu.c 23 Mar 2004 13:55:22 -0000 @@ -58,6 +58,8 @@ * smpp_pdu.c - parse and generate SMPP PDUs * * Lars Wirzenius + * Alexander Malysh <[email protected]>: + * Extended optional parameters implementation. */ @@ -122,9 +124,10 @@ SMPP_PDU *smpp_pdu_create(unsigned long pdu->type = type; switch (type) { - #define OPTIONAL_BEGIN(num_expected) \ - p->optional_parameters = dict_create(num_expected, (void (*)(void *))octstr_destroy); - #define TLV(tag_id, min_len, max_len) + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, octets) p->name = -1; + #define TLV_NULTERMINATED(name, max_len) p->name = NULL; + #define TLV_OCTETS(name, min_len, max_len) p->name = NULL; #define OPTIONAL_END #define INTEGER(name, octets) \ if (strcmp(#name, "command_id") == 0) p->name = type; \ @@ -154,8 +157,10 @@ void smpp_pdu_destroy(SMPP_PDU *pdu) return; switch (pdu->type) { - #define OPTIONAL_BEGIN(num_expected) dict_destroy(p->optional_parameters); - #define TLV(tag_id, min_len, max_len) + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, octets) p->name = -1; + #define TLV_NULTERMINATED(name, max_octets) octstr_destroy(p->name); + #define TLV_OCTETS(name, min_len, max_len) octstr_destroy(p->name); #define OPTIONAL_END #define INTEGER(name, octets) p->name = 0; /* Make sure "p" is used */ #define NULTERMINATED(name, max_octets) octstr_destroy(p->name); @@ -183,8 +188,10 @@ Octstr *smpp_pdu_pack(SMPP_PDU *pdu) * Fix lengths of octet string fields. */ switch (pdu->type) { - #define OPTIONAL_BEGIN(num_expected) - #define TLV(tag_id, min_len, max_len) + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, octets) + #define TLV_NULTERMINATED(name, max_len) + #define TLV_OCTETS(name, min_len, max_len) #define OPTIONAL_END #define INTEGER(name, octets) p = *(&p); #define NULTERMINATED(name, max_octets) p = *(&p); @@ -198,21 +205,31 @@ Octstr *smpp_pdu_pack(SMPP_PDU *pdu) } switch (pdu->type) { - #define OPTIONAL_BEGIN(num_expected) - #define TLV(tag_id, min_len, max_len) \ - { /* Add optional parameter - if existing */ \ - short tag_id_buffer = tag_id; \ - Octstr *opt_tag = octstr_create_from_data((char*) &tag_id_buffer, 2); \ - Octstr *opt_val = dict_get(p->optional_parameters, opt_tag); \ - if (opt_val != NULL) { \ - long opt_len = octstr_len(opt_val); \ - gw_assert(min_len == -1 || (min_len <= opt_len && opt_len <= max_len)); \ - octstr_append(os, opt_tag); \ - octstr_append_data(os, (char*) &opt_len, 2); \ - octstr_append(os, opt_val); \ - } \ - octstr_destroy(opt_tag); \ - } + #define TL(name, octets) \ + append_encoded_integer(os, SMPP_##name, 2); \ + append_encoded_integer(os, octets, 2); + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, octets) \ + if (p->name != -1) { \ + TL(name, octets); \ + INTEGER(name, octets) \ + } + #define TLV_NULTERMINATED(name, max_len) \ + if (p->name != NULL) { \ + TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name))); \ + NULTERMINATED(name, max_len) \ + } + #define TLV_OCTETS(name, min_len, max_len) \ + if (p->name != NULL) { \ + unsigned long len = octstr_len(p->name); \ + if (len > max_len || len < min_len) { \ + error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \ + #name, len, min_len, max_len);\ + } else { \ + TL(name, len); \ + octstr_append(os, p->name); \ + } \ + } #define OPTIONAL_END #define INTEGER(name, octets) \ append_encoded_integer(os, p->name, octets); @@ -230,7 +247,7 @@ Octstr *smpp_pdu_pack(SMPP_PDU *pdu) } \ octstr_append_char(os, '\0'); #define OCTETS(name, field_giving_octets) \ - octstr_append(os, p->name); + if (p->name) octstr_append(os, p->name); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields } break; #include "smpp_pdu.def" @@ -273,37 +290,51 @@ SMPP_PDU *smpp_pdu_unpack(Octstr *data_w pos = 0; switch (type) { - #define OPTIONAL_BEGIN(num_expected) \ - { /* Read optional parameters */ \ - while (pos+4 <= len) { \ - unsigned long opt_tag, opt_len; \ - Octstr *opt_val = NULL; \ - Octstr *tag_str = NULL; \ - opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \ - debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \ - opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \ + #define OPTIONAL_BEGIN \ + { /* Read optional parameters */ \ + while (pos + 4 <= len) { \ + unsigned long opt_tag, opt_len; \ + opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \ + debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \ + opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \ debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len); - #define TLV(tag_id, min_len, max_len) \ - if (tag_id == opt_tag) { \ - if ((min_len != -1 && opt_len < min_len) || (max_len != -1 && opt_len > max_len) || \ - (pos+opt_len > len)) { \ - error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #tag_id, opt_len);\ - pos += opt_len; \ - continue; \ - } \ - opt_val = octstr_copy(data_without_len, pos, opt_len); pos += opt_len; \ - debug("sms.smpp", 0, "Optional parameter value (%s)", octstr_get_cstr(opt_val)); \ - tag_str = octstr_create_from_data((char*) &opt_tag, 2); \ - dict_put(p->optional_parameters, tag_str, opt_val); \ - octstr_destroy(tag_str); \ - opt_val = NULL; \ - } else - #define OPTIONAL_END \ - { \ + #define TLV_INTEGER(name, octets) \ + if (SMPP_##name == opt_tag) { \ + /* check length */ \ + if (opt_len > octets) { \ + error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len); \ + pos += opt_len; \ + continue; \ + } \ + INTEGER(name, opt_len); \ + } else + #define TLV_NULTERMINATED(name, max_len) \ + if (SMPP_##name == opt_tag) { \ + /* check length */ \ + if (opt_len > max_len || pos+opt_len > len) { \ + error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #name, opt_len); \ + pos += opt_len; \ + continue; \ + } \ + NULTERMINATED(name, opt_len); \ + } else + #define TLV_OCTETS(name, min_len, max_len) \ + if (SMPP_##name == opt_tag) { \ + /* check length */ \ + if (opt_len < min_len || opt_len > max_len || pos + opt_len > len) { \ + error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \ + #name, opt_len, min_len, max_len); \ + pos += opt_len; \ + continue; \ + } \ + p->name = octstr_copy(data_without_len, pos, opt_len); \ + } else + #define OPTIONAL_END \ + { \ error(0, "SMPP: Unknown optional parameter (0x%04lx) for PDU type (%s) received!", \ - opt_tag, pdu->type_name); \ - } \ - } \ + opt_tag, pdu->type_name); \ + } \ + } \ } #define INTEGER(name, octets) \ p->name = decode_integer(data_without_len, pos, octets); \ @@ -337,24 +368,20 @@ void smpp_pdu_dump(SMPP_PDU *pdu) debug("sms.smpp", 0, "SMPP PDU %p dump:", (void *) pdu); debug("sms.smpp", 0, " type_name: %s", pdu->type_name); switch (pdu->type) { - #define OPTIONAL_BEGIN(num_expected) \ - if (p->optional_parameters != NULL) { \ - Octstr *key = NULL, *tag_val = NULL; - unsigned long id; - #define TLV(tag_id, min_len, max_len) \ - id = tag_id; \ - key = octstr_create_from_data((char*)&id, 2); \ - tag_val = dict_get(p->optional_parameters, key); \ - if (tag_val != NULL) { \ - debug("sms.smpp",0," %s: ", #tag_id); \ - debug("sms.smpp",0," tag: 0x%04lx", id); \ - debug("sms.smpp",0," length: 0x%04lx", \ - octstr_len(tag_val)); \ - octstr_dump_short(tag_val, 2, " value"); \ - } \ - octstr_destroy(key); - #define OPTIONAL_END \ - } + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, max_len) \ + if (p->name != -1) { \ + INTEGER(name, max_len) \ + } + #define TLV_NULTERMINATED(name, max_len) \ + if (p->name != NULL) { \ + NULTERMINATED(name, max_len) \ + } + #define TLV_OCTETS(name, min_len, max_len) \ + if (p->name != NULL) { \ + OCTETS(name, max_len) \ + } + #define OPTIONAL_END #define INTEGER(name, octets) \ debug("sms.smpp", 0, " %s: %lu = 0x%08lx", #name, p->name, p->name); #define NULTERMINATED(name, max_octets) \ Index: gw/smsc/smpp_pdu.h =================================================================== RCS file: /home/cvs/gateway/gw/smsc/smpp_pdu.h,v retrieving revision 1.9 diff -a -u -p -r1.9 smpp_pdu.h --- gw/smsc/smpp_pdu.h 22 Jan 2004 14:08:24 -0000 1.9 +++ gw/smsc/smpp_pdu.h 23 Mar 2004 13:55:22 -0000 @@ -58,6 +58,8 @@ * smpp_pdu.h - declarations for SMPP PDUs * * Lars Wirzenius + * Alexander Malysh <[email protected]>: + * Extended optional parameters implementation. */ @@ -70,8 +72,10 @@ enum { - #define OPTIONAL_BEGIN(num_expected) - #define TLV(tag_id, min_len, max_len) + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, max_len) + #define TLV_NULTERMINATED(name, max_len) + #define TLV_OCTETS(name, min_len, max_len) #define OPTIONAL_END #define INTEGER(name, octets) #define NULTERMINATED(name, max_octets) @@ -87,14 +91,16 @@ struct SMPP_PDU { unsigned long type; const char *type_name; union { - #define OPTIONAL_BEGIN(num_expected) Dict * optional_parameters; - #define TLV(tag_id, min_len, max_len) - #define OPTIONAL_END - #define INTEGER(name, octets) unsigned long name; - #define NULTERMINATED(name, max_octets) Octstr *name; - #define OCTETS(name, field_giving_octets) Octstr *name; - #define PDU(name, id, fields) struct name { fields } name; - #include "smpp_pdu.def" + #define OPTIONAL_BEGIN + #define TLV_INTEGER(name, octets) unsigned long name; + #define TLV_NULTERMINATED(name, max_len) Octstr *name; + #define TLV_OCTETS(name, min_len, max_len) Octstr *name; + #define OPTIONAL_END + #define INTEGER(name, octets) unsigned long name; + #define NULTERMINATED(name, max_octets) Octstr *name; + #define OCTETS(name, field_giving_octets) Octstr *name; + #define PDU(name, id, fields) struct name { fields } name; + #include "smpp_pdu.def" } u; };