Kannel: Open Source WAP and SMS gateway  svn-r5262
smpp_pdu.h File Reference
#include "gwlib/gwlib.h"
#include "gwlib/dict.h"
#include "smpp_pdu.def"

Go to the source code of this file.

Data Structures

struct  SMPP_PDU
 

Macros

#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)
 
#define OCTETS(name, field_giving_octets)
 
#define PDU(name, id, fields)   name = id,
 
#define OPTIONAL_BEGIN
 
#define TLV_INTEGER(name, octets)   long name;
 
#define TLV_NULTERMINATED(name, max_len)   Octstr *name;
 
#define TLV_OCTETS(name, min_len, max_len)   Octstr *name;
 
#define OPTIONAL_END   Dict *tlv;
 
#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;
 
#define GSM_ADDR_TON_UNKNOWN   0x00000000
 
#define GSM_ADDR_TON_INTERNATIONAL   0x00000001
 
#define GSM_ADDR_TON_NATIONAL   0x00000002
 
#define GSM_ADDR_TON_NETWORKSPECIFIC   0x00000003
 
#define GSM_ADDR_TON_SUBSCRIBER   0x00000004
 
#define GSM_ADDR_TON_ALPHANUMERIC   0x00000005 /* GSM TS 03.38 */
 
#define GSM_ADDR_TON_ABBREVIATED   0x00000006
 
#define GSM_ADDR_TON_EXTENSION   0x00000007 /* Reserved */
 
#define GSM_ADDR_NPI_UNKNOWN   0x00000000
 
#define GSM_ADDR_NPI_E164   0x00000001
 
#define GSM_ADDR_NPI_X121   0x00000003
 
#define GSM_ADDR_NPI_TELEX   0x00000004
 
#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 */
 
#define ESM_CLASS_SUBMIT_DEFAULT_SMSC_MODE   0x00000000
 
#define ESM_CLASS_SUBMIT_DATAGRAM_MODE   0x00000001
 
#define ESM_CLASS_SUBMIT_FORWARD_MODE   0x00000002
 
#define ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE   0x00000003
 
#define ESM_CLASS_SUBMIT_DELIVERY_ACK   0x00000008
 
#define ESM_CLASS_SUBMIT_USER_ACK   0x00000010
 
#define ESM_CLASS_SUBMIT_UDH_INDICATOR   0x00000040
 
#define ESM_CLASS_SUBMIT_RPI   0x00000080
 
#define ESM_CLASS_SUBMIT_UDH_AND_RPI   0x000000C0
 
#define ESM_CLASS_DELIVER_DEFAULT_TYPE   0x00000000
 
#define ESM_CLASS_DELIVER_SMSC_DELIVER_ACK   0x00000004
 
#define ESM_CLASS_DELIVER_SME_DELIVER_ACK   0x00000008
 
#define ESM_CLASS_DELIVER_SME_MANULAL_ACK   0x00000010
 
#define ESM_CLASS_DELIVER_INTERM_DEL_NOTIFICATION   0x00000020
 
#define ESM_CLASS_DELIVER_UDH_INDICATOR   0x00000040
 
#define ESM_CLASS_DELIVER_RPI   0x00000080
 
#define ESM_CLASS_DELIVER_UDH_AND_RPI   0x000000C0
 

Typedefs

typedef struct SMPP_PDU SMPP_PDU
 

Enumerations

enum  { PDU, PDU }
 
enum  SMPP_ERROR_MESSAGES {
  SMPP_ESME_ROK = 0x00000000, SMPP_ESME_RINVMSGLEN = 0x00000001, SMPP_ESME_RINVCMDLEN = 0x00000002, SMPP_ESME_RINVCMDID = 0x00000003,
  SMPP_ESME_RINVBNDSTS = 0x00000004, SMPP_ESME_RALYBND = 0x00000005, SMPP_ESME_RINVPRTFLG = 0x00000006, SMPP_ESME_RINVREGDLVFLG = 0x00000007,
  SMPP_ESME_RSYSERR = 0x00000008, SMPP_ESME_RINVSRCADR = 0x0000000A, SMPP_ESME_RINVDSTADR = 0x0000000B, SMPP_ESME_RINVMSGID = 0x0000000C,
  SMPP_ESME_RBINDFAIL = 0x0000000D, SMPP_ESME_RINVPASWD = 0x0000000E, SMPP_ESME_RINVSYSID = 0x0000000F, SMPP_ESME_RCANCELFAIL = 0x00000011,
  SMPP_ESME_RREPLACEFAIL = 0x00000013, SMPP_ESME_RMSGQFUL = 0x00000014, SMPP_ESME_RINVSERTYP = 0x00000015, SMPP_ESME_RINVNUMDESTS = 0x00000033,
  SMPP_ESME_RINVDLNAME = 0x00000034, SMPP_ESME_RINVDESTFLAG = 0x00000040, SMPP_ESME_RINVSUBREP = 0x00000042, SMPP_ESME_RINVESMCLASS = 0x00000043,
  SMPP_ESME_RCNTSUBDL = 0x00000044, SMPP_ESME_RSUBMITFAIL = 0x00000045, SMPP_ESME_RINVSRCTON = 0x00000048, SMPP_ESME_RINVSRCNPI = 0x00000049,
  SMPP_ESME_RINVDSTTON = 0x00000050, SMPP_ESME_RINVDSTNPI = 0x00000051, SMPP_ESME_RINVSYSTYP = 0x00000053, SMPP_ESME_RINVREPFLAG = 0x00000054,
  SMPP_ESME_RINVNUMMSGS = 0x00000055, SMPP_ESME_RTHROTTLED = 0x00000058, SMPP_ESME_RINVSCHED = 0x00000061, SMPP_ESME_RINVEXPIRY = 0x00000062,
  SMPP_ESME_RINVDFTMSGID = 0x00000063, SMPP_ESME_RX_T_APPN = 0x00000064, SMPP_ESME_RX_P_APPN = 0x00000065, SMPP_ESME_RX_R_APPN = 0x00000066,
  SMPP_ESME_RQUERYFAIL = 0x00000067, SMPP_ESME_RINVTLVSTREAM = 0x000000C0, SMPP_ESME_RTLVNOTALLWD = 0x000000C1, SMPP_ESME_RINVTLVLEN = 0x000000C2,
  SMPP_ESME_RMISSINGTLV = 0x000000C3, SMPP_ESME_RINVTLVVAL = 0x000000C4, SMPP_ESME_RDELIVERYFAILURE = 0x000000FE, SMPP_ESME_RUNKNOWNERR = 0x000000FF,
  SMPP_ESME_RSERTYPUNAUTH = 0x00000100, SMPP_ESME_RPROHIBITED = 0x00000101, SMPP_ESME_RSERTYPUNAVAIL = 0x00000102, SMPP_ESME_RSERTYPDENIED = 0x00000103,
  SMPP_ESME_RINVDCS = 0x00000104, SMPP_ESME_RINVSRCADDRSUBUNIT = 0x00000105, SMPP_ESME_RINVDSTADDRSUBUNIT = 0x00000106, SMPP_ESME_RINVBCASTFREQINT = 0x00000107,
  SMPP_ESME_RINVBCASTALIAS_NAME = 0x00000108, SMPP_ESME_RINVBCASTAREAFMT = 0x00000109, SMPP_ESME_RINVNUMBCAST_AREAS = 0x0000010A, SMPP_ESME_RINVBCASTCNTTYPE = 0x0000010B,
  SMPP_ESME_RINVBCASTMSGCLASS = 0x0000010C, SMPP_ESME_RBCASTFAIL = 0x0000010D, SMPP_ESME_RBCASTQUERYFAIL = 0x0000010E, SMPP_ESME_RBCASTCANCELFAIL = 0x0000010F,
  SMPP_ESME_RINVBCAST_REP = 0x00000110, SMPP_ESME_RINVBCASTSRVGRP = 0x00000111, SMPP_ESME_RINVBCASTCHANIND = 0x00000112
}
 

Functions

int smpp_pdu_init (Cfg *cfg)
 
int smpp_pdu_shutdown (void)
 
SMPP_PDUsmpp_pdu_create (unsigned long type, unsigned long seq_no)
 
void smpp_pdu_destroy (SMPP_PDU *pdu)
 
int smpp_pdu_is_valid (SMPP_PDU *pdu)
 
Octstrsmpp_pdu_pack (Octstr *smsc_id, SMPP_PDU *pdu)
 
SMPP_PDUsmpp_pdu_unpack (Octstr *smsc_id, Octstr *data_without_len)
 
void smpp_pdu_dump (Octstr *smsc_id, SMPP_PDU *pdu)
 
void smpp_pdu_dump_line (Octstr *smsc_id, SMPP_PDU *pdu)
 
long smpp_pdu_read_len (Connection *conn)
 
Octstrsmpp_pdu_read_data (Connection *conn, long len)
 
