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