| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| extern "C" |
| void *ril_socket_process_requests_loop(void *arg); |
| |
| #include "RilSocket.h" |
| #include <cutils/sockets.h> |
| #include <utils/Log.h> |
| #include <assert.h> |
| #define SOCKET_LISTEN_BACKLOG 0 |
| |
| int RilSocket::socketInit(void) { |
| int ret; |
| |
| listenCb = &RilSocket::sSocketListener; |
| commandCb = &RilSocket::sSocketRequestsHandler; |
| listenFd = android_get_control_socket(name); |
| |
| //Start listening |
| ret = listen(listenFd, SOCKET_LISTEN_BACKLOG); |
| |
| if (ret < 0) { |
| RLOGE("Failed to listen on %s socket '%d': %s", |
| name, listenFd, strerror(errno)); |
| return ret; |
| } |
| //Add listen event to the event loop |
| ril_event_set(&listenEvent, listenFd, false, listenCb, this); |
| rilEventAddWakeup_helper(&listenEvent); |
| return ret; |
| } |
| |
| void RilSocket::sSocketListener(int fd, short flags, void *param) { |
| RilSocket *theSocket = (RilSocket *) param; |
| MySocketListenParam listenParam; |
| listenParam.socket = theSocket; |
| listenParam.sListenParam.type = RIL_SAP_SOCKET; |
| |
| listenCallback_helper(fd, flags, (void*)&listenParam); |
| } |
| |
| void RilSocket::onNewCommandConnect() { |
| pthread_attr_t attr; |
| PthreadPtr pptr = ril_socket_process_requests_loop; |
| int result; |
| |
| pthread_attr_init(&attr); |
| pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
| |
| //Start socket request processing loop thread |
| result = pthread_create(&socketThreadId, &attr, pptr, this); |
| if(result < 0) { |
| RLOGE("pthread_create failed with result:%d",result); |
| } |
| |
| RLOGE("New socket command connected and socket request thread started"); |
| } |
| |
| void RilSocket::sSocketRequestsHandler(int fd, short flags, void *param) { |
| socketClient *sc = (socketClient *) param; |
| RilSocket *theSocket = sc->socketPtr; |
| RecordStream *rs = sc->rs; |
| |
| theSocket->socketRequestsHandler(fd, flags, rs); |
| } |
| |
| void RilSocket::socketRequestsHandler(int fd, short flags, RecordStream *p_rs) { |
| int ret; |
| assert(fd == commandFd); |
| void *p_record; |
| size_t recordlen; |
| |
| for (;;) { |
| /* loop until EAGAIN/EINTR, end of stream, or other error */ |
| ret = record_stream_get_next(p_rs, &p_record, &recordlen); |
| |
| if (ret == 0 && p_record == NULL) { |
| /* end-of-stream */ |
| break; |
| } else if (ret < 0) { |
| break; |
| } else if (ret == 0) { |
| pushRecord(p_record, recordlen); |
| } |
| } |
| |
| if (ret == 0 || !(errno == EAGAIN || errno == EINTR)) { |
| /* fatal error or end-of-stream */ |
| if (ret != 0) { |
| RLOGE("error on reading command socket errno:%d\n", errno); |
| } else { |
| RLOGW("EOS. Closing command socket."); |
| } |
| |
| close(commandFd); |
| commandFd = -1; |
| |
| ril_event_del(&callbackEvent); |
| |
| record_stream_free(p_rs); |
| |
| /* start listening for new connections again */ |
| |
| rilEventAddWakeup_helper(&listenEvent); |
| |
| onCommandsSocketClosed(); |
| } |
| } |
| |
| void RilSocket::setListenFd(int fd) { |
| listenFd = fd; |
| } |
| |
| void RilSocket::setCommandFd(int fd) { |
| commandFd = fd; |
| } |
| |
| int RilSocket::getListenFd(void) { |
| return listenFd; |
| } |
| |
| int RilSocket::getCommandFd(void) { |
| return commandFd; |
| } |
| |
| void RilSocket::setListenCb(ril_event_cb cb) { |
| listenCb = cb; |
| } |
| |
| void RilSocket::setCommandCb(ril_event_cb cb) { |
| commandCb = cb; |
| } |
| |
| ril_event_cb RilSocket::getListenCb(void) { |
| return listenCb; |
| } |
| |
| ril_event_cb RilSocket::getCommandCb(void) { |
| return commandCb; |
| } |
| |
| void RilSocket::setListenEvent(ril_event event) { |
| listenEvent = event; |
| } |
| |
| void RilSocket::setCallbackEvent(ril_event event) { |
| callbackEvent = event; |
| } |
| |
| ril_event* RilSocket::getListenEvent(void) { |
| return &listenEvent; |
| } |
| |
| ril_event* RilSocket::getCallbackEvent(void) { |
| return &callbackEvent; |
| } |
| |
| RIL_SOCKET_ID RilSocket::getSocketId(void) { |
| return id; |
| } |
| |
| extern "C" |
| void *ril_socket_process_requests_loop(void *arg) { |
| RilSocket *socket = (RilSocket *)arg; |
| socket->processRequestsLoop(); |
| return NULL; |
| } |