const char * smpp_error_to_string (enum SMPP_ERROR_MESSAGES error)
 
void smpp_tlv_add_constant (Octstr *smsc_id, Dict **tlvs)
 

Macro Definition Documentation

◆ ESM_CLASS_DELIVER_DEFAULT_TYPE

#define ESM_CLASS_DELIVER_DEFAULT_TYPE   0x00000000

Definition at line 146 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_INTERM_DEL_NOTIFICATION

#define ESM_CLASS_DELIVER_INTERM_DEL_NOTIFICATION   0x00000020

Definition at line 150 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_RPI

#define ESM_CLASS_DELIVER_RPI   0x00000080

Definition at line 152 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_SME_DELIVER_ACK

#define ESM_CLASS_DELIVER_SME_DELIVER_ACK   0x00000008

Definition at line 148 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_SME_MANULAL_ACK

#define ESM_CLASS_DELIVER_SME_MANULAL_ACK   0x00000010

Definition at line 149 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_SMSC_DELIVER_ACK

#define ESM_CLASS_DELIVER_SMSC_DELIVER_ACK   0x00000004

Definition at line 147 of file smpp_pdu.h.

Referenced by msg_to_pdu().

◆ ESM_CLASS_DELIVER_UDH_AND_RPI

#define ESM_CLASS_DELIVER_UDH_AND_RPI   0x000000C0

Definition at line 153 of file smpp_pdu.h.

◆ ESM_CLASS_DELIVER_UDH_INDICATOR

#define ESM_CLASS_DELIVER_UDH_INDICATOR   0x00000040

Definition at line 151 of file smpp_pdu.h.

Referenced by msg_to_pdu().

◆ ESM_CLASS_SUBMIT_DATAGRAM_MODE

#define ESM_CLASS_SUBMIT_DATAGRAM_MODE   0x00000001

Definition at line 137 of file smpp_pdu.h.

◆ ESM_CLASS_SUBMIT_DEFAULT_SMSC_MODE

#define ESM_CLASS_SUBMIT_DEFAULT_SMSC_MODE   0x00000000

Definition at line 136 of file smpp_pdu.h.

◆ ESM_CLASS_SUBMIT_DELIVERY_ACK

#define ESM_CLASS_SUBMIT_DELIVERY_ACK   0x00000008

Definition at line 140 of file smpp_pdu.h.

◆ ESM_CLASS_SUBMIT_FORWARD_MODE

#define ESM_CLASS_SUBMIT_FORWARD_MODE   0x00000002

Definition at line 138 of file smpp_pdu.h.

◆ ESM_CLASS_SUBMIT_RPI

#define ESM_CLASS_SUBMIT_RPI   0x00000080

Definition at line 143 of file smpp_pdu.h.

Referenced by data_sm_to_msg(), msg_to_pdu(), and pdu_to_msg().

◆ ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE

#define ESM_CLASS_SUBMIT_STORE_AND_FORWARD_MODE   0x00000003

Definition at line 139 of file smpp_pdu.h.

Referenced by smsc_smpp_create().

◆ ESM_CLASS_SUBMIT_UDH_AND_RPI

#define ESM_CLASS_SUBMIT_UDH_AND_RPI   0x000000C0

Definition at line 144 of file smpp_pdu.h.

◆ ESM_CLASS_SUBMIT_UDH_INDICATOR

#define ESM_CLASS_SUBMIT_UDH_INDICATOR   0x00000040

Definition at line 142 of file smpp_pdu.h.

Referenced by data_sm_to_msg(), handle_mo_dcs(), msg_to_pdu(), and pdu_to_msg().

◆ ESM_CLASS_SUBMIT_USER_ACK

#define ESM_CLASS_SUBMIT_USER_ACK   0x00000010

Definition at line 141 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_E164

#define GSM_ADDR_NPI_E164   0x00000001

Definition at line 123 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_ERMES

#define GSM_ADDR_NPI_ERMES   0x0000000A /* ETSI DE/PS 3 01-3 */

Definition at line 128 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_EXTENSION

#define GSM_ADDR_NPI_EXTENSION   0x0000000F /* Reserved */

Definition at line 130 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_INTERNET

#define GSM_ADDR_NPI_INTERNET   0x0000000E /* SMPP v5.0, sec. 4.7.2, page 113 */

Definition at line 129 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_NATIONAL

#define GSM_ADDR_NPI_NATIONAL   0x00000008

Definition at line 126 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_PRIVATE

#define GSM_ADDR_NPI_PRIVATE   0x00000009

Definition at line 127 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_TELEX

#define GSM_ADDR_NPI_TELEX   0x00000004

Definition at line 125 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_UNKNOWN

#define GSM_ADDR_NPI_UNKNOWN   0x00000000

Definition at line 122 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_WAP_CLIENT_ID

#define GSM_ADDR_NPI_WAP_CLIENT_ID   0x00000012 /* SMPP v5.0, sec. 4.7.2, page 113 */

Definition at line 131 of file smpp_pdu.h.

◆ GSM_ADDR_NPI_X121

#define GSM_ADDR_NPI_X121   0x00000003

Definition at line 124 of file smpp_pdu.h.

◆ GSM_ADDR_TON_ABBREVIATED

#define GSM_ADDR_TON_ABBREVIATED   0x00000006

Definition at line 119 of file smpp_pdu.h.

◆ GSM_ADDR_TON_ALPHANUMERIC

#define GSM_ADDR_TON_ALPHANUMERIC   0x00000005 /* GSM TS 03.38 */

Definition at line 118 of file smpp_pdu.h.

◆ GSM_ADDR_TON_EXTENSION

#define GSM_ADDR_TON_EXTENSION   0x00000007 /* Reserved */

Definition at line 120 of file smpp_pdu.h.

◆ GSM_ADDR_TON_INTERNATIONAL

#define GSM_ADDR_TON_INTERNATIONAL   0x00000001

Definition at line 114 of file smpp_pdu.h.

◆ GSM_ADDR_TON_NATIONAL

#define GSM_ADDR_TON_NATIONAL   0x00000002

Definition at line 115 of file smpp_pdu.h.

◆ GSM_ADDR_TON_NETWORKSPECIFIC

#define GSM_ADDR_TON_NETWORKSPECIFIC   0x00000003

Definition at line 116 of file smpp_pdu.h.

◆ GSM_ADDR_TON_SUBSCRIBER

#define GSM_ADDR_TON_SUBSCRIBER   0x00000004

Definition at line 117 of file smpp_pdu.h.

◆ GSM_ADDR_TON_UNKNOWN

#define GSM_ADDR_TON_UNKNOWN   0x00000000

Definition at line 113 of file smpp_pdu.h.

◆ INTEGER [1/2]

#define INTEGER (   name,
  octets 
)

Definition at line 99 of file smpp_pdu.h.

◆ INTEGER [2/2]

#define INTEGER (   name,
  octets 
)    unsigned long name;

Definition at line 99 of file smpp_pdu.h.

◆ NULTERMINATED [1/2]

#define NULTERMINATED (   name,
  max_octets 
)

Definition at line 100 of file smpp_pdu.h.

◆ NULTERMINATED [2/2]

#define NULTERMINATED (   name,
  max_octets 
)    Octstr *name;

Definition at line 100 of file smpp_pdu.h.

◆ OCTETS [1/2]

#define OCTETS (   name,
  field_giving_octets 
)

Definition at line 101 of file smpp_pdu.h.

◆ OCTETS [2/2]

#define OCTETS (   name,
  field_giving_octets 
)    Octstr *name;

Definition at line 101 of file smpp_pdu.h.

◆ OPTIONAL_BEGIN [1/2]

#define OPTIONAL_BEGIN

Definition at line 94 of file smpp_pdu.h.

◆ OPTIONAL_BEGIN [2/2]

#define OPTIONAL_BEGIN

Definition at line 94 of file smpp_pdu.h.

◆ OPTIONAL_END [1/2]

#define OPTIONAL_END

Definition at line 98 of file smpp_pdu.h.

◆ OPTIONAL_END [2/2]

#define OPTIONAL_END   Dict *tlv;

Definition at line 98 of file smpp_pdu.h.

◆ PDU [1/2]

#define PDU (   name,
  id,
  fields 
)    name = id,

Definition at line 102 of file smpp_pdu.h.

◆ PDU [2/2]

#define PDU (   name,
  id,
  fields 
)    struct name { fields } name;

Definition at line 102 of file smpp_pdu.h.

◆ TLV_INTEGER [1/2]

#define TLV_INTEGER (   name,
  max_len 
)

Definition at line 95 of file smpp_pdu.h.

◆ TLV_INTEGER [2/2]

#define TLV_INTEGER (   name,
  octets 
)    long name;

Definition at line 95 of file smpp_pdu.h.

◆ TLV_NULTERMINATED [1/2]

#define TLV_NULTERMINATED (   name,
  max_len 
)

