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