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
OnNotifyOps(const char * s,const char * smsPdu)197 void OnNotifyOps(const char *s, const char *smsPdu)
198 {
199 if (s == NULL) {
200 return;
201 }
202 char *str = NULL;
203 struct ReportInfo reportInfo = {0};
204 ReportInfoInit(&reportInfo);
205 if (GetRadioState() == HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
206 return;
207 }
208 str = strdup(s);
209 if (str == NULL) {
210 return;
211 }
212 if (IsCallNoticeCmd(s)) {
213 CallReportInfoProcess(s);
214 } else if (ReportStrWith(s, "+CMT:")) {
215 HRilSmsResponse smsResponse = {};
216 smsResponse.pdu = (char *)smsPdu;
217 reportInfo.notifyId = HNOTI_SMS_NEW_SMS;
218 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&smsResponse, strlen(smsResponse.pdu));
219 } else if (ReportStrWith(s, "+CDS:")) {
220 SmsStatus(smsPdu, &reportInfo);
221 } else if (ReportStrWith(s, "+CBM:") || ReportStrWith(s, "+CSCB:")) {
222 ReportCBMOrCSCB(&reportInfo);
223 ReportCBMOrCSCB(&reportInfo); // The test requires send twice
224 } else if (ReportStrWith(s, "+COPS: (")) {
225 char *copsStr = strdup(s);
226 ProcessOperListToUse(copsStr);
227 free(copsStr);
228 } else if (ReportStrWith(s, "^SIMST:")) {
229 reportInfo.notifyId = HNOTI_SIM_STATUS_CHANGED;
230 OnSimReport(GetSlotId(NULL), reportInfo, NULL, 0);
231 } else if (ReportStrWith(s, "^MONSC:")) {
232 ProcessCurrentCellList(reportInfo, str);
233 } else if (ReportStrWith(s, "^DATACONNECT") || ReportStrWith(s, "^DATADISCONN")) {
234 PdpContextListUpdate();
235 } else if (OnNotifyStkOps(s, str)) {
236 TELEPHONY_LOGI("STK notify completed.");
237 } else {
238 HRilSmsResponse response = {0};
239 if ((reportInfo.notifyId = CdmaSmsNotifyMock(s, &response)) > 0) {
240 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&response, sizeof(HRilSmsResponse));
241 }
242 if ((reportInfo.notifyId = WapPushNotifyMock(s, &response)) > 0) {
243 OnSmsReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&response, strlen(response.pdu));
244 }
245 OnNotifyNetWorksOps(s, str);
246 }
247 free(str);
248 }
249
ParseStkResponseStr(const char * s,char ** cmdResponseInfo)250 static int32_t ParseStkResponseStr(const char *s, char **cmdResponseInfo)
251 {
252 char *str = (char *)s;
253 if (str == NULL) {
254 TELEPHONY_LOGE("ProcessStkNotify, s or cmdResponse param is null");
255 return HRIL_ERR_NULL_POINT;
256 }
257 int32_t err = SkipATPrefix(&str);
258 if (err != VENDOR_SUCCESS) {
259 TELEPHONY_LOGE("ProcessStkNotify, invalid response");
260 return HRIL_ERR_INVALID_RESPONSE;
261 }
262 err = NextStr(&str, cmdResponseInfo);
263 TELEPHONY_LOGD("ParseStkResponseStr, cmdResponse: %{public}s", *cmdResponseInfo);
264 if (err != 0) {
265 return HRIL_ERR_INVALID_PARAMETER;
266 }
267 return VENDOR_SUCCESS;
268 }
269
OnNotifyStkOps(const char * s,const char * strInfo)270 bool OnNotifyStkOps(const char *s, const char *strInfo)
271 {
272 bool isStkNotify = true;
273 struct ReportInfo reportInfo = {0};
274 reportInfo.error = HRIL_ERR_SUCCESS;
275 reportInfo.type = HRIL_NOTIFICATION;
276 if (ReportStrWith(s, "SoftwareVersion:")) {
277 reportInfo.notifyId = HNOTI_SIM_STK_SESSION_END_NOTIFY;
278 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
279 } else if (ReportStrWith(s, "HardwareVersion:")) {
280 reportInfo.notifyId = HNOTI_SIM_STK_PROACTIVE_NOTIFY;
281 char *cmdResponse = (char *)strInfo;
282 int32_t ret = ParseStkResponseStr(s, &cmdResponse);
283 if (ret != VENDOR_SUCCESS) {
284 reportInfo.error = ret;
285 }
286 if (cmdResponse == NULL) {
287 TELEPHONY_LOGE("cmdResponse is NULL");
288 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
289 } else {
290 TELEPHONY_LOGD("OnNotifyStkOps, cmdResponse: %{public}s", cmdResponse);
291 OnSimReport(GetSlotId(NULL), reportInfo, (const uint8_t *)cmdResponse, sizeof(char));
292 }
293 } else if (ReportStrWith(s, "+CGMM:")) {
294 reportInfo.notifyId = HNOTI_SIM_STK_ALPHA_NOTIFY;
295 OnSimReport(GetSlotId(NULL), reportInfo, NULL, ZERO_RESPONSE_LEN);
296 } else {
297 isStkNotify = false;
298 }
299 return isStkNotify;
300 }
301
OnCsRegStatusNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)302 static void OnCsRegStatusNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
303 {
304 reportInfo.notifyId = HNOTI_NETWORK_CS_REG_STATUS_UPDATED;
305 HRilRegStatusInfo regStatusInfo;
306 ret = ProcessRegStatus(str, ®StatusInfo);
307 if (ret == 0) {
308 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(®StatusInfo), sizeof(HRilRegStatusInfo));
309 } else {
310 TELEPHONY_LOGW("CREG notify str format unexpected: %{public}s", s);
311 }
312 }
313
RadioTurnNotify(struct ReportInfo reportInfo,char * str)314 static void RadioTurnNotify(struct ReportInfo reportInfo, char *str)
315 {
316 HRilRadioState radioState = HRIL_RADIO_POWER_STATE_UNAVAILABLE;
317 if (ReportStrWith(str, "^RADIO: 1")) {
318 radioState = HRIL_RADIO_POWER_STATE_ON;
319 } else if (ReportStrWith(str, "^RADIO: 0")) {
320 radioState = HRIL_RADIO_POWER_STATE_OFF;
321 } else {
322 TELEPHONY_LOGW("^RADIO notify str format unexpected: %{public}s", str);
323 }
324 if (radioState != HRIL_RADIO_POWER_STATE_UNAVAILABLE) {
325 reportInfo.error = HRIL_ERR_SUCCESS;
326 reportInfo.type = HRIL_NOTIFICATION;
327 reportInfo.notifyId = HNOTI_MODEM_RADIO_STATE_UPDATED;
328 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&radioState, sizeof(HRilRadioState));
329 }
330 }
331
DsdsModeNotify(struct ReportInfo reportInfo,char * str)332 static void DsdsModeNotify(struct ReportInfo reportInfo, char *str)
333 {
334 HRilDsdsMode dsdsMode = HRIL_DSDS_MODE_V2;
335 reportInfo.error = HRIL_ERR_SUCCESS;
336 reportInfo.type = HRIL_NOTIFICATION;
337 reportInfo.notifyId = HNOTI_MODEM_DSDS_MODE_UPDATED;
338 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)&dsdsMode, sizeof(HRilDsdsMode));
339 }
340
OnPsRegStatusNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)341 static void OnPsRegStatusNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
342 {
343 reportInfo.notifyId = HNOTI_NETWORK_PS_REG_STATUS_UPDATED;
344 HRilRegStatusInfo regStatusInfo;
345 ret = ProcessRegStatus(str, ®StatusInfo);
346 if (ret == 0) {
347 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(®StatusInfo), sizeof(HRilRegStatusInfo));
348 } else {
349 TELEPHONY_LOGW("CGREG notify str format unexpected: %{public}s", s);
350 }
351 }
352
OnNotifyNetWorksOpsJudgeTwo(struct ReportInfo reportInfo,const char * infoStr,char * responseData[MAX_REG_INFO_ITEM])353 static void OnNotifyNetWorksOpsJudgeTwo(
354 struct ReportInfo reportInfo, const char *infoStr, char *responseData[MAX_REG_INFO_ITEM])
355 {
356 reportInfo.notifyId = HNOTI_NETWORK_TIME_UPDATED;
357 char *time[DEFAULT_INDEX] = {""};
358 if (GenerateCommand((char *)time, DEFAULT_INDEX, "^TIME:\"20%s", infoStr + DEFAULT_ADD_NUM) < 0) {
359 TELEPHONY_LOGE("GenerateCommand is failed!");
360 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)responseData, MAX_REG_INFO_ITEM * sizeof(char));
361 return;
362 }
363 TELEPHONY_LOGW("Report TIME: %{public}s", (char *)time);
364 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)time, MAX_REG_INFO_ITEM * sizeof(char));
365 }
366
SignalStrengthNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)367 static void SignalStrengthNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
368 {
369 HRilRssi response = {0};
370 reportInfo.notifyId = HNOTI_NETWORK_SIGNAL_STRENGTH_UPDATED;
371 TELEPHONY_LOGD("start report SignalStrengthNotify ");
372 ret = ProcessParamSignalStrengthNotify(str, &response);
373 if (ret == 0) {
374 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(&response), sizeof(HRilRssi));
375 } else {
376 TELEPHONY_LOGW("HCSQ notify str format unexpected: %{public}s", s);
377 }
378 }
379
VoiceRadioInfoNotify(struct ReportInfo reportInfo,int32_t ret,char * str,const char * s)380 static void VoiceRadioInfoNotify(struct ReportInfo reportInfo, int32_t ret, char *str, const char *s)
381 {
382 HRilVoiceRadioInfo voiceRadioInfo = {0};
383 ret = ProcessVoiceRadioInfo(str, &voiceRadioInfo);
384 if (ret != 0) {
385 TELEPHONY_LOGE("ProcessVoiceRadioInfo format unexpected: %{public}s", s);
386 return;
387 }
388 reportInfo.notifyId = HNOTI_MODEM_VOICE_TECH_UPDATED;
389 OnModemReport(GetSlotId(NULL), reportInfo, (const uint8_t *)(&voiceRadioInfo), sizeof(HRilVoiceRadioInfo));
390 }
391
OnNotifyNetWorksOps(const char * s,const char * infoStr)392 void OnNotifyNetWorksOps(const char *s, const char *infoStr)
393 {
394 int32_t ret = 0;
395 char *str = (char *)infoStr;
396 char *responseData[MAX_REG_INFO_ITEM] = {""};
397 struct ReportInfo reportInfo = {0};
398 reportInfo.error = HRIL_ERR_SUCCESS;
399 reportInfo.type = HRIL_NOTIFICATION;
400 if (ReportStrWith(s, "+CREG:")) {
401 OnCsRegStatusNotify(reportInfo, ret, str, s);
402 } else if (ReportStrWith(s, "+CGREG:")) {
403 OnPsRegStatusNotify(reportInfo, ret, str, s);
404 } else if (ReportStrWith(s, "^TIME:")) {
405 OnNotifyNetWorksOpsJudgeTwo(reportInfo, infoStr, responseData);
406 } else if (ReportStrWith(s, "+CTZV:")) {
407 reportInfo.notifyId = HNOTI_NETWORK_TIME_ZONE_UPDATED;
408 OnNetworkReport(GetSlotId(NULL), reportInfo, (const uint8_t *)responseData, MAX_REG_INFO_ITEM * sizeof(char));
409 } else if (ReportStrWith(s, "^HCSQ:")) {
410 SignalStrengthNotify(reportInfo, ret, str, s);
411 } else if (ReportStrWith(s, "^RADIO:")) {
412 RadioTurnNotify(reportInfo, str);
413 } else if (ReportStrWith(s, "^PHYCHLCFG:")) {
414 ProcessPhyChnlCfgNotify(reportInfo, str);
415 } else if (ReportStrWith(s, "^SYSINFOEX:")) {
416 VoiceRadioInfoNotify(reportInfo, ret, str, s);
417 } else if (ReportStrWith(s, "^DSDS:")) {
418 DsdsModeNotify(reportInfo, str);
419 } else {
420 TELEPHONY_LOGW("enter to is unrecognized command");
421 }
422 }
423