Definition at line 96 of file smpp_pdu.h.

◆ TLV_NULTERMINATED [2/2]

#define TLV_NULTERMINATED (   name,
  max_len 
)    Octstr *name;

Definition at line 96 of file smpp_pdu.h.

◆ TLV_OCTETS [1/2]

#define TLV_OCTETS (   name,
  min_len,
  max_len 
)

Definition at line 97 of file smpp_pdu.h.

◆ TLV_OCTETS [2/2]

#define TLV_OCTETS (   name,
  min_len,
  max_len 
)    Octstr *name;

Definition at line 97 of file smpp_pdu.h.

Typedef Documentation

◆ SMPP_PDU

typedef struct SMPP_PDU SMPP_PDU

Definition at line 89 of file smpp_pdu.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
PDU 
PDU 

Definition at line 74 of file smpp_pdu.h.

74  {
75  #define OPTIONAL_BEGIN
76  #define TLV_INTEGER(name, max_len)
77  #define TLV_NULTERMINATED(name, max_len)
78  #define TLV_OCTETS(name, min_len, max_len)
79  #define OPTIONAL_END
80  #define INTEGER(name, octets)
81  #define NULTERMINATED(name, max_octets)
82  #define OCTETS(name, field_giving_octets)
83  #define PDU(name, id, fields) name = id,
84  #include "smpp_pdu.def"
85  SMPP_PDU_DUMMY_TYPE
86 };

◆ SMPP_ERROR_MESSAGES

Enumerator
SMPP_ESME_ROK 
SMPP_ESME_RINVMSGLEN 
SMPP_ESME_RINVCMDLEN 
SMPP_ESME_RINVCMDID 
SMPP_ESME_RINVBNDSTS 
SMPP_ESME_RALYBND 
SMPP_ESME_RINVPRTFLG 
SMPP_ESME_RINVREGDLVFLG 
SMPP_ESME_RSYSERR 
SMPP_ESME_RINVSRCADR 
SMPP_ESME_RINVDSTADR 
SMPP_ESME_RINVMSGID 
SMPP_ESME_RBINDFAIL 
SMPP_ESME_RINVPASWD 
SMPP_ESME_RINVSYSID 
SMPP_ESME_RCANCELFAIL 
SMPP_ESME_RREPLACEFAIL 
SMPP_ESME_RMSGQFUL 
SMPP_ESME_RINVSERTYP 
SMPP_ESME_RINVNUMDESTS 
SMPP_ESME_RINVDLNAME 
SMPP_ESME_RINVDESTFLAG 
SMPP_ESME_RINVSUBREP 
SMPP_ESME_RINVESMCLASS 
SMPP_ESME_RCNTSUBDL 
SMPP_ESME_RSUBMITFAIL 
SMPP_ESME_RINVSRCTON 
SMPP_ESME_RINVSRCNPI 
SMPP_ESME_RINVDSTTON 
SMPP_ESME_RINVDSTNPI 
SMPP_ESME_RINVSYSTYP 
SMPP_ESME_RINVREPFLAG 
SMPP_ESME_RINVNUMMSGS 
SMPP_ESME_RTHROTTLED 
SMPP_ESME_RINVSCHED 
SMPP_ESME_RINVEXPIRY 
SMPP_ESME_RINVDFTMSGID 
SMPP_ESME_RX_T_APPN 
SMPP_ESME_RX_P_APPN 
SMPP_ESME_RX_R_APPN 
SMPP_ESME_RQUERYFAIL 
SMPP_ESME_RINVTLVSTREAM 
SMPP_ESME_RTLVNOTALLWD 
SMPP_ESME_RINVTLVLEN 
SMPP_ESME_RMISSINGTLV 
SMPP_ESME_RINVTLVVAL 
SMPP_ESME_RDELIVERYFAILURE 
SMPP_ESME_RUNKNOWNERR 
SMPP_ESME_RSERTYPUNAUTH 
SMPP_ESME_RPROHIBITED 
SMPP_ESME_RSERTYPUNAVAIL 
SMPP_ESME_RSERTYPDENIED 
SMPP_ESME_RINVDCS 
SMPP_ESME_RINVSRCADDRSUBUNIT 
SMPP_ESME_RINVDSTADDRSUBUNIT 
SMPP_ESME_RINVBCASTFREQINT 
SMPP_ESME_RINVBCASTALIAS_NAME 
SMPP_ESME_RINVBCASTAREAFMT 
SMPP_ESME_RINVNUMBCAST_AREAS 
SMPP_ESME_RINVBCASTCNTTYPE 
SMPP_ESME_RINVBCASTMSGCLASS 
SMPP_ESME_RBCASTFAIL 
SMPP_ESME_RBCASTQUERYFAIL 
SMPP_ESME_RBCASTCANCELFAIL 
SMPP_ESME_RINVBCAST_REP 
SMPP_ESME_RINVBCASTSRVGRP 
SMPP_ESME_RINVBCASTCHANIND 

Definition at line 159 of file smpp_pdu.h.

159  {
160  SMPP_ESME_ROK = 0x00000000,
161  SMPP_ESME_RINVMSGLEN = 0x00000001,
162  SMPP_ESME_RINVCMDLEN = 0x00000002,
163  SMPP_ESME_RINVCMDID = 0x00000003,
164  SMPP_ESME_RINVBNDSTS = 0x00000004,
165  SMPP_ESME_RALYBND = 0x00000005,
166  SMPP_ESME_RINVPRTFLG = 0x00000006,
167  SMPP_ESME_RINVREGDLVFLG = 0x00000007,
168  SMPP_ESME_RSYSERR = 0x00000008,
169  SMPP_ESME_RINVSRCADR = 0x0000000A,
170  SMPP_ESME_RINVDSTADR = 0x0000000B,
171  SMPP_ESME_RINVMSGID = 0x0000000C,
172  SMPP_ESME_RBINDFAIL = 0x0000000D,
173  SMPP_ESME_RINVPASWD = 0x0000000E,
174  SMPP_ESME_RINVSYSID = 0x0000000F,
175  SMPP_ESME_RCANCELFAIL = 0x00000011,
176  SMPP_ESME_RREPLACEFAIL = 0x00000013,
177  SMPP_ESME_RMSGQFUL = 0x00000014,
178  SMPP_ESME_RINVSERTYP = 0x00000015,
179  SMPP_ESME_RINVNUMDESTS = 0x00000033,
180  SMPP_ESME_RINVDLNAME = 0x00000034,
181  SMPP_ESME_RINVDESTFLAG = 0x00000040,
182  SMPP_ESME_RINVSUBREP = 0x00000042,
183  SMPP_ESME_RINVESMCLASS = 0x00000043,
184  SMPP_ESME_RCNTSUBDL = 0x00000044,
185  SMPP_ESME_RSUBMITFAIL = 0x00000045,
186  SMPP_ESME_RINVSRCTON = 0x00000048,
187  SMPP_ESME_RINVSRCNPI = 0x00000049,
188  SMPP_ESME_RINVDSTTON = 0x00000050,
189  SMPP_ESME_RINVDSTNPI = 0x00000051,
190  SMPP_ESME_RINVSYSTYP = 0x00000053,
191  SMPP_ESME_RINVREPFLAG = 0x00000054,
192  SMPP_ESME_RINVNUMMSGS = 0x00000055,
193  SMPP_ESME_RTHROTTLED = 0x00000058,
194  SMPP_ESME_RINVSCHED = 0x00000061,
195  SMPP_ESME_RINVEXPIRY = 0x00000062,
196  SMPP_ESME_RINVDFTMSGID = 0x00000063,
197  SMPP_ESME_RX_T_APPN = 0x00000064,
198  SMPP_ESME_RX_P_APPN = 0x00000065,
199  SMPP_ESME_RX_R_APPN = 0x00000066,
200  SMPP_ESME_RQUERYFAIL = 0x00000067,
201  SMPP_ESME_RINVTLVSTREAM = 0x000000C0,
202  SMPP_ESME_RTLVNOTALLWD = 0x000000C1,
203  SMPP_ESME_RINVTLVLEN = 0x000000C2,
204  SMPP_ESME_RMISSINGTLV = 0x000000C3,
205  SMPP_ESME_RINVTLVVAL = 0x000000C4,
206  SMPP_ESME_RDELIVERYFAILURE = 0x000000FE,
207  SMPP_ESME_RUNKNOWNERR = 0x000000FF,
208  SMPP_ESME_RSERTYPUNAUTH = 0x00000100,
209  SMPP_ESME_RPROHIBITED = 0x00000101,
210  SMPP_ESME_RSERTYPUNAVAIL = 0x00000102,
211  SMPP_ESME_RSERTYPDENIED = 0x00000103,
212  SMPP_ESME_RINVDCS = 0x00000104,
213  SMPP_ESME_RINVSRCADDRSUBUNIT = 0x00000105,
214  SMPP_ESME_RINVDSTADDRSUBUNIT = 0x00000106,
215  SMPP_ESME_RINVBCASTFREQINT = 0x00000107,
216  SMPP_ESME_RINVBCASTALIAS_NAME = 0x00000108,
217  SMPP_ESME_RINVBCASTAREAFMT = 0x00000109,
218  SMPP_ESME_RINVNUMBCAST_AREAS = 0x0000010A,
219  SMPP_ESME_RINVBCASTCNTTYPE = 0x0000010B,
220  SMPP_ESME_RINVBCASTMSGCLASS = 0x0000010C,
221  SMPP_ESME_RBCASTFAIL = 0x0000010D,
222  SMPP_ESME_RBCASTQUERYFAIL = 0x0000010E,
223  SMPP_ESME_RBCASTCANCELFAIL = 0x0000010F,
224  SMPP_ESME_RINVBCAST_REP = 0x00000110,
225  SMPP_ESME_RINVBCASTSRVGRP = 0x00000111,
226  SMPP_ESME_RINVBCASTCHANIND = 0x00000112,
227 };

