2 * Copyright (C) 2015 Carsten Bock, ng-voice GmbH
4 * This file is part of Kamailio, a free SIP server.
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
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.
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
23 * \brief Support for transformations
30 #include <sys/types.h>
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"
41 #include "../../core/strutils.h"
42 #include "../../core/parser/parse_content.h"
45 #include "smsops_impl.h"
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,
59 SMS_RPDATA_ORIGINATOR,
60 SMS_RPDATA_DESTINATION,
68 SMS_TPDU_ORIGINATING_ADDRESS,
71 SMS_UDH_CONCATSM_MAX_NUM_SM,
75 // Types of the PDU-Message
76 typedef enum _pdu_message_type {
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
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;
105 struct ie_concat_sm_8bit_ref concat_sm_8bit_ref;
108 tp_udh_inf_element_t* next;
111 // TS 23.040, Sec. 9.2.3.24
112 typedef struct _tp_user_data {
113 tp_udh_inf_element_t* header;
117 // PDU (GSM 03.40) of the SMS
118 typedef struct _sms_pdu {
119 pdu_message_type_t msg_type;
120 unsigned char reference;
123 unsigned char coding;
124 unsigned char validity;
125 str originating_address;
127 tp_user_data_t payload;
130 // RP-Data of the message
131 typedef struct _sms_rp_data {
132 rp_message_type_t msg_type;
133 unsigned char reference;
136 unsigned char pdu_len;
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;
145 // ID of current message
146 static unsigned int current_msg_id = 0;
148 /*******************************************************************
150 *******************************************************************/
152 // Frees internal pointers within the SMS-PDU-Type:
153 void freeRP_DATA(sms_rp_data_t * 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);
164 pkg_free(rpdata->pdu.payload.header);
165 rpdata->pdu.payload.header = next;
167 if (rpdata->pdu.payload.sm.s) pkg_free(rpdata->pdu.payload.sm.s);
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
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)
187 int output_buffer_length = 0;
188 int carry_on_bits = 1;
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));
196 if (carry_on_bits == 8) {
203 output_buffer[output_buffer_length++] = (sms.s[i] & BITMASK_7BITS) >> (carry_on_bits - 1);
205 return output_buffer_length;
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;
212 if(buffer_length <= 2)
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;
221 // Used to iterate over buffer. Declared here, because if there are fill_bits it have to be incremented
224 // First remove the fill bits, if any
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.
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;
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
237 carry_on_bits = fill_bits - 1;
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
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
260 carry_on_bits = carry_on_bits * -1; //return the original value
262 else {// carry_on_bits == 0
263 sms.s[output_text_length++] = buffer[i] & BITMASK_7BITS;
266 //Update carry_on bits. It is always decremented, because we iterate over octests but read just septets
269 if (output_text_length == sms.len) break;
271 if (carry_on_bits == -8) {
273 sms.s[output_text_length++] = buffer[i] & BITMASK_7BITS;
274 if (output_text_length == sms.len) break;
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.
284 if (output_text_length < sms.len) // Add last remainder.
285 sms.s[output_text_length++] = buffer[i - 1] >> (8 - carry_on_bits);
287 return output_text_length;
290 // Decode UCS2 message by splitting the buffer into utf8 characters
291 int ucs2_to_utf8 (int ucs2, char * utf8) {
297 if (ucs2 >= 0x80 && ucs2 < 0x800) {
298 utf8[0] = (ucs2 >> 6) | 0xC0;
299 utf8[1] = (ucs2 & 0x3F) | 0x80;
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;
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));
319 // Decode UTF8 to UCS2
320 int utf8_to_ucs2 (const unsigned char * input, const unsigned char ** end_ptr) {
324 if (input[0] < 0x80) {
325 * end_ptr = input + 1;
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);
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);
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)
349 for (; i < phone.len; ++i) {
350 if (phone.s[i] < '0' && phone.s[i] > '9')
353 output_buffer[output_buffer_length++] = BITMASK_HIGH_4BITS | (phone.s[i] - '0');
355 output_buffer[output_buffer_length - 1] = (output_buffer[output_buffer_length - 1] & BITMASK_LOW_4BITS) | ((phone.s[i] - '0') << 4);
359 return output_buffer_length;
362 // Decode a digit based phone number for SMS based format.
363 static int DecodePhoneNumber(char* buffer, int len, str phone) {
365 for (; i < len; ++i) {
367 phone.s[i] = (buffer[i / 2] & BITMASK_LOW_4BITS) + '0';
369 phone.s[i] = ((buffer[i / 2] & BITMASK_HIGH_4BITS) >> 4) + '0';
374 // Generate a 7 Byte Long Time
375 static void EncodeTime(char * buffer) {
384 i = now.tm_year % 100;
385 buffer[0] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
387 buffer[1] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
389 buffer[2] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
391 buffer[3] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
393 buffer[4] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
395 buffer[5] = (unsigned char)((((i % 10) << 4) | (i / 10)) & 0xff);
396 buffer[6] = 0; // Timezone, we use no time offset.
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)
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
406 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF)
413 //If not found - create it
414 ie = pkg_malloc(sizeof(tp_udh_inf_element_t));
416 LM_ERR("no more pkg\n");
419 memset(ie, 0, sizeof(tp_udh_inf_element_t));
420 ie->identifier = TP_UDH_IE_CONCAT_SM_8BIT_REF;
423 //If the previous IE is not NULL - link to it
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;
434 return &(ie->concat_sm_8bit_ref);
437 // Decode SMS-Body into the given structure:
438 int decode_3gpp_sms(struct sip_msg *msg) {
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);
446 LM_ERR("failed to get the message body\n");
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.
455 if (msg->content_length==0) {
456 LM_ERR("failed to get the content length in message\n");
460 body.len = get_content_length(msg);
462 LM_ERR("message body has length zero\n");
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)));
472 // Get structure for RP-DATA:
474 rp_data = (sms_rp_data_t*)pkg_malloc(sizeof(struct _sms_rp_data));
476 LM_ERR("Error allocating %lu bytes!\n", (unsigned long)sizeof(struct _sms_rp_data));
480 freeRP_DATA(rp_data);
483 // Initialize structure:
484 memset(rp_data, 0, sizeof(struct _sms_rp_data));
486 ////////////////////////////////////////////////
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)) {
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);
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);
509 ////////////////////////////////////////////////
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++];
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;
526 p += (rp_data->pdu.destination.len/2)+1;
530 rp_data->pdu.pid = (unsigned char)body.s[p++];
531 rp_data->pdu.coding = (unsigned char)body.s[p++];
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++];
541 case BITMASK_TP_VPF_ENHANCED: // 3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format)
543 LM_WARN("3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format) is not supported\n");
545 case BITMASK_TP_VPF_ABSOLUTE: // 3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format)
547 LM_WARN("3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format) is not supported\n");
554 //TP-User-Data-Length and TP-User-Data
555 len = (unsigned char)body.s[p++];
558 if((unsigned char)rp_data->pdu.flags & BITMASK_TP_UDHI) { //TP-UDHI
559 int udh_len = (unsigned char)body.s[p++];
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!
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");
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));
581 LM_ERR("no more pkg\n");
584 memset(ie, 0, sizeof(tp_udh_inf_element_t));
586 ie->identifier = (unsigned char)body.s[p++];
587 ie->data.len = (unsigned char)body.s[p++];
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",
597 if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) {
598 if(contains_8bit_refnum) {
600 LM_ERR("IE Concatenated Short Message 8bit Reference occurred more than once in UDH\n");
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++];
608 contains_8bit_refnum = 1;
610 else { /* Unsupported IE, save it as binary */
611 ie->data.s = pkg_malloc(ie->data.len);
612 if(ie->data.s == NULL) {
614 LM_ERR("no more pkg\n");
617 memset(ie->data.s, 0, ie->data.len);
618 memcpy(ie->data.s, &body.s[p], ie->data.len);
622 if(prev_ie == NULL) {
623 rp_data->pdu.payload.header = ie;
630 udh_read += (1 /* IE ID */ + 1 /* IE Len */ + ie->data.len /* IE data */);
633 // TS 23.040, Sec. 9.2.3.16
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);
640 len -= (1 + udh_len); // add 1 octet for the udh length
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");
650 memset(rp_data->pdu.payload.sm.s, 0, blen);
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);
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;
660 j = (body.s[p] << 8) + body.s[p + 1];
662 rp_data->pdu.payload.sm.len += ucs2_to_utf8(j, &rp_data->pdu.payload.sm.s[rp_data->pdu.payload.sm.len]);
674 int dumpRPData(sms_rp_data_t * rpdata, int level) {
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);
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);
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);
695 LOG(level, " Payload: %.*s (%i)\n", rpdata->pdu.payload.sm.len, rpdata->pdu.payload.sm.s, rpdata->pdu.payload.sm.len);
700 /*******************************************************************
702 *******************************************************************/
705 * Creates the body for SMS-ACK from the current message
707 int pv_sms_ack(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
708 str rp_data_ack = {0, 0};
710 // Decode the 3GPP-SMS:
711 if (decode_3gpp_sms(msg) != 1) {
712 LM_ERR("Error getting/decoding RP-Data from request!\n");
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);
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;
732 rp_data_ack.s[3] = 9;
735 rp_data_ack.s[4] = SUBMIT;
737 rp_data_ack.s[5] = 0x0;
739 EncodeTime(&rp_data_ack.s[6]);
741 return pv_get_strval(msg, param, res, &rp_data_ack);
746 * Creates the body for SMS-ACK from the current message
748 int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
749 dumpRPData(rp_send_data, L_DBG);
751 str sms_body = {0, 0};
752 int buffer_size = 1024, lenpos = 0, i = 0;
754 // We assume a maximum size of 1024 Bytes, to be verified.
755 sms_body.s = (char*)pkg_malloc(buffer_size);
757 LM_ERR("Error allocating %i bytes!\n", buffer_size);
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;
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;
780 // Store the position of the length for later usage:
781 lenpos = sms_body.len;
782 sms_body.s[sms_body.len++] = 0x00;
784 ///////////////////////////////////////////////////
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);
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]);
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;
803 // Update the len of the PDU
804 sms_body.s[lenpos] = (unsigned char)(sms_body.len - lenpos - 1);
806 return pv_get_strval(msg, param, res, &sms_body);
809 int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
810 if (param==NULL) return -1;
812 // Decode the 3GPP-SMS:
813 if (decode_3gpp_sms(msg) != 1) {
814 LM_ERR("Error getting/decoding RP-Data from request!\n");
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);
828 return pv_get_sintval(msg, param, res, (int)rp_data->pdu.msg_type);
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;
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);
854 case SMS_UDH_CONCATSM_MAX_NUM_SM: {
855 tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
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);
863 case SMS_UDH_CONCATSM_SEQ: {
864 tp_udh_inf_element_t* ie = rp_data->pdu.payload.header;
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);
876 int pv_set_sms(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val) {
881 rp_send_data = (sms_rp_data_t*)pkg_malloc(sizeof(struct _sms_rp_data));
883 LM_ERR("Error allocating %lu bytes!\n", (unsigned long)sizeof(struct _sms_rp_data));
886 // Initialize structure:
887 memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
890 switch(param->pvn.u.isname.name.n) {
892 freeRP_DATA(rp_send_data);
893 // Initialize structure:
894 memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
896 case SMS_RPDATA_TYPE:
898 rp_send_data->msg_type = 0;
901 if (!(val->flags & PV_VAL_INT)) {
902 LM_ERR("Invalid value type\n");
905 rp_send_data->msg_type = (unsigned char)val->ri;
907 case SMS_RPDATA_REFERENCE:
909 rp_send_data->reference = 0;
912 if (!(val->flags & PV_VAL_INT)) {
913 LM_ERR("Invalid value type\n");
916 rp_send_data->reference = (unsigned char)val->ri;
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;
926 if (!(val->flags&PV_VAL_STR)) {
927 LM_ERR("Invalid type\n");
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");
935 rp_send_data->originator.len = val->rs.len;
936 memcpy(rp_send_data->originator.s, val->rs.s, val->rs.len);
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;
946 if (!(val->flags&PV_VAL_STR)) {
947 LM_ERR("Invalid type\n");
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");
955 rp_send_data->destination.len = val->rs.len;
956 memcpy(rp_send_data->destination.s, val->rs.s, val->rs.len);
960 rp_send_data->pdu.msg_type = 0;
963 if (!(val->flags & PV_VAL_INT)) {
964 LM_ERR("Invalid value type\n");
967 rp_send_data->pdu.msg_type = (unsigned char)val->ri;
972 rp_send_data->pdu.flags = 0;
975 if (!(val->flags & PV_VAL_INT)) {
976 LM_ERR("Invalid value type\n");
979 rp_send_data->pdu.flags = (unsigned char)val->ri;
981 case SMS_TPDU_CODING:
983 rp_send_data->pdu.coding = 0;
986 if (!(val->flags & PV_VAL_INT)) {
987 LM_ERR("Invalid value type\n");
990 rp_send_data->pdu.coding = (unsigned char)val->ri;
992 case SMS_TPDU_PROTOCOL:
994 rp_send_data->pdu.pid = 0;
997 if (!(val->flags & PV_VAL_INT)) {
998 LM_ERR("Invalid value type\n");
1001 rp_send_data->pdu.pid = (unsigned char)val->ri;
1003 case SMS_TPDU_REFERENCE:
1005 rp_send_data->pdu.reference = 0;
1008 if (!(val->flags & PV_VAL_INT)) {
1009 LM_ERR("Invalid value type\n");
1012 rp_send_data->pdu.reference = (unsigned char)val->ri;
1014 case SMS_TPDU_VALIDITY:
1016 rp_send_data->pdu.validity = 0;
1019 if (!(val->flags & PV_VAL_INT)) {
1020 LM_ERR("Invalid value type\n");
1023 rp_send_data->pdu.validity = (unsigned char)val->ri;
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;
1033 if (!(val->flags&PV_VAL_STR)) {
1034 LM_ERR("Invalid type\n");
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");
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);
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;
1053 if (!(val->flags&PV_VAL_STR)) {
1054 LM_ERR("Invalid type\n");
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");
1062 rp_send_data->pdu.destination.len = val->rs.len;
1063 memcpy(rp_send_data->pdu.destination.s, val->rs.s, val->rs.len);
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;
1073 if (!(val->flags&PV_VAL_STR)) {
1074 LM_ERR("Invalid type\n");
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");
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);
1085 case SMS_UDH_CONCATSM_REF: {
1088 if (!(val->flags&PV_VAL_INT)) {
1089 LM_ERR("Invalid type\n");
1092 struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1096 concat->ref = (unsigned char)val->ri;
1099 case SMS_UDH_CONCATSM_MAX_NUM_SM: {
1102 if (!(val->flags&PV_VAL_INT)) {
1103 LM_ERR("Invalid type\n");
1106 struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1110 concat->max_num_sm = (unsigned char)val->ri;
1113 case SMS_UDH_CONCATSM_SEQ: {
1116 if (!(val->flags&PV_VAL_INT)) {
1117 LM_ERR("Invalid type\n");
1120 struct ie_concat_sm_8bit_ref* concat = GetConcatShortMsg8bitRefIE(rp_data);
1124 concat->seq = (unsigned char)val->ri;
1131 int pv_parse_rpdata_name(pv_spec_p sp, str *in) {
1132 if (sp==NULL || in==NULL || in->len<=0) return -1;
1136 if (strncmp(in->s, "all", 3) == 0) sp->pvp.pvn.u.isname.name.n = SMS_ALL;
1140 if (strncmp(in->s, "type", 4) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_TYPE;
1144 if (strncmp(in->s, "reference", 9) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_REFERENCE;
1148 if (strncmp(in->s, "originator", 10) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_ORIGINATOR;
1152 if (strncmp(in->s, "destination", 11) == 0) sp->pvp.pvn.u.isname.name.n = SMS_RPDATA_DESTINATION;
1158 sp->pvp.pvn.type = PV_NAME_INTSTR;
1159 sp->pvp.pvn.u.isname.type = 0;
1164 LM_ERR("unknown uac_req name %.*s\n", in->len, in->s);
1168 int pv_parse_tpdu_name(pv_spec_p sp, str *in) {
1169 if (sp==NULL || in==NULL || in->len<=0) return -1;
1173 if (strncmp(in->s, "all", 3) == 0) sp->pvp.pvn.u.isname.name.n = SMS_ALL;
1177 if (strncmp(in->s, "type", 4) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_TYPE;
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;
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;
1191 if (strncmp(in->s, "payload", 7) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_PAYLOAD;
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;
1201 if (strncmp(in->s, "reference", 9) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_REFERENCE;
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;
1212 sp->pvp.pvn.type = PV_NAME_INTSTR;
1213 sp->pvp.pvn.u.isname.type = 0;
1218 LM_ERR("unknown pdu name %.*s\n", in->len, in->s);
1223 * Dumps the content of the SMS-Message:
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");
1232 return dumpRPData(rp_data, L_DBG);
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");
1241 if ((rp_data->msg_type == RP_DATA_MS_TO_NETWORK) || (rp_data->msg_type == RP_DATA_NETWORK_TO_MS))