smsops: fix parsing of validity period
[kamailio] / src / modules / smsops / smsops_impl.c
1 /*
2  * Copyright (C) 2015 Carsten Bock, ng-voice GmbH
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 /*! \file
23  * \brief Support for transformations
24  */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <time.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32
33 #include "../../core/dprint.h"
34 #include "../../core/mem/mem.h"
35 #include "../../core/ut.h"
36 #include "../../core/trim.h"
37 #include "../../core/pvapi.h"
38 #include "../../core/dset.h"
39 #include "../../core/basex.h"
40
41 #include "../../core/strutils.h"
42 #include "../../core/parser/parse_content.h"
43
44
45 #include "smsops_impl.h"
46
47 // Types of RP-DATA
48 typedef enum _rp_message_type {
49         RP_DATA_MS_TO_NETWORK = 0x00,
50         RP_DATA_NETWORK_TO_MS = 0x01,
51         RP_ACK_MS_TO_NETWORK  = 0x02,
52         RP_ACK_NETWORK_TO_MS  = 0x03,
53 } rp_message_type_t;
54
55 enum SMS_DATA {
56         SMS_ALL,
57         SMS_RPDATA_TYPE,
58         SMS_RPDATA_REFERENCE,
59         SMS_RPDATA_ORIGINATOR,
60         SMS_RPDATA_DESTINATION,
61         SMS_TPDU_TYPE,
62         SMS_TPDU_FLAGS,
63         SMS_TPDU_CODING,
64         SMS_TPDU_PAYLOAD,
65         SMS_TPDU_PROTOCOL,
66         SMS_TPDU_VALIDITY,
67         SMS_TPDU_REFERENCE,
68         SMS_TPDU_ORIGINATING_ADDRESS,
69         SMS_TPDU_DESTINATION,
70         SMS_UDH_CONCATSM_REF,
71         SMS_UDH_CONCATSM_MAX_NUM_SM,
72         SMS_UDH_CONCATSM_SEQ
73 };
74
75 // Types of the PDU-Message
76 typedef enum _pdu_message_type {
77         DELIVER = 0x00,
78         SUBMIT = 0x01,
79         COMMAND = 0x02,
80         ANY = 0x03,
81 } pdu_message_type_t;
82
83 #define TP_RD 0x4;
84 #define TP_VPF 0x16;
85 #define TP_SRR 0x32;
86 #define TP_UDHI 0x64;
87 #define TP_RP 0x128;
88
89 // Information element identifiers and corresponding structs.
90 // Only the supported ones are listed.
91 // Defined in TS 23.040, Sec. 9.2.3.24 and 9.2.3.24.1
92 #define TP_UDH_IE_CONCAT_SM_8BIT_REF 0x00       // 9.2.3.24
93 struct ie_concat_sm_8bit_ref {
94         unsigned char ref;                      //Concatenated short message reference number
95         unsigned char max_num_sm;       //Maximum number of short messages in the concatenated short message.
96         unsigned char seq;                      //Sequence number of the current short message
97 };
98
99 // Information element in User Data Header
100 typedef struct _tp_udh_inf_element tp_udh_inf_element_t;
101 struct _tp_udh_inf_element {
102         unsigned char identifier;
103         union {
104                 str data;
105                 struct ie_concat_sm_8bit_ref concat_sm_8bit_ref;
106         };
107
108         tp_udh_inf_element_t* next;
109 };
110
111 // TS 23.040, Sec. 9.2.3.24
112 typedef struct _tp_user_data {
113         tp_udh_inf_element_t* header;
114         str sm;
115 } tp_user_data_t;
116
117 // PDU (GSM 03.40) of the SMS
118 typedef struct _sms_pdu {
119         pdu_message_type_t msg_type;
120         unsigned char reference;
121         unsigned char flags;
122         unsigned char pid;
123         unsigned char coding;
124         unsigned char validity;
125         str originating_address;
126         str destination;
127         tp_user_data_t payload;
128 } sms_pdu_t;
129
130 // RP-Data of the message
131 typedef struct _sms_rp_data {
132         rp_message_type_t msg_type;
133         unsigned char reference;
134         str originator;
135         str destination;
136         unsigned char pdu_len;
137         sms_pdu_t pdu;
138 } sms_rp_data_t;
139
140 // Pointer to current parsed rp_data/tpdu
141 static sms_rp_data_t * rp_data = NULL;
142 // Pointer to rp_data/tpdu used for sending
143 static sms_rp_data_t * rp_send_data = NULL;
144
145 // ID of current message
146 static unsigned int current_msg_id = 0;
147
148 /*******************************************************************
149  * Helper Functions
150  *******************************************************************/
151
152 // Frees internal pointers within the SMS-PDU-Type:
153 void freeRP_DATA(sms_rp_data_t * rpdata) {
154         if (rpdata) {
155                 if (rpdata->originator.s) pkg_free(rpdata->originator.s);
156                 if (rpdata->destination.s) pkg_free(rpdata->destination.s);
157                 if (rpdata->pdu.originating_address.s) pkg_free(rpdata->pdu.originating_address.s);
158                 if (rpdata->pdu.destination.s) pkg_free(rpdata->pdu.destination.s);
159                 while (rpdata->pdu.payload.header) {
160                         tp_udh_inf_element_t* next = rpdata->pdu.payload.header->next;
161                         if(rpdata->pdu.payload.header->identifier != TP_UDH_IE_CONCAT_SM_8BIT_REF) {
162                                 if(rpdata->pdu.payload.header->data.s) pkg_free(rpdata->pdu.payload.header->data.s);
163                         }
164                         pkg_free(rpdata->pdu.payload.header);
165                         rpdata->pdu.payload.header = next;
166                 }
167                 if (rpdata->pdu.payload.sm.s) pkg_free(rpdata->pdu.payload.sm.s);
168         }
169 }
170
171 #define BITMASK_7BITS 0x7F
172 #define BITMASK_8BITS 0xFF
173 #define BITMASK_HIGH_4BITS 0xF0
174 #define BITMASK_LOW_4BITS 0x0F
175 #define BITMASK_TP_UDHI 0x40
176 #define BITMASK_TP_VPF 0x18
177 #define BITMASK_TP_VPF_RELATIVE 0x10 
178 #define BITMASK_TP_VPF_ENHANCED 0x08
179 #define BITMASK_TP_VPF_ABSOLUTE 0x18
180
181 // Encode SMS-Message by merging 7 bit ASCII characters into 8 bit octets.
182 static int ascii_to_gsm(str sms, char * output_buffer, int buffer_size) {
183         // Check if output buffer is big enough.
184         if ((sms.len * 7 + 7) / 8 > buffer_size)
185                 return -1;
186
187         int output_buffer_length = 0;
188         int carry_on_bits = 1;
189         int i = 0;
190
191         for (; i < sms.len; ++i) {
192                 output_buffer[output_buffer_length++] =
193                         ((sms.s[i] & BITMASK_7BITS) >> (carry_on_bits - 1)) |
194                         ((sms.s[i + 1] & BITMASK_7BITS) << (8 - carry_on_bits));
195                 carry_on_bits++;
196                 if (carry_on_bits == 8) {
197                         carry_on_bits = 1;
198                         ++i;
199                 }
200         }
201
202         if (i < sms.len)
203                 output_buffer[output_buffer_length++] = (sms.s[i] & BITMASK_7BITS) >> (carry_on_bits - 1);
204
205         return output_buffer_length;
206 }
207
208 // Decode 7bit encoded message by splitting 8 bit encoded buffer into 7 bit ASCII characters.
209 int gsm_to_ascii(char* buffer, int buffer_length, str sms, const int fill_bits) {
210                 int output_text_length = 0;
211
212                 if(buffer_length <= 2)
213                         return 0;
214
215                 // How many bits we have carried from the next octet. This number can be positive or negative:
216                 // positive: We have carried n bits FROM the next octet.
217                 // negative: We have to carry n bits TO the next octet.
218                 // 0: Nothing carried. Default value!
219                 int carry_on_bits = 0;
220
221                 // Used to iterate over buffer. Declared here, because if there are fill_bits it have to be incremented
222                 int i = 0;
223
224                 // First remove the fill bits, if any
225                 if(fill_bits) {
226                         // We need 7 bits in the first octet, so if there is only 1 fill bit, we don't have to
227                         // carry from the next octet.
228
229                         // cmask stands for carry mask or how many bits to carry from the 2nd octet
230                         unsigned char cmask = (1 << (fill_bits - 1)) - 1;
231
232                         sms.s[output_text_length++] = ( (buffer[0] >> fill_bits) |      // remove the fill bits from the first octet
233                                                                                         (buffer[1] & cmask << (8 - fill_bits)) // mask the required number of bits
234                                                                                                                                                                         //and shift them accordingly
235                                                                                 ) & BITMASK_7BITS;      // mask just 7 bits from the first octet
236
237                         carry_on_bits = fill_bits - 1;
238                         i++;
239                 }
240
241
242                 for (; i < buffer_length; ++i) {
243                         if(carry_on_bits > 0) {
244                                 unsigned char cmask = (1 << (carry_on_bits - 1)) - 1;   //mask for the rightmost carry_on_bits
245                                                                                                                                                 //E.g. carry_on_bits=3 -> _ _ _ _ _ X X X
246                                 sms.s[output_text_length++] = ( (buffer[i] >> carry_on_bits) | //shift right to remove carried bits
247                                                                                                 (buffer[i+1] & cmask) << (8 - carry_on_bits)    // carry from the next
248                                                                                                                                                                                                 // and shift accordingly
249                                                                                                 ) & BITMASK_7BITS;      // mask just 7 bits from the first octet
250                         }
251                         else if(carry_on_bits < 0) {
252                                 carry_on_bits = carry_on_bits * -1;     //make carry_on_bits positive for the bitwise ops
253                                 unsigned char cmask = ((1 << carry_on_bits) - 1) << (8 - carry_on_bits);        //mask for the leftmost carry_on_bits.
254                                                                                                                                                                                 //E.g. carry_on_bits=3 -> X X X _ _ _ _ _
255                                 sms.s[output_text_length++] = ( (buffer[i] << carry_on_bits) | //shift left to make space for the carried bits
256                                                                                                 (buffer[i-1] & cmask) >> (8 - carry_on_bits)    // get the bits from the previous octet
257                                                                                                                                                                                                 // and shift accordingly
258                                                                                                 ) & BITMASK_7BITS;      // mask just 7 bits from the first octet
259
260                                 carry_on_bits = carry_on_bits * -1;     //return the original value
261                         }
262                         else {// carry_on_bits == 0
263                                 sms.s[output_text_length++] = buffer[i] & BITMASK_7BITS;
264                         }
265
266                         //Update carry_on bits. It is always decremented, because we iterate over octests but read just septets
267                         carry_on_bits--;
268
269                         if (output_text_length == sms.len) break;
270
271                         if (carry_on_bits == -8) {
272                                 carry_on_bits = -1;
273                                 sms.s[output_text_length++] = buffer[i] & BITMASK_7BITS;
274                                 if (output_text_length == sms.len) break;
275                         }
276
277                         if(carry_on_bits > 0 && (i + 2 >= buffer_length)) {
278                                 //carry_on_bits is positive, which means thah we have to borrow from the next octet on next iteration
279                                 //However i + 2 >= buffer_length so there is no next octet. This is error.
280                                 break;
281                         }
282                 }
283
284                 if (output_text_length < sms.len)  // Add last remainder.
285                         sms.s[output_text_length++] = buffer[i - 1] >> (8 - carry_on_bits);
286
287                 return output_text_length;
288 }
289
290 // Decode UCS2 message by splitting the buffer into utf8 characters
291 int ucs2_to_utf8 (int ucs2, char * utf8) {
292         if (ucs2 < 0x80) {
293                 utf8[0] = ucs2;
294         utf8[1] = 0;
295                 return 1;
296         }
297         if (ucs2 >= 0x80  && ucs2 < 0x800) {
298                 utf8[0] = (ucs2 >> 6)   | 0xC0;
299                 utf8[1] = (ucs2 & 0x3F) | 0x80;
300                 return 2;
301         }
302         if (ucs2 >= 0x800 && ucs2 < 0xFFFF) {
303                 if (ucs2 >= 0xD800 && ucs2 <= 0xDFFF) return -1;
304                 utf8[0] = ((ucs2 >> 12)       ) | 0xE0;
305                 utf8[1] = ((ucs2 >> 6 ) & 0x3F) | 0x80;
306                 utf8[2] = ((ucs2      ) & 0x3F) | 0x80;
307                 return 3;
308         }
309         if (ucs2 >= 0x10000 && ucs2 < 0x10FFFF) {
310         utf8[0] = 0xF0 | (ucs2 >> 18);
311         utf8[1] = 0x80 | ((ucs2 >> 12) & 0x3F);
312         utf8[2] = 0x80 | ((ucs2 >> 6) & 0x3F);
313         utf8[3] = 0x80 | ((ucs2 & 0x3F));
314                 return 4;
315         }
316         return -1;
317 }
318
319 // Decode UTF8 to UCS2
320 int utf8_to_ucs2 (const unsigned char * input, const unsigned char ** end_ptr) {
321         *end_ptr = input;
322         if (input[0] == 0)
323                 return -1;
324         if (input[0] < 0x80) {
325                 * end_ptr = input + 1;
326                 return input[0];
327         }
328         if ((input[0] & 0xE0) == 0xE0) {
329                 if (input[1] == 0 || input[2] == 0) return -1;
330                 *end_ptr = input + 3;
331                 return (input[0] & 0x0F) << 12 | (input[1] & 0x3F) << 6  | (input[2] & 0x3F);
332         }
333         if ((input[0] & 0xC0) == 0xC0) {
334                 if (input[1] == 0) return -1;
335                 * end_ptr = input + 2;
336                 return (input[0] & 0x1F) << 6 | (input[1] & 0x3F);
337         }
338         return -1;
339 }
340
341 // Encode a digit based phone number for SMS based format.
342 static int EncodePhoneNumber(str phone, char * output_buffer, int buffer_size) {
343         int output_buffer_length = 0;
344         // Check if the output buffer is big enough.
345         if ((phone.len + 1) / 2 > buffer_size)
346                 return -1;
347
348         int i = 0;
349         for (; i < phone.len; ++i) {
350                 if (phone.s[i] < '0' && phone.s[i] > '9')
351                         return -1;
352                 if (i % 2 == 0) {
353                         output_buffer[output_buffer_length++] = BITMASK_HIGH_4BITS | (phone.s[i] - '0');
354                 } else {
355                         output_buffer[output_buffer_length - 1] = (output_buffer[output_buffer_length - 1] & BITMASK_LOW_4BITS) | ((phone.s[i] - '0') << 4);
356                 }
357         }
358
359         return output_buffer_length;
360 }
361
362 // Decode a digit based phone number for SMS based format.
363 static int DecodePhoneNumber(char* buffer, int len, str phone) {
364         int i = 0;
365         for (; i < len; ++i) {
366                 if (i % 2 == 0)
367                         phone.s[i] = (buffer[i / 2] & BITMASK_LOW_4BITS) + '0';
368                 else
369                         phone.s[i] = ((buffer[i / 2] & BITMASK_HIGH_4BITS) >> 4) + '0';
370         }
371         return i;
372 }
373
374 // Generate a 7 Byte Long Time
375 static void EncodeTime(char * buffer) {
376         time_t ts;
377         struct tm now;
378         int i = 0;
379
380         time(&ts);
381         /* Get GMT time */
382         gmtime_r(&ts, &now);
383
384         i = now.tm_year % 100;
385         buffer[0] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
386         i = now.tm_mon + 1;
387         buffer[1] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
388         i = now.tm_mday;
389         buffer[2] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
390         i = now.tm_hour;
391         buffer[3] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
392         i = now.tm_min;
393         buffer[4] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
394         i = now.tm_sec;
395         buffer[5] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
396         buffer[6] = 0; // Timezone, we use no time offset.
397 }
398
399 //The function is called GetXXX but it actually creates the IE if it doesn't exist
400 static struct ie_concat_sm_8bit_ref* GetConcatShortMsg8bitRefIE(sms_rp_data_t* rp_data)
401 {
402         tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
403         tp_udh_inf_element_t* prev = rp_data->pdu.payload.header;
404         //Look for Concatenated SM 8bit Reference IE
405         while(ie) {
406                 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF)
407                         break;
408                 prev = ie;
409                 ie = ie->next;
410         }
411
412         if(ie == NULL) {
413                 //If not found - create it
414                 ie = pkg_malloc(sizeof(tp_udh_inf_element_t));
415                 if(ie == NULL) {
416                         LM_ERR("no more pkg\n");
417                         return NULL;
418                 }
419                 memset(ie, 0, sizeof(tp_udh_inf_element_t));
420                 ie->identifier = TP_UDH_IE_CONCAT_SM_8BIT_REF;
421
422                 if(prev) {
423                         //If the previous IE is not NULL - link to it
424                         prev->next = ie;
425                 }
426                 else {
427                         //There are not IEs at all
428                         rp_data->pdu.payload.header = ie;
429                         //Set TP-UDHI flag to 1
430                         rp_data->pdu.flags |= BITMASK_TP_UDHI;
431                 }
432         }
433
434         return &(ie->concat_sm_8bit_ref);
435 }
436
437 // Decode SMS-Body into the given structure:
438 int decode_3gpp_sms(struct sip_msg *msg) {
439         str body;
440         int len, blen, j, p = 0;
441         // Parse only the body again, if the mesage differs from the last call:
442         if (msg->id != current_msg_id) {
443                 // Extract Message-body and length: taken from RTPEngine's code
444                 body.s = get_body(msg);
445                 if (body.s == 0) {
446                         LM_ERR("failed to get the message body\n");
447                         return -1;
448                 }
449
450                 /*
451                  * Better use the content-len value - no need of any explicit
452                  * parcing as get_body() parsed all headers and Conten-Length
453                  * body header is automaticaly parsed when found.
454                  */
455                 if (msg->content_length==0) {
456                         LM_ERR("failed to get the content length in message\n");
457                         return -1;
458                 }
459
460                 body.len = get_content_length(msg);
461                 if (body.len==0) {
462                         LM_ERR("message body has length zero\n");
463                         return -1;
464                 }
465
466                 if (body.len + body.s > msg->buf + msg->len) {
467                         LM_ERR("content-length exceeds packet-length by %d\n",
468                                         (int)((body.len + body.s) - (msg->buf + msg->len)));
469                         return -1;
470                 }
471
472                 // Get structure for RP-DATA:
473                 if (!rp_data) {
474                         rp_data = (sms_rp_data_t*)pkg_malloc(sizeof(struct _sms_rp_data));
475                         if (!rp_data) {
476                                 LM_ERR("Error allocating %lu bytes!\n", (unsigned long)sizeof(struct _sms_rp_data));
477                                 return -1;
478                         }
479                 } else {
480                         freeRP_DATA(rp_data);
481                 }
482
483                 // Initialize structure:
484                 memset(rp_data, 0, sizeof(struct _sms_rp_data));
485
486                 ////////////////////////////////////////////////
487                 // RP-Data
488                 ////////////////////////////////////////////////
489                 rp_data->msg_type = (unsigned char)body.s[p++];
490                 rp_data->reference = (unsigned char)body.s[p++];
491                 if ((rp_data->msg_type == RP_DATA_MS_TO_NETWORK) || (rp_data->msg_type == RP_DATA_NETWORK_TO_MS)) {
492                         len = body.s[p++];
493                         if (len > 0) {
494                                 p++; // Type of Number, we assume E164, thus ignored
495                                 len--; // Deduct the type of number from the len
496                                 rp_data->originator.s = pkg_malloc(len * 2);
497                                 rp_data->originator.len = DecodePhoneNumber(&body.s[p], len * 2, rp_data->originator);
498                                 p += len;
499                         }
500                         len = body.s[p++];
501                         if (len > 0) {
502                                 p++; // Type of Number, we assume E164, thus ignored
503                                 len--; // Deduct the type of number from the len
504                                 rp_data->destination.s = pkg_malloc(len * 2);
505                                 rp_data->destination.len = DecodePhoneNumber(&body.s[p], len * 2, rp_data->destination);
506                                 p += len;
507                         }
508
509                         ////////////////////////////////////////////////
510                         // TPDU
511                         ////////////////////////////////////////////////
512                         rp_data->pdu_len = body.s[p++];
513                         if (rp_data->pdu_len > 0) {
514                                 rp_data->pdu.flags = (unsigned char)body.s[p++];
515                                 rp_data->pdu.msg_type = (unsigned char)rp_data->pdu.flags & 0x03;
516                                 rp_data->pdu.reference = (unsigned char)body.s[p++];
517                                 // TP-DA
518                                 rp_data->pdu.destination.len = body.s[p++];
519                                 if (rp_data->pdu.destination.len > 0) {
520                                         p++; // Type of Number, we assume E164, thus ignored
521                                         rp_data->pdu.destination.s = pkg_malloc(rp_data->pdu.destination.len);
522                                         DecodePhoneNumber(&body.s[p], rp_data->pdu.destination.len, rp_data->pdu.destination);
523                                         if (rp_data->pdu.destination.len % 2 == 0) {
524                                                 p += rp_data->pdu.destination.len/2;
525                                         } else {
526                                                 p += (rp_data->pdu.destination.len/2)+1;
527                                         }
528
529                                 }
530                                 rp_data->pdu.pid = (unsigned char)body.s[p++];
531                                 rp_data->pdu.coding = (unsigned char)body.s[p++];
532
533                                 // 3GPP TS 03.40 9.2.2.2 SMS SUBMIT type
534                                 // https://en.wikipedia.org/wiki/GSM_03.40
535                                 if(rp_data->pdu.msg_type == SUBMIT){
536                                         // 3GPP TS 03.40 9.2.3.3 TP Validity Period Format (TP VPF)
537                                         switch (rp_data->pdu.flags & BITMASK_TP_VPF){
538                                                 case BITMASK_TP_VPF_RELATIVE:   // 3GPP TS 03.40 9.2.3.12.1 TP-VP (Relative format)
539                                                         rp_data->pdu.validity = (unsigned char)body.s[p++];
540                                                         break;
541                                                 case BITMASK_TP_VPF_ENHANCED:   // 3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format)
542                                                         p += 7;
543                                                         LM_WARN("3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format) is not supported\n");
544                                                         break;
545                                                 case BITMASK_TP_VPF_ABSOLUTE:   // 3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format)
546                                                         p += 7;
547                                                         LM_WARN("3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format) is not supported\n");
548                                                         break;
549                                                 default:
550                                                         break;
551                                         }
552                                 }
553
554                                 //TP-User-Data-Length and TP-User-Data
555                                 len = (unsigned char)body.s[p++];
556                                 int fill_bits = 0;
557                                 if (len > 0) {
558                                         if((unsigned char)rp_data->pdu.flags & BITMASK_TP_UDHI) { //TP-UDHI
559                                                 int udh_len = (unsigned char)body.s[p++];
560                                                 int udh_read = 0;
561
562                                                 if(rp_data->pdu.coding == 0) {
563                                                         //calcucate padding size for 7bit coding
564                                                         //udh_len + 1, because the length field itself should be included
565                                                         fill_bits = (7 - (udh_len + 1) % 7) % 7; //padding size is in bits!
566                                                 }
567
568                                                 // Check for malicious length, which might cause buffer overflow
569                                                 if(udh_len > body.len - p) {
570                                                         LM_ERR("TP-User-Data-Length is bigger than the remaining message buffer!\n");
571                                                         return -1;
572                                                 }
573
574                                                 //User-Data-Header
575                                                 tp_udh_inf_element_t* prev_ie = NULL;
576                                                 // IE 'Concatenated short messages, 8-bit reference number' should not be repeated
577                                                 int contains_8bit_refnum = 0;
578                                                 while(udh_read < udh_len) {
579                                                         tp_udh_inf_element_t* ie = pkg_malloc(sizeof(tp_udh_inf_element_t));
580                                                         if(ie == NULL) {
581                                                                 LM_ERR("no more pkg\n");
582                                                                 return -1;
583                                                         }
584                                                         memset(ie, 0, sizeof(tp_udh_inf_element_t));
585
586                                                         ie->identifier = (unsigned char)body.s[p++];
587                                                         ie->data.len = (unsigned char)body.s[p++];
588
589                                                         // Check for malicious length, which might cause buffer overflow
590                                                         if(udh_read + ie->data.len + 2 /* two octets are read so far */ > udh_len) {
591                                                                 LM_ERR("IE Length for IE id %d is bigger than the remaining User-Data element!\n",
592                                                                                                                                                                                                         ie->identifier);
593                                                                 pkg_free(ie);
594                                                                 return -1;
595                                                         }
596
597                                                         if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) {
598                                                                 if(contains_8bit_refnum) {
599                                                                         pkg_free(ie);
600                                                                         LM_ERR("IE Concatenated Short Message 8bit Reference occurred more than once in UDH\n");
601                                                                         return -1;
602                                                                 }
603
604                                                                 ie->concat_sm_8bit_ref.ref = body.s[p++];
605                                                                 ie->concat_sm_8bit_ref.max_num_sm = body.s[p++];
606                                                                 ie->concat_sm_8bit_ref.seq = body.s[p++];
607
608                                                                 contains_8bit_refnum = 1;
609                                                         }
610                                                         else { /* Unsupported IE, save it as binary */
611                                                                 ie->data.s = pkg_malloc(ie->data.len);
612                                                                 if(ie->data.s == NULL) {
613                                                                         pkg_free(ie);
614                                                                         LM_ERR("no more pkg\n");
615                                                                         return -1;
616                                                                 }
617                                                                 memset(ie->data.s, 0, ie->data.len);
618                                                                 memcpy(ie->data.s, &body.s[p], ie->data.len);
619                                                                 p += ie->data.len;
620                                                         }
621
622                                                         if(prev_ie == NULL) {
623                                                                 rp_data->pdu.payload.header = ie;
624                                                         }
625                                                         else {
626                                                                 prev_ie->next = ie;
627                                                         }
628
629                                                         prev_ie = ie;
630                                                         udh_read += (1 /* IE ID */ + 1 /* IE Len */ + ie->data.len /* IE data */);
631                                                 }
632
633                                                 // TS 23.040, Sec. 9.2.3.16
634                                                 // Coding: 7 Bit
635                                                 if (rp_data->pdu.coding == 0x00) {
636                                                         int udh_bit_len = (1 + udh_len) * 8; // add 1 octet for the udh length
637                                                         udh_bit_len += (7 - (udh_bit_len % 7));
638                                                         len -= (udh_bit_len / 7);
639                                                 }else{
640                                                         len -= (1 + udh_len); // add 1 octet for the udh length
641                                                 }
642                                         }
643
644                                         blen = 2 + len*4;
645                                         rp_data->pdu.payload.sm.s = pkg_malloc(blen);
646                                         if(rp_data->pdu.payload.sm.s==NULL) {
647                                                 LM_ERR("no more pkg\n");
648                                                 return -1;
649                                         }
650                                         memset(rp_data->pdu.payload.sm.s, 0, blen);
651                                         // Coding: 7 Bit
652                                         if (rp_data->pdu.coding == 0x00) {
653                                                 // We don't care about the extra used bytes here.
654                                                 rp_data->pdu.payload.sm.len = len;
655                                                 rp_data->pdu.payload.sm.len = gsm_to_ascii(&body.s[p], len, rp_data->pdu.payload.sm, fill_bits);
656                                         } else {
657                                                 // Length is worst-case 2 * len (UCS2 is 2 Bytes, UTF8 is worst-case 4 Bytes)
658                                                 rp_data->pdu.payload.sm.len = 0;
659                                                 while (len > 0) {
660                                                         j = (body.s[p] << 8) + body.s[p + 1];
661                                                         p += 2;
662                                                         rp_data->pdu.payload.sm.len += ucs2_to_utf8(j, &rp_data->pdu.payload.sm.s[rp_data->pdu.payload.sm.len]);
663                                                         len -= 2;
664                                                 }
665                                         }
666                                 }
667                         }
668                 }
669         }
670
671         return 1;
672 }
673
674 int dumpRPData(sms_rp_data_t * rpdata, int level) {
675         if (rpdata) {
676                 LOG(level, "SMS-Message\n");
677                 LOG(level, "------------------------\n");
678                 LOG(level, "RP-Data\n");
679                 LOG(level, "  Type:                       %x\n", rpdata->msg_type);
680                 LOG(level, "  Reference:                  %x (%i)\n", rpdata->reference, rpdata->reference);
681                 LOG(level, "  Originator:                 %.*s (%i)\n", rpdata->originator.len, rpdata->originator.s, rpdata->originator.len);
682                 LOG(level, "  Destination:                %.*s (%i)\n", rpdata->destination.len, rpdata->destination.s, rpdata->destination.len);
683                 LOG(level, "T-PDU\n");
684                 LOG(level, "  Type:                       %x\n", rpdata->pdu.msg_type);
685                 LOG(level, "  Flags:                      %x (%i)\n", rpdata->pdu.flags, rpdata->pdu.flags);
686                 LOG(level, "  Reference:                  %x (%i)\n", rpdata->pdu.reference, rpdata->pdu.reference);
687
688                 LOG(level, "  Originating-Address:        %.*s (%i)\n", rpdata->pdu.originating_address.len, rpdata->pdu.originating_address.s, rpdata->pdu.originating_address.len);
689                 LOG(level, "  Destination:                %.*s (%i)\n", rpdata->pdu.destination.len, rpdata->pdu.destination.s, rpdata->pdu.destination.len);
690
691                 LOG(level, "  Protocol:                   %x (%i)\n", rpdata->pdu.pid, rpdata->pdu.pid);
692                 LOG(level, "  Coding:                     %x (%i)\n", rpdata->pdu.coding, rpdata->pdu.coding);
693                 LOG(level, "  Validity:                   %x (%i)\n", rpdata->pdu.validity, rpdata->pdu.validity);
694
695                 LOG(level, "  Payload:                    %.*s (%i)\n", rpdata->pdu.payload.sm.len, rpdata->pdu.payload.sm.s, rpdata->pdu.payload.sm.len);
696         }
697         return 1;
698 }
699
700 /*******************************************************************
701  * Implementation
702  *******************************************************************/
703
704 /*
705  * Creates the body for SMS-ACK from the current message
706  */
707 int pv_sms_ack(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
708         str rp_data_ack = {0, 0};
709
710         // Decode the 3GPP-SMS:
711         if (decode_3gpp_sms(msg) != 1) {
712                 LM_ERR("Error getting/decoding RP-Data from request!\n");
713                 return -1;
714         }
715
716         // RP-Type (1) + RP-Ref (1) + RP-User-Data (Element-ID (1) + Length (9 => Msg-Type (1) + Parameter (1) + Service-Centre-Time (7)) = 13;
717         rp_data_ack.len = 13;
718         rp_data_ack.s = (char*)pkg_malloc(rp_data_ack.len);
719         if (!rp_data_ack.s) {
720                 LM_ERR("Error allocating %d bytes!\n", rp_data_ack.len);
721                 return -1;
722         }
723
724         // Encode the data (RP-Data)
725         // Always ACK NETWORK to MS
726         rp_data_ack.s[0] = RP_ACK_NETWORK_TO_MS;
727         // Take the reference from request:
728         rp_data_ack.s[1] = rp_data->reference;
729         // RP-Data-Element-ID
730         rp_data_ack.s[2] = 0x41;
731         // Length
732         rp_data_ack.s[3] = 9;
733         // PDU
734         // SMS-SUBMIT-Report
735         rp_data_ack.s[4] = SUBMIT;
736         // Parameters (none)
737         rp_data_ack.s[5] = 0x0;
738
739         EncodeTime(&rp_data_ack.s[6]);
740
741         return pv_get_strval(msg, param, res, &rp_data_ack);
742 }
743
744
745 /*
746  * Creates the body for SMS-ACK from the current message
747  */
748 int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
749         dumpRPData(rp_send_data, L_DBG);
750
751         str sms_body = {0, 0};
752         int buffer_size = 1024, lenpos = 0, i = 0;
753
754         // We assume a maximum size of 1024 Bytes, to be verified.
755         sms_body.s = (char*)pkg_malloc(buffer_size);
756         if (!sms_body.s) {
757                 LM_ERR("Error allocating %i bytes!\n", buffer_size);
758                 return -1;
759         }
760
761         // Encode the data (RP-Data)
762         sms_body.s[sms_body.len++] = rp_send_data->msg_type;
763         sms_body.s[sms_body.len++] = rp_send_data->reference;
764         lenpos = sms_body.len;
765         sms_body.s[sms_body.len++] = 0x00;
766         if (rp_send_data->originator.len > 0) {
767                 sms_body.s[sms_body.len++] = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension
768                 i = EncodePhoneNumber(rp_send_data->originator, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
769                 sms_body.s[lenpos] = i + 1;
770                 sms_body.len += i;
771         }
772         lenpos = sms_body.len;
773         sms_body.s[sms_body.len++] = 0x00;
774         if (rp_send_data->destination.len > 0) {
775                 sms_body.s[sms_body.len++] = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension
776                 i = EncodePhoneNumber(rp_send_data->destination, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
777                 sms_body.s[lenpos] = i + 1;
778                 sms_body.len += i;
779         }
780         // Store the position of the length for later usage:
781         lenpos = sms_body.len;
782         sms_body.s[sms_body.len++] = 0x00;
783
784         ///////////////////////////////////////////////////
785         // T-PDU
786         ///////////////////////////////////////////////////
787         sms_body.s[sms_body.len++] = rp_send_data->pdu.msg_type | rp_send_data->pdu.flags | 0x4; // We've always got no more messages to send.
788         // Originating Address:
789         sms_body.s[sms_body.len++] = rp_send_data->pdu.originating_address.len;
790         sms_body.s[sms_body.len++] = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension
791         sms_body.len += EncodePhoneNumber(rp_send_data->pdu.originating_address, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
792         // Protocol ID
793         sms_body.s[sms_body.len++] = rp_send_data->pdu.pid;
794         // Encoding (0 => default 7 Bit)
795         sms_body.s[sms_body.len++] = rp_send_data->pdu.coding;
796         // Service-Center-Timestamp (always 7 octets)
797         EncodeTime(&sms_body.s[sms_body.len]);
798         sms_body.len += 7;
799         sms_body.s[sms_body.len++] = rp_send_data->pdu.payload.sm.len;
800         i = ascii_to_gsm(rp_send_data->pdu.payload.sm, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
801         sms_body.len += i - 1;
802
803         // Update the len of the PDU
804         sms_body.s[lenpos] = (unsigned char)(sms_body.len - lenpos - 1);
805
806         return pv_get_strval(msg, param, res, &sms_body);
807 }
808
809 int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
810         if (param==NULL) return -1;
811
812         // Decode the 3GPP-SMS:
813         if (decode_3gpp_sms(msg) != 1) {
814                 LM_ERR("Error getting/decoding RP-Data from request!\n");
815                 return -1;
816         }
817
818         switch(param->pvn.u.isname.name.n) {
819                 case SMS_RPDATA_TYPE:
820                         return pv_get_sintval(msg, param, res, (int)rp_data->msg_type);
821                 case SMS_RPDATA_REFERENCE:
822                         return pv_get_sintval(msg, param, res, (int)rp_data->reference);
823                 case SMS_RPDATA_ORIGINATOR:
824                         return pv_get_strval(msg, param, res, &rp_data->originator);
825                 case SMS_RPDATA_DESTINATION:
826                         return pv_get_strval(msg, param, res, &rp_data->destination);
827                 case SMS_TPDU_TYPE:
828                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.msg_type);
829                 case SMS_TPDU_FLAGS:
830                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.flags);
831                 case SMS_TPDU_CODING:
832                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.coding);
833                 case SMS_TPDU_PROTOCOL:
834                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.pid);
835                 case SMS_TPDU_VALIDITY:
836                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.validity);
837                 case SMS_TPDU_REFERENCE:
838                         return  pv_get_sintval(msg, param, res, (int)rp_data->pdu.reference);
839                 case SMS_TPDU_PAYLOAD:
840                         return pv_get_strval(msg, param, res, &rp_data->pdu.payload.sm);
841                 case SMS_TPDU_DESTINATION:
842                         return pv_get_strval(msg, param, res, &rp_data->pdu.destination);
843                 case SMS_TPDU_ORIGINATING_ADDRESS:
844                         return pv_get_strval(msg, param, res, &rp_data->pdu.originating_address);
845                 case SMS_UDH_CONCATSM_REF: {
846                         tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
847                         while(ie) {
848                                 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF)
849                                         return pv_get_uintval(msg, param, res, (unsigned int)ie->concat_sm_8bit_ref.ref);
850                                 ie = ie->next;
851                         }
852                         return -1;
853                 }
854                 case SMS_UDH_CONCATSM_MAX_NUM_SM: {
855                         tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
856                         while(ie) {
857                                 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF)
858                                         return pv_get_uintval(msg, param, res, (unsigned int)ie->concat_sm_8bit_ref.max_num_sm);
859                                 ie = ie->next;
860                         }
861                         return -1;
862                 }
863                 case SMS_UDH_CONCATSM_SEQ: {
864                         tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
865                         while(ie) {
866                                 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF)
867                                         return pv_get_uintval(msg, param, res, (unsigned int)ie->concat_sm_8bit_ref.seq);
868                                 ie = ie->next;
869                         }
870                         return -1;
871                 }
872         }
873         return 0;
874 }
875
876 int pv_set_sms(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) {
877         if (param==NULL)
878                 return -1;
879
880         if (!rp_send_data) {
881                 rp_send_data = (sms_rp_data_t*)pkg_malloc(sizeof(struct _sms_rp_data));
882                 if (!rp_send_data) {
883                         LM_ERR("Error allocating %lu bytes!\n", (unsigned long)sizeof(struct _sms_rp_data));
884                         return -1;
885                 }
886                 // Initialize structure:
887                 memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
888         }
889
890         switch(param->pvn.u.isname.name.n) {
891                 case SMS_ALL:
892                         freeRP_DATA(rp_send_data);
893                         // Initialize structure:
894                         memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
895                         break;
896                 case SMS_RPDATA_TYPE:
897                         if (val == NULL) {
898                                 rp_send_data->msg_type = 0;
899                                 return 0;
900                         }
901                         if (!(val->flags & PV_VAL_INT)) {
902                                 LM_ERR("Invalid value type\n");
903                                 return -1;
904                         }
905                         rp_send_data->msg_type = (unsigned char)val->ri;
906                         break;
907                 case SMS_RPDATA_REFERENCE:
908                         if (val == NULL) {
909                                 rp_send_data->reference = 0;
910                                 return 0;
911                         }
912                         if (!(val->flags & PV_VAL_INT)) {
913                                 LM_ERR("Invalid value type\n");
914                                 return -1;
915                         }
916                         rp_send_data->reference = (unsigned char)val->ri;
917                         break;
918                 case SMS_RPDATA_ORIGINATOR:
919                         if (rp_send_data->originator.s) {
920                                 pkg_free(rp_send_data->originator.s);
921                                 rp_send_data->originator.s = 0;
922                                 rp_send_data->originator.len = 0;
923                         }
924                         if (val == NULL)
925                                 return 0;
926                         if (!(val->flags&PV_VAL_STR)) {
927                                 LM_ERR("Invalid type\n");
928                                 return -1;
929                         }
930                         rp_send_data->originator.s = pkg_malloc(val->rs.len);
931                         if(rp_send_data->originator.s==NULL) {
932                                 LM_ERR("no more pkg\n");
933                                 return -1;
934                         }
935                         rp_send_data->originator.len = val->rs.len;
936                         memcpy(rp_send_data->originator.s, val->rs.s, val->rs.len);
937                         break;
938                 case SMS_RPDATA_DESTINATION:
939                         if (rp_send_data->destination.s) {
940                                 pkg_free(rp_send_data->destination.s);
941                                 rp_send_data->destination.s = 0;
942                                 rp_send_data->destination.len = 0;
943                         }
944                         if (val == NULL)
945                                 return 0;
946                         if (!(val->flags&PV_VAL_STR)) {
947                                 LM_ERR("Invalid type\n");
948                                 return -1;
949                         }
950                         rp_send_data->destination.s = pkg_malloc(val->rs.len);
951                         if(rp_send_data->destination.s==NULL) {
952                                 LM_ERR("no more pkg\n");
953                                 return -1;
954                         }
955                         rp_send_data->destination.len = val->rs.len;
956                         memcpy(rp_send_data->destination.s, val->rs.s, val->rs.len);
957                         break;
958                 case SMS_TPDU_TYPE:
959                         if (val == NULL) {
960                                 rp_send_data->pdu.msg_type = 0;
961                                 return 0;
962                         }
963                         if (!(val->flags & PV_VAL_INT)) {
964                                 LM_ERR("Invalid value type\n");
965                                 return -1;
966                         }
967                         rp_send_data->pdu.msg_type = (unsigned char)val->ri;
968                         break;
969
970                 case SMS_TPDU_FLAGS:
971                         if (val == NULL) {
972                                 rp_send_data->pdu.flags = 0;
973                                 return 0;
974                         }
975                         if (!(val->flags & PV_VAL_INT)) {
976                                 LM_ERR("Invalid value type\n");
977                                 return -1;
978                         }
979                         rp_send_data->pdu.flags = (unsigned char)val->ri;
980                         break;
981                 case SMS_TPDU_CODING:
982                         if (val == NULL) {
983                                 rp_send_data->pdu.coding = 0;
984                                 return 0;
985                         }
986                         if (!(val->flags & PV_VAL_INT)) {
987                                 LM_ERR("Invalid value type\n");
988                                 return -1;
989                         }
990                         rp_send_data->pdu.coding = (unsigned char)val->ri;
991                         break;
992                 case SMS_TPDU_PROTOCOL:
993                         if (val == NULL) {
994                                 rp_send_data->pdu.pid = 0;
995                                 return 0;
996                         }
997                         if (!(val->flags & PV_VAL_INT)) {
998                                 LM_ERR("Invalid value type\n");
999                                 return -1;
1000                         }
1001                         rp_send_data->pdu.pid = (unsigned char)val->ri;
1002                         break;
1003                 case SMS_TPDU_REFERENCE:
1004                         if (val == NULL) {
1005                                 rp_send_data->pdu.reference = 0;
1006                                 return 0;
1007                         }
1008                         if (!(val->flags & PV_VAL_INT)) {
1009                                 LM_ERR("Invalid value type\n");
1010                                 return -1;
1011                         }
1012                         rp_send_data->pdu.reference = (unsigned char)val->ri;
1013                         break;
1014                 case SMS_TPDU_VALIDITY:
1015                         if (val == NULL) {
1016                                 rp_send_data->pdu.validity = 0;
1017                                 return 0;
1018                         }
1019                         if (!(val->flags & PV_VAL_INT)) {
1020                                 LM_ERR("Invalid value type\n");
1021                                 return -1;
1022                         }
1023                         rp_send_data->pdu.validity = (unsigned char)val->ri;
1024                         break;
1025                 case SMS_TPDU_PAYLOAD:
1026                         if (rp_send_data->pdu.payload.sm.s) {
1027                                 pkg_free(rp_send_data->pdu.payload.sm.s);
1028                                 rp_send_data->pdu.payload.sm.s = 0;
1029                                 rp_send_data->pdu.payload.sm.len = 0;
1030                         }
1031                         if (val == NULL)
1032                                 return 0;
1033                         if (!(val->flags&PV_VAL_STR)) {
1034                                 LM_ERR("Invalid type\n");
1035                                 return -1;
1036                         }
1037                         rp_send_data->pdu.payload.sm.s = pkg_malloc(val->rs.len);
1038                         if(rp_send_data->pdu.payload.sm.s==NULL) {
1039                                 LM_ERR("no more pkg\n");
1040                                 return -1;
1041                         }
1042                         rp_send_data->pdu.payload.sm.len = val->rs.len;
1043                         memcpy(rp_send_data->pdu.payload.sm.s, val->rs.s, val->rs.len);
1044                         break;
1045                 case SMS_TPDU_DESTINATION:
1046                         if (rp_send_data->pdu.destination.s) {
1047                                 pkg_free(rp_send_data->pdu.destination.s);
1048                                 rp_send_data->pdu.destination.s = 0;
1049                                 rp_send_data->pdu.destination.len = 0;
1050                         }
1051                         if (val == NULL)
1052                                 return 0;
1053                         if (!(val->flags&PV_VAL_STR)) {
1054                                 LM_ERR("Invalid type\n");
1055                                 return -1;
1056                         }
1057                         rp_send_data->pdu.destination.s = pkg_malloc(val->rs.len);
1058                         if(rp_send_data->pdu.destination.s==NULL) {
1059                                 LM_ERR("no more pkg\n");
1060                                 return -1;
1061                         }
1062                         rp_send_data->pdu.destination.len = val->rs.len;
1063                         memcpy(rp_send_data->pdu.destination.s, val->rs.s, val->rs.len);
1064                         break;
1065                 case SMS_TPDU_ORIGINATING_ADDRESS:
1066                         if (rp_send_data->pdu.originating_address.s) {
1067                                 pkg_free(rp_send_data->pdu.originating_address.s);
1068                                 rp_send_data->pdu.originating_address.s = 0;
1069                                 rp_send_data->pdu.originating_address.len = 0;
1070                         }
1071                         if (val == NULL)
1072                                 return 0;
1073                         if (!(val->flags&PV_VAL_STR)) {
1074                                 LM_ERR("Invalid type\n");
1075                                 return -1;
1076                         }
1077                         rp_send_data->pdu.originating_address.s = pkg_malloc(val->rs.len);
1078                         if(rp_send_data->pdu.originating_address.s==NULL) {
1079                                 LM_ERR("no more pkg\n");
1080                                 return -1;
1081                         }
1082                         rp_send_data->pdu.originating_address.len = val->rs.len;
1083                         memcpy(rp_send_data->pdu.originating_address.s, val->rs.s, val->rs.len);
1084                         break;
1085                 case SMS_UDH_CONCATSM_REF: {
1086                         if (val == NULL)
1087                                 return 0;
1088                         if (!(val->flags&PV_VAL_INT)) {
1089                                 LM_ERR("Invalid type\n");
1090                                 return -1;
1091                         }
1092                         struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1093                         if(concat == NULL)
1094                                 return -1;
1095
1096                         concat->ref = (unsigned char)val->ri;
1097                         break;
1098                 }
1099                 case SMS_UDH_CONCATSM_MAX_NUM_SM: {
1100                         if (val == NULL)
1101                                 return 0;
1102                         if (!(val->flags&PV_VAL_INT)) {
1103                                 LM_ERR("Invalid type\n");
1104                                 return -1;
1105                         }
1106                         struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1107                         if(concat == NULL)
1108                                 return -1;
1109
1110                         concat->max_num_sm = (unsigned char)val->ri;
1111                         break;
1112                 }
1113                 case SMS_UDH_CONCATSM_SEQ: {
1114                         if (val == NULL)
1115                                 return 0;
1116                         if (!(val->flags&PV_VAL_INT)) {
1117                                 LM_ERR("Invalid type\n");
1118                                 return -1;
1119                         }
1120                         struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1121                         if(concat == NULL)
1122                                 return -1;
1123
1124                         concat->seq = (unsigned char)val->ri;
1125                         break;
1126                 }
1127         }
1128         return 0;
1129 }
1130
1131 int pv_parse_rpdata_name(pv_spec_p sp, str *in) {
1132         if (sp==NULL || in==NULL || in->len<=0) return -1;
1133
1134         switch(in->len) {
1135                 case 3:
1136                         if (strncmp(in->s, "all", 3) == 0) sp->pvp.pvn.u.isname.name.n = SMS_ALL;
1137                         else goto error;
1138                         break;
1139                 case 4:
1140                         if (strncmp(in->s, "type", 4) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_TYPE;
1141                         else goto error;
1142                         break;
1143                 case 9:
1144                         if (strncmp(in->s, "reference", 9) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_REFERENCE;
1145                         else goto error;
1146                         break;
1147                 case 10:
1148                         if (strncmp(in->s, "originator", 10) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_ORIGINATOR;
1149                         else goto error;
1150                         break;
1151                 case 11:
1152                         if (strncmp(in->s, "destination", 11) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_DESTINATION;
1153                         else goto error;
1154                         break;
1155                 default:
1156                         goto error;
1157         }
1158         sp->pvp.pvn.type = PV_NAME_INTSTR;
1159         sp->pvp.pvn.u.isname.type = 0;
1160
1161         return 0;
1162
1163 error:
1164         LM_ERR("unknown uac_req name %.*s\n", in->len, in->s);
1165         return -1;
1166 }
1167
1168 int pv_parse_tpdu_name(pv_spec_p sp, str *in) {
1169         if (sp==NULL || in==NULL || in->len<=0) return -1;
1170
1171         switch(in->len) {
1172                 case 3:
1173                         if (strncmp(in->s, "all", 3) == 0) sp->pvp.pvn.u.isname.name.n = SMS_ALL;
1174                         else goto error;
1175                         break;
1176                 case 4:
1177                         if (strncmp(in->s, "type", 4) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_TYPE;
1178                         else goto error;
1179                         break;
1180                 case 5:
1181                         if (strncmp(in->s, "flags", 5) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_FLAGS;
1182                         else if (strncmp(in->s, "mp_id", 5) == 0) sp->pvp.pvn.u.isname.name.n = SMS_UDH_CONCATSM_REF;
1183                         else goto error;
1184                         break;
1185                 case 6:
1186                         if (strncmp(in->s, "coding", 6) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_CODING;
1187                         else if (strncmp(in->s, "origen", 6) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_ORIGINATING_ADDRESS;
1188                         else goto error;
1189                         break;
1190                 case 7:
1191                         if (strncmp(in->s, "payload", 7) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_PAYLOAD;
1192                         else goto error;
1193                         break;
1194                 case 8:
1195                         if (strncmp(in->s, "protocol", 8) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_PROTOCOL;
1196                         else if (strncmp(in->s, "validity", 8) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_VALIDITY;
1197                         else if (strncmp(in->s, "mp_parts", 8) == 0) sp->pvp.pvn.u.isname.name.n = SMS_UDH_CONCATSM_MAX_NUM_SM;
1198                         else goto error;
1199                         break;
1200                 case 9:
1201                         if (strncmp(in->s, "reference", 9) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_REFERENCE;
1202                         else goto error;
1203                         break;
1204                 case 11:
1205                         if (strncmp(in->s, "destination", 11) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_DESTINATION;
1206                         else if (strncmp(in->s, "mp_part_num", 11) == 0) sp->pvp.pvn.u.isname.name.n = SMS_UDH_CONCATSM_SEQ;
1207                         else goto error;
1208                         break;
1209                 default:
1210                         goto error;
1211         }
1212         sp->pvp.pvn.type = PV_NAME_INTSTR;
1213         sp->pvp.pvn.u.isname.type = 0;
1214
1215         return 0;
1216
1217 error:
1218         LM_ERR("unknown pdu name %.*s\n", in->len, in->s);
1219         return -1;
1220 }
1221
1222 /*
1223  * Dumps the content of the SMS-Message:
1224  */
1225 int smsdump(struct sip_msg *msg, char *str1, char *str2) {
1226         // Decode the 3GPP-SMS:
1227         if (decode_3gpp_sms(msg) != 1) {
1228                 LM_ERR("Error getting/decoding RP-Data from request!\n");
1229                 return -1;
1230         }
1231
1232         return dumpRPData(rp_data, L_DBG);
1233 }
1234
1235 int isRPDATA(struct sip_msg *msg, char *str1, char *str2) {
1236         // Decode the 3GPP-SMS:
1237         if (decode_3gpp_sms(msg) != 1) {
1238                 LM_ERR("Error getting/decoding RP-Data from request!\n");
1239                 return -1;
1240         }
1241         if ((rp_data->msg_type == RP_DATA_MS_TO_NETWORK) || (rp_data->msg_type == RP_DATA_NETWORK_TO_MS))
1242                 return 1;
1243         else
1244                 return -1;
1245 }
1246