Added new socket connection for communication between the SAP module in Telephony and User Identity Module with DSDA support. New classes added are: RilSocket --------- Base class(virtual) for any type of socket. Has listen and commands callbacks similar to that of the existing telephony->rild socket. RilSapSocket ------------ Derived class for socket for communication between BT SAP and the sim module in the modem. It initialises socket, calls Sap_Uim_Init to get the handles and starts the socket thread. rilSocketQueue -------------- Queue for managing socket requests. Change-Id: I8828173941d6ae76f1f9cc0d567efaf41a77d175tirimbino
parent
6187ef8378
commit
cc231015f2
@ -0,0 +1,457 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#define __STDC_LIMIT_MACROS |
||||
#include <stdint.h> |
||||
#define RIL_SHLIB |
||||
#include "telephony/ril.h" |
||||
#include "RilSapSocket.h" |
||||
#include "pb_decode.h" |
||||
#include "pb_encode.h" |
||||
#define LOG_TAG "RIL_UIM_SOCKET" |
||||
#include <utils/Log.h> |
||||
#include <arpa/inet.h> |
||||
|
||||
RilSapSocket::RilSapSocketList *head; |
||||
|
||||
void ril_sap_on_request_complete ( |
||||
RIL_Token t, RIL_Errno e, |
||||
void *response, size_t responselen |
||||
); |
||||
|
||||
void ril_sap_on_unsolicited_response ( |
||||
int unsolResponse, const void *data, |
||||
size_t datalen |
||||
); |
||||
extern "C" void |
||||
RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, |
||||
const struct timeval *relativeTime); |
||||
|
||||
struct RIL_Env RilSapSocket::uimRilEnv = { |
||||
.OnRequestComplete = RilSapSocket::sOnRequestComplete, |
||||
.OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse, |
||||
.RequestTimedCallback = RIL_requestTimedCallback |
||||
}; |
||||
|
||||
void RilSapSocket::sOnRequestComplete (RIL_Token t, |
||||
RIL_Errno e, |
||||
void *response, |
||||
size_t responselen) { |
||||
RilSapSocket *sap_socket; |
||||
SapSocketRequest *request = (SapSocketRequest*) t; |
||||
|
||||
RLOGD("Socket id:%d", request->socketId); |
||||
|
||||
sap_socket = getSocketById(request->socketId); |
||||
|
||||
if (sap_socket) { |
||||
sap_socket->onRequestComplete(t,e,response,responselen); |
||||
} else { |
||||
RLOGE("Invalid socket id"); |
||||
free(request->curr); |
||||
free(request); |
||||
} |
||||
} |
||||
|
||||
#if defined(ANDROID_MULTI_SIM) |
||||
void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, |
||||
const void *data, |
||||
size_t datalen, |
||||
RIL_SOCKET_ID socketId) { |
||||
RilSapSocket *sap_socket = getSocketById(socketId); |
||||
if (sap_socket) { |
||||
sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); |
||||
} |
||||
} |
||||
#else |
||||
void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, |
||||
const void *data, |
||||
size_t datalen) { |
||||
RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1); |
||||
sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); |
||||
} |
||||
#endif |
||||
|
||||
void RilSapSocket::printList() { |
||||
RilSapSocketList *current = head; |
||||
RLOGD("Printing socket list"); |
||||
while(NULL != current) { |
||||
RLOGD("SocketName:%s",current->socket->name); |
||||
RLOGD("Socket id:%d",current->socket->id); |
||||
current = current->next; |
||||
} |
||||
} |
||||
|
||||
RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) { |
||||
RilSapSocket *sap_socket; |
||||
RilSapSocketList *current = head; |
||||
|
||||
RLOGD("Entered getSocketById"); |
||||
printList(); |
||||
|
||||
while(NULL != current) { |
||||
if(socketId == current->socket->id) { |
||||
sap_socket = current->socket; |
||||
return sap_socket; |
||||
} |
||||
current = current->next; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
void RilSapSocket::initSapSocket(const char *socketName, |
||||
RIL_RadioFunctions *uimFuncs) { |
||||
|
||||
if (strcmp(socketName, "sap_uim_socket1") == 0) { |
||||
if(!SocketExists(socketName)) { |
||||
addSocketToList(socketName, RIL_SOCKET_1, uimFuncs); |
||||
} |
||||
} |
||||
|
||||
#if (SIM_COUNT >= 2) |
||||
if (strcmp(socketName, "sap_uim_socket2") == 0) { |
||||
if(!SocketExists(socketName)) { |
||||
addSocketToList(socketName, RIL_SOCKET_2, uimFuncs); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
#if (SIM_COUNT >= 3) |
||||
if (strcmp(socketName, "sap_uim_socket3") == 0) { |
||||
if(!SocketExists(socketName)) { |
||||
addSocketToList(socketName, RIL_SOCKET_3, uimFuncs); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
#if (SIM_COUNT >= 4) |
||||
if (strcmp(socketName, "sap_uim_socket4") == 0) { |
||||
if(!SocketExists(socketName)) { |
||||
addSocketToList(socketName, RIL_SOCKET_4, uimFuncs); |
||||
} |
||||
} |
||||
#endif |
||||
} |
||||
|
||||
void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid, |
||||
RIL_RadioFunctions *uimFuncs) { |
||||
RilSapSocket* socket = NULL; |
||||
RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList)); |
||||
RilSapSocketList *current; |
||||
|
||||
if(!SocketExists(socketName)) { |
||||
socket = new RilSapSocket(socketName, socketid, uimFuncs); |
||||
listItem->socket = socket; |
||||
listItem->next = NULL; |
||||
|
||||
RLOGD("Adding socket with id: %d", socket->id); |
||||
|
||||
if(NULL == head) { |
||||
head = listItem; |
||||
head->next = NULL; |
||||
} |
||||
else { |
||||
current = head; |
||||
while(NULL != current->next) { |
||||
current = current->next; |
||||
} |
||||
current->next = listItem; |
||||
} |
||||
socket->socketInit(); |
||||
} |
||||
} |
||||
|
||||
bool RilSapSocket::SocketExists(const char *socketName) { |
||||
RilSapSocketList* current = head; |
||||
|
||||
while(NULL != current) { |
||||
if(strcmp(current->socket->name, socketName) == 0) { |
||||
return true; |
||||
} |
||||
current = current->next; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void* RilSapSocket::processRequestsLoop(void) { |
||||
SapSocketRequest *req = (SapSocketRequest*)malloc(sizeof(SapSocketRequest)); |
||||
RLOGI("UIM_SOCKET:Request loop started"); |
||||
|
||||
while(true) { |
||||
req = dispatchQueue.dequeue(); |
||||
|
||||
RLOGI("New request from the dispatch Queue"); |
||||
|
||||
if (req != NULL) { |
||||
processRequest(req->curr); |
||||
free(req); |
||||
} else { |
||||
RLOGE("Fetched null buffer from queue!"); |
||||
} |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
RilSapSocket::RilSapSocket(const char *socketName, |
||||
RIL_SOCKET_ID socketId, |
||||
RIL_RadioFunctions *inputUimFuncs): |
||||
RilSocket(socketName, socketId) { |
||||
if (inputUimFuncs) { |
||||
uimFuncs = inputUimFuncs; |
||||
} |
||||
} |
||||
|
||||
int RilSapSocket::processRequest(MsgHeader *request) { |
||||
dispatchRequest(request); |
||||
return 0; |
||||
} |
||||
|
||||
#define BYTES_PER_LINE 16 |
||||
|
||||
#define NIBBLE_TO_HEX(n) ({ \ |
||||
uint8_t __n = (uint8_t) n & 0x0f; \
|
||||
__nibble >= 10 ? 'A' + __n - 10: '0' + __n; \
|
||||
}) |
||||
|
||||
#define HEX_HIGH(b) ({ \ |
||||
uint8_t __b = (uint8_t) b; \
|
||||
uint8_t __nibble = (__b >> 4) & 0x0f; \
|
||||
NIBBLE_TO_HEX(__nibble); \
|
||||
}) |
||||
|
||||
#define HEX_LOW(b) ({ \ |
||||
uint8_t __b = (uint8_t) b; \
|
||||
uint8_t __nibble = __b & 0x0f; \
|
||||
NIBBLE_TO_HEX(__nibble); \
|
||||
}) |
||||
|
||||
void log_hex(const char *who, const uint8_t *buffer, int length) { |
||||
char out[80]; |
||||
int source = 0; |
||||
int dest = 0; |
||||
int dest_len = sizeof(out); |
||||
int per_line = 0; |
||||
|
||||
do { |
||||
dest += sprintf(out, "%8.8s [%8.8x] ", who, source); |
||||
for(; source < length && dest_len - dest > 3 && per_line < BYTES_PER_LINE; source++, |
||||
per_line ++) { |
||||
out[dest++] = HEX_HIGH(buffer[source]); |
||||
out[dest++] = HEX_LOW(buffer[source]); |
||||
out[dest++] = ' '; |
||||
} |
||||
if (dest < dest_len && (per_line == BYTES_PER_LINE || source >= length)) { |
||||
out[dest++] = 0; |
||||
per_line = 0; |
||||
dest = 0; |
||||
RLOGD("%s\n", out); |
||||
} |
||||
} while(source < length && dest < dest_len); |
||||
} |
||||
|
||||
void RilSapSocket::dispatchRequest(MsgHeader *req) { |
||||
SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); |
||||
currRequest->token = req->token; |
||||
currRequest->curr = req; |
||||
currRequest->p_next = NULL; |
||||
currRequest->socketId = id; |
||||
|
||||
pendingResponseQueue.enqueue(currRequest); |
||||
|
||||
if (uimFuncs) { |
||||
RLOGI("[%d] > SAP REQUEST type: %d. id: %d. error: %d", |
||||
req->token, |
||||
req->type, |
||||
req->id, |
||||
req->error ); |
||||
|
||||
#if defined(ANDROID_MULTI_SIM) |
||||
uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); |
||||
#else |
||||
uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response, |
||||
size_t response_len) { |
||||
SapSocketRequest* request= (SapSocketRequest*)t; |
||||
MsgHeader *hdr = request->curr; |
||||
pb_bytes_array_t *payload = (pb_bytes_array_t *) |
||||
calloc(1,sizeof(pb_bytes_array_t) + response_len); |
||||
|
||||
if (hdr && payload) { |
||||
memcpy(payload->bytes, response, response_len); |
||||
payload->size = response_len; |
||||
hdr->payload = payload; |
||||
hdr->type = MsgType_RESPONSE; |
||||
hdr->error = (Error) e; |
||||
|
||||
RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id); |
||||
|
||||
if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) { |
||||
RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id); |
||||
RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id"); |
||||
return; |
||||
} |
||||
|
||||
sendResponse(hdr); |
||||
free(hdr); |
||||
} |
||||
} |
||||
|
||||
void RilSapSocket::sendResponse(MsgHeader* hdr) { |
||||
size_t encoded_size = 0; |
||||
uint32_t written_size; |
||||
size_t buffer_size = 0; |
||||
pb_ostream_t ostream; |
||||
bool success = false; |
||||
|
||||
pthread_mutex_lock(&write_lock); |
||||
|
||||
if ((success = pb_get_encoded_size(&encoded_size, MsgHeader_fields, |
||||
hdr)) && encoded_size <= INT32_MAX && commandFd != -1) { |
||||
buffer_size = encoded_size + sizeof(uint32_t); |
||||
uint8_t buffer[buffer_size]; |
||||
written_size = htonl((uint32_t) encoded_size); |
||||
ostream = pb_ostream_from_buffer(buffer, buffer_size); |
||||
pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size)); |
||||
success = pb_encode(&ostream, MsgHeader_fields, hdr); |
||||
|
||||
if (success) { |
||||
RLOGD("Size: %d (0x%x) Size as written: 0x%x", encoded_size, encoded_size, |
||||
written_size); |
||||
log_hex("onRequestComplete", &buffer[sizeof(written_size)], encoded_size); |
||||
RLOGI("[%d] < SAP RESPONSE type: %d. id: %d. error: %d", |
||||
hdr->token, hdr->type, hdr->id,hdr->error ); |
||||
|
||||
if ( 0 != blockingWrite_helper(commandFd, buffer, buffer_size)) { |
||||
RLOGE("Error %d while writing to fd", errno); |
||||
} else { |
||||
RLOGD("Write successful"); |
||||
} |
||||
} else { |
||||
RLOGE("Error while encoding response of type %d id %d buffer_size: %d: %s.", |
||||
hdr->type, hdr->id, buffer_size, PB_GET_ERROR(&ostream)); |
||||
} |
||||
} else { |
||||
RLOGE("Not sending response type %d: encoded_size: %u. commandFd: %d. encoded size result: %d", |
||||
hdr->type, encoded_size, commandFd, success); |
||||
} |
||||
|
||||
pthread_mutex_unlock(&write_lock); |
||||
} |
||||
|
||||
void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) { |
||||
MsgHeader *hdr = new MsgHeader; |
||||
pb_bytes_array_t *payload = (pb_bytes_array_t *) |
||||
calloc(1, sizeof(pb_bytes_array_t) + datalen); |
||||
if (hdr && payload) { |
||||
memcpy(payload->bytes, data, datalen); |
||||
payload->size = datalen; |
||||
hdr->payload = payload; |
||||
hdr->type = MsgType_UNSOL_RESPONSE; |
||||
hdr->id = (MsgId)unsolResponse; |
||||
hdr->error = Error_RIL_E_SUCCESS; |
||||
sendResponse(hdr); |
||||
delete hdr; |
||||
} |
||||
} |
||||
|
||||
void RilSapSocket::pushRecord(void *p_record, size_t recordlen) { |
||||
int ret; |
||||
SapSocketRequest *recv = (SapSocketRequest*)malloc(sizeof(SapSocketRequest)); |
||||
MsgHeader *reqHeader; |
||||
pb_istream_t stream; |
||||
|
||||
stream = pb_istream_from_buffer((uint8_t *)p_record, recordlen); |
||||
reqHeader = (MsgHeader *)malloc(sizeof (MsgHeader)); |
||||
memset(reqHeader, 0, sizeof(MsgHeader)); |
||||
|
||||
log_hex("BtSapTest-Payload", (const uint8_t*)p_record, recordlen); |
||||
|
||||
if (!pb_decode(&stream, MsgHeader_fields, reqHeader) ) { |
||||
RLOGE("Error decoding protobuf buffer : %s", PB_GET_ERROR(&stream)); |
||||
} else { |
||||
recv->token = reqHeader->token; |
||||
recv->curr = reqHeader; |
||||
recv->socketId = id; |
||||
|
||||
dispatchQueue.enqueue(recv); |
||||
} |
||||
} |
||||
|
||||
void RilSapSocket::sendDisconnect() { |
||||
MsgHeader *hdr = new MsgHeader; |
||||
pb_bytes_array_t *payload ; |
||||
size_t encoded_size = 0; |
||||
uint32_t written_size; |
||||
size_t buffer_size = 0; |
||||
pb_ostream_t ostream; |
||||
bool success = false; |
||||
ssize_t written_bytes; |
||||
|
||||
RIL_SIM_SAP_DISCONNECT_REQ disconnectReq; |
||||
|
||||
if ((success = pb_get_encoded_size(&encoded_size, RIL_SIM_SAP_DISCONNECT_REQ_fields, |
||||
&disconnectReq)) && encoded_size <= INT32_MAX) { |
||||
buffer_size = encoded_size + sizeof(uint32_t); |
||||
uint8_t buffer[buffer_size]; |
||||
written_size = htonl((uint32_t) encoded_size); |
||||
ostream = pb_ostream_from_buffer(buffer, buffer_size); |
||||
pb_write(&ostream, (uint8_t *)&written_size, sizeof(written_size)); |
||||
success = pb_encode(&ostream, RIL_SIM_SAP_DISCONNECT_REQ_fields, buffer); |
||||
|
||||
if(success) { |
||||
pb_bytes_array_t *payload = (pb_bytes_array_t *) |
||||
calloc(1,sizeof(pb_bytes_array_t) + written_size); |
||||
|
||||
memcpy(payload->bytes, buffer, written_size); |
||||
payload->size = written_size; |
||||
hdr->payload = payload; |
||||
hdr->type = MsgType_REQUEST; |
||||
hdr->id = MsgId_RIL_SIM_SAP_DISCONNECT; |
||||
hdr->error = Error_RIL_E_SUCCESS; |
||||
dispatchDisconnect(hdr); |
||||
} |
||||
else { |
||||
RLOGE("Encode failed in send disconnect!"); |
||||
delete hdr; |
||||
free(payload); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void RilSapSocket::dispatchDisconnect(MsgHeader *req) { |
||||
SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); |
||||
currRequest->token = -1; |
||||
currRequest->curr = req; |
||||
currRequest->p_next = NULL; |
||||
currRequest->socketId = (RIL_SOCKET_ID)99; |
||||
|
||||
RLOGD("Sending disconnect on command close!"); |
||||
|
||||
#if defined(ANDROID_MULTI_SIM) |
||||
uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); |
||||
#else |
||||
uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest); |
||||
#endif |
||||
} |
||||
|
||||
void RilSapSocket::onCommandsSocketClosed() { |
||||
sendDisconnect(); |
||||
RLOGE("Socket command closed"); |
||||
} |
@ -0,0 +1,262 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef RIL_UIM_SOCKET_H_INCLUDED |
||||
#define RIL_UIM_SOCKET_H_INCLUDED |
||||
#define RIL_SHLIB |
||||
#include "telephony/ril.h" |
||||
#include "RilSocket.h" |
||||
#include <hardware/ril/librilutils/proto/sap-api.pb.h> |
||||
|
||||
/**
|
||||
* RilSapSocket is a derived class, derived from the RilSocket abstract |
||||
* class, representing sockets for communication between bluetooth SAP module and |
||||
* the ril daemon. |
||||
* <p> |
||||
* This class performs the following functions : |
||||
* <ul> |
||||
* <li>Initialize the socket. |
||||
* <li>Process the requests coming on the socket. |
||||
* <li>Provide handlers for Unsolicited and request responses. |
||||
* <li>Request and pending response queue handling. |
||||
* </ul> |
||||
*/ |
||||
class RilSapSocket : public RilSocket { |
||||
/**
|
||||
* Function pointer to the ril initialization funtion. |
||||
* |
||||
* @param Ril environment variable with place request and |
||||
* response handlers and timeout handler. |
||||
* |
||||
* @param Number of arguements for the initialization function. |
||||
* |
||||
* @param Arguements to the initialization function used to |
||||
* generate instance id of the ril daemon. |
||||
* |
||||
* @return Radio functions with handlers for onRequest, onStateRequest, |
||||
* supports, onCancel and getVersion. |
||||
*/ |
||||
RIL_RadioFunctions *(*UimInit)(const struct RIL_Env *, int argc, char **argv); |
||||
|
||||
/**
|
||||
* Place holder for the radio functions returned by the initialization |
||||
* function. Currenty only onRequest handler is being used. |
||||
*/ |
||||
RIL_RadioFunctions* uimFuncs; |
||||
|
||||
/**
|
||||
* Wrapper struct for handling the requests in the queue. |
||||
*/ |
||||
typedef struct SapSocketRequest { |
||||
int token; |
||||
MsgHeader* curr; |
||||
struct SapSocketRequest* p_next; |
||||
RIL_SOCKET_ID socketId; |
||||
} SapSocketRequest; |
||||
|
||||
/**
|
||||
* Queue for requests that are pending dispatch. |
||||
*/ |
||||
Ril_queue<SapSocketRequest> dispatchQueue; |
||||
|
||||
/**
|
||||
* Queue for requests that are dispatched but are pending response |
||||
*/ |
||||
Ril_queue<SapSocketRequest> pendingResponseQueue; |
||||
|
||||
public: |
||||
/**
|
||||
* Initialize the socket and add the socket to the list. |
||||
* |
||||
* @param Name of the socket. |
||||
* @param Radio functions to be used by the socket. |
||||
*/ |
||||
static void initSapSocket(const char *socketName, |
||||
RIL_RadioFunctions *uimFuncs); |
||||
|
||||
/**
|
||||
* Process requests from the dispatch request queue. |
||||
* @param Request to be dispatched. |
||||
*/ |
||||
int processRequest(MsgHeader *request); |
||||
|
||||
/**
|
||||
* Ril envoronment variable that holds the request and |
||||
* unsol response handlers. |
||||
*/ |
||||
static struct RIL_Env uimRilEnv; |
||||
|
||||
/**
|
||||
* Function to print the socket list. |
||||
*/ |
||||
static void printList(); |
||||
|
||||
/**
|
||||
* Clean up method to be called on command close. |
||||
*/ |
||||
void onCommandsSocketClosed(void); |
||||
|
||||
/**
|
||||
* Datatype to handle the socket list. |
||||
*/ |
||||
typedef struct RilSapSocketList { |
||||
RilSapSocket* socket; |
||||
RilSapSocketList *next; |
||||
} RilSapSocketList; |
||||
|
||||
protected: |
||||
/**
|
||||
* Process each record read from the socket and |
||||
* push a new request created from that record to |
||||
* the dispatch request queue. |
||||
* |
||||
* @param The record data. |
||||
* @param The record length. |
||||
*/ |
||||
void pushRecord(void *record, size_t recordlen); |
||||
|
||||
/**
|
||||
* Socket handler to be called when a request has |
||||
* been completed. |
||||
* |
||||
* @param Token associated with the request. |
||||
* @param Error, if any, while processing the request. |
||||
* @param The response payload. |
||||
* @param Response payload length. |
||||
*/ |
||||
void onRequestComplete(RIL_Token t,RIL_Errno e, |
||||
void *response, size_t response_len); |
||||
|
||||
/**
|
||||
* Socket handler to be called when there is an |
||||
* unsolicited response. |
||||
* |
||||
* @param Message id. |
||||
* @param Response data. |
||||
* @param Response data length. |
||||
*/ |
||||
void onUnsolicitedResponse(int unsolResponse, |
||||
void *data, size_t datalen); |
||||
|
||||
/**
|
||||
* Class method to get the socket from the socket list. |
||||
* |
||||
* @param Socket id. |
||||
* @return the sap socket. |
||||
*/ |
||||
static RilSapSocket* getSocketById(RIL_SOCKET_ID socketId); |
||||
|
||||
/**
|
||||
* Method to send response to SAP. It does an atomic write operation on the |
||||
* socket. |
||||
* |
||||
* @param the response header with the payload. |
||||
*/ |
||||
void sendResponse(MsgHeader *hdr); |
||||
|
||||
/**
|
||||
* A loop for processing the requests in the request dispatch queue. |
||||
*/ |
||||
void *processRequestsLoop(void); |
||||
|
||||
/**
|
||||
* Class method to add the sap socket to the list of sockets. |
||||
* Does nothing if the socket is already present in the list. |
||||
* Otherwise, calls the constructor of the parent class(To startlistening) |
||||
* and add socket to the socket list. |
||||
*/ |
||||
static void addSocketToList(const char *socketName, RIL_SOCKET_ID socketid, |
||||
RIL_RadioFunctions *uimFuncs); |
||||
|
||||
/**
|
||||
* Check if a socket of the given name exists in the socket list. |
||||
* |
||||
* @param Socket name. |
||||
* @return true if exists, false otherwise. |
||||
*/ |
||||
static bool SocketExists(const char *socketName); |
||||
|
||||
/**
|
||||
* Send a clean up SAP DISCONNECT if the socket disconnects before doing a SAP |
||||
* disconnect. |
||||
*/ |
||||
void sendDisconnect(void); |
||||
|
||||
/**
|
||||
* Dispatch the clean up disconnect request. |
||||
*/ |
||||
void dispatchDisconnect(MsgHeader *req); |
||||
|
||||
|
||||
private: |
||||
/**
|
||||
* Constructor. |
||||
* |
||||
* @param Socket name. |
||||
* @param Socket id. |
||||
* @param Radio functions. |
||||
*/ |
||||
RilSapSocket(const char *socketName, |
||||
RIL_SOCKET_ID socketId, |
||||
RIL_RadioFunctions *inputUimFuncs); |
||||
|
||||
/**
|
||||
* Called by the processRequest method to dispatch the request to |
||||
* the lower layers. It calls the on request function. |
||||
* |
||||
* @param The request message. |
||||
*/ |
||||
void dispatchRequest(MsgHeader *request); |
||||
|
||||
/**
|
||||
* Class method that selects the socket on which the onRequestComplete |
||||
* is called. |
||||
* |
||||
* @param Token associated with the request. |
||||
* @param Error, if any, while processing the request. |
||||
* @param The response payload. |
||||
* @param Response payload length. |
||||
*/ |
||||
static void sOnRequestComplete(RIL_Token t, |
||||
RIL_Errno e, void *response, size_t responselen); |
||||
|
||||
#if defined(ANDROID_MULTI_SIM) |
||||
/**
|
||||
* Class method that selects the socket on which the onUnsolicitedResponse |
||||
* is called. |
||||
* |
||||
* @param Message id. |
||||
* @param Response data. |
||||
* @param Response data length. |
||||
* @param Socket id. |
||||
*/ |
||||
static void sOnUnsolicitedResponse(int unsolResponse, const void *data, |
||||
size_t datalen, RIL_SOCKET_ID socket_id); |
||||
#else |
||||
/**
|
||||
* Class method that selects the socket on which the onUnsolicitedResponse |
||||
* is called. |
||||
* |
||||
* @param Message id. |
||||
* @param Response data. |
||||
* @param Response data length. |
||||
*/ |
||||
static void sOnUnsolicitedResponse(int unsolResponse, const void *data, |
||||
size_t datalen); |
||||
#endif |
||||
}; |
||||
|
||||
#endif /*RIL_UIM_SOCKET_H_INCLUDED*/ |
@ -0,0 +1,177 @@ |
||||
/*
|
||||
* 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; |
||||
} |
||||
|
||||
extern "C" |
||||
void *ril_socket_process_requests_loop(void *arg) { |
||||
RilSocket *socket = (RilSocket *)arg; |
||||
socket->processRequestsLoop(); |
||||
return NULL; |
||||
} |
@ -0,0 +1,270 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef RIL_SOCKET_H_INCLUDED |
||||
#define RIL_SOCKET_H_INCLUDED |
||||
#include "ril_ex.h" |
||||
#include "rilSocketQueue.h" |
||||
#include <ril_event.h> |
||||
|
||||
using namespace std; |
||||
|
||||
/**
|
||||
* Abstract socket class representing sockets in rild. |
||||
* <p> |
||||
* This class performs the following functions : |
||||
* <ul> |
||||
* <li> Start socket listen. |
||||
* <li> Handle socket listen and command callbacks. |
||||
* </ul> |
||||
*/ |
||||
class RilSocket { |
||||
protected: |
||||
|
||||
/**
|
||||
* Socket name. |
||||
*/ |
||||
const char* name; |
||||
|
||||
/**
|
||||
* Socket id. |
||||
*/ |
||||
RIL_SOCKET_ID id; |
||||
|
||||
/**
|
||||
* Listen socket file descriptor. |
||||
*/ |
||||
int listenFd = -1; |
||||
|
||||
/**
|
||||
* Commands socket file descriptor. |
||||
*/ |
||||
int commandFd = -1; |
||||
|
||||
/**
|
||||
* Socket request loop thread id. |
||||
*/ |
||||
pthread_t socketThreadId; |
||||
|
||||
/**
|
||||
* Listen event callack. Callback called when the other ends does accept. |
||||
*/ |
||||
ril_event_cb listenCb; |
||||
|
||||
/**
|
||||
* Commands event callack.Callback called when there are requests from the other side. |
||||
*/ |
||||
ril_event_cb commandCb; |
||||
|
||||
/**
|
||||
* Listen event to be added to eventloop after socket listen. |
||||
*/ |
||||
struct ril_event listenEvent; |
||||
|
||||
/**
|
||||
* Commands event to be added to eventloop after accept. |
||||
*/ |
||||
struct ril_event callbackEvent; |
||||
|
||||
/**
|
||||
* Static socket listen handler. Chooses the socket to call the listen callback |
||||
* from ril.cpp. |
||||
* |
||||
* @param Listen fd. |
||||
* @param flags. |
||||
* @param Parameter for the listen handler. |
||||
*/ |
||||
static void sSocketListener(int fd, short flags, void *param); |
||||
|
||||
/**
|
||||
* Static socket request handler. Chooses the socket to call the request handler on. |
||||
* |
||||
* @param Commands fd. |
||||
* @param flags. |
||||
* @param Parameter for the request handler. |
||||
*/ |
||||
static void sSocketRequestsHandler(int fd, short flags, void *param); |
||||
|
||||
/**
|
||||
* Process record from the record stream and push the requests onto the queue. |
||||
* |
||||
* @param record data. |
||||
* @param record length. |
||||
*/ |
||||
virtual void pushRecord(void *record, size_t recordlen) = 0; |
||||
|
||||
/**
|
||||
* Socket lock for writing data on the socket. |
||||
*/ |
||||
pthread_mutex_t write_lock = PTHREAD_MUTEX_INITIALIZER; |
||||
|
||||
/**
|
||||
* The loop to process the incoming requests. |
||||
*/ |
||||
virtual void *processRequestsLoop(void) = 0; |
||||
|
||||
private: |
||||
friend void *::ril_socket_process_requests_loop(void *arg); |
||||
|
||||
public: |
||||
|
||||
/**
|
||||
* Constructor. |
||||
* |
||||
* @param Socket name. |
||||
* @param Socket id. |
||||
*/ |
||||
RilSocket(const char* socketName, RIL_SOCKET_ID socketId) { |
||||
name = socketName; |
||||
id = socketId; |
||||
} |
||||
|
||||
/**
|
||||
* Clean up function on commands socket close. |
||||
*/ |
||||
virtual void onCommandsSocketClosed(void) = 0; |
||||
|
||||
/**
|
||||
* Function called on new commands socket connect. Request loop thread is started here. |
||||
*/ |
||||
void onNewCommandConnect(void); |
||||
|
||||
/**
|
||||
* Set listen socket fd. |
||||
* |
||||
* @param Input fd. |
||||
*/ |
||||
void setListenFd(int listenFd); |
||||
|
||||
/**
|
||||
* Set commands socket fd. |
||||
* |
||||
* @param Input fd. |
||||
*/ |
||||
void setCommandFd(int commandFd); |
||||
|
||||
/**
|
||||
* Get listen socket fd. |
||||
* |
||||
* @return Listen fd. |
||||
*/ |
||||
int getListenFd(void); |
||||
|
||||
/**
|
||||
* Get commands socket fd. |
||||
* |
||||
* @return Commands fd. |
||||
*/ |
||||
int getCommandFd(void); |
||||
|
||||
/**
|
||||
* Set listen event callback. |
||||
* |
||||
* @param Input event callback. |
||||
*/ |
||||
void setListenCb(ril_event_cb listenCb); |
||||
|
||||
/**
|
||||
* Set command event callback. |
||||
* |
||||
* @param Input event callback. |
||||
*/ |
||||
void setCommandCb(ril_event_cb commandCb); |
||||
|
||||
/**
|
||||
* Get listen event callback. |
||||
* |
||||
* @return Listen event callback. |
||||
*/ |
||||
ril_event_cb getListenCb(void); |
||||
|
||||
/**
|
||||
* Gey command event callback. |
||||
* |
||||
* @return Command event callback. |
||||
*/ |
||||
ril_event_cb getCommandCb(void); |
||||
|
||||
/**
|
||||
* Set listen event. |
||||
* |
||||
* @param Input event. |
||||
*/ |
||||
void setListenEvent(ril_event listenEvent); |
||||
|
||||
/**
|
||||
* Set command callback event. |
||||
* |
||||
* @param Input event. |
||||
*/ |
||||
void setCallbackEvent(ril_event commandEvent); |
||||
|
||||
/**
|
||||
* Get listen event. |
||||
* |
||||
* @return Listen event. |
||||
*/ |
||||
ril_event* getListenEvent(void); |
||||
|
||||
/**
|
||||
* Get commands callback event. |
||||
* |
||||
* @return Commands callback event. |
||||
*/ |
||||
ril_event* getCallbackEvent(void); |
||||
|
||||
virtual ~RilSocket(){} |
||||
|
||||
protected: |
||||
|
||||
/**
|
||||
* Start listening on the socket and add the socket listen callback event. |
||||
* |
||||
* @return Result of the socket listen. |
||||
*/ |
||||
int socketInit(void); |
||||
|
||||
/**
|
||||
* Socket request handler |
||||
* |
||||
* @param Commands fd. |
||||
* @param flags. |
||||
* @param Record stream. |
||||
*/ |
||||
void socketRequestsHandler(int fd, short flags, RecordStream *rs); |
||||
}; |
||||
|
||||
class socketClient { |
||||
public: |
||||
RilSocket *socketPtr; |
||||
RecordStream *rs; |
||||
|
||||
socketClient(RilSocket *socketPtr, RecordStream *rs) { |
||||
this->socketPtr = socketPtr; |
||||
this->rs = rs; |
||||
} |
||||
}; |
||||
|
||||
typedef struct MySocketListenParam { |
||||
SocketListenParam sListenParam; |
||||
RilSocket *socket; |
||||
} MySocketListenParam; |
||||
|
||||
typedef void* (RilSocket::*RilSocketFuncPtr)(void); |
||||
typedef void (RilSocket::*RilSocketEventPtr)(int fd,short flags, void *param); |
||||
typedef void* (*PthreadPtr)(void*); |
||||
|
||||
#endif |
@ -0,0 +1,167 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#include "pb_decode.h" |
||||
#include <pthread.h> |
||||
#include <hardware/ril/librilutils/proto/sap-api.pb.h> |
||||
#include <utils/Log.h> |
||||
|
||||
using namespace std; |
||||
|
||||
/**
|
||||
* Template queue class to handling requests for a rild socket. |
||||
* <p> |
||||
* This class performs the following functions : |
||||
* <ul> |
||||
* <li>Enqueue. |
||||
* <li>Dequeue. |
||||
* <li>Check and dequeue. |
||||
* </ul> |
||||
*/ |
||||
|
||||
template <typename T> |
||||
class Ril_queue { |
||||
|
||||
/**
|
||||
* Mutex attribute used in queue mutex initialization. |
||||
*/ |
||||
pthread_mutexattr_t attr; |
||||
|
||||
/**
|
||||
* Queue mutex variable for synchronized queue access. |
||||
*/ |
||||
pthread_mutex_t mutex_instance; |
||||
|
||||
/**
|
||||
* Condition to be waited on for dequeuing. |
||||
*/ |
||||
pthread_cond_t cond; |
||||
|
||||
/**
|
||||
* Front of the queue. |
||||
*/ |
||||
T *front; |
||||
|
||||
public: |
||||
|
||||
/**
|
||||
* Remove the first element of the queue. |
||||
* |
||||
* @return first element of the queue. |
||||
*/ |
||||
T* dequeue(void); |
||||
|
||||
/**
|
||||
* Add a request to the front of the queue. |
||||
* |
||||
* @param Request to be added. |
||||
*/ |
||||
void enqueue(T* request); |
||||
|
||||
/**
|
||||
* Check if the queue is empty. |
||||
*/ |
||||
int empty(void); |
||||
|
||||
/**
|
||||
* Check and remove an element with a particular message id and token. |
||||
* |
||||
* @param Request message id. |
||||
* @param Request token. |
||||
*/ |
||||
int checkAndDequeue( MsgId id, int token); |
||||
|
||||
/**
|
||||
* Queue constructor. |
||||
*/ |
||||
Ril_queue(void); |
||||
}; |
||||
|
||||
template <typename T> |
||||
Ril_queue<T>::Ril_queue(void) { |
||||
pthread_mutexattr_init(&attr); |
||||
pthread_mutex_init(&mutex_instance, &attr); |
||||
cond = PTHREAD_COND_INITIALIZER; |
||||
front = NULL; |
||||
} |
||||
|
||||
template <typename T> |
||||
T* Ril_queue<T>::dequeue(void) { |
||||
T* temp = NULL; |
||||
|
||||
pthread_mutex_lock(&mutex_instance); |
||||
while(empty()) { |
||||
pthread_cond_wait(&cond, &mutex_instance); |
||||
} |
||||
temp = this->front; |
||||
if(NULL != this->front->p_next) { |
||||
this->front = this->front->p_next; |
||||
} else { |
||||
this->front = NULL; |
||||
} |
||||
pthread_mutex_unlock(&mutex_instance); |
||||
|
||||
return temp; |
||||
} |
||||
|
||||
template <typename T> |
||||
void Ril_queue<T>::enqueue(T* request) { |
||||
|
||||
pthread_mutex_lock(&mutex_instance); |
||||
|
||||
if(NULL == this->front) { |
||||
this->front = request; |
||||
request->p_next = NULL; |
||||
} else { |
||||
request->p_next = this->front; |
||||
this->front = request; |
||||
} |
||||
pthread_cond_broadcast(&cond); |
||||
pthread_mutex_unlock(&mutex_instance); |
||||
} |
||||
|
||||
template <typename T> |
||||
int Ril_queue<T>::checkAndDequeue(MsgId id, int token) { |
||||
int ret = 0; |
||||
T* temp; |
||||
|
||||
pthread_mutex_lock(&mutex_instance); |
||||
|
||||
for(T **ppCur = &(this->front); *ppCur != NULL; ppCur = &((*ppCur)->p_next)) { |
||||
if (token == (*ppCur)->token && id == (*ppCur)->curr->id) { |
||||
ret = 1; |
||||
temp = *ppCur; |
||||
*ppCur = (*ppCur)->p_next; |
||||
free(temp); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
pthread_mutex_unlock(&mutex_instance); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
|
||||
template <typename T> |
||||
int Ril_queue<T>::empty(void) { |
||||
|
||||
if(this->front == NULL) { |
||||
return 1; |
||||
} else { |
||||
return 0; |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
/*
|
||||
* 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. |
||||
*/ |
||||
|
||||
#ifndef RIL_EX_H_INCLUDED |
||||
#define RIL_EX_H_INCLUDED |
||||
|
||||
#include <telephony/ril.h> |
||||
#include <telephony/record_stream.h> |
||||
|
||||
#define NUM_ELEMS_SOCKET(a) (sizeof (a) / sizeof (a)[0]) |
||||
|
||||
void rilEventAddWakeup_helper(struct ril_event *ev); |
||||
void listenCallback_helper(int fd, short flags, void *param); |
||||
int blockingWrite_helper(int fd, void* data, size_t len); |
||||
|
||||
enum SocketWakeType {DONT_WAKE, WAKE_PARTIAL}; |
||||
|
||||
typedef enum { |
||||
RIL_TELEPHONY_SOCKET, |
||||
RIL_SAP_SOCKET |
||||
} RIL_SOCKET_TYPE; |
||||
|
||||
typedef struct SocketListenParam { |
||||
RIL_SOCKET_ID socket_id; |
||||
int fdListen; |
||||
int fdCommand; |
||||
char* processName; |
||||
struct ril_event* commands_event; |
||||
struct ril_event* listen_event; |
||||
void (*processCommandsCallback)(int fd, short flags, void *param); |
||||
RecordStream *p_rs; |
||||
RIL_SOCKET_TYPE type; |
||||
} SocketListenParam; |
||||
|
||||
#endif |
Loading…
Reference in new issue