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