Browse code

smsops: Imrovements in decode_3gpp_sms() and pv_sms_body()

- Added new sms pdu data: originating & destination address flags;
SCTS(DELIVER)/VP(SUBMIT) absolute time format.
- decode_3gpp_sms(): added support for DELIVER type;
Added VP-AbsoluteTimeFormat for SUBMIT type.
- pv_sms_body(): added support for ucs2 coding.
- Extends of pv_get_sms() and pv_set_sms(): added support for
originating & destination address flags.

Aleksandar Yosifov authored on 07/04/2021 07:59:24
Showing 1 changed files
... ...
@@ -69,7 +69,9 @@ enum SMS_DATA {
69 69
 	SMS_TPDU_DESTINATION,
70 70
 	SMS_UDH_CONCATSM_REF,
71 71
 	SMS_UDH_CONCATSM_MAX_NUM_SM,
72
-	SMS_UDH_CONCATSM_SEQ
72
+	SMS_UDH_CONCATSM_SEQ,
73
+	SMS_TPDU_ORIGINATING_ADDRESS_FLAGS,
74
+	SMS_TPDU_DESTINATION_FLAGS
73 75
 };
74 76
 
75 77
 // Types of the PDU-Message
... ...
@@ -125,6 +127,9 @@ typedef struct _sms_pdu {
125 127
 	str originating_address;
126 128
 	str destination;
127 129
 	tp_user_data_t payload;
130
+	unsigned char originating_address_flags;
131
+	unsigned char destination_flags;
132
+	struct tm time; // Either SCTS (DELIVER) or VP (SUBMIT)
128 133
 } sms_pdu_t;
129 134
 
130 135
 // RP-Data of the message
... ...
@@ -396,6 +401,22 @@ static void EncodeTime(char * buffer) {
396 401
 	buffer[6] = 0; // Timezone, we use no time offset.
397 402
 }
398 403
 
404
+static void DecodeTime(char* buffer, struct tm* decoded_time)
405
+{
406
+	time_t ts;
407
+
408
+	time(&ts);
409
+	/* Get GMT time */
410
+	gmtime_r(&ts, decoded_time);
411
+
412
+	decoded_time->tm_year	= 100 + ((buffer[0] & 0x0F) * 10) + ((buffer[0] >> 4) & 0x0F);
413
+	decoded_time->tm_mon	= ((buffer[1] & 0x0F) * 10) + ((buffer[1] >> 4) & 0x0F) - 1;
414
+	decoded_time->tm_mday	= ((buffer[2] & 0x0F) * 10) + ((buffer[2] >> 4) & 0x0F);
415
+	decoded_time->tm_hour	= ((buffer[3] & 0x0F) * 10) + ((buffer[3] >> 4) & 0x0F);
416
+	decoded_time->tm_min	= ((buffer[4] & 0x0F) * 10) + ((buffer[4] >> 4) & 0x0F);
417
+	decoded_time->tm_sec	= ((buffer[5] & 0x0F) * 10) + ((buffer[5] >> 4) & 0x0F);
418
+}
419
+
399 420
 //The function is called GetXXX but it actually creates the IE if it doesn't exist
400 421
 static struct ie_concat_sm_8bit_ref* GetConcatShortMsg8bitRefIE(sms_rp_data_t* rp_data)
