1 /*
2 * Copyright (C) 2006 Raul Tremsal
3 * File : smpp34_pack.c
4 * Author: Raul Tremsal <ultraismo@yahoo.com>
5 *
6 * This file is part of libsmpp34 (c-open-smpp3.4 library).
7 *
8 * The libsmpp34 library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this library; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <netinet/in.h>
28
29 #ifdef __linux__
30 #include <stdint.h>
31 #endif
32
33 #include "smpp34.h"
34 #include "smpp34_structs.h"
35 #include "smpp34_params.h"
36
37 /* GLOBALS ********************************************************************/
38 /* EXTERN *********************************************************************/
39 extern int smpp34_errno;
40 extern char smpp34_strerror[2048];
41 extern char *ptrerror;
42
43 /* FUNCTIONS ******************************************************************/
44 int
smpp34_pack(uint32_t type,uint8_t * ptrBuf,int ptrSize,int * ptrLen,void * tt)45 smpp34_pack(uint32_t type, uint8_t *ptrBuf, int ptrSize, int *ptrLen, void* tt)
46 {
47
48 char dummy_b[SMALL_BUFF];
49 uint32_t v = 0;
50 uint32_t *dd = (uint32_t*)tt;
51 uint8_t *aux = ptrBuf;
52 uint8_t *aux2 = ptrBuf;
53 int lenval = 0;
54 int left = ptrSize;
55 int lefterror = 0;
56
57 memset(smpp34_strerror, 0, sizeof(smpp34_strerror));
58 ptrerror = smpp34_strerror;
59 lefterror = sizeof(smpp34_strerror);
60
61 #define instancia t1->
62
63 #define U32( inst, par, _str ){\
64 uint32_t v32 = htonl(inst par);\
65 lenval = sizeof(uint32_t);\
66 if( lenval >= left ){\
67 PUTLOG("[%s:%08X(%s)]", par, inst par,\
68 "Value lenght exceed buffer lenght");\
69 return( -1 );\
70 };\
71 _str(inst par,dummy_b);\
72 if( strcmp("", dummy_b) == 0 ){\
73 PUTLOG( "[%s:%08X(%s)]", par, inst par, "Invalid value");\
74 return( -1 );\
75 }\
76 PUTLOG("[%s:%08X(%s)]", par, inst par, "OK");\
77 memcpy(aux, &v32, lenval);\
78 left -= lenval; aux += lenval;\
79 };
80
81 #define U16( inst, par, _str ) {\
82 uint16_t v16 = htons(inst par);\
83 lenval = sizeof(uint16_t);\
84 if( lenval >= left ){\
85 PUTLOG("[%s:%04X(%s)]", par, inst par,\
86 "Value lenght exceed buffer lenght");\
87 return( -1 );\
88 };\
89 _str(inst par,dummy_b);\
90 if( strcmp("", dummy_b) == 0 ){\
91 PUTLOG( "[%s:%04X(%s)]", par, inst par, "Invalid value");\
92 return( -1 );\
93 }\
94 PUTLOG("[%s:%04X(%s)]", par, inst par, "OK");\
95 memcpy(aux, &v16, lenval);\
96 left -= lenval; aux += lenval;\
97 };
98
99 #define U08( inst, par, _str ){\
100 lenval = sizeof(uint8_t);\
101 if( lenval >= left ){\
102 PUTLOG("[%s:%02X(%s)]", par, inst par,\
103 "Value lenght exceed buffer lenght");\
104 return( -1 );\
105 };\
106 _str(inst par,dummy_b);\
107 if( strcmp("", dummy_b) == 0 ){\
108 PUTLOG( "[%s:%02X(%s)]", par, inst par, "Invalid value");\
109 return( -1 );\
110 }\
111 PUTLOG("[%s:%02X(%s)]", par, inst par, "OK");\
112 memcpy(aux,&inst par, sizeof(inst par));\
113 left -= lenval; aux += lenval;\
114 };
115
116 #define O_C_OCTET( inst, par, sizeval ){\
117 if( !(inst command_status) ){\
118 C_OCTET( inst, par, sizeval );\
119 } else {\
120 PUTLOG("[%s:%s(%s)]", par, inst par, "OK");\
121 };\
122 }
123
124 #define C_OCTET( inst, par, sizeval ){\
125 lenval = strlen((char*)inst par) + 1;\
126 if( lenval > left ){\
127 PUTLOG("[len(%s):%d(%s)]", par, lenval, \
128 "Value lenght exceed buffer lenght");\
129 return( -1 );\
130 };\
131 if( lenval > sizeval ){\
132 memcpy(aux, &inst par, sizeval);\
133 *(inst par + sizeval-1) = *(aux+sizeval-1) = '\0';\
134 left -= sizeval; aux += sizeval;\
135 PUTLOG("[%s:%s(%s)]", par, inst par, \
136 "Data length is invalid (truncate)");\
137 } else {\
138 memcpy(aux, &inst par, lenval);\
139 left -= lenval; aux += lenval;\
140 PUTLOG("[%s:%s(%s)]", par, inst par, "OK");\
141 }\
142 };
143
144 #define OCTET8( inst, par, sizeval ){\
145 lenval = *((inst par) - 1);\
146 if( lenval >= left ){\
147 PUTLOG("[leng %s:%d(%s)]", par, lenval,\
148 "Value lenght exceed buffer lenght");\
149 return( -1 );\
150 };\
151 if( lenval >= sizeval ){\
152 PUTLOG("[%s:%s(%s)]", par, "<bin>",\
153 "Data length is invalid (truncate)");\
154 return( -1 );\
155 };\
156 memcpy(aux, &inst par, (lenval > sizeval)?sizeval:lenval);\
157 left -= (lenval > sizeval)?sizeval:lenval;\
158 aux += (lenval > sizeval)?sizeval:lenval;\
159 PUTLOG("[%s:%s(%s)]", par, "<bin>", "OK");\
160 };
161
162 #define OCTET16( inst, par, sizeval ){\
163 uint16_t l_lenval = 0;\
164 memcpy(&l_lenval, ((inst par) - sizeof(uint16_t)), sizeof(uint16_t));\
165 if( l_lenval >= left ){\
166 PUTLOG("[leng %s:%d(%s)]", par, l_lenval,\
167 "Value lenght exceed buffer lenght");\
168 return( -1 );\
169 };\
170 if( l_lenval > sizeval ){\
171 PUTLOG("[%s:%s(%s)]", par, "<bin>", "Data length is invalid");\
172 return( -1 );\
173 };\
174 memcpy(aux, &inst par, (l_lenval > sizeval)?sizeval:l_lenval);\
175 left -= (l_lenval > sizeval)?sizeval:l_lenval;\
176 aux += (l_lenval > sizeval)?sizeval:l_lenval;\
177 PUTLOG("[%s:%s(%s)]", par, "<bin>", "OK");\
178 }
179
180 #define TLV( inst, tlv2, do_tlv ) {\
181 tlv_t *aux_tlv = inst tlv2;\
182 while( aux_tlv != NULL ){\
183 do_tlv( aux_tlv );\
184 aux_tlv = aux_tlv->next;\
185 };\
186 };
187
188 #define UDAD( inst, udad2, do_udad ) {\
189 udad_t *aux_udad = inst udad2;\
190 while( aux_udad != NULL ){\
191 do_udad( aux_udad );\
192 aux_udad = aux_udad->next;\
193 };\
194 };
195
196 #define DAD( inst, dad2, do_dad ) {\
197 dad_t *aux_dad = inst dad2;\
198 while( aux_dad != NULL ){\
199 do_dad( aux_dad );\
200 aux_dad = aux_dad->next;\
201 };\
202 };
203
204 #include "def_frame/alert_notification.tlv"
205 #include "def_frame/bind_receiver_resp.tlv"
206 #include "def_frame/bind_transceiver_resp.tlv"
207 #include "def_frame/bind_transmitter_resp.tlv"
208 #include "def_frame/data_sm.tlv"
209 #include "def_frame/data_sm_resp.tlv"
210 #include "def_frame/deliver_sm.tlv"
211 #include "def_frame/submit_multi_resp.udad"
212 #include "def_frame/submit_multi.dad"
213 #include "def_frame/submit_multi.tlv"
214 #include "def_frame/submit_sm.tlv"
215 #include "def_list/smpp34_protocol.def"
216
217 /* Hace algunas correcciones ******************************************/
218 *dd = aux - aux2; /* Escribe largo en el source */
219 v = htonl(aux - aux2); /* Calcula largo del PDU */
220 memcpy(aux2, &v, sizeof(uint32_t)); /* escribe largo en el dest */
221 *ptrLen = (int) (aux - aux2);
222
223 #include "def_frame/clean.frame"
224 return( 0 );
225 };
226
227
228 int
smpp34_pack2(uint8_t * ptrBuf,int ptrSize,int * ptrLen,void * tt)229 smpp34_pack2(uint8_t *ptrBuf, int ptrSize, int *ptrLen, void* tt)
230 {
231 uint32_t cmdid;
232 memcpy(&cmdid, tt+4, sizeof(uint32_t));
233 return( smpp34_pack(cmdid, ptrBuf, ptrSize, ptrLen, tt) );
234 };
235