1 /*
2 * Copyright (C) 2021-2022 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 "vendor_report.h"
17
18 #include "at_call.h"
19 #include "at_sms.h"
20 #include "vendor_adapter.h"
21
22 #include "hril_notification.h"
23
24 static const struct HRilReport *g_reportOps = NULL;
25 static const size_t ZERO_RESPONSE_LEN = 0;
26
OnModemReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)27 void OnModemReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
28 {
29 if (g_reportOps != NULL) {
30 g_reportOps->OnModemReport(slotId, reportInfo, response, responseLen);
31 } else {
32 TELEPHONY_LOGE("g_reportOps is NULL");
33 }
34 }
35
OnCallReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)36 void OnCallReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
37 {
38 if (g_reportOps != NULL) {
39 g_reportOps->OnCallReport(slotId, reportInfo, response, responseLen);
40 } else {
41 TELEPHONY_LOGE("g_reportOps is NULL");
42 }
43 }
44
OnDataReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)45 void OnDataReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
46 {
47 if (g_reportOps != NULL) {
48 g_reportOps->OnDataReport(slotId, reportInfo, response, responseLen);
49 } else {
50 TELEPHONY_LOGE("g_reportOps is NULL");
51 }
52 }
53
OnSmsReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)54 void OnSmsReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
55 {
56 if (g_reportOps != NULL) {
57 g_reportOps->OnSmsReport(slotId, reportInfo, response, responseLen);
58 } else {
59 TELEPHONY_LOGE("g_reportOps is NULL");
60 }
61 }
62
OnNetworkReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)63 void OnNetworkReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
64 {
65 if (g_reportOps != NULL) {
66 g_reportOps->OnNetworkReport(slotId, reportInfo, response, responseLen);
67 } else {
68 TELEPHONY_LOGE("g_reportOps is NULL");
69 }
70 }
71
OnSimReport(int32_t slotId,struct ReportInfo reportInfo,const uint8_t * response,size_t responseLen)72 void OnSimReport(int32_t slotId, struct ReportInfo reportInfo, const uint8_t *response, size_t responseLen)
73 {
74 if (g_reportOps != NULL) {
75 g_reportOps->OnSimReport(slotId, reportInfo, response, responseLen);
76 } else {
77 TELEPHONY_LOGE("g_reportOps is NULL");
78 }
79 }
80
OnTimerCallback(HRilCallbackFun func,uint8_t * param,const struct timeval * tv)81 void OnTimerCallback(HRilCallbackFun func, uint8_t *param, const struct timeval *tv)
82 {
83 if (g_reportOps != NULL) {
84 g_reportOps->OnTimerCallback(func, param, tv);
85 } else {
86 TELEPHONY_LOGE("g_reportOps is NULL");
87 }
88 }
89
CreateReportInfo(const ReqDataInfo * requestInfo,int32_t err,uint32_t type,int32_t notifyId)90 struct ReportInfo CreateReportInfo(const ReqDataInfo *requestInfo, int32_t err, uint32_t type, int32_t notifyId)
91 {
92 struct ReportInfo reportInfo = {(ReqDataInfo *)requestInfo, notifyId, type, err, {0, 0}};
93 return reportInfo;
94 }
95
SetReportOps(const struct HRilReport * reportOps)96 void SetReportOps(const struct HRilReport *reportOps)
97 {
98 g_reportOps = reportOps;
99 }
100
ReportCBMOrCSCB(struct ReportInfo * reportInfo)101 static void ReportCBMOrCSCB(struct ReportInfo *reportInfo)
102 {
103 if (reportInfo == NULL) {
104 TELEPHONY_LOGE("reportInfo is null");
105 return;
106 }
107 static int32_t testCount = 0;
108 char *tempData = NULL;
109 char *testDataStr =
110 ("01a41f51101102ea3030a830ea30a230e130fc30eb914d4fe130c630b930c8000d000a305330"
111 "8c306f8a669a137528306e30e130c330bb30fc30b8306730593002000d000aff0800320030003"
112 "10033002f00310031002f003252ea300037002000310035003a00340034ff09000d000aff0830"
113 "a830ea30a25e02ff0900000000000000000000000000000000000000"
114 "000000000000000000000000000000000000000000000000000000000022");
115 char *testDataTmp =
116 ("C0000032401174747A0E4ACF41E8B0BCFD76E741EF39685C66B34162F93B4C1E87E77410BD3CA7836EC2341D440ED3C321");
117 if (testCount == 0) {
118 tempData = testDataStr;
119 testCount++;
120 } else {
121 tempData = testDataTmp;
122 testCount = 0;
123 }
124 HRilCBConfigReportInfo response = {0};
125 reportInfo->notifyId = HNOTI_CB_CONFIG_REPORT;
126 int32_t ret = ProcessCellBroadcast("+CBM:100", &response);
127 if (ret > 1) {
128 response.data = (char *)tempData;
129 } else {
130 response.pdu = (char *)tempData;
131 }
132 OnSmsReport(GetSlotId(NULL), *reportInfo, (const uint8_t *)&response, sizeof(HRilCBConfigReportInfo));
133 }
134
SmsStatus(const char * smsPdu,struct ReportInfo * reportInfo)135 static void SmsStatus(const char *smsPdu, struct ReportInfo *reportInfo)
136 {
137 if (smsPdu == NULL || reportInfo == NULL) {
138 TELEPHONY_LOGE("reportInfo is NULL");
139 return;
140 }
141 int32_t size = (smsPdu != NULL) ? strlen(smsPdu) : 0;
142 reportInfo->notifyId = HNOTI_SMS_STATUS_REPORT;
143 OnSmsReport(GetSlotId(NULL), *reportInfo, (const uint8_t *)smsPdu, size);
144 }
145
ReportInfoInit(struct ReportInfo * reportInfo)146 static void ReportInfoInit(struct ReportInfo *reportInfo)
147 {
148 if (reportInfo == NULL) {
149 TELEPHONY_LOGE("reportInfo is NULL");
150 return;
151 }
152 reportInfo->error = HRIL_ERR_SUCCESS;
153 reportInfo->type = HRIL_NOTIFICATION;
154 }
155
CdmaSmsNotifyMock(const char * s,HRilSmsResponse * smsResponse)156 static int32_t CdmaSmsNotifyMock(const char *s, HRilSmsResponse *smsResponse)
157 {
158 if (s == NULL || smsResponse == NULL) {
159 return 0;
160 }
161 char *testDataStr = ("0101020004081300031008d00106102c2870e1420801c00c01c0");
162 char *testDataTmp =
163 ("0000021002040602448d159e240601fc081b0003200010010910461c58d8b266a9180306211024102051080100");
164 if (ReportStrWith(s, "+CMMS:")) {
165 smsResponse->pdu = testDataTmp;
166 } else if (ReportStrWith(s, "+CSDH:")) {
167 smsResponse->pdu = testDataStr;
168 } else {
169 return 0;
170 }
171 return HNOTI_SMS_NEW_CDMA_SMS;
172 }
173
WapPushNotifyMock(const char * s,HRilSmsResponse * smsResponse)174 static int32_t WapPushNotifyMock(const char *s, HRilSmsResponse *smsResponse)
175 {
176 if (s == NULL || smsResponse == NULL) {
177 return 0;
178 }
179 char *testDataStr =
180 ("0891683108200105f04408a0015608860104216092902512236e0605040b8423f0120601ae020"
181 "56a0045c60c033231312e3133362e3130372e37382f646f776e2e7068703f703d413063303026"
182 "733d383500080103e68e8ce68fa1e882a1e5b882e58588e69cbaefbc8ce6aca2e8bf8ee4bdbfe"
183 "794a8e6898be69cbae8af81e588b8e38082000101");
184 char *testDataTmp =
185 ("0041000B915121551532F400042E0B05040B84C0020003F001010A060403B0"
186 "81EA02066A008509036D6F62696C65746964696E67732E636F6D2F0001");
187 if (ReportStrWith(s, "+CMGF:")) {
188 smsResponse->pdu = testDataStr;
189 } else if (ReportStrWith(s, "+CSMP:")) {
190 smsResponse->pdu = testDataTmp;
191 } else {
192 return 0;
193 }
194 return HNOTI_SMS_NEW_SMS;
195 }
196
ProcessNotifyMock(const char * s,struct ReportInfo reportInfo)197 static void ProcessNotifyMock(const char *s, struct ReportInfo reportInfo)
198 {
199 HRilSmsResponse response = {0};
200 if ((reportInfo.notifyId = CdmaSmsNotifyMock(s, &response)) > 0) {
201 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&response, sizeof(HRilSmsResponse));
202 }
203 if ((reportInfo.notifyId = WapPushNotifyMock(s, &response)) > 0) {
204 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&response, strlen(response.pdu));
205 }
206 return;
207 }
208
OnNotifyOps(const char * s,const char * smsPdu)209 void OnNotifyOps(const char *s, const char *smsPdu)
210 {
211 if (s == NULL) {
212 return;
213 }
214 char *str = NULL;
215 struct ReportInfo reportInfo = {0};
216 ReportInfoInit(&reportInfo);
217 if (GetRadioState() == HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
218 return;
219 }
220 str = strdup(s);
221 if (str == NULL) {
222 return;
223 }
224 if (IsCallNoticeCmd(s)) {
225 CallReportInfoProcess(s);
226 } else if (ReportStrWith(s, "+CMT:")) {
227 HRilSmsResponse smsResponse = {};
228 smsResponse.pdu = (char *)smsPdu;
229 reportInfo.notifyId = HNOTI_SMS_NEW_SMS;
230 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&smsResponse, strlen(smsResponse.pdu));
231 } else if (ReportStrWith(s, "+CDS:")) {
232 SmsStatus(smsPdu, &reportInfo);
233 } else if (ReportStrWith(s, "+CBM:") || ReportStrWith(s, "+CSCB:")) {
234 ReportCBMOrCSCB(&reportInfo);
235 ReportCBMOrCSCB(&reportInfo); // The test requires send twice
236 } else if (ReportStrWith(s, "+COPS: (")) {
237 char *copsStr = strdup(s);
238 ProcessOperListToUse(copsStr);
239 free(copsStr);
240 } else if (ReportStrWith(s, "^SIMST:")) {
241 reportInfo.notifyId = HNOTI_SIM_STATUS_CHANGED;
242 OnSimReport(GetSlotId(NULL), reportInfo, NULL, 0);
243 } else if (ReportStrWith(s, "^MONSC:")) {
244 ProcessCurrentCellList(reportInfo, str);
245 } else if (ReportStrWith(s, "^DATACONNECT") || ReportStrWith(s, "^DATADISCONN")) {
246 PdpContextListUpdate();
247 } else if (OnNotifyStkOps(s, str)) {
248 TELEPHONY_LOGI("STK notify completed.");
249 } else {
250 ProcessNotifyMock(s, reportInfo);
251 OnNotifyNetWorksOps(s, str);
252 }
253 free(str);
254 }
255
ParseStkResponseStr(const char * s,char ** cmdResponseInfo)256 static int32_t ParseStkResponseStr(const char *s, char **cmdResponseInfo)
257 {
258 char *str = (char *)s;
259 if (str == NULL) {
260 TELEPHONY_LOGE("ProcessStkNotify, s or cmdResponse param is null");
261 return HRIL_ERR_NULL_POINT;
262 }
263 int32_t err = SkipATPrefix(&str);
264 if (err != VENDOR_SUCCESS) {
265 TELEPHONY_LOGE("ProcessStkNotify, invalid response");
266 return HRIL_ERR_INVALID_RESPONSE;
267 }
268 err = NextStr(&str, cmdResponseInfo);
269 TELEPHONY_LOGD("ParseStkResponseStr, cmdResponse: %{public}s", *cmdResponseInfo);
270 if (err != 0) {
271 return HRIL_ERR_INVALID_PARAMETER;
272 }
273 return VENDOR_SUCCESS;
274 }
275
OnNotifyStkOps(const char * s,const char * strInfo)276 bool OnNotifyStkOps(const char *s, const char *strInfo)
277 {
278 bool isStkNotify = true;
279 struct ReportInfo reportInfo = {0};
280 reportInfo.error = HRIL_ERR_SUCCESS;
281 reportInfo.type = HRIL_NOTIFICATION;
282 if (ReportStrWith(s, "SoftwareVersion:")) {
283 reportInfo.notifyId = HNOTI_SIM_STK_SESSION_END_NOTIFY;
284 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
285 } else if (ReportStrWith(s, "HardwareVersion:")) {
286 reportInfo.notifyId = HNOTI_SIM_STK_PROACTIVE_NOTIFY;
287 char *cmdResponse = (char *)strInfo;
288 int32_t ret = ParseStkResponseStr(s, &cmdResponse);
289 if (ret != VENDOR_SUCCESS) {
290 reportInfo.error = ret;
291 }
292 if (cmdResponse == NULL) {
293 TELEPHONY_LOGE("cmdResponse is NULL");
294 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
295 } else {
296 TELEPHONY_LOGD("OnNotifyStkOps, cmdResponse: %{public}s", cmdResponse);
297 OnSimReport(GetSlotId(NULL), reportInfo, (const uint8_t *)cmdResponse, sizeof(char));
298 }
299 } else if (ReportStrWith(s, "+CGMM:")) {
300 reportInfo.notifyId = HNOTI_SIM_STK_ALPHA_NOTIFY;
301 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
302 } else {
303 isStkNotify = false;
304 }
305 return isStkNotify;
306 }
307
OnCsRegStatusNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)308 static void OnCsRegStatusNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
309 {
310 reportInfo.notifyId = HNOTI_NETWORK_CS_REG_STATUS_UPDATED;
311 HRilRegStatusInfo regStatusInfo;
312 ret = ProcessRegStatus(str, ®StatusInfo);
313 if (ret == 0) {
314 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(®StatusInfo), sizeof(HRilRegStatusInfo));
315 } else {
316 TELEPHONY_LOGW("CREG notify str format unexpected: %{public}s", s);
317 }
318 }
319
RadioTurnNotify(struct ReportInfo reportInfo,char * str)320 static void RadioTurnNotify(struct ReportInfo reportInfo, char *str)
321 {
322 HRilRadioState radioState = HRIL_RADIO_POWER_STATE_UNAVAILABLE;
323 if (ReportStrWith(str, "^RADIO: 1")) {
324 radioState = HRIL_RADIO_POWER_STATE_ON;
325 } else if (ReportStrWith(str, "^RADIO: 0")) {
326 radioState = HRIL_RADIO_POWER_STATE_OFF;
327 } else {
328 TELEPHONY_LOGW("^RADIO notify str format unexpected: %{public}s", str);
329 }
330 if (radioState != HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
331 reportInfo.error = HRIL_ERR_SUCCESS;
332 reportInfo.type = HRIL_NOTIFICATION;
333 reportInfo.notifyId = HNOTI_MODEM_RADIO_STATE_UPDATED;
334 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&radioState, sizeof(HRilRadioState));
335 }
336 }
337
DsdsModeNotify(struct ReportInfo reportInfo,char * str)338 static void DsdsModeNotify(struct ReportInfo reportInfo, char *str)
339 {
340 HRilDsdsMode dsdsMode = HRIL_DSDS_MODE_V2;
341 reportInfo.error = HRIL_ERR_SUCCESS;
342 reportInfo.type = HRIL_NOTIFICATION;
343 reportInfo.notifyId = HNOTI_MODEM_DSDS_MODE_UPDATED;
344 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&dsdsMode, sizeof(HRilDsdsMode));
345 }
346
OnPsRegStatusNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)347 static void OnPsRegStatusNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
348 {
349 reportInfo.notifyId = HNOTI_NETWORK_PS_REG_STATUS_UPDATED;
350 HRilRegStatusInfo regStatusInfo;
351 ret = ProcessRegStatus(str, ®StatusInfo);
352 if (ret == 0) {
353 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(®StatusInfo), sizeof(HRilRegStatusInfo));
354 } else {
355 TELEPHONY_LOGW("CGREG notify str format unexpected: %{public}s", s);
356 }
357 }
358
OnNotifyNetWorksOpsJudgeTwo(struct ReportInfo reportInfo,const char * infoStr,char * responseData[MAX_REG_INFO_ITEM])359 static void OnNotifyNetWorksOpsJudgeTwo(
360 struct ReportInfo reportInfo, const char *infoStr, char *responseData[MAX_REG_INFO_ITEM])
361 {
362 reportInfo.notifyId = HNOTI_NETWORK_TIME_UPDATED;
363 char *time[DEFAULT_INDEX] = {""};
364 if (GenerateCommand((char *)time, DEFAULT_INDEX, "^TIME:\"20%s", infoStr + DEFAULT_ADD_NUM) < 0) {
365 TELEPHONY_LOGE("GenerateCommand is failed!");
366 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)responseData, MAX_REG_INFO_ITEM * sizeof(char));
367 return;
368 }
369 TELEPHONY_LOGW("Report TIME: %{public}s", (char *)time);
370 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)time, MAX_REG_INFO_ITEM * sizeof(char));
371 }
372
SignalStrengthNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)373 static void SignalStrengthNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
374 {
375 HRilRssi response = {0};
376 reportInfo.notifyId = HNOTI_NETWORK_SIGNAL_STRENGTH_UPDATED;
377 TELEPHONY_LOGD("start report SignalStrengthNotify ");
378 ret = ProcessParamSignalStrengthNotify(str, &response);
379 if (ret == 0) {
380 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(&response), sizeof(HRilRssi));
381 } else {
382 TELEPHONY_LOGW("HCSQ notify str format unexpected: %{public}s", s);
383 }
384 }
385
VoiceRadioInfoNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)386 static void VoiceRadioInfoNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
387 {
388 HRilVoiceRadioInfo voiceRadioInfo = {0};
389 ret = ProcessVoiceRadioInfo(str, &voiceRadioInfo);
390 if (ret != 0) {
391 TELEPHONY_LOGE("ProcessVoiceRadioInfo format unexpected: %{public}s", s);
392 return;
393 }
394 reportInfo.notifyId = HNOTI_MODEM_VOICE_TECH_UPDATED;
395 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(&voiceRadioInfo), sizeof(HRilVoiceRadioInfo));
396 }
397
OnNotifyNetWorksOps(const char * s,const char * infoStr)398 void OnNotifyNetWorksOps(const char *s, const char *infoStr)
399 {
400 int32_t ret = 0;
401 char *str = (char *)infoStr;
402 char *responseData[MAX_REG_INFO_ITEM] = {""};
403 struct ReportInfo reportInfo = {0};
404 reportInfo.error = HRIL_ERR_SUCCESS;
405 reportInfo.type = HRIL_NOTIFICATION;
406 if (ReportStrWith(s, "+CREG:")) {
407 OnCsRegStatusNotify(reportInfo, ret, str, s);
408 } else if (ReportStrWith(s, "+CGREG:")) {
409 OnPsRegStatusNotify(reportInfo, ret, str, s);
410 } else if (ReportStrWith(s, "^TIME:")) {
411 OnNotifyNetWorksOpsJudgeTwo(reportInfo, infoStr, responseData);
412 } else if (ReportStrWith(s, "+CTZV:")) {
413 reportInfo.notifyId = HNOTI_NETWORK_TIME_ZONE_UPDATED;
414 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)responseData, MAX_REG_INFO_ITEM * sizeof(char));
415 } else if (ReportStrWith(s, "^HCSQ:")) {
416 SignalStrengthNotify(reportInfo, ret, str, s);
417 } else if (ReportStrWith(s, "^RADIO:")) {
418 RadioTurnNotify(reportInfo, str);
419 } else if (ReportStrWith(s, "^PHYCHLCFG:")) {
420 ProcessPhyChnlCfgNotify(reportInfo, str);
421 } else if (ReportStrWith(s, "^SYSINFOEX:")) {
422 VoiceRadioInfoNotify(reportInfo, ret, str, s);
423 } else if (ReportStrWith(s, "^DSDS:")) {
424 DsdsModeNotify(reportInfo, str);
425 } else if (ReportStrWith(s, "^PLMN:")) {
426 ResidentNetworkUpdated(reportInfo, str);
427 } else {
428 TELEPHONY_LOGW("enter to is unrecognized command");
429 }
430 }
431