Home | History | Annotate | Download | only in libril
      1 /*
      2 * Copyright (C) 2014 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 *     http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 extern "C"
     18 void *ril_socket_process_requests_loop(void *arg);
     19 
     20 #include "RilSocket.h"
     21 #include <cutils/sockets.h>
     22 #include <utils/Log.h>
     23 #include <assert.h>
     24 #define SOCKET_LISTEN_BACKLOG 0
     25 
     26 int RilSocket::socketInit(void) {
     27     int ret;
     28 
     29     listenCb = &RilSocket::sSocketListener;
     30     commandCb = &RilSocket::sSocketRequestsHandler;
     31     listenFd = android_get_control_socket(name);
     32 
     33     //Start listening
     34     ret = listen(listenFd, SOCKET_LISTEN_BACKLOG);
     35 
     36     if (ret < 0) {
     37         RLOGE("Failed to listen on %s socket '%d': %s",
     38         name, listenFd, strerror(errno));
     39         return ret;
     40     }
     41     //Add listen event to the event loop
     42     ril_event_set(&listenEvent, listenFd, false, listenCb, this);
     43     rilEventAddWakeup_helper(&listenEvent);
     44     return ret;
     45 }
     46 
     47 void RilSocket::sSocketListener(int fd, short flags, void *param) {
     48     RilSocket *theSocket = (RilSocket *) param;
     49     MySocketListenParam listenParam;
     50     listenParam.socket = theSocket;
     51     listenParam.sListenParam.type = RIL_SAP_SOCKET;
     52 
     53     listenCallback_helper(fd, flags, (void*)&listenParam);
     54 }
     55 
     56 void RilSocket::onNewCommandConnect() {
     57     pthread_attr_t attr;
     58     PthreadPtr pptr = ril_socket_process_requests_loop;
     59     int result;
     60 
     61     pthread_attr_init(&attr);
     62     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     63 
     64     //Start socket request processing loop thread
     65     result = pthread_create(&socketThreadId, &attr, pptr, this);
     66     if(result < 0) {
     67         RLOGE("pthread_create failed with result:%d",result);
     68     }
     69 
     70     RLOGE("New socket command connected and socket request thread started");
     71 }
     72 
     73 void RilSocket::sSocketRequestsHandler(int fd, short flags, void *param) {
     74     socketClient *sc = (socketClient *) param;
     75     RilSocket *theSocket = sc->socketPtr;
     76     RecordStream *rs = sc->rs;
     77 
     78     theSocket->socketRequestsHandler(fd, flags, rs);
     79 }
     80 
     81 void RilSocket::socketRequestsHandler(int fd, short flags, RecordStream *p_rs) {
     82     int ret;
     83     assert(fd == commandFd);
     84     void *p_record;
     85     size_t recordlen;
     86 
     87     for (;;) {
     88         /* loop until EAGAIN/EINTR, end of stream, or other error */
     89         ret = record_stream_get_next(p_rs, &p_record, &recordlen);
     90 
     91         if (ret == 0 && p_record == NULL) {
     92             /* end-of-stream */
     93             break;
     94         } else if (ret < 0) {
     95             break;
     96         } else if (ret == 0) {
     97             pushRecord(p_record, recordlen);
     98         }
     99     }
    100 
    101     if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) {
    102         /* fatal error or end-of-stream */
    103         if (ret != 0) {
    104             RLOGE("error on reading command socket errno:%d\n", errno);
    105         } else {
    106             RLOGW("EOS.  Closing command socket.");
    107         }
    108 
    109         close(commandFd);
    110         commandFd = -1;
    111 
    112         ril_event_del(&callbackEvent);
    113 
    114         record_stream_free(p_rs);
    115 
    116         /* start listening for new connections again */
    117 
    118         rilEventAddWakeup_helper(&listenEvent);
    119 
    120         onCommandsSocketClosed();
    121     }
    122 }
    123 
    124 void RilSocket::setListenFd(int fd) {
    125     listenFd = fd;
    126 }
    127 
    128 void RilSocket::setCommandFd(int fd) {
    129     commandFd = fd;
    130 }
    131 
    132 int RilSocket::getListenFd(void) {
    133     return listenFd;
    134 }
    135 
    136 int RilSocket::getCommandFd(void) {
    137     return commandFd;
    138 }
    139 
    140 void RilSocket::setListenCb(ril_event_cb cb) {
    141     listenCb = cb;
    142 }
    143 
    144 void RilSocket::setCommandCb(ril_event_cb cb) {
    145     commandCb = cb;
    146 }
    147 
    148 ril_event_cb RilSocket::getListenCb(void) {
    149     return listenCb;
    150 }
    151 
    152 ril_event_cb RilSocket::getCommandCb(void) {
    153     return commandCb;
    154 }
    155 
    156 void RilSocket::setListenEvent(ril_event event) {
    157     listenEvent = event;
    158 }
    159 
    160 void RilSocket::setCallbackEvent(ril_event event) {
    161     callbackEvent = event;
    162 }
    163 
    164 ril_event* RilSocket::getListenEvent(void)  {
    165     return &listenEvent;
    166 }
    167 
    168 ril_event* RilSocket::getCallbackEvent(void) {
    169     return &callbackEvent;
    170 }
    171 
    172 extern "C"
    173 void *ril_socket_process_requests_loop(void *arg) {
    174     RilSocket *socket = (RilSocket *)arg;
    175     socket->processRequestsLoop();
    176     return NULL;
    177 }
    178