401 422
 {
... ...
@@ -513,22 +534,44 @@ int decode_3gpp_sms(struct sip_msg *msg) {
513 534
 			if (rp_data->pdu_len > 0) {
514 535
 				rp_data->pdu.flags = (unsigned char)body.s[p++];
515 536
 				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 537
 
538
+				if (rp_data->pdu.msg_type == SUBMIT || rp_data->pdu.msg_type == COMMAND) {
539
+					rp_data->pdu.reference = (unsigned char)body.s[p++];
540
+				}
541
+
542
+				if (rp_data->pdu.msg_type == SUBMIT) {
543
+					// TP-DA
544
+					rp_data->pdu.destination.len = body.s[p++];
545
+					if (rp_data->pdu.destination.len > 0) {
546
+						rp_data->pdu.destination_flags = (unsigned char)body.s[p++];
547
+						rp_data->pdu.destination.s = pkg_malloc(rp_data->pdu.destination.len);
548
+						DecodePhoneNumber(&body.s[p], rp_data->pdu.destination.len, rp_data->pdu.destination);
549
+						if (rp_data->pdu.destination.len % 2 == 0) {
550
+							p += rp_data->pdu.destination.len/2;
551
+						} else {
552
+							p += (rp_data->pdu.destination.len/2)+1;
553
+						}
554
+					}
555
+				}else if (rp_data->pdu.msg_type == DELIVER) {
556
+					// TP-OA
557
+					rp_data->pdu.originating_address.len = body.s[p++];
558
+					if (rp_data->pdu.originating_address.len > 0) {
559
+						rp_data->pdu.originating_address_flags = (unsigned char)body.s[p++];
560
+						rp_data->pdu.originating_address.s = pkg_malloc(rp_data->pdu.originating_address.len);
561
+						DecodePhoneNumber(&body.s[p], rp_data->pdu.originating_address.len, rp_data->pdu.originating_address);
562
+						if (rp_data->pdu.originating_address.len % 2 == 0) {
563
+							p += rp_data->pdu.originating_address.len/2;
564
+						} else {
565
+							p += (rp_data->pdu.originating_address.len/2)+1;
566
+						}
567
+					}
529 568
 				}
569
+
530 570
 				rp_data->pdu.pid = (unsigned char)body.s[p++];
531
-				rp_data->pdu.coding = (unsigned char)body.s[p++];
571
+
572
+				if (rp_data->pdu.msg_type == SUBMIT || rp_data->pdu.msg_type == DELIVER) {
573
+					rp_data->pdu.coding = (unsigned char)body.s[p++];
574
+				}
532 575
 
533 576
 				// 3GPP TS 03.40 9.2.2.2 SMS SUBMIT type
534 577
 				// https://en.wikipedia.org/wiki/GSM_03.40
... ...
@@ -538,129 +581,135 @@ int decode_3gpp_sms(struct sip_msg *msg) {
538 581
 						case BITMASK_TP_VPF_RELATIVE:	// 3GPP TS 03.40 9.2.3.12.1 TP-VP (Relative format)
539 582
 							rp_data->pdu.validity = (unsigned char)body.s[p++];
540 583
 							break;
541
-						case BITMASK_TP_VPF_ENHANCED:	// 3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format)
584
+						case BITMASK_TP_VPF_ABSOLUTE:	// 3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format)
585
+							DecodeTime(&body.s[p], &rp_data->pdu.time);
542 586
 							p += 7;
543
-							LM_WARN("3GPP TS 03.40 9.2.3.12.2 TP-VP (Absolute format) is not supported\n");
544 587
 							break;
545
-						case BITMASK_TP_VPF_ABSOLUTE:	// 3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format)
588
+						case BITMASK_TP_VPF_ENHANCED:	// 3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format)
546 589
 							p += 7;
547 590
 							LM_WARN("3GPP TS 03.40 9.2.3.12.3 TP-VP (Enhanced format) is not supported\n");
548 591
 							break;
549 592
 						default:
550 593
 							break;
551 594
 					}
595
+				} else if (rp_data->pdu.msg_type == DELIVER) {
596
+					// TP-SCTS
597
+					DecodeTime(&body.s[p], &rp_data->pdu.time);
598
+					p += 7;
552 599
 				}
553 600
 
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;
601
+				if (rp_data->pdu.msg_type == SUBMIT || rp_data->pdu.msg_type == DELIVER) {
602
+					//TP-User-Data-Length and TP-User-Data
603
+					len = (unsigned char)body.s[p++];
604
+					int fill_bits = 0;
605
+					if (len > 0) {
606
+						if((unsigned char)rp_data->pdu.flags & BITMASK_TP_UDHI) { //TP-UDHI
607
+							int udh_len = (unsigned char)body.s[p++];
608
+							int udh_read = 0;
609
+
610
+							if(rp_data->pdu.coding == 0) {
611
+								//calcucate padding size for 7bit coding
612
+								//udh_len + 1, because the length field itself should be included
613
+								fill_bits = (7 - (udh_len + 1) % 7) % 7; //padding size is in bits!
583 614
 							}
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 615
 
589 616
 							// 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);
617
+							if(udh_len > body.len - p) {
618
+								LM_ERR("TP-User-Data-Length is bigger than the remaining message buffer!\n");
594 619
 								return -1;
595 620
 							}
596 621
 
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");
622
+							//User-Data-Header
623
+							tp_udh_inf_element_t* prev_ie = NULL;
624
+							// IE 'Concatenated short messages, 8-bit reference number' should not be repeated
625
+							int contains_8bit_refnum = 0;
626
+							while(udh_read < udh_len) {
627
+								tp_udh_inf_element_t* ie = pkg_malloc(sizeof(tp_udh_inf_element_t));
628
+								if(ie == NULL) {
629
+									LM_ERR("no more pkg\n");
601 630
 									return -1;
602 631
 								}
632
+								memset(ie, 0, sizeof(tp_udh_inf_element_t));
603 633
 
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++];
634
+								ie->identifier = (unsigned char)body.s[p++];
635
+								ie->data.len = (unsigned char)body.s[p++];
607 636
 
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) {
637
+								// Check for malicious length, which might cause buffer overflow
638
+								if(udh_read + ie->data.len + 2 /* two octets are read so far */ > udh_len) {
639
+									LM_ERR("IE Length for IE id %d is bigger than the remaining User-Data element!\n",
640
+																										ie->identifier);
613 641
 									pkg_free(ie);
614
-									LM_ERR("no more pkg\n");
615 642
 									return -1;
616 643
 								}
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 644
 
622
-							if(prev_ie == NULL) {
623
-								rp_data->pdu.payload.header = ie;
624
-							}
625
-							else {
626
-								prev_ie->next = ie;
645
+								if(ie->identifier == TP_UDH_IE_CONCAT_SM_8BIT_REF) {
646
+									if(contains_8bit_refnum) {
647
+										pkg_free(ie);
648
+										LM_ERR("IE Concatenated Short Message 8bit Reference occurred more than once in UDH\n");
649
+										return -1;
650
+									}
651
+
652
+									ie->concat_sm_8bit_ref.ref = body.s[p++];
653
+									ie->concat_sm_8bit_ref.max_num_sm = body.s[p++];
654
+									ie->concat_sm_8bit_ref.seq = body.s[p++];
655
+
656
+									contains_8bit_refnum = 1;
657
+								}
658
+								else { /* Unsupported IE, save it as binary */
659
+									ie->data.s = pkg_malloc(ie->data.len);
660
+									if(ie->data.s == NULL) {
661
+										pkg_free(ie);
662
+										LM_ERR("no more pkg\n");
663
+										return -1;
664
+									}
665
+									memset(ie->data.s, 0, ie->data.len);
666
+									memcpy(ie->data.s, &body.s[p], ie->data.len);
667
+									p += ie->data.len;
668
+								}
669
+
670
+								if(prev_ie == NULL) {
671
+									rp_data->pdu.payload.header = ie;
672
+								}
673
+								else {
674
+									prev_ie->next = ie;
675
+								}
676
+
677
+								prev_ie = ie;
678
+								udh_read += (1 /* IE ID */ + 1 /* IE Len */ + ie->data.len /* IE data */);
627 679
 							}
628 680
 
629
-							prev_ie = ie;
630
-							udh_read += (1 /* IE ID */ + 1 /* IE Len */ + ie->data.len /* IE data */);
681
+							// TS 23.040, Sec. 9.2.3.16
682
+							// Coding: 7 Bit
683
+							if (rp_data->pdu.coding == 0x00) {
684
+								int udh_bit_len = (1 + udh_len) * 8; // add 1 octet for the udh length
685
+								udh_bit_len += (7 - (udh_bit_len % 7));
686
+								len -= (udh_bit_len / 7);
687
+							}else{
688
+								len -= (1 + udh_len); // add 1 octet for the udh length
689
+							}
631 690
 						}
632 691
 
633
-						// TS 23.040, Sec. 9.2.3.16
692
+						blen = 2 + len*4;
693
+						rp_data->pdu.payload.sm.s = pkg_malloc(blen);
694
+						if(rp_data->pdu.payload.sm.s==NULL) {
695
+							LM_ERR("no more pkg\n");
696
+							return -1;
697
+						}
698
+						memset(rp_data->pdu.payload.sm.s, 0, blen);
634 699
 						// Coding: 7 Bit
635 700
 						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;
701
+							// We don't care about the extra used bytes here.
702
+							rp_data->pdu.payload.sm.len = len;
703
+							rp_data->pdu.payload.sm.len = gsm_to_ascii(&body.s[p], len, rp_data->pdu.payload.sm, fill_bits);
704
+						} else {
705
+							// Length is worst-case 2 * len (UCS2 is 2 Bytes, UTF8 is worst-case 4 Bytes)
706
+							rp_data->pdu.payload.sm.len = 0;
707
+							while (len > 0) {
708
+								j = (body.s[p] << 8) + body.s[p + 1];
709
+								p += 2;
710
+								rp_data->pdu.payload.sm.len += ucs2_to_utf8(j, &rp_data->pdu.payload.sm.s[rp_data->pdu.payload.sm.len]);
711
+								len -= 2;
712
+							}
664 713
 						}
665 714
 					}
666 715
 				}
... ...
@@ -685,7 +734,9 @@ int dumpRPData(sms_rp_data_t * rpdata, int level) {
685 734
 		LOG(level, "  Flags:                      %x (%i)\n", rpdata->pdu.flags, rpdata->pdu.flags);
686 735
 		LOG(level, "  Reference:                  %x (%i)\n", rpdata->pdu.reference, rpdata->pdu.reference);
687 736
 
737
+		LOG(level, "  Originating-Address flags:  %x (%i)\n", rpdata->pdu.originating_address_flags, rpdata->pdu.originating_address_flags);
688 738
 		LOG(level, "  Originating-Address:        %.*s (%i)\n", rpdata->pdu.originating_address.len, rpdata->pdu.originating_address.s, rpdata->pdu.originating_address.len);
739
+		LOG(level, "  Destination flags:          %x (%i)\n", rpdata->pdu.destination_flags, rpdata->pdu.destination_flags);
689 740
 		LOG(level, "  Destination:                %.*s (%i)\n", rpdata->pdu.destination.len, rpdata->pdu.destination.s, rpdata->pdu.destination.len);
690 741
 
691 742
 		LOG(level, "  Protocol:                   %x (%i)\n", rpdata->pdu.pid, rpdata->pdu.pid);
... ...
@@ -743,13 +794,13 @@ int pv_sms_ack(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
743 794
 
744 795
 
745 796
 /*
746
- * Creates the body for SMS-ACK from the current message
797
+ * Creates the body for SMS-DELIVER from the constructed rp data
747 798
  */
748 799
 int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
749 800
 	dumpRPData(rp_send_data, L_DBG);
750 801
 
751 802
 	str sms_body = {0, 0};
752
-	int buffer_size = 1024, lenpos = 0, i = 0;
803
+	int buffer_size = 1024, lenpos = 0, i = 0, smstext_len_pos = 0;
753 804
 
754 805
 	// We assume a maximum size of 1024 Bytes, to be verified.
755 806
 	sms_body.s = (char*)pkg_malloc(buffer_size);
... ...
@@ -787,7 +838,7 @@ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
787 838
 	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 839
 	// Originating Address:
789 840
 	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
841
+	sms_body.s[sms_body.len++] = rp_send_data->pdu.originating_address_flags;
791 842
 	sms_body.len += EncodePhoneNumber(rp_send_data->pdu.originating_address, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
792 843
 	// Protocol ID
793 844
 	sms_body.s[sms_body.len++] = rp_send_data->pdu.pid;
... ...
@@ -796,9 +847,37 @@ int pv_sms_body(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
796 847
 	// Service-Center-Timestamp (always 7 octets)
797 848
 	EncodeTime(&sms_body.s[sms_body.len]);
798 849
 	sms_body.len += 7;
850
+	smstext_len_pos = sms_body.len;
799 851
 	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;
852
+
853
+	// Coding: 7 Bit
854
+	if (rp_send_data->pdu.coding == 0x00) {
855
+		i = ascii_to_gsm(rp_send_data->pdu.payload.sm, &sms_body.s[sms_body.len], buffer_size - sms_body.len);
856
+		sms_body.len += i;
857
+	} else {
858
+	// Coding: ucs2
859
+		int i, ucs2, ucs2len = 0;
860
+		const unsigned char* p_input = (unsigned char*)rp_send_data->pdu.payload.sm.s;
861
+		const unsigned char* p_end = p_input;
862
+
863
+		for (i = 0; i < rp_send_data->pdu.payload.sm.len;) {
864
+			ucs2 = utf8_to_ucs2(p_input, &p_end);
865
+			if (ucs2 < 0) {
866
+				break;
867
+			}
868
+
869
+			sms_body.s[sms_body.len++] = (ucs2 >> 8) & 0xFF;
870
+			sms_body.s[sms_body.len++] = ucs2 & 0xFF;
871
+
872
+			ucs2len += 2;
873
+
874
+			i += (p_end - p_input);
875
+			p_input = p_end;
876
+		}
877
+
878
+		// Update the sms text len
879
+		sms_body.s[smstext_len_pos] = (unsigned char)ucs2len;
880
+	}
802 881
 
803 882
 	// Update the len of the PDU
804 883
 	sms_body.s[lenpos] = (unsigned char)(sms_body.len - lenpos - 1);
... ...
@@ -869,6 +948,10 @@ int pv_get_sms(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) {
869 948
 			}
870 949
 			return -1;
871 950
 		}
951
+		case SMS_TPDU_ORIGINATING_ADDRESS_FLAGS:
952
+			return pv_get_sintval(msg, param, res, (int)rp_data->pdu.originating_address_flags);
953
+		case SMS_TPDU_DESTINATION_FLAGS:
954
+			return pv_get_sintval(msg, param, res, (int)rp_data->pdu.destination_flags);
872 955
 	}
873 956
 	return 0;
874 957
 }
... ...
@@ -885,6 +968,8 @@ int pv_set_sms(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val)
885 968
 		}
886 969
 		// Initialize structure:
887 970
 		memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
971
+		rp_send_data->pdu.originating_address_flags = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension
972
+		rp_send_data->pdu.destination_flags = 0x91;
888 973
 	}