Function Documentation

◆ smpp_error_to_string()

const char* smpp_error_to_string ( enum SMPP_ERROR_MESSAGES  error)

Definition at line 911 of file smpp_pdu.c.

References SMPP_ESME_RALYBND, SMPP_ESME_RBCASTCANCELFAIL, SMPP_ESME_RBCASTFAIL, SMPP_ESME_RBCASTQUERYFAIL, SMPP_ESME_RBINDFAIL, SMPP_ESME_RCANCELFAIL, SMPP_ESME_RCNTSUBDL, SMPP_ESME_RDELIVERYFAILURE, SMPP_ESME_RINVBCAST_REP, SMPP_ESME_RINVBCASTALIAS_NAME, SMPP_ESME_RINVBCASTAREAFMT, SMPP_ESME_RINVBCASTCHANIND, SMPP_ESME_RINVBCASTCNTTYPE, SMPP_ESME_RINVBCASTFREQINT, SMPP_ESME_RINVBCASTMSGCLASS, SMPP_ESME_RINVBCASTSRVGRP, SMPP_ESME_RINVBNDSTS, SMPP_ESME_RINVCMDID, SMPP_ESME_RINVCMDLEN, SMPP_ESME_RINVDCS, SMPP_ESME_RINVDESTFLAG, SMPP_ESME_RINVDFTMSGID, SMPP_ESME_RINVDLNAME, SMPP_ESME_RINVDSTADDRSUBUNIT, SMPP_ESME_RINVDSTADR, SMPP_ESME_RINVDSTNPI, SMPP_ESME_RINVDSTTON, SMPP_ESME_RINVESMCLASS, SMPP_ESME_RINVEXPIRY, SMPP_ESME_RINVMSGLEN, SMPP_ESME_RINVNUMBCAST_AREAS, SMPP_ESME_RINVNUMDESTS, SMPP_ESME_RINVNUMMSGS, SMPP_ESME_RINVPASWD, SMPP_ESME_RINVPRTFLG, SMPP_ESME_RINVREGDLVFLG, SMPP_ESME_RINVREPFLAG, SMPP_ESME_RINVSCHED, SMPP_ESME_RINVSERTYP, SMPP_ESME_RINVSRCADDRSUBUNIT, SMPP_ESME_RINVSRCADR, SMPP_ESME_RINVSRCNPI, SMPP_ESME_RINVSRCTON, SMPP_ESME_RINVSUBREP, SMPP_ESME_RINVSYSID, SMPP_ESME_RINVSYSTYP, SMPP_ESME_RINVTLVLEN, SMPP_ESME_RINVTLVSTREAM, SMPP_ESME_RINVTLVVAL, SMPP_ESME_RMISSINGTLV, SMPP_ESME_RMSGQFUL, SMPP_ESME_ROK, SMPP_ESME_RPROHIBITED, SMPP_ESME_RQUERYFAIL, SMPP_ESME_RREPLACEFAIL, SMPP_ESME_RSERTYPDENIED, SMPP_ESME_RSERTYPUNAUTH, SMPP_ESME_RSERTYPUNAVAIL, SMPP_ESME_RSUBMITFAIL, SMPP_ESME_RSYSERR, SMPP_ESME_RTHROTTLED, SMPP_ESME_RTLVNOTALLWD, SMPP_ESME_RUNKNOWNERR, SMPP_ESME_RX_P_APPN, SMPP_ESME_RX_R_APPN, and SMPP_ESME_RX_T_APPN.

Referenced by handle_pdu().

912 {
913  switch (error) {
914  case SMPP_ESME_ROK:
915  return "OK";
917  return "Message Length is invalid";
919  return "Command Length is invalid";
920  case SMPP_ESME_RINVCMDID:
921  return "Invalid Command ID";
923  return "Incorrect BIND Status for given command";
924  case SMPP_ESME_RALYBND:
925  return "ESME Already in Bound State";
927  return "Invalid Priority Flag";
929  return "Invalid Registered Delivery Flag";
930  case SMPP_ESME_RSYSERR:
931  return "System Error";
933  return "Invalid Source Address";
935  return "Invalid Destination Address";
936  case SMPP_ESME_RBINDFAIL:
937  return "Bind Failed";
938  case SMPP_ESME_RINVPASWD:
939  return "Invalid Password";
940  case SMPP_ESME_RINVSYSID:
941  return "Invalid System ID";
943  return "Cancel SM Failed";
945  return "Replace SM Failed";
946  case SMPP_ESME_RMSGQFUL:
947  return "Message Queue Full";
949  return "Invalid Service Type";
951  return "Invalid number of destinations";
953  return "Invalid Distribution List Name";
955  return "Destination flag is invalid";
957  return "Submit w/replace not supported/allowed";
959  return "Invalid esm_class field data";
960  case SMPP_ESME_RCNTSUBDL:
961  return "Cannot Submit to Distribution List";
963  return "Submit failed";
965  return "Invalid Source address TON";
967  return "Invalid Source address NPI";
969  return "Invalid Destination address TON";
971  return "Invalid Destination address NPI";
973  return "Invalid system_type field";
975  return "Invalid replace_if_present flag";
977  return "Invalid number of messages";
979  return "Throttling error";
980  case SMPP_ESME_RINVSCHED:
981  return "Invalid Scheduled Delivery Time";
983  return "Invalid message validity period";
985  return "Predefined Message ID is Invalid or specific predefined message was not found";
986  case SMPP_ESME_RX_T_APPN:
987  return "ESME Receiver Temporary App Error Code";
988  case SMPP_ESME_RX_P_APPN:
989  return "ESME Receiver Permanent App Error Code";
990  case SMPP_ESME_RX_R_APPN:
991  return "ESME Receiver Reject Message Error Code";
993  return "query_sm request failed";
995  return "Error in optional part of the PDU Body";
997  return "TLV not allowed";
999  return "Invalid Parameter Length";
1000  case SMPP_ESME_RMISSINGTLV:
1001  return "Expected TLV missing";
1002  case SMPP_ESME_RINVTLVVAL:
1003  return "Invalid TLV value";
1005  return "Transaction Delivery Failure";
1006  case SMPP_ESME_RUNKNOWNERR:
1007  return "Unknown Error";
1009  return "ESME Not authorized to use specified service_type";
1010  case SMPP_ESME_RPROHIBITED:
1011  return "ESME Prohibited from using specified operation";
1013  return "Specified service_type is unavailable";
1015  return "Specified service_type is denied";
1016  case SMPP_ESME_RINVDCS:
1017  return "Invalid Data Coding Scheme";
1019  return "Source Address Sub unit is invalid";
1021  return "Destination Address Sub unit is invalid";
1023  return "Broadcast Frequency Interval is invalid";
1025  return "Broadcast Alias Name is invalid";
1027  return "Broadcast Area Format is invalid";
1029  return "Number of Broadcast Areas is invalid";
1031  return "Broadcast Content Type is invalid";
1033  return "Broadcast Message Class is invalid";
1034  case SMPP_ESME_RBCASTFAIL:
1035  return "broadcast_sm operation failed";
1037  return "broadcast_query_sm operation failed";
1039  return "broadcast_cancel_sm operation failed";
1041  return "Number of Repeated Broadcasts is invalid";
1043  return "Broadcast Service Group is invalid";
1045  return "Broadcast Channel Indicator is invalid";
1046 
1047  default:
1048  /* tell the user that we have a vendor-specific beast here */
1049  if (error >= 0x0400 && error <= 0x04FF)
1050  return "Vendor-specific error, please refer to your SMPP provider";
1051  else
1052  return "Unknown/Reserved";
1053  }
1054 }
void error(int err, const char *fmt,...)
Definition: log.c:648

◆ smpp_pdu_create()

SMPP_PDU* smpp_pdu_create ( unsigned long  type,
unsigned long  seq_no 
)

