[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp
new file mode 100644
index 0000000..efa8f6d
--- /dev/null
+++ b/src/lynq/lib/liblynq-tele-ril/lynq-riltel/powerManager.cpp
@@ -0,0 +1,506 @@
+/*
+* Copyright Statement:
+*
+* This software/firmware and related documentation ("MediaTek Software") are
+* protected under relevant copyright laws. The information contained herein is
+* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
+* the prior written permission of MediaTek inc. and/or its licensors, any
+* reproduction, modification, use or disclosure of MediaTek Software, and
+* information contained herein, in whole or in part, shall be strictly
+* prohibited.
+*
+* MediaTek Inc. (C) 2017. All rights reserved.
+*
+* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+* ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
+* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+* NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
+* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
+* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
+* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
+* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
+* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
+* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
+* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <log/log.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string>
+#include <vector>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <vector>
+#include <deque>
+#include <iterator>
+#include <algorithm>
+
+#include "common.h"
+#include "powerManager.h"
+#include "util/utils.h"
+#include "stateManager/stateManager.h"
+#include  <vendor-ril/telephony/ril.h>
+
+#undef DEMOAPP_SOCKET_NAME
+#define DEMOAPP_SOCKET_NAME "/tmp/socket-demoapp"
+#define SOCKET_BUF_SIZE 1024
+#define MAX_CLIENT_SIZE 30
+#undef LOG_TAG
+#define LOG_TAG "DEMO_powermanager"
+int cli_socket[MAX_CLIENT_SIZE];
+std::vector<int> keepalive_start;
+std::vector<int> Keepalive_stop;
+
+//global variable
+static pthread_mutex_t s_WakeupMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_WakeupCond = PTHREAD_COND_INITIALIZER;
+//marco define
+#define LIST_LOCK()  pthread_mutex_lock(&s_WakeupMutex)
+#define LIST_UNLOCK() pthread_mutex_unlock(&s_WakeupMutex)
+#define WAITLIST() pthread_cond_wait(&s_WakeupCond,&s_WakeupMutex)
+#define WAKEUPLIST() pthread_cond_signal(&s_WakeupCond)
+#define WAKEUPREASONPATH "/sys/power/spm/wakeup_reason"
+//#define WAKEUPSTATUS "/sys/power/suspend_status"
+
+static std::deque<std::string> wakeup_reasons;
+
+std::string read_wakeup_reason() {
+    if(access(WAKEUPREASONPATH, R_OK) == -1) {
+        RLOGD("read_wakeup_reason, %s cann't read(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        return "";
+    }
+
+    int fd;
+    fd = open(WAKEUPREASONPATH , O_RDONLY);
+    if(fd == -1) {
+        RLOGD("read_wakeup_reason, open %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        return "";
+    }
+
+    ssize_t len;
+    char buf[50]={0};
+    std::string reason("");
+    len = read(fd, buf,sizeof(buf) -1);
+    if(len == -1) {
+        RLOGD("read_wakeup_reason, read %s fail(%s),just return", WAKEUPREASONPATH, strerror(errno));
+        reason="";
+        goto fail;
+    }
+    RLOGD("read_wakeup_reason is %s", buf);
+    reason = buf;
+fail:
+    close(fd);
+    return reason;
+}
+
+void write_wakeup_reason(std::string reason) {
+    int fd;
+    ssize_t len;
+    if(reason.empty()) {
+        RLOGD("write_wakeup_reason is empty, just return");
+        return;
+    }
+    std::string save = read_wakeup_reason();
+    if(save == reason) {
+        RLOGD("write_wakeup_reason is same, just return");
+//        return; //don't need return, handle initial reason equal to first write reason.
+    }
+    RLOGD("write_wakeup_reason: %s", reason.c_str());
+    if(access(WAKEUPREASONPATH, W_OK) == -1) {
+        RLOGD("write_wakeup_reason, %s cann't write(%s), just return", WAKEUPREASONPATH, strerror(errno));
+        return ;
+    }
+    fd = open(WAKEUPREASONPATH , O_WRONLY);
+    if(fd == -1) {
+        RLOGD("write_wakeup_reason, open %s fail(%s), just return", WAKEUPREASONPATH,strerror(errno));
+        return ;
+    }
+    len = write(fd, reason.c_str(), reason.size());
+    if(len == -1) {
+        RLOGD("write_wakeup_reason, write %s fail(%s)", WAKEUPREASONPATH,strerror(errno));
+    }
+    close(fd);
+}
+
+void *wakeup_reason_loop(void *param)
+{
+    std::string reason("");
+    RLOGD("wakeup_reason_loop start");
+
+    prctl(PR_SET_NAME,(unsigned long)"demo_wakeup_reason_loop");
+
+    LIST_LOCK();
+    wakeup_reasons.clear();
+    LIST_UNLOCK();
+
+    for(;;){
+
+        LIST_LOCK();
+        if(wakeup_reasons.empty()) {    //if blank list  then wait
+            RLOGD("wakeup reason list is empty ,then wait!");
+            while(wakeup_reasons.empty()){
+                WAITLIST();
+            }
+        }
+        reason = wakeup_reasons.front();
+        wakeup_reasons.pop_front();
+        LIST_UNLOCK();
+        write_wakeup_reason(reason);
+    }
+    return 0;
+}
+
+void handle_wakeup_reason(int requestCode) {
+    RLOGD("handle_wakeup_reason %s:", android::requestToString(requestCode));
+    std::string reason("");
+    switch (requestCode){
+    //CCIF_CALL
+    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+    case RIL_UNSOL_CALL_RING:
+    case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
+    case RIL_UNSOL_RINGBACK_TONE:
+    case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+    case RIL_UNSOL_SRVCC_STATE_NOTIFY:
+    case RIL_UNSOL_ECONF_SRVCC_INDICATION:
+    case RIL_UNSOL_ECONF_RESULT_INDICATION:
+    case RIL_UNSOL_CRSS_NOTIFICATION:
+    case RIL_UNSOL_INCOMING_CALL_INDICATION:
+    case RIL_UNSOL_CALL_INFO_INDICATION:
+    case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
+    {
+        reason = "CCIF_CALL";
+        break;
+    }
+    //CCIF_NW
+    case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
+    case RIL_UNSOL_NITZ_TIME_RECEIVED:
+    case RIL_UNSOL_SIGNAL_STRENGTH:
+    case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
+    case RIL_UNSOL_CELL_INFO_LIST:
+    case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
+    {
+        reason = "CCIF_NW";
+        break;
+    }
+    //CCIF_Message
+    case RIL_UNSOL_RESPONSE_NEW_SMS:
+    case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
+    case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
+    case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
+    case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
+    case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+    case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
+    case RIL_UNSOL_SMS_READY_NOTIFICATION:
+    case RIL_UNSOL_ON_USSD:
+    {
+        reason = "CCIF_MESSAGE";
+        break;
+    }
+    //CCIF_Other
+    case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+    case RIL_UNSOL_ECALL_MSDHACK:
+    case RIL_UNSOL_SIM_REFRESH:
+    case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+    case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
+    case RIL_UNSOL_STK_SESSION_END:
+    case RIL_UNSOL_STK_PROACTIVE_COMMAND:
+    case RIL_UNSOL_STK_EVENT_NOTIFY:
+    case RIL_UNSOL_STK_CALL_SETUP:
+    case RIL_UNSOL_STK_BIP_PROACTIVE_COMMAND:
+    case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+    case RIL_UNSOL_RIL_CONNECTED:
+    case RIL_UNSOL_RADIO_CAPABILITY:
+    {
+        reason = "CCIF_OTHER";
+        break;
+    }
+    default:
+        RLOGD("handle_wakeup_reason no wakeup reason, just return");
+        return;
+    }
+    if(reason.empty()) {
+        RLOGE("handle_wakeup_reason error , reason is empty, return");
+        return;
+    }
+    LIST_LOCK();
+    wakeup_reasons.push_back(reason);
+    WAKEUPLIST();
+    LIST_UNLOCK();
+}
+
+int demo_open_socket(const char *path)
+{
+    RLOGD("demo_open_socket");
+    int sd;
+    int res;
+    struct sockaddr_un addr;
+
+    sd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (sd < 0) {
+        RLOGE("socket error: %s", strerror(errno));
+        return sd;
+    }
+
+    if(remove(path) == -1 && errno != ENOENT)
+    {
+        RLOGD("remove-%s, remove error: %s", path, strerror(errno));
+    }
+
+    memset(&addr, 0, sizeof(struct sockaddr_un));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, path, sizeof(addr.sun_path)-1);
+
+    res = bind(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un));
+    if (res != 0) {
+        RLOGE("bind error: %s\n", strerror(errno));
+        goto error;
+    }
+
+    res = listen(sd, 8);
+    if (res != 0) {
+        RLOGE("listen error: %s\n", strerror(errno));
+        goto error;
+    }
+    return sd;
+error:
+    if (sd >=0)
+        close(sd);
+    return -1;
+}
+
+int send_data(int sockfd, const char *buf, int len) {
+    int ret = 0;
+    int cur_pos = 0;
+
+    if (sockfd <= 0)
+        return 0;
+
+    while(cur_pos < len) {
+        ret = send(sockfd, &buf[cur_pos], len - cur_pos, MSG_DONTWAIT);
+        if (ret == len - cur_pos)
+            break;
+
+        if (ret <= 0) {
+            RLOGE("SOCKET ERROR errno:%d,%s", errno, strerror(errno));
+            if (errno == EAGAIN || errno == EINTR)
+            {
+                RLOGD("send to internet buffer full, wait(10ms)");
+                usleep(10000);
+                continue;
+            }
+            if (errno == ECONNRESET || errno == EPIPE)
+            {
+                sockfd = -1;
+                RLOGD("buffer client connect is reset");
+            }
+            break;
+        } else
+            cur_pos += ret;
+    }
+
+    return ret;
+}
+
+void sendSmsMsg(RIL_SOCKET_ID soc_id)
+{
+    char *msg = "sms_on";
+    for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
+        if(cli_socket[i] > 0 ) {
+            auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
+            auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
+            if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
+                RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
+                send_data(cli_socket[i], msg, strlen(msg));
+            }
+        }
+    }
+}
+
+void sendCallMsg(bool call_on)
+{
+    char* on = "call_on";
+    char* off = "call_off";
+    char *msg = call_on ? on : off;
+    for (int i = 0 ; i < MAX_CLIENT_SIZE; i++) {
+        if(cli_socket[i] > 0 ) {
+            auto it_start = std::find(keepalive_start.begin(), keepalive_start.end(), cli_socket[i]);
+            auto it_stop = std::find(Keepalive_stop.begin(), Keepalive_stop.end(), cli_socket[i]);
+            if(it_start == std::end(keepalive_start) && it_stop == std::end(Keepalive_stop)) {
+                RLOGD("sendSmsMsg(%d): %s", cli_socket[i], msg);
+                send_data(cli_socket[i], msg, strlen(msg));
+            }
+        }
+    }
+}
+
+void sendKeepAlive(const char* msg)
+{
+    std::string str(msg);
+    if (str.find("RIL_REQUEST_START_KEEPALIVE_PRO") != std::string::npos) {
+        for (auto it : keepalive_start) {
+            RLOGD("sendKeepAlive response(RIL_REQUEST_START_KEEPALIVE_PRO(%d)): %s",it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+
+    if (str.find("RIL_REQUEST_STOP_KEEPALIVE_PRO") != std::string::npos) {
+        for (auto it : Keepalive_stop) {
+            RLOGD("sendKeepAlive response(RIL_REQUEST_STOP_KEEPALIVE_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+
+    if (str.find("RIL_UNSOL_KEEPALIVE_STATUS_PRO") != std::string::npos) {
+        for (auto it : keepalive_start) {
+            RLOGD("sendKeepAlive notify((start)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+        for (auto it : Keepalive_stop) {
+            RLOGD("sendKeepAlive notify((stop)RIL_UNSOL_KEEPALIVE_STATUS_PRO(%d)): %s", it, msg);
+            send_data(it, msg, strlen(msg));
+        }
+    }
+}
+
+#define SOCKET_ZERO   0
+#define SOCKET_SUCC   1
+#define SOCKET_FAIL  -1
+
+void dispatch_cmd(int fd, char* msg) {
+    RLOGD("dispatch_cmd: %s", msg);
+    std::vector<std::string> v;
+    utils::tokenize(std::string(msg),',',v);
+    int i = 0;
+    for(auto s: v) {
+        RLOGD("%d:%s",i, s.c_str());
+        i++;
+    }
+    if(v.size() != 10 && v.size() != 2) {
+        RLOGE("transfer parameters num is wrong: %d", v.size());
+        return ;
+    }
+    int id = get_default_sim_data();
+    if(v[0] == std::string("RIL_REQUEST_START_KEEPALIVE_PRO")) {
+        keepalive_start.push_back(fd);
+        RLOGD("[SIM%d]start keepalive", id);
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_START_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
+        char* argv[10] = {0};
+        for(int i=0; i< v.size() && i < 10; i++){
+            argv[i] = const_cast<char*>(v[i].c_str());
+        }
+        startKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
+    } else if(v[0] == std::string("RIL_REQUEST_STOP_KEEPALIVE_PRO")) {
+        Keepalive_stop.push_back(fd);
+        RLOGD("[SIM%d]stop keepalive", id);
+        RequestInfo *info = creatRILInfoAndInit(RIL_REQUEST_STOP_KEEPALIVE_PRO, OTHER, (RIL_SOCKET_ID)id);
+        char* argv[2] = {0};
+        for(int i=0; i< v.size() && i < 2; i++){
+            argv[i] = const_cast<char*>(v[i].c_str());
+        }
+        stopKeepAlivePro(v.size(), argv, (RIL_SOCKET_ID)id, info);
+    } else {
+        RLOGD("dispatch_cmd(%s) error", v[0].c_str());
+    }
+}
+
+void eraseSocket(std::vector<int> &v, int sd) {
+    auto it = std::find(v.begin(), v.end(), sd);
+    if (it != std::end(v)) {
+        v.erase(it);
+    }
+}
+
+void *StartPMSocket(void *param)
+{
+    RLOGD("StartPMSocket start");
+    char buf[SOCKET_BUF_SIZE] = {0};
+    int max_fd;
+    fd_set readfds;
+    for (int i=0; i < MAX_CLIENT_SIZE; i++) {
+        cli_socket[i] = 0;
+    }
+    int ssd = -1;
+    struct sockaddr_un addr;
+    socklen_t socke_len;
+
+    ssd = demo_open_socket(DEMOAPP_SOCKET_NAME);
+    if(ssd < 0)
+    {
+        RLOGE("ssd < 0, just return");
+        return NULL;
+    }
+
+    while (true) {
+        FD_ZERO(&readfds);
+        FD_SET(ssd, &readfds);
+        max_fd = ssd;
+        for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+            int sd = cli_socket[i];
+            if(sd > 0) {
+                FD_SET(sd, &readfds);
+            }
+            if(sd > max_fd) {
+                max_fd = sd;
+            }
+        }
+        int act_fd_num = select(max_fd +1, &readfds, NULL, NULL, NULL);
+        if(act_fd_num < 0 && (errno != EINTR)) {
+            RLOGE("select error");
+        }
+        if(FD_ISSET(ssd, &readfds)) {
+            int cli_soc = accept(ssd, (struct sockaddr*)&addr, &socke_len);
+            if (cli_soc < 0)
+            {
+                RLOGE("accept error: %s", strerror(errno));
+                close(cli_soc);
+                return NULL;
+            }
+            RLOGD("Accept a client , client id is %d", cli_soc);
+            //TBD send sometings.
+            for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+                if(cli_socket[i] == 0) {
+                    cli_socket[i] = cli_soc;
+                    RLOGD("add new socket %d", cli_soc);
+                    break;
+                }
+            }
+        }
+        for(int i = 0; i < MAX_CLIENT_SIZE; i++) {
+            int sd = cli_socket[i];
+            if(FD_ISSET(sd, &readfds)) {
+                memset(buf, 0, sizeof(buf));
+                int ret = recv(sd, buf,SOCKET_BUF_SIZE, 0);
+                if (ret < 0) {
+                    RLOGE("data_recv select error, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
+                } else if (ret == SOCKET_ZERO) {
+                    RLOGE("data_recv recv error, maybe client socket closed, ret=%d, error=%s(%d),fd=%d", ret, strerror(errno), errno, sd);
+                    close(sd);
+                    cli_socket[i] = 0;
+                    eraseSocket(keepalive_start,sd);
+                    eraseSocket(Keepalive_stop,sd);
+                } else {
+                    buf[ret] = '\0';
+                    dispatch_cmd(sd, buf);
+                }
+            }
+        }
+    }
+    RLOGD("start PowerManager Done");
+    return 0;
+}