889 974
 
890 975
 	switch(param->pvn.u.isname.name.n) {
... ...
@@ -892,6 +977,8 @@ int pv_set_sms(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val)
892 977
 			freeRP_DATA(rp_send_data);
893 978
 			// Initialize structure:
894 979
 			memset(rp_send_data, 0, sizeof(struct _sms_rp_data));
980
+			rp_send_data->pdu.originating_address_flags = 0x91; // Type of number: ISDN/Telephony Numbering (E164), no extension
981
+			rp_send_data->pdu.destination_flags = 0x91;
895 982
 			break;
896 983
 		case SMS_RPDATA_TYPE:
897 984
 			if (val == NULL) {
... ...
@@ -1124,6 +1211,30 @@ int pv_set_sms(struct sip_msg* msg, pv_param_t *param, int op, pv_value_t *val)
1124 1211
 			concat->seq = (unsigned char)val->ri;
1125 1212
 			break;
1126 1213
 		}
1214
+		case SMS_TPDU_ORIGINATING_ADDRESS_FLAGS: {
1215
+			if (val == NULL) {
1216
+				rp_send_data->pdu.originating_address_flags = 0;
1217
+				return 0;
1218
+			}
1219
+			if (!(val->flags & PV_VAL_INT)) {
1220
+				LM_ERR("Invalid value type\n");
1221
+				return -1;
1222
+			}
1223
+			rp_send_data->pdu.originating_address_flags = (unsigned char)val->ri;
1224
+			break;
1225
+		}
1226
+		case SMS_TPDU_DESTINATION_FLAGS: {
1227
+			if (val == NULL) {
1228
+				rp_send_data->pdu.destination_flags = 0;
1229
+				return 0;
1230
+			}
1231
+			if (!(val->flags & PV_VAL_INT)) {
1232
+				LM_ERR("Invalid value type\n");
1233
+				return -1;
1234
+			}
1235
+			rp_send_data->pdu.destination_flags = (unsigned char)val->ri;
1236
+			break;
1237
+		}
1127 1238
 	}
1128 1239
 	return 0;
1129 1240
 }
... ...
@@ -1206,6 +1317,14 @@ int pv_parse_tpdu_name(pv_spec_p sp, str *in) {
1206 1317
 			else if (strncmp(in->s, "mp_part_num", 11) == 0) sp->pvp.pvn.u.isname.name.n = SMS_UDH_CONCATSM_SEQ;
1207 1318
 			else goto error;
1208 1319
 			break;
1320
+		case 12:
1321
+			if (strncmp(in->s, "origen_flags", 12) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_ORIGINATING_ADDRESS_FLAGS;
1322
+			else goto error;
1323
+			break;
1324
+		case 17:
1325
+			if (strncmp(in->s, "destination_flags", 17) == 0) sp->pvp.pvn.u.isname.name.n = SMS_TPDU_DESTINATION_FLAGS;
1326
+			else goto error;
1327
+			break;
1209 1328
 		default:
1210 1329
 			goto error;
1211 1330
 	}