1
2 /*
3 * Copyright (C) 2006 Raul Tremsal
4 * File : smpp.c
5 * Author: Raul Tremsal <ultraismo@yahoo.com>
6 *
7 * This file is part of libsmpp34 (c-open-smpp3.4 library).
8 *
9 * The libsmpp34 library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of the
12 * License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <libxml/xmlmemory.h>
32 #include <libxml/parser.h>
33
34 #ifdef __linux__
35 #include <stdint.h>
36 #endif
37
38 #include "smpp34.h"
39 #include "smpp34_structs.h"
40 #include "smpp34_params.h"
41
42 #include "esme.h"
43
44 extern int smpp34_errno;
45 extern char smpp34_strerror[2048];
46
47 uint8_t print_buffer[2048];
48 uint8_t local_buffer[1024];
49 int local_buffer_len = 0;
50 int ret = 0;
51 uint32_t tempo = 0;
52 uint32_t cmd_id = 0;
53
unhex(char c)54 int unhex(char c) {
55 if (c >= '0' && c <= '9')
56 return (c - '0');
57 if (c >= 'a' && c <= 'f')
58 return (c - 'a' + 10);
59 if (c >= 'A' && c <= 'F')
60 return (c - 'A' + 10);
61 return (-1);
62 }
63
hex2bin(char * hex,unsigned char * bin)64 int hex2bin(char *hex, unsigned char *bin) {
65 int i = 0;
66 int j = 0;
67
68 /* Trim string if comments present */
69 if (strchr(hex, '#') != NULL)
70 *strchr(hex, '#') = 0;
71 if (strchr(hex, '*') != NULL)
72 *strchr(hex, '*') = 0;
73 if (strchr(hex, '\'') != NULL)
74 *strchr(hex, '\'') = 0;
75
76 for (i = 0; i < strlen(hex); i++) {
77 if (hex[i] >= '0' && unhex(hex[i]) < 0){
78 printf("Bad hex digit encountered.\n");
79 return( -1 );
80 }
81 }
82
83 for (i = 0; i < strlen(hex); i++) {
84 if (hex[i] < '0')
85 continue;
86 if (hex[i] >= '0' && hex[i+1] >= '0') {
87 bin[j++] = unhex(hex[i])*16+unhex(hex[i+1]);
88 i++; // skip one
89 continue;
90 }
91 if (hex[i] >= '0') {
92 bin[j++] = unhex(hex[i]);
93 }
94 }
95 return (j);
96 }
97
do_smpp_connect(xmlNodePtr p,int sock_tcp)98 int do_smpp_connect( xmlNodePtr p, int sock_tcp )
99 {
100 bind_transmitter_t req;
101 bind_transmitter_resp_t res;
102 memset(&req, 0, sizeof(bind_transmitter_t));
103 memset(&res, 0, sizeof(bind_transmitter_resp_t));
104
105 /* Init PDU ***********************************************************/
106 req.command_length = 0;
107 req.command_id = BIND_TRANSMITTER;
108 req.command_status = ESME_ROK;
109 req.sequence_number = 1;
110 GET_PROP_STR( req.system_id, p, "system_id" );
111 GET_PROP_STR( req.password, p, "password" );
112 GET_PROP_STR( req.system_type, p, "system_type" );
113 req.interface_version = SMPP_VERSION;
114 #if 0 /* if you need add */
115 req.addr_ton = 2;
116 req.addr_npi = 1;
117 snprintf( b.address_range, sizeof(b.address_range), "%s", "");
118 #endif
119
120 /* FIRST STEP: PACK AND SEND */
121 #include "pack_and_send.inc"
122 /* Set a timer (PENDIENTE) ********************************************/
123 /* SECOND STEP: READ AND UNPACK Response */
124 #include "recv_and_unpack.inc"
125 destroy_tlv( res.tlv ); /* Por las dudas */
126
127 if( res.command_id != BIND_TRANSMITTER_RESP ||
128 res.command_status != ESME_ROK ){
129 printf("Error in BIND(BIND_TRANSMITTER)[%d:%d]\n",
130 res.command_id, res.command_status);
131 return( -1 );
132 };
133 return( 0 );
134 };
135
136
do_smpp_send_message(xmlNodePtr p,int sock_tcp)137 int do_smpp_send_message( xmlNodePtr p, int sock_tcp )
138 {
139
140 char message[256];
141 tlv_t tlv;
142 submit_sm_t req;
143 submit_sm_resp_t res;
144 memset(&req, 0, sizeof(submit_sm_t));
145 memset(&res, 0, sizeof(submit_sm_resp_t));
146
147 /* Init PDU ***********************************************************/
148 req.command_length = 0;
149 req.command_id = SUBMIT_SM;
150 req.command_status = ESME_ROK;
151 req.sequence_number = 2;
152 #if 0 /* if you need this */
153 snprintf(b.service_type, sizeof(b.service_type), "%s", "SMS");
154 b.source_addr_ton = 2;
155 b.source_addr_npi = 1;
156 #endif
157 GET_PROP_STR( req.source_addr, p, "src" );
158 #if 0 /* if you need this */
159 b.dest_addr_ton = 2;
160 b.dest_addr_npi = 0;
161 #endif
162 GET_PROP_STR( req.destination_addr, p, "dst" );
163 #if 0 /* if you need this */
164 b.esm_class = 0;
165 b.protocol_id = 0;
166 b.priority_flag = 0;
167 snprintf( b.schedule_delivery_time, TIME_LENGTH, "%s", "");
168 snprintf( b.validity_period, TIME_LENGTH, "%s", "");
169 b.registered_delivery = 0;
170 b.replace_if_present_flag =0;
171 b.data_coding = 0;
172 b.sm_default_msg_id = 0;
173 #endif
174 GET_PROP_STR( message, p, "msg" );
175
176 #if 0 /* Message in short_message scope */
177 b.sm_length = strlen(TEXTO);
178 memcpy(b.short_message, TEXTO, b.sm_length);
179 #else /* Message in Payload */
180 tlv.tag = TLVID_message_payload;
181 tlv.length = strlen(message);
182 memcpy(tlv.value.octet, message, tlv.length);
183 build_tlv( &(req.tlv), &tlv );
184 #endif
185
186 /* Add other optional param */
187 tlv.tag = TLVID_user_message_reference;
188 tlv.length = sizeof(uint16_t);
189 tlv.value.val16 = 0x0024;
190 build_tlv( &(req.tlv), &tlv );
191
192 /* FIRST STEP: PACK AND SEND */
193 #include "pack_and_send.inc"
194 destroy_tlv( req.tlv ); /* Por las dudas */
195 /* Set a timer (PENDIENTE) ********************************************/
196 /* SECOND STEP: READ AND UNPACK Response */
197 #include "recv_and_unpack.inc"
198
199 if( res.command_id != SUBMIT_SM_RESP ||
200 res.command_status != ESME_ROK ){
201 printf("Error in send(SUBMIT_SM)[%08X:%08X]\n",
202 res.command_id, res.command_status);
203 return( -1 );
204 };
205 return( 0 );
206 };
207
208
do_smpp_send_message2(xmlNodePtr p,int sock_tcp,int sequence)209 int do_smpp_send_message2( xmlNodePtr p, int sock_tcp, int sequence )
210 {
211
212 char message[512];
213 submit_sm_t req;
214 submit_sm_resp_t res;
215 memset(&req, 0, sizeof(submit_sm_t));
216 memset(&res, 0, sizeof(submit_sm_resp_t));
217
218 /* Init PDU ***********************************************************/
219 req.command_length = 0;
220 req.command_id = SUBMIT_SM;
221 req.command_status = ESME_ROK;
222 req.sequence_number = sequence;
223 GET_PROP_STR( req.service_type, p, "service_type" );
224
225 GET_PROP_INT( req.source_addr_ton, p, "source_addr_ton" );
226 GET_PROP_INT( req.source_addr_npi, p, "source_addr_npi" );
227 GET_PROP_STR( req.source_addr, p, "src" );
228
229 GET_PROP_INT( req.dest_addr_ton, p, "dest_addr_ton" );
230 GET_PROP_INT( req.dest_addr_npi, p, "dest_addr_npi" );
231 GET_PROP_STR( req.destination_addr, p, "dst" );
232
233 GET_PROP_INT( req.esm_class, p, "esm_class" );
234 GET_PROP_INT( req.protocol_id, p, "protocol_id" );
235 GET_PROP_INT( req.priority_flag, p, "priority_flag" );
236 GET_PROP_STR( req.schedule_delivery_time, p, "schedule_delivery_time" );
237 GET_PROP_STR( req.validity_period, p, "validity_period" );
238 GET_PROP_INT( req.registered_delivery, p, "registered_delivery" );
239 GET_PROP_INT( req.replace_if_present_flag, p, "replace_if_present_flag" );
240 GET_PROP_INT( req.data_coding, p, "data_coding" );
241 GET_PROP_INT( req.sm_default_msg_id, p, "sm_default_msg_id" );
242 GET_PROP_STR( message, p, "hex" );
243 req.sm_length = hex2bin(message, req.short_message);
244
245 /* FIRST STEP: PACK AND SEND */
246 #include "pack_and_send.inc"
247 destroy_tlv( req.tlv ); /* Por las dudas */
248 /* Set a timer (PENDIENTE) ********************************************/
249 /* SECOND STEP: READ AND UNPACK Response */
250 #include "recv_and_unpack.inc"
251
252 if( res.command_id != SUBMIT_SM_RESP ||
253 res.command_status != ESME_ROK ){
254 printf("Error in send(SUBMIT_SM)[%d:%d]\n",
255 res.command_id, res.command_status);
256 return( -1 );
257 };
258 return( 0 );
259 };
260
261
do_smpp_close(int sock_tcp)262 int do_smpp_close( int sock_tcp )
263 {
264 unbind_t req;
265 unbind_resp_t res;
266 memset(&req, 0, sizeof(unbind_t));
267 memset(&res, 0, sizeof(unbind_resp_t));
268
269 /* Init PDU ***********************************************************/
270 req.command_length = 0;
271 req.command_id = UNBIND;
272 req.command_status = ESME_ROK;
273 req.sequence_number = 3;
274
275 /* FIRST STEP: PACK AND SEND */
276 #include "pack_and_send.inc"
277 /* Set a timer (PENDIENTE) ********************************************/
278 /* SECOND STEP: READ AND UNPACK Response */
279 #include "recv_and_unpack.inc"
280
281 if( res.command_id != UNBIND_RESP ||
282 res.command_status != ESME_ROK ){
283 printf("Error in send(UNBIND)[%d:%d]\n",
284 res.command_id, res.command_status);
285 return( -1 );
286 };
287
288 return( 0 );
289 };
290