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 "cdma_sms_test.h"
17 
18 #include <chrono>
19 #include <codecvt>
20 #include <iostream>
21 #include <locale>
22 #include <sstream>
23 
24 #include "cdma_sms_sender.h"
25 #include "cdma_sms_transport_message.h"
26 #include "delivery_short_message_callback_stub.h"
27 #include "send_short_message_callback_stub.h"
28 #include "sms_sender.h"
29 #include "string_utils.h"
30 
31 namespace OHOS {
32 namespace Telephony {
33 using namespace std;
34 using namespace OHOS::Telephony;
35 static constexpr uint8_t TEST_MENU_TEXT_DELIVERY = 0;
36 static constexpr uint8_t TEST_MENU_ENCODE_SUBMIT = 1;
37 static constexpr uint8_t TEST_MENU_ENCODE_CANCEL = 2;
38 static constexpr uint8_t TEST_MENU_ENCODE_DELIVER_REPORT = 3;
39 static constexpr uint8_t TEST_MENU_ENCODE_ACK = 4;
40 static constexpr uint8_t TEST_MENU_DECODE_MSG = 5;
41 static constexpr uint8_t TEST_MENU_DECODE_BEARER_DATA = 6;
42 static constexpr uint8_t TEST_MENU_EXIT = 100;
43 static constexpr uint8_t BIT_8 = 8;
44 static constexpr uint8_t HEX_CHAR_LEN = 2;
45 static constexpr uint8_t VALUE_INDEX = 2;
46 static constexpr uint16_t MSG_ID = 100;
47 static constexpr uint8_t TP_FAIL_CAUSE = 0x81;
48 static constexpr uint8_t REPLY_SEQ = 10;
49 
SetPduSeqInfo(const std::size_t size,const std::unique_ptr<CdmaTransportMsg> & transMsg,const std::size_t index,const uint8_t msgRef8bit) const50 void CdmaSmsTest::SetPduSeqInfo(const std::size_t size, const std::unique_ptr<CdmaTransportMsg> &transMsg,
51     const std::size_t index, const uint8_t msgRef8bit) const
52 {
53     if (size > 1) {
54         transMsg->data.p2p.teleserviceId = static_cast<uint16_t>(SmsTransTelsvcId::WEMT);
55         transMsg->data.p2p.telesvcMsg.data.submit.msgId.headerInd = true;
56         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.headerCnt = 1;
57         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.header[0].udhType = UDH_CONCAT_8BIT;
58         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.msgRef = msgRef8bit;
59         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.totalSeg =
60             static_cast<uint8_t>(size);
61         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.seqNum = index + 1;
62     }
63 }
64 
UnicodeToString(uint8_t * s,int len) const65 std::string CdmaSmsTest::UnicodeToString(uint8_t *s, int len) const
66 {
67     std::string u8str;
68     std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
69     for (int i = 0; i < len; i += HEX_CHAR_LEN) {
70         char32_t u8char = (s[i] << BIT_8) | s[i + 1];
71         u8str += converter.to_bytes(u8char);
72     }
73     return u8str;
74 }
75 
PrintAddr(TransportAddr & addr,string s) const76 void CdmaSmsTest::PrintAddr(TransportAddr &addr, string s) const
77 {
78     if (addr.addrLen == 0) {
79         return;
80     }
81     stringstream ss;
82     ss << s << "digitMode  : " << addr.digitMode << endl;
83     ss << s << "numberMode : " << addr.numberMode << endl;
84     ss << s << "numberType : " << static_cast<int>(addr.numberType) << endl;
85     ss << s << "numberPlan : " << static_cast<int>(addr.numberPlan) << endl;
86     ss << s << "addrLen    : " << addr.addrLen << endl;
87     ss << s << "szData     : ";
88     for (uint8_t i = 0; i < addr.addrLen; i++) {
89         ss << addr.szData[i];
90     }
91     ss << endl;
92     cout << ss.str() << flush;
93 }
94 
PrintSubAddr(TransportSubAddr & addr,string s) const95 void CdmaSmsTest::PrintSubAddr(TransportSubAddr &addr, string s) const
96 {
97     if (addr.addrLen == 0) {
98         return;
99     }
100     switch (addr.type) {
101         case TransportSubAddrType::NSAP:
102             cout << s << "type    : NSAP - " << static_cast<int>(addr.type) << endl;
103             break;
104         case TransportSubAddrType::USER:
105             cout << s << "type    : USER - " << static_cast<int>(addr.type) << endl;
106             break;
107         default:
108             cout << s << "type    : " << static_cast<int>(addr.type) << endl;
109             break;
110     }
111     cout << s << "odd     : " << addr.odd << endl;
112     cout << s << "addrLen : " << addr.addrLen << endl;
113     stringstream ss;
114     for (uint8_t i = 0; i < addr.addrLen; i++) {
115         ss << addr.szData[i];
116     }
117     cout << s << "szData  : " << ss.str() << endl << flush;
118 }
119 
PrintSmsTeleSvcAddr(SmsTeleSvcAddr & addr,string s) const120 void CdmaSmsTest::PrintSmsTeleSvcAddr(SmsTeleSvcAddr &addr, string s) const
121 {
122     if (addr.addrLen == 0) {
123         return;
124     }
125     cout << s << "digitMode  : " << addr.digitMode << endl;
126     cout << s << "numberType : " << static_cast<int>(addr.numberType) << endl;
127     cout << s << "numberPlan : " << static_cast<int>(addr.numberPlan) << endl;
128     cout << s << "addrLen    : " << addr.addrLen << endl;
129     stringstream ss;
130     for (uint8_t i = 0; i < addr.addrLen; i++) {
131         ss << addr.szData[i];
132     }
133     cout << s << "szData     : " << ss.str() << endl << flush;
134 }
135 
PrintHeader(const SmsUDH & header,string s) const136 void CdmaSmsTest::PrintHeader(const SmsUDH &header, string s) const
137 {
138     switch (header.udhType) {
139         case UDH_CONCAT_8BIT: {
140             cout << s << "udhType : UDH_CONCAT_8BIT - " << static_cast<int>(header.udhType) << endl;
141             cout << s << "concat8bit: msgRef[" << static_cast<int>(header.udh.concat8bit.msgRef) << "] totalSeg["
142                  << static_cast<int>(header.udh.concat8bit.totalSeg) << "] seqNum["
143                  << static_cast<int>(header.udh.concat8bit.seqNum) << "]" << endl;
144             break;
145         }
146         case UDH_CONCAT_16BIT: {
147             cout << s << "udhType : UDH_CONCAT_16BIT - " << static_cast<int>(header.udhType) << endl;
148             cout << s << "concat16bit.seqNum [" << static_cast<int>(header.udh.concat16bit.seqNum) << "]" << endl;
149             break;
150         }
151         case UDH_APP_PORT_8BIT: {
152             cout << s << "udhType : UDH_APP_PORT_8BIT - " << static_cast<int>(header.udhType) << endl;
153             cout << s << "appPort8bit.destPort [" << static_cast<int>(header.udh.appPort8bit.destPort) << "]" << endl;
154             cout << s << "appPort8bit.originPort [" << static_cast<int>(header.udh.appPort8bit.originPort) << "]"
155                  << endl;
156             break;
157         }
158         case UDH_APP_PORT_16BIT: {
159             cout << s << "udhType : UDH_APP_PORT_16BIT - " << static_cast<int>(header.udhType) << endl;
160             cout << s << "appPort16bit.destPort [" << static_cast<int>(header.udh.appPort16bit.destPort) << "]" << endl;
161             cout << s << "appPort16bit.originPort [" << static_cast<int>(header.udh.appPort16bit.originPort) << "]"
162                  << endl;
163             break;
164         }
165         case UDH_SPECIAL_SMS: {
166             cout << s << "udhType : UDH_SPECIAL_SMS - " << static_cast<int>(header.udhType) << endl;
167             cout << s << "Decoding special sms udh." << endl;
168             break;
169         }
170         case UDH_SINGLE_SHIFT: {
171             cout << s << "udhType : UDH_SINGLE_SHIFT - " << static_cast<int>(header.udhType) << endl;
172             cout << s << "singleShift.langId [" << static_cast<int>(header.udh.singleShift.langId) << "]" << endl;
173             break;
174         }
175         case UDH_LOCKING_SHIFT: {
176             cout << s << "udhType : UDH_LOCKING_SHIFT - " << static_cast<int>(header.udhType) << endl;
177             cout << s << "lockingShift.langId [" << static_cast<int>(header.udh.lockingShift.langId) << "]" << endl;
178             break;
179         }
180         default:
181             cout << s << "udhType : " << static_cast<int>(header.udhType) << endl;
182             break;
183     }
184     cout << flush;
185 }
186 
PrintTimeAbs(SmsTimeAbs & time,string s) const187 void CdmaSmsTest::PrintTimeAbs(SmsTimeAbs &time, string s) const
188 {
189     cout << dec << s << static_cast<int>(time.year) << "/" << static_cast<int>(time.month) << "/"
190          << static_cast<int>(time.day) << " " << static_cast<int>(time.hour) << ":" << static_cast<int>(time.minute)
191          << ":" << static_cast<int>(time.second) << endl;
192     cout << flush;
193 }
194 
PrintEncodeType(SmsEncodingType encodeType,string s) const195 void CdmaSmsTest::PrintEncodeType(SmsEncodingType encodeType, string s) const
196 {
197     switch (encodeType) {
198         case SmsEncodingType::OCTET:
199             cout << s << "encodeType : OCTET - " << static_cast<int>(encodeType) << endl;
200             break;
201         case SmsEncodingType::EPM:
202             cout << s << "encodeType : EPM - " << static_cast<int>(encodeType) << endl;
203             break;
204         case SmsEncodingType::ASCII_7BIT:
205             cout << s << "encodeType : ASCII_7BIT - " << static_cast<int>(encodeType) << endl;
206             break;
207         case SmsEncodingType::IA5:
208             cout << s << "encodeType : IA5 - " << static_cast<int>(encodeType) << endl;
209             break;
210         case SmsEncodingType::UNICODE:
211             cout << s << "encodeType : UNICODE - " << static_cast<int>(encodeType) << endl;
212             break;
213         case SmsEncodingType::SHIFT_JIS:
214             cout << s << "encodeType : SHIFT_JIS - " << static_cast<int>(encodeType) << endl;
215             break;
216         case SmsEncodingType::KOREAN:
217             cout << s << "encodeType : KOREAN - " << static_cast<int>(encodeType) << endl;
218             break;
219         case SmsEncodingType::LATIN_HEBREW:
220             cout << s << "encodeType : LATIN_HEBREW - " << static_cast<int>(encodeType) << endl;
221             break;
222         case SmsEncodingType::LATIN:
223             cout << s << "encodeType : LATIN - " << static_cast<int>(encodeType) << endl;
224             break;
225         case SmsEncodingType::GSM7BIT:
226             cout << s << "encodeType : GSM7BIT - " << static_cast<int>(encodeType) << endl;
227             break;
228         case SmsEncodingType::GSMDCS:
229             cout << s << "encodeType : GSMDCS - " << static_cast<int>(encodeType) << endl;
230             break;
231         case SmsEncodingType::EUCKR:
232             cout << s << "encodeType : EUCKR - " << static_cast<int>(encodeType) << endl;
233             break;
234         case SmsEncodingType::RESERVED:
235             cout << s << "encodeType : RESERVED - " << static_cast<int>(encodeType) << endl;
236             break;
237         default:
238             cout << s << "encodeType : - " << static_cast<int>(encodeType) << endl;
239             break;
240     }
241     cout << flush;
242 }
243 
PrintUserData(SmsTeleSvcUserData & userData,string s) const244 void CdmaSmsTest::PrintUserData(SmsTeleSvcUserData &userData, string s) const
245 {
246     if (userData.userData.length == 0) {
247         return;
248     }
249     PrintEncodeType(userData.encodeType, s);
250     cout << s << "msgType    : " << static_cast<int>(userData.msgType) << endl;
251     cout << s << "headerCnt  : " << static_cast<int>(userData.userData.headerCnt) << endl;
252     for (int i = 0; i < userData.userData.headerCnt; i++) {
253         PrintHeader(userData.userData.header[i]);
254     }
255     cout << s << "length     : " << userData.userData.length << endl;
256     stringstream ss;
257     if (userData.encodeType == SmsEncodingType::UNICODE) {
258         unsigned char unicodeChar[userData.userData.length];
259         for (uint8_t i = 0; i < userData.userData.length; i++) {
260             unicodeChar[i] = userData.userData.data[i];
261         }
262         cout << s << "data       : " << UnicodeToString(unicodeChar, userData.userData.length) << endl;
263     } else {
264         for (uint8_t i = 0; i < userData.userData.length; i++) {
265             ss << userData.userData.data[i];
266         }
267         cout << s << "data       : " << ss.str() << endl;
268     }
269     cout << flush;
270 }
271 
PrintCmasData(SmsTeleSvcCmasData cmasData,string s) const272 void CdmaSmsTest::PrintCmasData(SmsTeleSvcCmasData cmasData, string s) const
273 {
274     if (cmasData.dataLen == 0) {
275         return;
276     }
277     PrintEncodeType(cmasData.encodeType, s);
278     cout << s << "dataLen : " << cmasData.dataLen << endl;
279     stringstream ss;
280     if (cmasData.encodeType == SmsEncodingType::UNICODE) {
281         unsigned char unicodeChar[cmasData.dataLen];
282         for (uint8_t i = 0; i < cmasData.dataLen; i++) {
283             unicodeChar[i] = cmasData.alertText[i];
284         }
285         ss << UnicodeToString(unicodeChar, cmasData.dataLen);
286     } else {
287         for (uint8_t i = 0; i < cmasData.dataLen; i++) {
288             ss << static_cast<uint8_t>(cmasData.alertText[i]);
289         }
290     }
291     cout << s << "alertText         : " << ss.str() << endl;
292     cout << s << "category          :  " << static_cast<uint32_t>(cmasData.category) << endl;
293     cout << s << "responseType      :  " << static_cast<uint32_t>(cmasData.responseType) << endl;
294     cout << s << "severity          :  " << static_cast<uint32_t>(cmasData.severity) << endl;
295     cout << s << "urgency           :  " << static_cast<uint32_t>(cmasData.urgency) << endl;
296     cout << s << "certainty         :  " << static_cast<uint32_t>(cmasData.certainty) << endl;
297     cout << s << "id                :  " << static_cast<uint32_t>(cmasData.id) << endl;
298     cout << s << "alertHandle       :  " << static_cast<uint32_t>(cmasData.alertHandle) << endl;
299     cout << s << "language          :  " << static_cast<uint32_t>(cmasData.language) << endl;
300     cout << s << "isWrongRecodeType :  " << static_cast<uint32_t>(cmasData.isWrongRecodeType) << endl;
301     cout << s << "expires           : " << endl;
302     PrintTimeAbs(cmasData.expires, "             ");
303     cout << flush;
304 }
305 
PrintSmsReplyOption(SmsReplyOption & replyOpt,string s) const306 void CdmaSmsTest::PrintSmsReplyOption(SmsReplyOption &replyOpt, string s) const
307 {
308     cout << s << "userAck : " << replyOpt.userAck << endl;
309     cout << s << "dak     : " << replyOpt.dak << endl;
310     cout << s << "readAck : " << replyOpt.readAck << endl;
311     cout << s << "report  : " << replyOpt.report << endl;
312     cout << flush;
313 }
314 
PrintSmsValPeriod(SmsValPeriod & valPeriod,string s) const315 void CdmaSmsTest::PrintSmsValPeriod(SmsValPeriod &valPeriod, string s) const
316 {
317     switch (valPeriod.format) {
318         case SMS_TIME_RELATIVE:
319             cout << s << "RELATIVE : " << static_cast<uint32_t>(valPeriod.time.relTime.time) << endl;
320             break;
321         case SMS_TIME_ABSOLUTE:
322             cout << s << "ABSOLUTE : " << endl;
323             PrintTimeAbs(valPeriod.time.absTime);
324             break;
325         case SMS_TIME_EMPTY:
326             cout << s << "EMPTY" << endl;
327             break;
328         default:
329             cout << s << " " << static_cast<uint32_t>(valPeriod.format) << endl;
330             break;
331     }
332     cout << flush;
333 }
334 
PrintSmsEnhancedVmn(SmsEnhancedVmn & vmn,string s) const335 void CdmaSmsTest::PrintSmsEnhancedVmn(SmsEnhancedVmn &vmn, string s) const
336 {
337     cout << s << "priority : " << static_cast<int>(vmn.priority) << endl;
338     cout << s << "vmMsgId : " << static_cast<int>(vmn.vmMsgId) << endl;
339     cout << s << "anNumField : " << static_cast<int>(vmn.anNumField) << endl;
340     cout << s << "cliNumField : " << static_cast<int>(vmn.cliNumField) << endl;
341     cout << flush;
342 }
343 
PrintTeleserviceDeliver(TeleserviceDeliver & deliver,bool isCMAS,string s) const344 void CdmaSmsTest::PrintTeleserviceDeliver(TeleserviceDeliver &deliver, bool isCMAS, string s) const
345 {
346     cout << s << "  msgId          : " << static_cast<int>(deliver.msgId.msgId) << endl;
347     cout << s << "  headerInd      : " << static_cast<int>(deliver.msgId.headerInd) << endl;
348     if (isCMAS) {
349         cout << s << "  cmasData       : " << endl;
350         PrintCmasData(deliver.cmasData);
351     } else {
352         cout << s << "  userData       : " << endl;
353         PrintUserData(deliver.userData);
354     }
355     cout << s << "  timeStamp      : " << endl;
356     PrintTimeAbs(deliver.timeStamp);
357     cout << s << "  valPeriod      : " << endl;
358     PrintSmsValPeriod(deliver.valPeriod);
359     cout << s << "  deferValPeriod : " << endl;
360     PrintSmsValPeriod(deliver.deferValPeriod);
361     cout << s << "  replyOpt       : " << endl;
362     PrintSmsReplyOption(deliver.replyOpt);
363     cout << s << "  numMsg         : " << static_cast<int>(deliver.numMsg) << endl;
364     cout << s << "  language       : " << static_cast<int>(deliver.language) << endl;
365     cout << s << "  callbackNumber : " << endl;
366     PrintSmsTeleSvcAddr(deliver.callbackNumber);
367     cout << s << "  depositId      : " << static_cast<int>(deliver.depositId) << endl;
368     cout << s << "  vmn            : " << endl;
369     PrintSmsEnhancedVmn(deliver.vmn);
370 }
371 
PrintTeleserviceSubmit(TeleserviceSubmit submit,string s) const372 void CdmaSmsTest::PrintTeleserviceSubmit(TeleserviceSubmit submit, string s) const
373 {
374     cout << s << "  msgId          : " << static_cast<int>(submit.msgId.msgId) << endl;
375     cout << s << "  headerInd      : " << static_cast<int>(submit.msgId.headerInd) << endl;
376     cout << s << "  userData       : " << endl;
377     PrintUserData(submit.userData);
378     cout << s << "  valPeriod      : " << endl;
379     PrintSmsValPeriod(submit.valPeriod);
380     cout << s << "  deferValPeriod : " << endl;
381     PrintSmsValPeriod(submit.deferValPeriod);
382     cout << s << "  replyOpt       : " << endl;
383     PrintSmsReplyOption(submit.replyOpt);
384     cout << s << "  language       : " << static_cast<int>(submit.language) << endl;
385     cout << s << "  callbackNumber : " << endl;
386     PrintSmsTeleSvcAddr(submit.callbackNumber);
387     cout << s << "  depositId      : " << static_cast<int>(submit.depositId) << endl;
388 }
389 
PrintTeleserviceDeliverAck(TeleserviceDeliverAck deliveryAck,string s) const390 void CdmaSmsTest::PrintTeleserviceDeliverAck(TeleserviceDeliverAck deliveryAck, string s) const
391 {
392     cout << s << "  msgId     : " << static_cast<int>(deliveryAck.msgId.msgId) << endl;
393     cout << s << "  headerInd : " << static_cast<int>(deliveryAck.msgId.headerInd) << endl;
394     cout << s << "  userData  : " << endl;
395     PrintUserData(deliveryAck.userData);
396     cout << s << "  timeStamp : " << endl;
397     PrintTimeAbs(deliveryAck.timeStamp);
398     cout << s << "  msgStatus : " << static_cast<int>(deliveryAck.msgStatus) << endl;
399 }
400 
PrintTelesvc(CdmaTeleserviceMsg & telesvcMsg,bool isCMAS,string s) const401 void CdmaSmsTest::PrintTelesvc(CdmaTeleserviceMsg &telesvcMsg, bool isCMAS, string s) const
402 {
403     cout << s << "TeleserviceMsg >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
404     switch (telesvcMsg.type) {
405         case TeleserviceMsgType::RESERVED:
406             cout << s << "Type: RESERVED - " << static_cast<int>(telesvcMsg.type) << endl;
407             break;
408         case TeleserviceMsgType::DELIVER:
409             cout << s << "Type: DELIVER - " << static_cast<int>(telesvcMsg.type) << endl;
410             PrintTeleserviceDeliver(telesvcMsg.data.deliver, isCMAS, s);
411             break;
412         case TeleserviceMsgType::SUBMIT: {
413             cout << s << "Type: SUBMIT - " << static_cast<int>(telesvcMsg.type) << endl;
414             PrintTeleserviceSubmit(telesvcMsg.data.submit, s);
415             break;
416         }
417         case TeleserviceMsgType::CANCEL:
418             cout << s << "Type: CANCEL - " << static_cast<int>(telesvcMsg.type) << endl;
419             cout << s << "  msgId     : " << static_cast<int>(telesvcMsg.data.cancel.msgId.msgId) << endl;
420             cout << s << "  headerInd : " << static_cast<int>(telesvcMsg.data.cancel.msgId.headerInd) << endl;
421             break;
422         case TeleserviceMsgType::DELIVERY_ACK:
423             cout << s << "Type: DELIVERY_ACK - " << static_cast<int>(telesvcMsg.type) << endl;
424             PrintTeleserviceDeliverAck(telesvcMsg.data.deliveryAck, s);
425             break;
426         case TeleserviceMsgType::DELIVER_REPORT:
427             cout << s << "Type: DELIVER_REPORT - " << static_cast<int>(telesvcMsg.type) << endl;
428             cout << s << "  msgId           : " << static_cast<int>(telesvcMsg.data.report.msgId.msgId) << endl;
429             cout << s << "  headerInd       : " << static_cast<int>(telesvcMsg.data.report.msgId.headerInd) << endl;
430             cout << s << "  userData        : " << endl;
431             PrintUserData(telesvcMsg.data.report.userData);
432             cout << s << "  tpFailCause     : " << static_cast<int>(telesvcMsg.data.report.tpFailCause) << endl;
433             cout << s << "  language        : " << static_cast<int>(telesvcMsg.data.report.language) << endl;
434             cout << s << "  multiEncodeData : " << static_cast<int>(telesvcMsg.data.report.multiEncodeData) << endl;
435             break;
436         case TeleserviceMsgType::SUBMIT_REPORT:
437             cout << s << "Type: SUBMIT_REPORT - " << static_cast<int>(telesvcMsg.type) << endl;
438             break;
439         default:
440             cout << s << "Type: RESERVED - " << static_cast<int>(telesvcMsg.type) << endl;
441             break;
442     }
443     cout << s << "TeleserviceMsg <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl << flush;
444 }
445 
PrintMsg(CdmaTransportMsg & msg) const446 void CdmaSmsTest::PrintMsg(CdmaTransportMsg &msg) const
447 {
448     cout << "TransportMsg >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << endl;
449     if (msg.type == CdmaTransportMsgType::P2P) {
450         cout << "P2P" << endl;
451         cout << "  teleserviceId : " << hex << showbase << static_cast<int>(msg.data.p2p.teleserviceId) << dec << endl;
452         cout << "  serviceCtg    : " << hex << showbase << static_cast<int>(msg.data.p2p.serviceCtg) << dec << endl;
453         cout << "  address       : " << endl;
454         PrintAddr(msg.data.p2p.address);
455         cout << "  subAddress    : " << endl;
456         PrintSubAddr(msg.data.p2p.subAddress);
457         cout << "  replySeq      : " << static_cast<int>(msg.data.p2p.replySeq) << endl;
458         cout << "  telesvcMsg    : " << endl;
459         PrintTelesvc(msg.data.p2p.telesvcMsg);
460     } else if (msg.type == CdmaTransportMsgType::BROADCAST) {
461         cout << "BROADCAST" << endl;
462         cout << "  serviceCtg : " << msg.data.broadcast.serviceCtg << endl;
463         cout << "  telesvcMsg : " << endl;
464         if (msg.data.broadcast.serviceCtg >= static_cast<uint16_t>(SmsServiceCtg::CMAS_PRESIDENTIAL) &&
465             msg.data.broadcast.serviceCtg <= static_cast<uint16_t>(SmsServiceCtg::CMAS_TEST)) {
466             PrintTelesvc(msg.data.broadcast.telesvcMsg, true);
467         } else {
468             PrintTelesvc(msg.data.broadcast.telesvcMsg);
469         }
470     } else if (msg.type == CdmaTransportMsgType::ACK) {
471         cout << "ACK" << endl;
472         cout << "  address       : " << endl;
473         PrintAddr(msg.data.ack.address);
474         cout << "  subAddress    : " << endl;
475         cout << "  causeCode     : " << endl;
476         cout << "  transReplySeq : " << static_cast<int>(msg.data.ack.causeCode.transReplySeq) << endl;
477         cout << "  errorClass    : " << static_cast<int>(msg.data.ack.causeCode.errorClass) << endl;
478         cout << "  causeCode     : " << static_cast<int>(msg.data.ack.causeCode.causeCode) << endl;
479     } else {
480         cout << "Unknown type : " << static_cast<int>(msg.type) << endl;
481     }
482     cout << "TransportMsg <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << endl << flush;
483 }
484 
EncodeMsg(CdmaTransportMsg & msg) const485 void CdmaSmsTest::EncodeMsg(CdmaTransportMsg &msg) const
486 {
487     std::unique_ptr<CdmaSmsTransportMessage> transportMessage = CdmaSmsTransportMessage::CreateTransportMessage(msg);
488     if (transportMessage == nullptr || transportMessage->IsEmpty()) {
489         std::cout << "create transport message error" << std::endl;
490         return;
491     }
492     SmsWriteBuffer pduBuffer;
493     if (!transportMessage->Encode(pduBuffer)) {
494         std::cout << "encode error" << std::endl;
495         return;
496     }
497     std::unique_ptr<std::vector<uint8_t>> pdu = pduBuffer.GetPduBuffer();
498     if (pdu == nullptr) {
499         std::cout << "get pdubuffer error" << std::endl;
500         return;
501     }
502     PrintMsg(msg);
503     std::cout << "TestEncodeSubmitMsg : " << StringUtils::StringToHex(*pdu) << std::endl;
504 }
505 
TestTextBasedSmsDelivery() const506 void CdmaSmsTest::TestTextBasedSmsDelivery() const
507 {
508     std::cout << "CdmaSmsTest::TestTextBasedSmsDelivery" << std::endl;
509     std::function<void(std::shared_ptr<SmsSendIndexer>)> fun = nullptr;
510     auto cdmaSmsSender = std::make_shared<CdmaSmsSender>(1, fun);
511     const sptr<ISendShortMessageCallback> sendCallback =
512         iface_cast<ISendShortMessageCallback>(new SendShortMessageCallbackStub());
513     if (sendCallback == nullptr) {
514         return;
515     }
516     const sptr<IDeliveryShortMessageCallback> deliveryCallback =
517         iface_cast<IDeliveryShortMessageCallback>(new DeliveryShortMessageCallbackStub());
518     if (deliveryCallback == nullptr) {
519         return;
520     }
521     const std::string desAddr = "qwe";
522     const std::string scAddr = "123";
523     const std::string text = "123";
524     cdmaSmsSender->TextBasedSmsDelivery(desAddr, scAddr, text, sendCallback, deliveryCallback);
525 }
526 
EncodeSubmitMsg(std::string desAddr,std::string scAddr,std::string text,bool force7Bit,bool statusReport) const527 void CdmaSmsTest::EncodeSubmitMsg(
528     std::string desAddr, std::string scAddr, std::string text, bool force7Bit, bool statusReport) const
529 {
530     CdmaSmsMessage message;
531     DataCodingScheme codingType;
532     std::vector<struct SplitInfo> splits;
533     message.SplitMessage(splits, text, force7Bit, codingType, false, "");
534     std::cout << "codingType : " << codingType << std::endl;
535     if (splits.size() > MAX_SEGMENT_NUM) {
536         std::cout << "message exceed the limit." << std::endl;
537         return;
538     }
539     std::unique_ptr<CdmaTransportMsg> transMsg =
540         message.CreateSubmitTransMsg(desAddr, scAddr, text, statusReport, codingType);
541     if (transMsg == nullptr) {
542         std::cout << "CreateSubmitTransMsg nullptr fail." << std::endl;
543         return;
544     }
545     /* 1. Set Reply sequence number. */
546     uint8_t msgRef8bit = 1;
547     transMsg->data.p2p.replySeq = msgRef8bit;
548     /* 2. Set msg ID. */
549     transMsg->data.p2p.telesvcMsg.data.submit.msgId.msgId = MSG_ID;
550     for (std::size_t i = 0; i < splits.size(); i++) {
551         (void)memset_s(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data,
552             sizeof(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data), 0x00,
553             sizeof(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data));
554         if (splits[i].encodeData.size() > sizeof(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data)) {
555             TELEPHONY_LOGE("data length invalid");
556             return;
557         }
558         if (memcpy_s(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data,
559             sizeof(transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.data), splits[i].encodeData.data(),
560             splits[i].encodeData.size()) != EOK) {
561             return;
562         }
563         SetPduSeqInfo(splits.size(), transMsg, i, msgRef8bit);
564         transMsg->data.p2p.telesvcMsg.data.submit.userData.userData.length =
565             static_cast<int>(splits[i].encodeData.size());
566 
567         /* encode msg data */
568         cout << "P2P SUBMIT" << endl;
569         EncodeMsg(*transMsg.get());
570     }
571 }
572 
TestEncodeSubmitMsg() const573 void CdmaSmsTest::TestEncodeSubmitMsg() const
574 {
575     std::cout << "CdmaSmsTest::TestEncodeSubmitMsg" << std::endl;
576 
577     std::cout << "Please enter the desAddr: " << std::endl;
578     std::string desAddr;
579     std::cin >> desAddr;
580 
581     std::cout << "Please enter the scAddr: " << std::endl;
582     std::string scAddr;
583     std::cin >> scAddr;
584 
585     std::cout << "Please enter the text: " << std::endl;
586     std::string text;
587     std::cin >> text;
588 
589     std::cout << "Please enter the force7Bit: " << std::endl;
590     bool force7Bit = true;
591     std::cin >> force7Bit;
592 
593     std::cout << "Please enter the statusReport: " << std::endl;
594     bool statusReport = true;
595     std::cin >> statusReport;
596 
597     EncodeSubmitMsg(desAddr, scAddr, text, force7Bit, statusReport);
598 }
599 
TestEncodeCancelMsg() const600 void CdmaSmsTest::TestEncodeCancelMsg() const
601 {
602     std::cout << "CdmaSmsTest::TestEncodeCancelMsg" << std::endl;
603     std::cout << "Please enter the address: " << std::endl;
604     std::string address;
605     std::cin >> address;
606 
607     CdmaTransportMsg msg;
608     memset_s(&msg, sizeof(msg), 0, sizeof(msg));
609     msg.type = CdmaTransportMsgType::P2P;
610     msg.data.p2p.teleserviceId = static_cast<uint16_t>(SmsTransTelsvcId::CMT_95);
611     msg.data.p2p.address.addrLen = address.length();
612     if (memcpy_s(msg.data.p2p.address.szData, msg.data.p2p.address.addrLen, address.c_str(),
613         msg.data.p2p.address.addrLen) != EOK) {
614         return;
615     }
616     msg.data.p2p.telesvcMsg.type = TeleserviceMsgType::CANCEL;
617     msg.data.p2p.telesvcMsg.data.cancel.msgId.msgId = MSG_ID;
618     msg.data.p2p.telesvcMsg.data.cancel.msgId.headerInd = 0;
619     cout << "P2P CANCEL" << endl;
620     EncodeMsg(msg);
621 }
622 
TestEncodeDeliverReportMsg() const623 void CdmaSmsTest::TestEncodeDeliverReportMsg() const
624 {
625     std::cout << "CdmaSmsTest::TestEncodeDeliverReportMsg" << std::endl;
626     std::cout << "Please enter the address: " << std::endl;
627     std::string address;
628     std::cin >> address;
629 
630     std::cout << "Please enter the text: " << std::endl;
631     std::string text;
632     std::cin >> text;
633 
634     CdmaTransportMsg msg;
635     memset_s(&msg, sizeof(msg), 0, sizeof(msg));
636     msg.type = CdmaTransportMsgType::P2P;
637     msg.data.p2p.teleserviceId = static_cast<uint16_t>(SmsTransTelsvcId::CMT_95);
638     msg.data.p2p.address.addrLen = address.length();
639     if (memcpy_s(msg.data.p2p.address.szData, msg.data.p2p.address.addrLen, address.c_str(),
640         msg.data.p2p.address.addrLen) != EOK) {
641         return;
642     }
643     msg.data.p2p.telesvcMsg.type = TeleserviceMsgType::DELIVER_REPORT;
644     msg.data.p2p.telesvcMsg.data.report.msgId.msgId = MSG_ID;
645     msg.data.p2p.telesvcMsg.data.report.msgId.headerInd = 0;
646     msg.data.p2p.telesvcMsg.data.report.tpFailCause = TP_FAIL_CAUSE;
647     msg.data.p2p.telesvcMsg.data.report.userData.encodeType = SmsEncodingType::ASCII_7BIT;
648     msg.data.p2p.telesvcMsg.data.report.userData.userData.length = text.length();
649     if (memcpy_s(msg.data.p2p.telesvcMsg.data.report.userData.userData.data,
650         msg.data.p2p.telesvcMsg.data.report.userData.userData.length, text.c_str(),
651         msg.data.p2p.telesvcMsg.data.report.userData.userData.length) != EOK) {
652         return;
653     }
654     cout << "P2P DELIVER_REPORT" << endl;
655     EncodeMsg(msg);
656 }
657 
TestEncodeAckMsg() const658 void CdmaSmsTest::TestEncodeAckMsg() const
659 {
660     std::cout << "CdmaSmsTest::TestEncodeAckMsg" << std::endl;
661     std::cout << "Please enter the address: " << std::endl;
662     std::string address;
663     std::cin >> address;
664 
665     std::cout << "Please enter the errorClass(NONE = 0, TEMPORARY = 2, PERMANENT = 3): " << std::endl;
666     int errorClass;
667     std::cin >> errorClass;
668 
669     std::cout << "Please enter the causeCode(INVAILD_TELESERVICE_ID = 4, SERVICE_TERMINATION_DENIED = 98): "
670               << std::endl;
671     int causeCode;
672     std::cin >> causeCode;
673 
674     CdmaTransportMsg msg;
675     memset_s(&msg, sizeof(msg), 0, sizeof(msg));
676     msg.type = CdmaTransportMsgType::ACK;
677     msg.data.ack.address.addrLen = address.length();
678     if (memcpy_s(msg.data.ack.address.szData, msg.data.ack.address.addrLen, address.c_str(),
679         msg.data.ack.address.addrLen) != EOK) {
680         return;
681     }
682     msg.data.ack.causeCode.transReplySeq = REPLY_SEQ;
683     msg.data.ack.causeCode.errorClass = TransportErrClass(errorClass);
684     msg.data.ack.causeCode.causeCode = TransportCauseCodeType(causeCode);
685     cout << "ACK" << endl;
686     EncodeMsg(msg);
687 }
688 
TestDecodeMsg() const689 void CdmaSmsTest::TestDecodeMsg() const
690 {
691     std::cout << "CdmaSmsTest::TestDecodeMsg" << std::endl;
692     std::cout << "Please enter the pdu: " << std::endl;
693     std::string pdu;
694     std::cin >> pdu;
695 
696     CdmaTransportMsg msg;
697     memset_s(&msg, sizeof(msg), 0, sizeof(msg));
698     SmsReadBuffer pduBuffer(StringUtils::HexToString(pdu));
699     std::unique_ptr<CdmaSmsTransportMessage> message = CdmaSmsTransportMessage::CreateTransportMessage(msg, pduBuffer);
700     if (message == nullptr) {
701         std::cout << "create transport message error" << std::endl;
702         return;
703     }
704     if (!message->Decode(pduBuffer)) {
705         std::cout << "decode error" << std::endl;
706         return;
707     }
708     cout << "TestDecodeMsg : " << pdu << endl;
709     PrintMsg(msg);
710 }
711 
TestDecodeBearerData() const712 void CdmaSmsTest::TestDecodeBearerData() const
713 {
714     std::cout << "CdmaSmsTest::TestDecodeBearerData" << std::endl;
715     std::cout << "Please enter the pdu: " << std::endl;
716     std::string pdu;
717     std::cin >> pdu;
718 
719     std::stringstream ss;
720     ss << static_cast<uint8_t>(CdmaSmsParameterRecord::BEARER_DATA);
721     ss << static_cast<uint8_t>(pdu.size() / HEX_CHAR_LEN);
722     ss << StringUtils::HexToString(pdu);
723 
724     CdmaTeleserviceMsg v;
725     memset_s(&v, sizeof(CdmaTeleserviceMsg), 0x00, sizeof(CdmaTeleserviceMsg));
726     SmsReadBuffer rBuffer(ss.str());
727     rBuffer.SetIndex(VALUE_INDEX);
728     auto message = std::make_shared<CdmaSmsBearerData>(v, rBuffer);
729     if (message == nullptr) {
730         std::cout << "create bearer data error" << std::endl;
731         return;
732     }
733     rBuffer.SetIndex(0);
734     if (!message->Decode(rBuffer)) {
735         cout << "Decode error!!!!!!!!!!!!!!!!!!!" << endl;
736         return;
737     }
738 
739     cout << "TestDecodeBearerData : " << pdu << endl;
740     PrintTelesvc(v);
741 }
742 
ProcessTest() const743 void CdmaSmsTest::ProcessTest() const
744 {
745     bool loopFlag = true;
746     while (loopFlag) {
747         std::cout << "\nusage:please input a cmd num:\n"
748                      "0:TestTextBasedSmsDelivery\n1:TestEncodeSubmitMsg\n2:TestEncodeCancelMsg\n"
749                      "3:TestEncodeDeliverReportMsg\n4:TestEncodeAckMsg\n5:TestDecodeMsg\n"
750                      "6:TestDecodeBearerData\n100:exit test cdma sms\n"
751                   << std::endl;
752 
753         int inputCMD = 0;
754         std::cin >> inputCMD;
755         while (std::cin.fail()) {
756             std::cin.clear();
757             std::cin.ignore();
758             std::cin >> inputCMD;
759         }
760 
761         std::cout << "inputCMD is:" << inputCMD << std::endl;
762 
763         switch (inputCMD) {
764             case TEST_MENU_TEXT_DELIVERY:
765                 TestTextBasedSmsDelivery();
766                 break;
767             case TEST_MENU_ENCODE_SUBMIT:
768                 TestEncodeSubmitMsg();
769                 break;
770             case TEST_MENU_ENCODE_CANCEL:
771                 TestEncodeCancelMsg();
772                 break;
773             case TEST_MENU_ENCODE_DELIVER_REPORT:
774                 TestEncodeDeliverReportMsg();
775                 break;
776             case TEST_MENU_ENCODE_ACK:
777                 TestEncodeAckMsg();
778                 break;
779             case TEST_MENU_DECODE_MSG:
780                 TestDecodeMsg();
781                 break;
782             case TEST_MENU_DECODE_BEARER_DATA:
783                 TestDecodeBearerData();
784                 break;
785             case TEST_MENU_EXIT:
786                 loopFlag = false;
787                 break;
788             default:
789                 break;
790         }
791     }
792 }
793 
794 } // namespace Telephony
795 } // namespace OHOS
796