1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "gsm_user_data_encode.h"
17 
18 #include "gsm_pdu_hex_value.h"
19 #include "gsm_sms_common_utils.h"
20 #include "securec.h"
21 #include "telephony_log_wrapper.h"
22 
23 namespace OHOS {
24 namespace Telephony {
25 using namespace std;
26 static constexpr uint8_t NORMAL_BYTE_BITS = 8;
27 static constexpr uint8_t GSM_ENCODE_BITS = 7;
28 static constexpr uint8_t SLIDE_DATA_STEP = 2;
29 static constexpr uint8_t MAX_TPDU_LEN = 255;
30 static constexpr uint8_t HEX_07 = 0x07;
31 static constexpr uint8_t HEX_08 = 0x08;
32 const std::string CT_SMSC = "10659401";
33 
GsmUserDataEncode(std::shared_ptr<GsmUserDataPdu> data)34 GsmUserDataEncode::GsmUserDataEncode(std::shared_ptr<GsmUserDataPdu> data)
35 {
36     userData_ = data;
37 }
38 
~GsmUserDataEncode()39 GsmUserDataEncode::~GsmUserDataEncode() {}
40 
EncodeGsmPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)41 bool GsmUserDataEncode::EncodeGsmPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
42 {
43     uint8_t fillBits = 0;
44     if (!EncodeGsmHeadPdu(buffer, userData, fillBits)) {
45         return false;
46     }
47     return EncodeGsmBodyPdu(buffer, userData, fillBits);
48 }
49 
EncodeGsmHeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,uint8_t & fillBits)50 bool GsmUserDataEncode::EncodeGsmHeadPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, uint8_t &fillBits)
51 {
52     if (userData == nullptr || userData_ == nullptr) {
53         TELEPHONY_LOGE("nullptr error.");
54         return false;
55     }
56 
57     uint16_t location = buffer.GetIndex();
58     if (userData->headerCnt > 0) {
59         buffer.MoveForward(SLIDE_DATA_STEP);
60     } else {
61         buffer.MoveForward(HEX_VALUE_01);
62     }
63     uint16_t udhl = buffer.GetIndex();
64     for (uint8_t i = 0; i < userData->headerCnt; i++) {
65         userData_->EncodeHeader(buffer, userData->header[i]);
66     }
67 
68     if (buffer.GetIndex() > udhl) {
69         udhl = buffer.GetIndex() - udhl;
70     } else {
71         udhl = 0;
72     }
73     if (udhl > 0) {
74         fillBits = ((udhl + 1) * NORMAL_BYTE_BITS) % GSM_ENCODE_BITS; /* + UDHL */
75     }
76     if (fillBits > 0 && GSM_ENCODE_BITS > fillBits) {
77         fillBits = GSM_ENCODE_BITS - fillBits;
78     } else {
79         fillBits = 0;
80     }
81 
82     /* Set UDL, UDHL */
83     if (udhl > 0) {
84         uint16_t value = ((udhl + 1) * HEX_08) + fillBits + (userData->length * HEX_07);
85         if (!buffer.InsertByte((value / HEX_07), location)) {
86             TELEPHONY_LOGE("write data error.");
87             return false;
88         }
89         if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
90             TELEPHONY_LOGE("write data error.");
91             return false;
92         }
93     } else {
94         if (!buffer.InsertByte(userData->length, location)) {
95             TELEPHONY_LOGE("write data error.");
96             return false;
97         }
98     }
99     return true;
100 }
101 
EncodeGsmBodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,uint8_t fillBits)102 bool GsmUserDataEncode::EncodeGsmBodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, uint8_t fillBits)
103 {
104     if (userData == nullptr) {
105         TELEPHONY_LOGE("nullptr error.");
106         return false;
107     }
108 
109     GsmSmsCommonUtils utils;
110     bool packResult =
111         utils.Pack7bitChar(buffer, reinterpret_cast<const uint8_t *>(userData->data), userData->length, fillBits);
112     return packResult;
113 }
114 
Encode8bitPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,std::string & destAddr)115 bool GsmUserDataEncode::Encode8bitPdu(
116     SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, std::string &destAddr)
117 {
118     if (!Encode8bitHeadPdu(buffer, userData, destAddr)) {
119         return false;
120     }
121     return Encode8bitBodyPdu(buffer, userData);
122 }
123 
Encode8bitHeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData,std::string & destAddr)124 bool GsmUserDataEncode::Encode8bitHeadPdu(
125     SmsWriteBuffer &buffer, const struct SmsUDPackage *userData, std::string &destAddr)
126 {
127     if (userData == nullptr || userData_ == nullptr) {
128         TELEPHONY_LOGE("nullptr error.");
129         return false;
130     }
131 
132     uint16_t location = buffer.GetIndex();
133     if (userData->headerCnt > 0 && CT_SMSC.compare(destAddr) != 0) {
134         buffer.MoveForward(SLIDE_DATA_STEP);
135     } else {
136         buffer.MoveForward(HEX_VALUE_01);
137     }
138 
139     /* Encode User Data Header */
140     uint16_t udhl = buffer.GetIndex();
141     for (uint8_t index = 0; index < userData->headerCnt && CT_SMSC.compare(destAddr) != 0; index++) {
142         userData_->EncodeHeader(buffer, userData->header[index]);
143     }
144     if (buffer.GetIndex() > udhl) {
145         udhl = buffer.GetIndex() - udhl;
146     } else {
147         udhl = 0;
148     }
149     /* Set UDL, UDHL */
150     if (udhl > 0) {
151         if (!buffer.InsertByte(static_cast<uint8_t>(udhl + 1 + userData->length), location)) {
152             TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
153             return false;
154         }
155         if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
156             TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
157             return false;
158         }
159     } else {
160         if (!buffer.InsertByte(userData->length, location)) {
161             TELEPHONY_LOGE("Encode8bitHeadPdu write data error.");
162             return false;
163         }
164     }
165     return true;
166 }
167 
Encode8bitBodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)168 bool GsmUserDataEncode::Encode8bitBodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
169 {
170     if (userData == nullptr || buffer.data_ == nullptr) {
171         TELEPHONY_LOGE("nullptr error");
172         return false;
173     }
174 
175     if (buffer.GetIndex() >= MAX_TPDU_LEN || userData->length + buffer.GetIndex() > MAX_TPDU_LEN) {
176         TELEPHONY_LOGE(" userData length error.");
177         return false;
178     }
179     if (buffer.GetIndex() >= buffer.GetSize() || userData->length + buffer.GetIndex() > buffer.GetSize()) {
180         TELEPHONY_LOGE("buffer error.");
181         return false;
182     }
183     uint16_t destLen = MAX_TPDU_LEN - buffer.GetIndex() - HEX_VALUE_01;
184     if (memcpy_s(buffer.data_.get() + buffer.GetIndex(), destLen, userData->data, userData->length) != EOK) {
185         TELEPHONY_LOGE("memcpy_s error");
186         return false;
187     }
188     buffer.MoveForward(userData->length);
189     return true;
190 }
191 
EncodeUcs2Pdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)192 bool GsmUserDataEncode::EncodeUcs2Pdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
193 {
194     if (!EncodeUcs2HeadPdu(buffer, userData)) {
195         return false;
196     }
197     return EncodeUcs2BodyPdu(buffer, userData);
198 }
199 
EncodeUcs2HeadPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)200 bool GsmUserDataEncode::EncodeUcs2HeadPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
201 {
202     if (userData == nullptr || userData_ == nullptr) {
203         TELEPHONY_LOGE("nullptr error");
204         return false;
205     }
206     uint16_t location = buffer.GetIndex();
207     if (userData->headerCnt == 0) {
208         buffer.MoveForward(1);
209     } else {
210         buffer.MoveForward(SLIDE_DATA_STEP);
211     }
212 
213     /* Encode User Data Header */
214     uint16_t udhl = buffer.GetIndex();
215     for (uint8_t j = 0; j < userData->headerCnt; j++) {
216         userData_->EncodeHeader(buffer, userData->header[j]);
217     }
218     if (buffer.GetIndex() > udhl) {
219         udhl = buffer.GetIndex() - udhl;
220     } else {
221         udhl = 0;
222     }
223 
224     /* Set UDL, UDHL */
225     if (udhl > 0) {
226         if (!buffer.InsertByte(static_cast<uint8_t>(udhl + 1 + userData->length), location)) {
227             TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
228             return false;
229         }
230         if (!buffer.InsertByte(static_cast<uint8_t>(udhl), location + 1)) {
231             TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
232             return false;
233         }
234     } else {
235         if (!buffer.InsertByte(userData->length, location)) {
236             TELEPHONY_LOGE("EncodeUcs2HeadPdu write data error.");
237             return false;
238         }
239     }
240     return true;
241 }
242 
EncodeUcs2BodyPdu(SmsWriteBuffer & buffer,const struct SmsUDPackage * userData)243 bool GsmUserDataEncode::EncodeUcs2BodyPdu(SmsWriteBuffer &buffer, const struct SmsUDPackage *userData)
244 {
245     if (userData == nullptr) {
246         TELEPHONY_LOGE("nullptr error");
247         return false;
248     }
249     if (userData->length + buffer.GetIndex() >= MAX_TPDU_LEN) {
250         TELEPHONY_LOGE("data length error");
251         return false;
252     }
253     if (buffer.data_ == nullptr || (buffer.GetIndex() + userData->length) > buffer.GetSize()) {
254         TELEPHONY_LOGE("buffer error.");
255         return false;
256     }
257     uint16_t destLen = MAX_TPDU_LEN - buffer.GetIndex() - HEX_VALUE_01;
258     if (memcpy_s(buffer.data_.get() + buffer.GetIndex(), destLen, userData->data, userData->length) != EOK) {
259         TELEPHONY_LOGE("memcpy_s error");
260         return false;
261     }
262     buffer.MoveForward(userData->length);
263     return true;
264 }
265 } // namespace Telephony
266 } // namespace OHOS