blob: efa8f6dacf073a16e223660f1733d61400290491 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2* Copyright Statement:
3*
4* This software/firmware and related documentation ("MediaTek Software") are
5* protected under relevant copyright laws. The information contained herein is
6* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
7* the prior written permission of MediaTek inc. and/or its licensors, any
8* reproduction, modification, use or disclosure of MediaTek Software, and
9* information contained herein, in whole or in part, shall be strictly
10* prohibited.
11*
12* MediaTek Inc. (C) 2017. All rights reserved.
13*
14* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
15* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
16* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
17* ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
18* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
19* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
20* NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
21* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
22* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
23* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
24* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
25* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
26* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
27* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
28* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
29* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
30* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
31* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
32* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
33*/
34#include <sys/types.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37#include <arpa/inet.h>
38#include <sys/types.h>
39#include <sys/un.h>
40#include <log/log.h>
41#include <string.h>
42#include <errno.h>
43#include <unistd.h>
44#include <fcntl.h>
45#include <string>
46#include <vector>
47#include <sys/time.h>
48#include <sys/select.h>
49#include <vector>
50#include <deque>
51#include <iterator>
52#include <algorithm>
53
54#include "common.h"
55#include "powerManager.h"
56#include "util/utils.h"
57#include "stateManager/stateManager.h"
58#include <vendor-ril/telephony/ril.h>
59
60#undef DEMOAPP_SOCKET_NAME
61#define DEMOAPP_SOCKET_NAME "/tmp/socket-demoapp"
62#define SOCKET_BUF_SIZE 1024
63#define MAX_CLIENT_SIZE 30
64#undef LOG_TAG
65#define LOG_TAG "DEMO_powermanager"
66int cli_socket[MAX_CLIENT_SIZE];
67std::vector<int> keepalive_start;
68std::vector<int> Keepalive_stop;
69
70//global variable
71static pthread_mutex_t s_WakeupMutex = PTHREAD_MUTEX_INITIALIZER;
72static pthread_cond_t s_WakeupCond = PTHREAD_COND_INITIALIZER;
73//marco define
74#define LIST_LOCK() pthread_mutex_lock(&s_WakeupMutex)
75#define LIST_UNLOCK() pthread_mutex_unlock(&s_WakeupMutex)
76#define WAITLIST() pthread_cond_wait(&s_WakeupCond,&s_WakeupMutex)
77#define WAKEUPLIST() pthread_cond_signal(&s_WakeupCond)
78#define WAKEUPREASONPATH "/sys/power/spm/wakeup_reason"
79//#define WAKEUPSTATUS "/sys/power/suspend_status"
80
81static std::deque<std::string> wakeup_reasons;
82
83std::string read_wakeup_reason() {
84 if(access(WAKEUPREASONPATH, R_OK) == -1) {
85 RLOGD("read_wakeup_reason, %s cann't read(%s),just return", WAKEUPREASONPATH, strerror(errno));
86 return "";
87 }
88
89 int fd;
90 fd = open(WAKEUPREASONPATH , O_RDONLY);
91 if(fd == -1) {
92 RLOGD("read_wakeup_reason, open %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
93 return "";
94 }
95
96 ssize_t len;
97 char buf[50]={0};
98 std::string reason("");
99 len = read(fd, buf,sizeof(buf) -1);
100 if(len == -1) {
101 RLOGD("read_wakeup_reason, read %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
102 reason="";
103 goto fail;
104 }
105 RLOGD("read_wakeup_reason is %s", buf);
106 reason = buf;
107fail:
108 close(fd);
109 return reason;
110}
111
112void write_wakeup_reason(std::string reason) {
113 int fd;
114 ssize_t len;
115 if(reason.empty()) {
116 RLOGD("write_wakeup_reason is empty, just return");
117 return;
118 }
119 std::string save = read_wakeup_reason();
120 if(save == reason) {
121 RLOGD("write_wakeup_reason is same, just return");
122// return; //don't need return, handle initial reason equal to first write reason.
123 }
124 RLOGD("write_wakeup_reason: %s", reason.c_str());
125 if(access(WAKEUPREASONPATH, W_OK) == -1) {
126 RLOGD("write_wakeup_reason, %s cann't write(%s), just return", WAKEUPREASONPATH, strerror(errno));
127 return ;
128 }
129 fd = open(WAKEUPREASONPATH , O_WRONLY);
130 if(fd == -1) {
131 RLOGD("write_wakeup_reason, open %s fail(%s), just return", WAKEUPREASONPATH,strerror(errno));
132 return ;
133 }
134 len = write(fd, reason.c_str(), reason.size());
135 if(len == -1) {
136 RLOGD("write_wakeup_reason, write %s fail(%s)", WAKEUPREASONPATH,strerror(errno));
137 }
138 close(fd);
139}
140
141void *wakeup_reason_loop(void *param)
142{
143 std::string reason("");
144 RLOGD("wakeup_reason_loop start");
145
146 prctl(PR_SET_NAME,(unsigned long)"demo_wakeup_reason_loop");
147
148 LIST_LOCK();
149 wakeup_reasons.clear();
150 LIST_UNLOCK();
151
152 for(;;){
153
154 LIST_LOCK();
155 if(wakeup_reasons.empty()) { //if blank list then wait
156 RLOGD("wakeup reason list is empty ,then wait!");
157 while(wakeup_reasons.empty()){
158 WAITLIST();
159 }
160 }
161 reason = wakeup_reasons.front();
162 wakeup_reasons.pop_front();
163 LIST_UNLOCK();
164 write_wakeup_reason(reason);
165 }
166 return 0;
167}
168
169void handle_wakeup_reason(int requestCode) {
170 RLOGD("handle_wakeup_reason %s:", android::requestToString(requestCode));
171 std::string reason("");
172 switch (requestCode){
173 //CCIF_CALL
174 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
175 case RIL_UNSOL_CALL_RING:
176 case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
177 case RIL_UNSOL_RINGBACK_TONE:
178 case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
179 case RIL_UNSOL_SRVCC_STATE_NOTIFY:
180 case RIL_UNSOL_ECONF_SRVCC_INDICATION:
181 case RIL_UNSOL_ECONF_RESULT_INDICATION:
182 case RIL_UNSOL_CRSS_NOTIFICATION:
183 case RIL_UNSOL_INCOMING_CALL_INDICATION:
184 case RIL_UNSOL_CALL_INFO_INDICATION:
185 case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
186 {
187 reason = "CCIF_CALL";
188 break;
189 }
190 //CCIF_NW
191 case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
192 case RIL_UNSOL_NITZ_TIME_RECEIVED:
193 case RIL_UNSOL_SIGNAL_STRENGTH:
194 case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
195 case RIL_UNSOL_CELL_INFO_LIST:
196 case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
197 {
198 reason = "CCIF_NW";
199 break;
200 }
201 //CCIF_Message
202 case RIL_UNSOL_RESPONSE_NEW_SMS:
203 case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
204 case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
205 case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
206 case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
207 case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
208 case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
209 case RIL_UNSOL_SMS_READY_NOTIFICATION:
210 case RIL_UNSOL_ON_USSD:
211 {
212 reason = "CCIF_MESSAGE";
213 break;
214 }
215 //CCIF_Other
216 case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
217 case RIL_UNSOL_ECALL_MSDHACK:
218 case RIL_UNSOL_SIM_REFRESH:
219 case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
220 case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
221 case RIL_UNSOL_STK_SESSION_END:
222 case RIL_UNSOL_STK_PROACTIVE_COMMAND:
223 case RIL_UNSOL_STK_EVENT_NOTIFY:
224 case RIL_UNSOL_STK_CALL_SETUP:
225 case RIL_UNSOL_STK_BIP_PROACTIVE_COMMAND:
226 case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
227 case RIL_UNSOL_RIL_CONNECTED:
228 case RIL_UNSOL_RADIO_CAPABILITY:
229 {
230 reason = "CCIF_OTHER";
231 break;
232 }
233 default:
234 RLOGD("handle_wakeup_reason no wakeup reason, just return");
235 return;
236 }
237 if(reason.empty()) {
238 RLOGE("handle_wakeup_reason error , reason is empty, return");
239 return;
240 }
241 LIST_LOCK();
242 wakeup_reasons.push_back(reason);
243 WAKEUPLIST();
244 LIST_UNLOCK();
245}
246
247int demo_open_socket(const char *path)
248{
249 RLOGD("demo_open_socket");
250 int sd;
251 int res;
252 struct sockaddr_un addr;
253
254 sd = socket(AF_UNIX, SOCK_STREAM, 0);
255 if (sd < 0) {
256 RLOGE("socket error: %s", strerror(errno));
257 return sd;
258 }
259
260 if(remove(path) == -1 && errno != ENOENT)
261 {
262 RLOGD("remove-%s, remove error: %s", path, strerror(errno));
263 }
264
265 memset(&addr, 0, sizeof(struct sockaddr_un));
266 addr.sun_family = AF_UNIX;
267 strncpy(addr.sun_path, path, sizeof(addr.sun_path)-1);
268
269 res = bind(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un));
270 if (res != 0) {
271 RLOGE("bind error: %s\n", strerror(errno));
272 goto error;
273 }
274
275 res = listen(sd, 8);
276 if (res != 0) {
277 RLOGE("listen error: %s\n", strerror(errno));
278 goto error;
279 }
280 return sd;
281error:
282 if (sd >=0)
283 close(sd);
284 return -1;
285}
286
287int send_data(int sockfd, const char *buf, int len) {
288 int ret = 0;
289 int cur_pos = 0;
290
291 if (sockfd <= 0)
292 return 0;
293
294 while(cur_pos < len) {
295 ret = send(sockfd, &buf[cur_pos], len - cur_pos, MSG_DONTWAIT);
296 if (ret == len - cur_pos)
297 break;
298
299 if (ret <= 0) {
300 RLOGE("SOCKET ERROR errno:%d,%s", errno, strerror(errno));
301 if (errno == EAGAIN || errno == EINTR)
302 {
303 RLOGD("send to internet buffer full, wait(10ms)");
304 usleep(10000);
305 continue;
306 }
307 if (errno == ECONNRESET || errno == EPIPE)
308 {
309 sockfd = -1;
310 RLOGD("buffer client connect is reset");
311 }
312 break;
313 } else
314 cur_pos += ret;
315 }
316
317 return ret;
318}
319
320void sendSmsMsg(RIL_SOCKET_ID soc_id)
321{
322 char *msg = "sms_on";
323 for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
324 if(cli_socket[i] > 0 ) {
325 auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
326 auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
327 if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
328 RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
329 send_data(cli_socket[i], msg, strlen(msg));
330 }
331 }
332 }
333}
334
335void sendCallMsg(bool call_on)
336{
337 char* on = "call_on";
338 char* off = "call_off";
339 char *msg = call_on ? on : off;
340 for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
341 if(cli_socket[i] > 0 ) {
342 auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
343 auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
344 if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
345 RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
346 send_data(cli_socket[i], msg, strlen(msg));
347 }
348 }
349 }
350}
351
352void sendKeepAlive(const char* msg)
353{
354 std::string str(msg);
355 if (str.find("RIL_REQUEST_START_KEEPALIVE_PRO") != std::string::npos) {
356 for (auto it : keepalive_start) {
357 RLOGD("sendKeepAlive response(RIL_REQUEST_START_KEEPALIVE_PRO(%d)): %s",it, msg);
358 send_data(it, msg, strlen(msg));
359 }
360 }
361
362 if (str.find("RIL_REQUEST_STOP_KEEPALIVE_PRO") != std::string::npos) {
363 for (auto it : Keepalive_stop) {
364 RLOGD("sendKeepAlive response(RIL_REQUEST_STOP_KEEPALIVE_PRO(%d)): %s", it, msg);
365 send_data(it, msg, strlen(msg));
366 }
367 }
368
369 if (str.find("RIL_UNSOL_KEEPALIVE_STATUS_PRO") != std::string::npos) {
370 for (auto it : keepalive_start) {
371 RLOGD("sendKeepAlive notify((start)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
372 send_data(it, msg, strlen(msg));
373 }
374 for (auto it : Keepalive_stop) {
375 RLOGD("sendKeepAlive notify((stop)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
376 send_data(it, msg, strlen(msg));
377 }
378 }
379}
380
381#define SOCKET_ZERO 0
382#define SOCKET_SUCC 1
383#define SOCKET_FAIL -1
384
385void dispatch_cmd(int fd, char* msg) {
386 RLOGD("dispatch_cmd: %s", msg);
387 std::vector<std::string> v;
388 utils::tokenize(std::string(msg),',',v);
389 int i = 0;
390 for(auto s: v) {
391 RLOGD("%d:%s",i, s.c_str());
392 i++;
393 }
394 if(v.size() != 10 && v.size() != 2) {
395 RLOGE("transfer parameters num is wrong: %d", v.size());
396 return ;
397 }
398 int id = get_default_sim_data();
399 if(v[0] == std::string("RIL_REQUEST_START_KEEPALIVE_PRO")) {
400 keepalive_start.push_back(fd);
401 RLOGD("[SIM%d]start keepalive", id);
402 RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_START_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
403 char* argv[10] = {0};
404 for(int i=0; i< v.size() && i < 10; i++){
405 argv[i] = const_cast<char*>(v[i].c_str());
406 }
407 startKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
408 } else if(v[0] == std::string("RIL_REQUEST_STOP_KEEPALIVE_PRO")) {
409 Keepalive_stop.push_back(fd);
410 RLOGD("[SIM%d]stop keepalive", id);
411 RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_STOP_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
412 char* argv[2] = {0};
413 for(int i=0; i< v.size() && i < 2; i++){
414 argv[i] = const_cast<char*>(v[i].c_str());
415 }
416 stopKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
417 } else {
418 RLOGD("dispatch_cmd(%s) error", v[0].c_str());
419 }
420}
421
422void eraseSocket(std::vector<int> &v, int sd) {
423 auto it = std::find(v.begin(), v.end(), sd);
424 if (it != std::end(v)) {
425 v.erase(it);
426 }
427}
428
429void *StartPMSocket(void *param)
430{
431 RLOGD("StartPMSocket start");
432 char buf[SOCKET_BUF_SIZE] = {0};
433 int max_fd;
434 fd_set readfds;
435 for (int i=0; i < MAX_CLIENT_SIZE; i++) {
436 cli_socket[i] = 0;
437 }
438 int ssd = -1;
439 struct sockaddr_un addr;
440 socklen_t socke_len;
441
442 ssd = demo_open_socket(DEMOAPP_SOCKET_NAME);
443 if(ssd < 0)
444 {
445 RLOGE("ssd < 0, just return");
446 return NULL;
447 }
448
449 while (true) {
450 FD_ZERO(&readfds);
451 FD_SET(ssd, &readfds);
452 max_fd = ssd;
453 for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
454 int sd = cli_socket[i];
455 if(sd > 0) {
456 FD_SET(sd, &readfds);
457 }
458 if(sd > max_fd) {
459 max_fd = sd;
460 }
461 }
462 int act_fd_num = select(max_fd +1, &readfds, NULL, NULL, NULL);
463 if(act_fd_num < 0 && (errno != EINTR)) {
464 RLOGE("select error");
465 }
466 if(FD_ISSET(ssd, &readfds)) {
467 int cli_soc = accept(ssd, (struct sockaddr*)&addr, &socke_len);
468 if (cli_soc < 0)
469 {
470 RLOGE("accept error: %s", strerror(errno));
471 close(cli_soc);
472 return NULL;
473 }
474 RLOGD("Accept a client , client id is %d", cli_soc);
475 //TBD send sometings.
476 for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
477 if(cli_socket[i] == 0) {
478 cli_socket[i] = cli_soc;
479 RLOGD("add new socket %d", cli_soc);
480 break;
481 }
482 }
483 }
484 for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
485 int sd = cli_socket[i];
486 if(FD_ISSET(sd, &readfds)) {
487 memset(buf, 0, sizeof(buf));
488 int ret = recv(sd, buf,SOCKET_BUF_SIZE, 0);
489 if (ret < 0) {
490 RLOGE("data_recv select error, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
491 } else if (ret == SOCKET_ZERO) {
492 RLOGE("data_recv recv error, maybe client socket closed, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
493 close(sd);
494 cli_socket[i] = 0;
495 eraseSocket(keepalive_start,sd);
496 eraseSocket(Keepalive_stop,sd);
497 } else {
498 buf[ret] = '\0';
499 dispatch_cmd(sd, buf);
500 }
501 }
502 }
503 }
504 RLOGD("start PowerManager Done");
505 return 0;
506}