Definition at line 400 of file smpp_pdu.c.

References error(), smpp_tlv::type, and SMPP_PDU::type.

Referenced by handle_bind_receiver(), handle_bind_transmitter(), handle_enquire_link(), handle_pdu(), handle_submit_sm(), handle_unbind(), msg_to_pdu(), open_receiver(), open_transceiver(), open_transmitter(), send_enquire_link(), send_gnack(), send_smpp_thread(), send_unbind(), smpp_emu_handle_pdu(), smpp_emu_writer(), smpp_pdu_unpack(), and smsc_emu_submit_ack().

401 {
402  SMPP_PDU *pdu;
403 
404  pdu = gw_malloc(sizeof(*pdu));
405  pdu->type = type;
406 
407  switch (type) {
408  #define OPTIONAL_BEGIN
409  #define TLV_INTEGER(name, octets) p->name = -1;
410  #define TLV_NULTERMINATED(name, max_len) p->name = NULL;
411  #define TLV_OCTETS(name, min_len, max_len) p->name = NULL;
412  #define OPTIONAL_END p->tlv = dict_create(1024, octstr_destroy_item);
413  #define INTEGER(name, octets) p->name = 0;
414  #define NULTERMINATED(name, max_octets) p->name = NULL;
415  #define OCTETS(name, field_giving_octetst) p->name = NULL;
416  #define PDU(name, id, fields) \
417  case id: { \
418  struct name *p = &pdu->u.name; \
419  pdu->type_name = #name; \
420  fields \
421  p->command_id = type; \
422  p->sequence_number = seq_no; \
423  } break;
424  #include "smpp_pdu.def"
425  default:
426  error(0, "Unknown SMPP_PDU type, internal error.");
427  gw_free(pdu);
428  return NULL;
429  }
430 
431  return pdu;
432 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int type
Definition: smsc_cimd2.c:215
unsigned long type
Definition: smpp_pdu.h:91

◆ smpp_pdu_destroy()

void smpp_pdu_destroy ( SMPP_PDU pdu)

Definition at line 434 of file smpp_pdu.c.

References error(), and SMPP_PDU::type.

Referenced by bearerbox_to_smpp(), handle_pdu(), io_thread(), msg_to_pdu(), open_receiver(), open_transceiver(), open_transmitter(), receive_smpp_thread(), send_enquire_link(), send_gnack(), send_messages(), send_smpp_thread(), send_unbind(), smpp_emu_handle_pdu(), smpp_emu_reader(), smpp_emu_writer(), smpp_pdu_destroy_item(), smpp_pdu_unpack(), and smsc_emu_submit_ack().

435 {
436  if (pdu == NULL)
437  return;
438 
439  switch (pdu->type) {
440  #define OPTIONAL_BEGIN
441  #define TLV_INTEGER(name, octets) p->name = -1;
442  #define TLV_NULTERMINATED(name, max_octets) octstr_destroy(p->name);
443  #define TLV_OCTETS(name, min_len, max_len) octstr_destroy(p->name);
444  #define OPTIONAL_END dict_destroy(p->tlv);
445  #define INTEGER(name, octets) p->name = 0; /* Make sure "p" is used */
446  #define NULTERMINATED(name, max_octets) octstr_destroy(p->name);
447  #define OCTETS(name, field_giving_octets) octstr_destroy(p->name);
448  #define PDU(name, id, fields) \
449  case id: { struct name *p = &pdu->u.name; fields } break;
450  #include "smpp_pdu.def"
451  default:
452  error(0, "Unknown SMPP_PDU type, internal error while destroying.");
453  }
454  gw_free(pdu);
455 }
void error(int err, const char *fmt,...)
Definition: log.c:648
unsigned long type
Definition: smpp_pdu.h:91

◆ smpp_pdu_dump()

void smpp_pdu_dump ( Octstr smsc_id,
SMPP_PDU pdu 
)

Definition at line 766 of file smpp_pdu.c.

References debug(), and error().

Referenced by handle_pdu().

767 {
768  debug("sms.smpp", 0, "SMPP PDU %p dump:", (void *) pdu);
769  debug("sms.smpp", 0, " type_name: %s", pdu->type_name);
770  switch (pdu->type) {
771  #define OPTIONAL_BEGIN
772  #define TLV_INTEGER(name, max_len) \
773  if (p->name != -1) { \
774  INTEGER(name, max_len) \
775  }
776  #define TLV_NULTERMINATED(name, max_len) \
777  if (p->name != NULL) { \
778  NULTERMINATED(name, max_len) \
779  }
780  #define TLV_OCTETS(name, min_len, max_len) \
781  if (p->name != NULL) { \
782  OCTETS(name, max_len) \
783  }
784  #define OPTIONAL_END \
785  if (p->tlv != NULL) { \
786  List *keys; \
787  Octstr *key; \
788  struct smpp_tlv *tlv; \
789  keys = dict_keys(p->tlv); \
790  while(keys != NULL && (key = gwlist_extract_first(keys)) != NULL) { \
791  tlv = smpp_tlv_get_by_name(smsc_id, key); \
792  if (tlv != NULL) { \
793  octstr_dump_short(dict_get(p->tlv, key), 2, octstr_get_cstr(key)); \
794  } \
795  octstr_destroy(key); \
796  } \
797  gwlist_destroy(keys, octstr_destroy_item); \
798  }
799  #define INTEGER(name, octets) \
800  debug("sms.smpp", 0, " %s: %lu = 0x%08lx", #name, p->name, p->name);
801  #define NULTERMINATED(name, max_octets) \
802  octstr_dump_short(p->name, 2, #name);
803  #define OCTETS(name, field_giving_octets) \
804  octstr_dump_short(p->name, 2, #name);
805  #define PDU(name, id, fields) \
806  case id: { struct name *p = &pdu->u.name; fields } break;
807  #include "smpp_pdu.def"
808  default:
809  error(0, "Unknown SMPP_PDU type, internal error.");
810  break;
811  }
812  debug("sms.smpp", 0, "SMPP PDU dump ends.");
813 }
void error(int err, const char *fmt,...)
Definition: log.c:648
const char * type_name
Definition: smpp_pdu.h:92
unsigned long type
Definition: smpp_pdu.h:91
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726

◆ smpp_pdu_dump_line()

void smpp_pdu_dump_line ( Octstr smsc_id,
SMPP_PDU pdu 
)

Definition at line 816 of file smpp_pdu.c.

References debug(), error(), octstr_create, octstr_destroy(), octstr_format_append(), octstr_get_cstr, and SMPP_PDU::type_name.

817 {
818  Octstr *str = octstr_create("");
819 
820  octstr_format_append(str, "SMPP PDU %p dump: [type_name:%d:%s]", (void *) pdu, strlen(pdu->type_name), pdu->type_name);
821  switch (pdu->type) {
822  #define OPTIONAL_BEGIN
823  #define TLV_INTEGER(name, max_len) \
824  if (p->name != -1) { \
825  INTEGER(name, max_len) \
826  }
827  #define TLV_NULTERMINATED(name, max_len) \
828  if (p->name != NULL) { \
829  NULTERMINATED(name, max_len) \
830  }
831  #define TLV_OCTETS(name, min_len, max_len) \
832  if (p->name != NULL) { \
833  OCTETS(name, max_len) \
834  }
835  #define OPTIONAL_END \
836  if (p->tlv != NULL) { \
837  List *keys; \
838  Octstr *key; \
839  struct smpp_tlv *tlv; \
840  keys = dict_keys(p->tlv); \
841  while(keys != NULL && (key = gwlist_extract_first(keys)) != NULL) { \
842  tlv = smpp_tlv_get_by_name(smsc_id, key); \
843  if (tlv != NULL) { \
844  Octstr *val = dict_get(p->tlv, key); \
845  octstr_format_append(str, " [%E:%d:%E]", key, octstr_len(val), val); \
846  } \
847  octstr_destroy(key); \
848  } \
849  gwlist_destroy(keys, octstr_destroy_item); \
850  }
851  #define INTEGER(name, octets) \
852  octstr_format_append(str, " [%s:0:0x%08lx]", #name, p->name);
853  #define NULTERMINATED(name, max_octets) \
854  octstr_format_append(str, " [%s:%d:%E]", #name, octstr_len(p->name), (p->name != NULL ? p->name : octstr_imm("NULL")));
855  #define OCTETS(name, field_giving_octets) \
856  octstr_format_append(str, " [%s:%d:%E]", #name, octstr_len(p->name), (p->name != NULL ? p->name : octstr_imm("NULL")));
857  #define PDU(name, id, fields) \
858  case id: { struct name *p = &pdu->u.name; fields } break;
859  #include "smpp_pdu.def"
860  default:
861  error(0, "Unknown SMPP_PDU type, internal error.");
862  break;
863  }
864  debug("sms.smpp", 0, "%s", octstr_get_cstr(str));
865  octstr_destroy(str);
866 }
void error(int err, const char *fmt,...)
Definition: log.c:648
const char * type_name
Definition: smpp_pdu.h:92
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2505

◆ smpp_pdu_init()

int smpp_pdu_init ( Cfg cfg)

Definition at line 184 of file smpp_pdu.c.

References cfg_get, cfg_get_integer(), cfg_get_multi_group(), smpp_tlv::constant, debug(), DEFAULT_SMSC_ID, dict_create(), dict_destroy(), dict_get(), dict_put(), dict_put_once(), error(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_produce(), initialized, smpp_tlv::length, smpp_tlv::name, octstr_create, octstr_destroy(), octstr_destroy_item(), octstr_format(), octstr_get_cstr, octstr_imm(), octstr_split(), octstr_str_case_compare(), smpp_tlv_destroy(), smpp_tlv::SMPP_TLV_INTEGER, smpp_tlv::SMPP_TLV_NULTERMINATED, smpp_tlv::SMPP_TLV_OCTETS, smsc_id, smpp_tlv::tag, and smpp_tlv::type.

Referenced by init_smppbox(), main(), and smsc2_start().

185 {
186  CfgGroup *grp;
187  List *l;
188 
189  if (initialized)
190  return 0;
191 
192  l = cfg_get_multi_group(cfg, octstr_imm("smpp-tlv"));
193  tlvs = gwlist_create();
194  tlvs_by_tag = dict_create(1024, (void(*)(void*))dict_destroy);
195  tlvs_by_name = dict_create(1024, (void(*)(void*))dict_destroy);
196  tlvs_by_const = dict_create(1024, (void(*)(void*))dict_destroy);
197  while (l != NULL && (grp = gwlist_extract_first(l)) != NULL) {
198  struct smpp_tlv *tlv;
199  Octstr *tmp, *smsc_id;
200  List *l2;
201 
202  tlv = gw_malloc(sizeof(*tlv));
203  if ((tlv->name = cfg_get(grp, octstr_imm("name"))) == NULL) {
204  error(0, "SMPP: Unable to get name for smpp-tlv.");
205  smpp_tlv_destroy(tlv);
206  goto failed;
207  }
208  tlv->constant = cfg_get(grp, octstr_imm("const"));
209  if (cfg_get_integer(&tlv->tag, grp, octstr_imm("tag")) == -1) {
210  error(0, "SMPP: Unable to get tag for smpp-tlv.");
211  smpp_tlv_destroy(tlv);
212  goto failed;
213  }
214  if (cfg_get_integer(&tlv->length, grp, octstr_imm("length")) == -1) {
215  error(0, "SMPP: Unable to get length for smpp-tlv.");
216  smpp_tlv_destroy(tlv);
217  goto failed;
218  }
219  if ((tmp = cfg_get(grp, octstr_imm("type"))) == NULL) {
220  error(0, "SMPP: Unable to get type for smpp-tlv.");
221  smpp_tlv_destroy(tlv);
222  goto failed;
223  }
224  if (octstr_str_case_compare(tmp, "octetstring") == 0)
225  tlv->type = SMPP_TLV_OCTETS;
226  else if (octstr_str_case_compare(tmp, "nulterminated") == 0)
228  else if (octstr_str_case_compare(tmp, "integer") == 0)
229  tlv->type = SMPP_TLV_INTEGER;
230  else {
231  error(0, "SMPP: Unknown type for smpp-tlv: `%s'", octstr_get_cstr(tmp));
232  octstr_destroy(tmp);
233  smpp_tlv_destroy(tlv);
234  goto failed;
235  }
236  octstr_destroy(tmp);
237 
238  /* put to all TLVs */
239  gwlist_produce(tlvs, tlv);
240 
241  smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
242  if (smsc_id != NULL) {
243  l2 = octstr_split(smsc_id, octstr_imm(";"));
244  octstr_destroy(smsc_id);
245  } else {
246  l2 = gwlist_create();
248  }
249  while(l2 != NULL && (smsc_id = gwlist_extract_first(l2)) != NULL) {
250  Dict *tmp_dict;
251 
252  debug("sms.smpp", 0, "adding smpp-tlv for smsc-id=%s", octstr_get_cstr(smsc_id));
253 
254  /* name */
255  tmp_dict = dict_get(tlvs_by_name, smsc_id);
256  if (tmp_dict == NULL) {
257  tmp_dict = dict_create(1024, NULL);
258  dict_put(tlvs_by_name, smsc_id, tmp_dict);
259  }
260  /* put into dict */
261  if (!dict_put_once(tmp_dict, tlv->name, tlv)) {
262  error(0, "SMPP: Double TLV name %s found.", octstr_get_cstr(tlv->name));
263  octstr_destroy(smsc_id);
264  goto failed;
265  }
266 
267  /* tag */
268  tmp_dict = dict_get(tlvs_by_tag, smsc_id);
269  if (tmp_dict == NULL) {
270  tmp_dict = dict_create(1024, NULL);
271  dict_put(tlvs_by_tag, smsc_id, tmp_dict);
272  }
273  tmp = octstr_format("%ld", tlv->tag);
274  if (!dict_put_once(tmp_dict, tmp, tlv)) {
275  error(0, "SMPP: Double TLV tag %s found.", octstr_get_cstr(tmp));
277  octstr_destroy(tmp);
278  octstr_destroy(smsc_id);
279  goto failed;
280  }
281 
282  /* const */
283  if (tlv->constant != NULL) {
284  tmp_dict = dict_get(tlvs_by_const, smsc_id);
285  if (tmp_dict == NULL) {
286  tmp_dict = dict_create(1024, NULL);
287  dict_put(tlvs_by_const, smsc_id, tmp_dict);
288  }
289  if (!dict_put_once(tmp_dict, tlv->name, tlv)) {
290  error(0, "SMPP: Double TLV name %s found.", octstr_get_cstr(tlv->name));
291  octstr_destroy(smsc_id);
292  goto failed;
293  }
294  }
295 
296  octstr_destroy(tmp);
297  octstr_destroy(smsc_id);
298  }
300  }
301  gwlist_destroy(l, NULL);
302 
303  initialized = 1;
304  return 0;
305 
306 failed:
307  gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy);
310  return -1;
311 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * constant
Definition: smpp_pdu.c:79
int octstr_str_case_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:984
static int initialized
Definition: smpp_pdu.c:89
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
enum smpp_tlv::@13 type
void gwlist_produce(List *list, void *item)
Definition: list.c:411
#define cfg_get(grp, varname)
Definition: cfg.h:86
static Dict * tlvs_by_name
Definition: smpp_pdu.c:86
static void smpp_tlv_destroy(struct smpp_tlv *tlv)
Definition: smpp_pdu.c:92
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Dict * tlvs_by_tag
Definition: smpp_pdu.c:84
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:281
void * gwlist_extract_first(List *list)
Definition: list.c:305
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
long tag
Definition: smpp_pdu.c:77
Definition: dict.c:116
static Octstr * smsc_id
Definition: mtbatch.c:98
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:642
#define DEFAULT_SMSC_ID
Definition: smpp_pdu.c:73
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2462
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:334
void dict_destroy(Dict *dict)
Definition: dict.c:215
long length
Definition: smpp_pdu.c:78
Definition: octstr.c:118
static Dict * tlvs_by_const
Definition: smpp_pdu.c:87
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:739
Definition: cfg.c:73
#define gwlist_create()
Definition: list.h:136
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
Octstr * name
Definition: smpp_pdu.c:76
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1638
Definition: list.c:102
static List * tlvs
Definition: smpp_pdu.c:88
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ smpp_pdu_is_valid()

int smpp_pdu_is_valid ( SMPP_PDU pdu)

◆ smpp_pdu_pack()

Octstr* smpp_pdu_pack ( Octstr smsc_id,
SMPP_PDU pdu 
)

Definition at line 458 of file smpp_pdu.c.

References append_encoded_integer(), error(), gw_assert(), octstr_create, octstr_destroy(), octstr_insert(), octstr_len(), and SMPP_PDU::type.

Referenced by handle_pdu(), send_enquire_link(), send_gnack(), send_pdu(), send_smpp_thread(), send_unbind(), smpp_emu_handle_pdu(), smpp_emu_writer(), and smsc_emu_submit_ack().

459 {
460  Octstr *os;
461  Octstr *temp;
462 
463  os = octstr_create("");
464 
465  gw_assert(pdu != NULL);
466 
467  /*
468  * Fix lengths of octet string fields.
469  */
470  switch (pdu->type) {
471  #define OPTIONAL_BEGIN
472  #define TLV_INTEGER(name, octets)
473  #define TLV_NULTERMINATED(name, max_len)
474  #define TLV_OCTETS(name, min_len, max_len)
475  #define OPTIONAL_END
476  #define INTEGER(name, octets) p = *(&p);
477  #define NULTERMINATED(name, max_octets) p = *(&p);
478  #define OCTETS(name, field_giving_octets) \
479  p->field_giving_octets = octstr_len(p->name);
480  #define PDU(name, id, fields) \
481  case id: { struct name *p = &pdu->u.name; fields } break;
482  #include "smpp_pdu.def"
483  default:
484  error(0, "Unknown SMPP_PDU type, internal error while packing.");
485  }
486 
487  switch (pdu->type) {
488  #define TL(name, octets) \
489  append_encoded_integer(os, SMPP_##name, 2); \
490  append_encoded_integer(os, octets, 2);
491  #define OPTIONAL_BEGIN
492  #define TLV_INTEGER(name, octets) \
493  if (p->name >= 0) { \
494  TL(name, octets); \
495  INTEGER(name, octets) \
496  }
497  #define TLV_NULTERMINATED(name, max_len) \
498  if (p->name != NULL) { \
499  TL(name, (octstr_len(p->name) > max_len ? max_len : octstr_len(p->name) + 1)); \
500  NULTERMINATED(name, max_len) \
501  }
502  #define TLV_OCTETS(name, min_len, max_len) \
503  if (p->name != NULL) { \
504  unsigned long len = octstr_len(p->name); \
505  if (len > max_len || len < min_len) { \
506  error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
507  #name, len, min_len, max_len);\
508  } else { \
509  TL(name, len); \
510  octstr_append(os, p->name); \
511  } \
512  }
513  #define OPTIONAL_END \
514  if (p->tlv != NULL) { \
515  Octstr *key; \
516  List *keys; \
517  struct smpp_tlv *tlv; \
518  keys = dict_keys(p->tlv); \
519  while(keys != NULL && (key = gwlist_extract_first(keys)) != NULL) { \
520  tlv = smpp_tlv_get_by_name(smsc_id, key); \
521  if (tlv == NULL) { \
522  if (!is_defined_field(pdu->type, octstr_get_cstr(key))) \
523  error(0, "SMPP: Unknown TLV `%s', don't send.", octstr_get_cstr(key)); \
524  octstr_destroy(key); \
525  continue; \
526  } \
527  switch(tlv->type) { \
528  case SMPP_TLV_INTEGER: { \
529  long val = atol(octstr_get_cstr(dict_get(p->tlv, key))); \
530  append_encoded_integer(os, tlv->tag, 2); \
531  append_encoded_integer(os, tlv->length, 2); \
532  append_encoded_integer(os, val, tlv->length); \
533  break; \
534  } \
535  case SMPP_TLV_OCTETS: \
536  case SMPP_TLV_NULTERMINATED: { \
537  Octstr *val = dict_get(p->tlv, key); \
538  unsigned long len = octstr_len(val); \
539  if (len > tlv->length) { \
540  error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %ld) dropped.", \
541  octstr_get_cstr(key), len, tlv->length);\
542  octstr_destroy(key); \
543  continue; \
544  } \
545  append_encoded_integer(os, tlv->tag, 2); \
546  if (tlv->type == SMPP_TLV_NULTERMINATED) \
547  append_encoded_integer(os, len + 1, 2); \
548  else \
549  append_encoded_integer(os, len, 2); \
550  octstr_append(os, val); \
551  if (tlv->type == SMPP_TLV_NULTERMINATED) \
552  octstr_append_char(os, '\0'); \
553  break; \
554  } \
555  default: \
556  panic(0, "SMPP: Internal error, unknown configured TLV type %d.", tlv->type); \
557  break; \
558  } \
559  octstr_destroy(key); \
560  } \
561  gwlist_destroy(keys, octstr_destroy_item); \
562  }
563  #define INTEGER(name, octets) \
564  append_encoded_integer(os, p->name, octets);
565  #define NULTERMINATED(name, max_octets) \
566  if (p->name != NULL) { \
567  if (octstr_len(p->name) >= max_octets) { \
568  warning(0, "SMPP: PDU element <%s> too long " \
569  "(length is %ld, should be %d)", \
570  #name, octstr_len(p->name), max_octets-1); \
571  temp = octstr_copy(p->name, 0, max_octets-1); \
572  } else \
573  temp = octstr_duplicate(p->name); \
574  octstr_append(os, temp); \
575  octstr_destroy(temp); \
576  } \
577  octstr_append_char(os, '\0');
578  #define OCTETS(name, field_giving_octets) \
579  if (p->name) octstr_append(os, p->name);
580  #define PDU(name, id, fields) \
581  case id: { struct name *p = &pdu->u.name; fields } break;
582  #include "smpp_pdu.def"
583  default:
584  error(0, "Unknown SMPP_PDU type 0x%08lx, internal error while packing.", pdu->type);
585  break;
586  }
587 
588  temp = octstr_create("");
589  append_encoded_integer(temp, octstr_len(os) + 4, 4);
590  octstr_insert(os, temp, 0);
591  octstr_destroy(temp);
592 
593  return os;
594 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
unsigned long type
Definition: smpp_pdu.h:91
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static void append_encoded_integer(Octstr *os, unsigned long u, long octets)
Definition: smpp_pdu.c:346

◆ smpp_pdu_read_data()

Octstr* smpp_pdu_read_data ( Connection conn,
long  len 
)

Definition at line 895 of file smpp_pdu.c.

References conn_read_fixed().

Referenced by read_pdu(), receive_smpp_thread(), and smpp_emu_reader().

896 {
897  Octstr *os;
898 
899  os = conn_read_fixed(conn, len - 4); /* `len' includes itself. */
900  return os;
901 }
Definition: octstr.c:118
Octstr * conn_read_fixed(Connection *conn, long length)
Definition: conn.c:1104

◆ smpp_pdu_read_len()

long smpp_pdu_read_len ( Connection conn)

Definition at line 869 of file smpp_pdu.c.

References conn_read_fixed(), decode_network_long(), error(), MAX_SMPP_PDU_LEN, MIN_SMPP_PDU_LEN, octstr_destroy(), and octstr_get_many_chars().

Referenced by read_pdu(), receive_smpp_thread(), and smpp_emu_reader().

870 {
871  Octstr *os;
872  unsigned char buf[4]; /* The length is 4 octets. */
873  long len;
874 
875  os = conn_read_fixed(conn, sizeof(buf));
876  if (os == NULL)
877  return 0;
878  octstr_get_many_chars((char*) buf, os, 0, sizeof(buf));
879  octstr_destroy(os);
880  len = decode_network_long(buf);
881  if (len < MIN_SMPP_PDU_LEN) {
882  error(0, "SMPP: PDU length was too small (%ld, minimum is %ld).",
883  len, (long) MIN_SMPP_PDU_LEN);
884  return -1;
885  }
886  if (len > MAX_SMPP_PDU_LEN) {
887  error(0, "SMPP: PDU length was too large (%ld, maximum is %ld).",
888  len, (long) MAX_SMPP_PDU_LEN);
889  return -1;
890  }
891  return len;
892 }
void error(int err, const char *fmt,...)
Definition: log.c:648
#define MAX_SMPP_PDU_LEN
Definition: smpp_pdu.c:71
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long decode_network_long(unsigned char *data)
Definition: utils.c:935
Definition: octstr.c:118
Octstr * conn_read_fixed(Connection *conn, long length)
Definition: conn.c:1104
#define MIN_SMPP_PDU_LEN
Definition: smpp_pdu.c:69
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
Definition: octstr.c:423

◆ smpp_pdu_shutdown()

int smpp_pdu_shutdown ( void  )

Definition at line 314 of file smpp_pdu.c.

References dict_destroy(), gwlist_destroy(), initialized, and smpp_tlv_destroy().

Referenced by smsc2_shutdown().

315 {
316  if (initialized == 0)
317  return 0;
318 
319  initialized = 0;
320  gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy);
321  tlvs = NULL;
324  tlvs_by_tag = tlvs_by_name = NULL;
325 
326  return 0;
327 }
static int initialized
Definition: smpp_pdu.c:89
static Dict * tlvs_by_name
Definition: smpp_pdu.c:86
static void smpp_tlv_destroy(struct smpp_tlv *tlv)
Definition: smpp_pdu.c:92
static Dict * tlvs_by_tag
Definition: smpp_pdu.c:84
void dict_destroy(Dict *dict)
Definition: dict.c:215
static List * tlvs
Definition: smpp_pdu.c:88
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ smpp_pdu_unpack()

SMPP_PDU* smpp_pdu_unpack ( Octstr smsc_id,
Octstr data_without_len 
)

Definition at line 597 of file smpp_pdu.c.

References decode_integer(), error(), octstr_dump, octstr_len(), smpp_pdu_create(), smpp_pdu_destroy(), and smpp_tlv::type.

Referenced by read_pdu(), receive_smpp_thread(), and smpp_emu_reader().

598 {
599  SMPP_PDU *pdu;
600  unsigned long type;
601  long len, pos;
602 
603  len = octstr_len(data_without_len);
604 
605  if (len < 4) {
606  error(0, "SMPP: PDU was too short (%ld bytes).",
607  octstr_len(data_without_len));
608  return NULL;
609  }
610 
611  /* get the PDU type */
612  if ((type = decode_integer(data_without_len, 0, 4)) == -1)
613  return NULL;
614 
615  /* create a coresponding representation structure */
616  pdu = smpp_pdu_create(type, 0);
617  if (pdu == NULL)
618  return NULL;
619 
620  pos = 0;
621 
622  switch (type) {
623  #define OPTIONAL_BEGIN \
624  { /* Read optional parameters */ \
625  while (pos + 4 <= len) { \
626  struct smpp_tlv *tlv; \
627  unsigned long opt_tag, opt_len; \
628  opt_tag = decode_integer(data_without_len, pos, 2); pos += 2; \
629  debug("sms.smpp", 0, "Optional parameter tag (0x%04lx)", opt_tag); \
630  opt_len = decode_integer(data_without_len, pos, 2); pos += 2; \
631  debug("sms.smpp", 0, "Optional parameter length read as %ld", opt_len); \
632  /* check configured TLVs */ \
633  tlv = smpp_tlv_get_by_tag(smsc_id, opt_tag); \
634  if (tlv != NULL) debug("sms.smpp", 0, "Found configured optional parameter `%s'", octstr_get_cstr(tlv->name));
635  #define TLV_INTEGER(mname, octets) \
636  if (SMPP_##mname == opt_tag) { \
637  /* check length */ \
638  if (opt_len > octets) { \
639  error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len); \
640  pos += opt_len; \
641  continue; \
642  } \
643  INTEGER(mname, opt_len); \
644  if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_format("%ld", p->mname)); \
645  } else
646  #define TLV_NULTERMINATED(mname, max_len) \
647  if (SMPP_##mname == opt_tag) { \
648  /* check length */ \
649  if (opt_len > max_len || pos+opt_len > len) { \
650  error(0, "SMPP: Optional field (%s) with invalid length (%ld) dropped.", #mname, opt_len); \
651  pos += opt_len; \
652  continue; \
653  } \
654  if(p->mname != NULL) { \
655  warning(0, "SMPP: Optional field (%s) was sent more than once, overwriting", #mname); \
656  octstr_destroy(p->mname); \
657  p->mname = NULL; \
658  } \
659  copy_until_nul(#mname, data_without_len, &pos, opt_len, &p->mname); \
660  if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \
661  } else
662  #define TLV_OCTETS(mname, min_len, max_len) \
663  if (SMPP_##mname == opt_tag) { \
664  /* check length */ \
665  if (opt_len < min_len || opt_len > max_len || pos + opt_len > len) { \
666  error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %d - %d) dropped.", \
667  #mname, opt_len, min_len, max_len); \
668  pos += opt_len; \
669  continue; \
670  } \
671  if(p->mname != NULL) { \
672  warning(0, "SMPP: Optional field (%s) was sent more than once, overwriting", #mname); \
673  octstr_destroy(p->mname); \
674  p->mname = NULL; \
675  } \
676  p->mname = octstr_copy(data_without_len, pos, opt_len); \
677  pos += opt_len; \
678  if (tlv != NULL) dict_put(p->tlv, tlv->name, octstr_duplicate(p->mname)); \
679  } else
680  #define OPTIONAL_END \
681  { \
682  Octstr *val = NULL; \
683  if (tlv != NULL) { \
684  /* found configured tlv */ \
685  /* check length */ \
686  if (opt_len > tlv->length) { \
687  error(0, "SMPP: Optional field (%s) with invalid length (%ld) (should be %ld) dropped.", \
688  octstr_get_cstr(tlv->name), opt_len, tlv->length); \
689  pos += opt_len; \
690  continue; \
691  } \
692  switch (tlv->type) { \
693  case SMPP_TLV_INTEGER: { \
694  long val_i; \
695  if ((val_i = decode_integer(data_without_len, pos, opt_len)) == -1) \
696  goto err; \
697  val = octstr_format("%ld", val_i); \
698  dict_put(p->tlv, tlv->name, val); \
699  pos += opt_len; \
700  break; \
701  } \
702  case SMPP_TLV_OCTETS: { \
703  val = octstr_copy(data_without_len, pos, opt_len); \
704  dict_put(p->tlv, tlv->name, val); \
705  pos += opt_len; \
706  break; \
707  } \
708  case SMPP_TLV_NULTERMINATED: { \
709  if (copy_until_nul(octstr_get_cstr(tlv->name), data_without_len, &pos, opt_len, &val) == 0) \
710  dict_put(p->tlv, tlv->name, val); \
711  break; \
712  } \
713  default: \
714  panic(0, "SMPP: Internal error, unknown configured TLV type %d.", tlv->type); \
715  break; \
716  } \
717  } else { \
718  val = octstr_copy(data_without_len, pos, opt_len); \
719  if (val) \
720  octstr_binary_to_hex(val, 0); \
721  else \
722  val = octstr_create(""); \
723  warning(0, "SMPP: Unknown TLV(0x%04lx,0x%04lx,%s) for PDU type (%s) received!", \
724  opt_tag, opt_len, octstr_get_cstr(val), pdu->type_name); \
725  octstr_destroy(val); \
726  pos += opt_len; \
727  } \
728  } \
729  } \
730  }
731  #define INTEGER(name, octets) \
732  if ((p->name = decode_integer(data_without_len, pos, octets)) == -1) \
733  goto err; \
734  pos += octets;
735  #define NULTERMINATED(name, max_octets) \
736  /* just warn about errors but not fail */ \
737  copy_until_nul(#name, data_without_len, &pos, max_octets, &p->name);
738  #define OCTETS(name, field_giving_octets) \
739  p->name = octstr_copy(data_without_len, pos, \
740  p->field_giving_octets); \
741  if (p->field_giving_octets != (unsigned long) octstr_len(p->name)) { \
742  error(0, "smpp_pdu: error while unpacking '" #name "', " \
743  "len is %ld but should have been %ld, dropping.", \
744  octstr_len(p->name), p->field_giving_octets); \
745  goto err; \
746  } else { \
747  pos += p->field_giving_octets; \
748  }
749  #define PDU(name, id, fields) \
750  case id: { struct name *p = &pdu->u.name; fields } break;
751  #include "smpp_pdu.def"
752  default:
753  error(0, "Unknown SMPP_PDU type 0x%08lx, internal error while unpacking.", type);
754  break;
755  }
756 
757  return pdu;
758 
759 err:
760  smpp_pdu_destroy(pdu);
761  octstr_dump(data_without_len, 0);
762  return NULL;
763 }
void smpp_pdu_destroy(SMPP_PDU *pdu)
Definition: smpp_pdu.c:434
void error(int err, const char *fmt,...)
Definition: log.c:648
int type
Definition: smsc_cimd2.c:215
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
SMPP_PDU * smpp_pdu_create(unsigned long type, unsigned long seq_no)
Definition: smpp_pdu.c:400
static long decode_integer(Octstr *os, long pos, int octets)
Definition: smpp_pdu.c:330

◆ smpp_tlv_add_constant()

void smpp_tlv_add_constant ( Octstr smsc_id,
Dict **  tlvs 
)

Definition at line 102 of file smpp_pdu.c.

References smpp_tlv::constant, dict_create(), dict_get(), dict_keys(), dict_put(), gwlist_destroy(), gwlist_extract_first(), octstr_destroy(), octstr_destroy_item(), and octstr_duplicate.

Referenced by msg_to_pdu().

103 {
104  Dict *constant;
105  List *keys;
106  Octstr *key;
107  struct smpp_tlv *tlv;
108 
109  constant = dict_get(tlvs_by_const, smsc_id);
110  if (constant == NULL)
111  return;
112 
113  keys = dict_keys(constant);
114  while ((key = gwlist_extract_first(keys)) != NULL) {
115  /* only add if not available already */
116  tlv = dict_get(constant, key);
117  if (tlv && tlv->constant) {
118  if (*tlvs) {
119  if (dict_get(*tlvs, key) == NULL)
120  dict_put(*tlvs, key, octstr_duplicate(tlv->constant));
121  } else {
122  *tlvs = dict_create(1024, octstr_destroy_item);
123  dict_put(*tlvs, key, octstr_duplicate(tlv->constant));
124  }
125  }
126  octstr_destroy(key);
127  }
128  gwlist_destroy(keys, NULL);
129 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
Octstr * constant
Definition: smpp_pdu.c:79
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void * gwlist_extract_first(List *list)
Definition: list.c:305
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
Definition: dict.c:116
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void octstr_destroy_item(void *os)
Definition: octstr.c:334
Definition: octstr.c:118
static Dict * tlvs_by_const
Definition: smpp_pdu.c:87
List * dict_keys(Dict *dict)
Definition: dict.c:347
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.