--Ril.h------------------------------------------------------------ typedef struct {
    int version;        /* set to RIL_VERSION */
    RIL_RequestFunc onRequest;
    RIL_RadioStateRequest onStateRequest;
    RIL_Supports supports;
    RIL_Cancel onCancel;
    RIL_GetVersion getVersion;
RIL_RadioFunctions;
struct  RIL_Env {
    void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,
                           void *response, size_t responselen);

    void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,
                                    size_t datalen);
    void* (*RequestTimedCallback) (RIL_TimedCallback callback,
                                   void *param, const struct timeval *relativeTime);
    void (*RemoveTimedCallback) (void *callbackInfo);
};

const RIL_RadioFunctions * RIL_Init(const struct RIL_Env *env, int argc, char **argv);

void  RIL_register (const RIL_RadioFunctions *callbacks);
void  RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
                           void *response, size_t responselen);
void  RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
                                size_t datalen);
void*  RIL_requestTimedCallback (RIL_TimedCallback callback,
                                void *param, const struct timeval *relativeTime);
void  RIL_removeTimedCallback(void *callbackInfo); --Rild--------------------------------------------------------------------- static struct RIL_Env  s_rilEnv = {
    RIL_onRequestComplete,
    RIL_onUnsolicitedResponse,
    RIL_requestTimedCallback,
    RIL_removeTimedCallback
};
int  main(int argc, char **argv)
{     const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
    const RIL_RadioFunctions *funcs;
    dlHandle =  dlopen(rilLibPath, RTLD_NOW);      RIL_startEventLoop();     rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, " RIL_Init");     funcs =  rilInit(& s_rilEnv, argc, rilArgv);

     RIL_register(funcs);     while(1) {
        // sleep(UINT32_MAX) seems to return immediately on bionic
        sleep(0x00ffffff);
    } } --libRil------------------------------------------------------------ RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
static int s_registerCalled = 0;

static pthread_t s_tid_dispatch;
static pthread_t s_tid_reader;
static int s_started = 0;

static int s_fdListen = -1;
static int s_fdCommand = -1;
static int s_fdDebug = -1;

static int s_fdWakeupRead;
static int s_fdWakeupWrite;

static struct ril_event s_commands_event;  // socket fd for writing to client
static struct ril_event s_wakeupfd_event;    // wakeup fd for reading
static struct ril_event s_listen_event;          // socket fd for linstening
static struct ril_event s_wake_timeout_event;
static struct ril_event s_debug_event;        // socket fd for debug linstening

extern "C" void RIL_register (const RIL_RadioFunctions *callbacks) {          RIL_startEventLoop();
     s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);     ret = listen(s_fdListen, 4);     /* note: non-persistent so we can accept only one connection at a time */
     ril_event_set (& s_listen_event, s_fdListen, false,
                 listenCallback, NULL);
     rilEventAddWakeup (&s_listen_event);
     s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG);     ret = listen(s_fdDebug, 4);
     ril_event_set (& s_debug_event, s_fdDebug, true,
                 debugCallback, NULL);

     rilEventAddWakeup (&s_debug_event); } extern "C" void RIL_startEventLoop(void) {
    int ret;
    pthread_attr_t attr;

    /* spin up eventLoop thread and wait for it to get started */
    s_started = 0;
    pthread_mutex_lock(&s_startupMutex);

    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);

    while (s_started == 0) {
        pthread_cond_wait(&s_startupCond, &s_startupMutex);
    }

    pthread_mutex_unlock(&s_startupMutex);
}
static void *eventLoop (void *param) { {      ril_event_init ();     pthread_mutex_lock(&s_startupMutex);

    s_started = 1;
    pthread_cond_broadcast(&s_startupCond);

    pthread_mutex_unlock(&s_startupMutex);

    ret = pipe(filedes);

    s_fdWakeupRead = filedes[0];
    s_fdWakeupWrite = filedes[1];

    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);

   
  ril_event_set  (& s_wakeupfd_event , s_fdWakeupRead, true,
               
  processWakeupCallback , NULL);

    
rilEventAddWakeup  (& s_wakeupfd_event );

    // Only returns on error
    
ril_event_loop ();
}
void  ril_event_loop()
{
    for (;;) {
        memcpy(&rfds, &readFds, sizeof(fd_set));            calcNextTimeout (&tv)         n =  select( nfds, & rfds, NULL, NULL,  ptv);
        // Check for timeouts
         processTimeouts();
        // Check for read-ready
         processReadReadies(&rfds, n);
        // Fire away
         firePending();
    }
}
static void  processTimeouts()
{
    MUTEX_ACQUIRE();
    while ((tev != & timer_list) && (timercmp(&now, &tev->timeout, >))) {
        next = tev->next;
         removeFromList(tev);
         addToList(tev, &pending_list);
        tev = next;
    }
    MUTEX_RELEASE();
}

static void  processReadReadies(fd_set * rfds, int n)
{
    MUTEX_ACQUIRE();
    for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
        struct ril_event * rev =  watch_table[i];
        if (rev != NULL &&  FD_ISSET(rev->fd, rfds)) {
             addToList(rev, &pending_list);
            if (rev->persist == false) {
                 removeWatch(rev, i);
            }
            n--;
        }
    }
    MUTEX_RELEASE();
}

static void  firePending()
{
    struct ril_event * ev =  pending_list.next;
    while (ev != &pending_list) {
        struct ril_event * next = ev->next;
         removeFromList(ev);
         ev->func(ev->fd, 0, ev->param);
        ev = next;
    }
} void  ril_event_init()
{
    MUTEX_INIT();
    FD_ZERO(& readFds);
    init_list(& timer_list);
    init_list(& pending_list);
    memset( watch_table, 0, sizeof(watch_table)); } // listener for s_fdListen static void  listenCallback (int fd, short flags, void *param) {      s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);     ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK);     p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES);

     ril_event_set (& s_commands_events_fdCommand, 1,
         processCommandsCallback, p_rs);

     rilEventAddWakeup (&s_commands_event);

    onNewCommandConnect(); } static void  rilEventAddWakeup(struct ril_event *ev) {
     ril_event_add(ev);   // Add event to watch list
     triggerEvLoop();     // trigger event loop to wakeup
} // Add event to watch list
void  ril_event_add(struct ril_event * ev)
{
    MUTEX_ACQUIRE();
    for (int i = 0; i < MAX_FD_EVENTS; i++) {
        if (watch_table[i] == NULL) {
             watch_table[i] = ev;
            ev->index = i;
             FD_SET( ev->fd, & readFds);
            if (ev->fd >= nfds) nfds = ev->fd+1;
            break;
        }
    }
    MUTEX_RELEASE();
} // listener for s_fdCommand static void  processCommandsCallback(int fd, short flags, void *param) {         ret = record_stream_get_next(p_rs, &p_record, &recordlen);              processCommandBuffer(p_record, recordlen);          close(s_fdCommand);
        s_fdCommand = -1;          ril_event_del(&s_commands_event);  // Remove event from watch or timer list

        record_stream_free(p_rs);

        /* start listening for new connections again */
         rilEventAddWakeup(&s_listen_event);

        onCommandsSocketClosed(); } static CommandInfo  s_commands[] = {
#include "ril_commands.h" // there are dispatch and reponse mapping here for Request from Client
}; static int  processCommandBuffer(void *buffer, size_t buflen) {  pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));     pRI->pCI = &( s_commands[request]);     pRI->pCI-> dispatchFunction(p, pRI); } // dispathc Dail to Reference-ril, it is synchronization operation static void  dispatchDial (Parcel &p, RequestInfo *pRI) {     s_callbacks. onRequest( pRI->pCI->requestNumber, &dial, sizeOfDial, pRI); } // called by Reference-ril for one Request, and reponse to Client(app) extern "C" void
RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {     pRI = (RequestInfo *)t;             ret =  pRI->pCI-> responseFunction(p, response, responselen);          sendResponse(p); } // // called by Reference-ril for one unsolicited response extern "C"
void  RIL_onUnsolicitedResponse(int unsolResponse, void *data,                                 size_t datalen) {     ret =  s_unsolResponses[ unsolResponseIndex]
                . responseFunction(p, data, datalen);     ret =  sendResponse(p); } extern "C" void *
RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
                                const struct timeval *relativeTime) {
   return internalRequestTimedCallback (callback, param, relativeTime);
}

extern "C" void
RIL_removeTimedCallback (void *callbackInfo) {
    internalRemoveTimedCallback(callbackInfo);
} --reference-ril------------------------------------------------------------ pthread_t  s_tid_mainloop; int  main (int argc, char **argv)
{
     RIL_register(&s_callbacks);

     mainLoop(NULL);

    return 0;
} const RIL_RadioFunctions * RIL_Init(const struct RIL_Env *env, int argc, char **argv)
{      s_rilenv = env;
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    ret = pthread_create(& s_tid_mainloop, &attr,  mainLoop, NULL);

    return & s_callbacks;
}
#else /* RIL_SHLIB */ static void * mainLoop(void *param) {   for (;;) {         ret =  at_open(fd, onUnsolicited);
         RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);

        // Give initializeCallback a chance to dispatched, since
        // we don't presently have a cancellation mechanism
         sleep(1);

         waitForClose();     } } static pthread_t  s_tid_reader;
static int s_fd = -1;    /* fd of the AT channel */
static ATUnsolHandler s_unsolHandler;

/* for input buffering */

static char s_ATBuffer[MAX_AT_RESPONSE+1];
static char *s_ATBufferCur = s_ATBuffer;

static int s_ackPowerIoctl; /* true if TTY has android byte-count
                                handshake for low power*/
static int s_readCount = 0; int  at_open(int fd, ATUnsolHandler h)
{
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    ret = pthread_create(& s_tid_reader, &attr,  readerLoop, &attr); } static void * readerLoop(void *arg) {     for (;;) { // Reads a line from the AT channel, returns NULL on timeout.
        line =  readline();

        if (line == NULL) {
            break;
        }
             processLine(line);
    }
    onReaderClosed();
} static void  processLine(const char *line) {     pthread_mutex_lock(& s_commandmutex);     if (sp_response == NULL) {
        /* no command pending */
         handleUnsolicited(line);
    } else if (isFinalResponseSuccess(line)) {
        sp_response->success = 1;
         handleFinalResponse(line);
    } else if (isFinalResponseError(line)) {
        sp_response->success = 0;
         handleFinalResponse(line);
    } else if (s_smsPDU != NULL && 0 == strcmp(line, "> ")) {
        writeCtrlZ(s_smsPDU);
        s_smsPDU = NULL;
    } else switch (s_type) {
        case NO_RESULT:
             handleUnsolicited(line);
            break;           case ....                break;         default: /* this should never be reached */
            LOGE("Unsupported AT command type %d\n", s_type);
             handleUnsolicited(line);
        break;     }     pthread_mutex_unlock(& s_commandmutex); } static void  handleUnsolicited(const char *line)
{
    if (s_unsolHandler != NULL) {
         s_unsolHandler(line, NULL);
    }
} /**
* Called by atchannel when an unsolicited line appears
* This is called on atchannel's reader thread. AT commands may
* not be issued here
*/
static void  onUnsolicited (const char *s, const char *sms_pdu)    } else  if ( strStartsWith(s,"+CRING:")
                || strStartsWith(s,"RING")
                || strStartsWith(s,"NO CARRIER")
                || strStartsWith(s,"+CCWA")
    ) {
         RIL_onUnsolicitedResponse (
             RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
            NULL, 0);
#ifdef WORKAROUND_FAKE_CGEV
        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
#endif /* WORKAROUND_FAKE_CGEV */
    } else  if ( strStartsWith(s,"+CREG:")
                || strStartsWith(s,"+CGREG:")
    ) {
         RIL_onUnsolicitedResponse (
             RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
            NULL, 0);
#ifdef WORKAROUND_FAKE_CGEV
        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
#endif /* WORKAROUND_FAKE_CGEV */
    } else  if ( strStartsWith(s, "+CMT:")) {
         RIL_onUnsolicitedResponse (
             RIL_UNSOL_RESPONSE_NEW_SMS,
            sms_pdu, strlen(sms_pdu));
    } else if ( strStartsWith(s, "+CDS:")) {
         RIL_onUnsolicitedResponse (
             RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
            sms_pdu, strlen(sms_pdu));
    }  } /** assumes s_commandmutex is held */
static void  handleFinalResponse(const char *line)
{
    sp_response->finalResponse = strdup(line);

     pthread_cond_signal(& s_commandcond);
}
/*** Callback methods from the RIL library to us ***/
* Call from RIL to us to make a RIL_REQUEST
*
* Must be completed with a call to RIL_onRequestComplete()
*
* RIL_onRequestComplete() may be called from any thread, before or after
* this function returns.
*
* Will always be called from the same thread, so returning here implies
* that the radio is ready to process another command (whether or not
* the previous command has completed).
*/ static void  onRequest (int request, void *data, size_t datalen, RIL_Token t) {     switch (request) {         case  RIL_REQUEST_SEND_SMS:
             requestSendSMS(data, datalen, t);
            break;
        case  RIL_REQUEST_CDMA_SEND_SMS:
             requestCdmaSendSMS(data, datalen, t);
            break;
        case  RIL_REQUEST_SETUP_DATA_CALL:
             requestSetupDataCall(data, datalen, t);
            break;
        case  RIL_REQUEST_GET_DATA_CALL_PROFILE:
             requestGetDataCallProfile(data, datalen, t);
            break;
        case  RIL_REQUEST_SMS_ACKNOWLEDGE:
             requestSMSAcknowledge(data, datalen, t);
            break;         case  RIL_REQUEST_GET_CURRENT_CALLS:
             requestGetCurrentCalls(data, datalen, t);
            break;
        case  RIL_REQUEST_DIAL:
             requestDial(data, datalen, t);
            break;
        case  RIL_REQUEST_HANGUP:
             requestHangup(data, datalen, t);
            break;         case  RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
            // 3GPP 22.030 6.5.5
            // "Releases all held calls or sets User Determined User Busy
            //  (UDUB) for a waiting call."
             at_send_command("AT+CHLD=0", NULL);

            /* success or failure is ignored by the upper layer here.
               it will call GET_CURRENT_CALLS and determine success that way */
             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
            break;
        case  RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
            // 3GPP 22.030 6.5.5
            // "Releases all active calls (if any exist) and accepts
            //  the other (held or waiting) call."
             at_send_command("AT+CHLD=1", NULL);

            /* success or failure is ignored by the upper layer here.
               it will call GET_CURRENT_CALLS and determine success that way */
             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
            break;
        case  RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
            // 3GPP 22.030 6.5.5
            // "Places all active calls (if any exist) on hold and accepts
            //  the other (held or waiting) call."
             at_send_command("AT+CHLD=2", NULL);           case ...                break;          default:
            LOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
             RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
            break;
    } } static void  requestDial(void *data, size_t datalen, RIL_Token t) {     ret =  at_send_command(cmd, NULL);     /* success or failure is ignored by the upper layer here.
       it will call GET_CURRENT_CALLS and determine success that way */      RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); } int at_send_command (const char *command, ATResponse **pp_outResponse)
{
    err =  at_send_command_full (command, NO_RESULT, NULL,
                                    NULL, 0, pp_outResponse);
} static int  at_send_command_full (const char *command, ATCommandType type,
                    const char *responsePrefix, const char *smspdu,
                    long long timeoutMsec, ATResponse **pp_outResponse)
{     if (0 !=  pthread_equal( s_tid_readerpthread_self())) {
        /* cannot be called from reader thread */
        return AT_ERROR_INVALID_THREAD;
    }     pthread_mutex_lock(& s_commandmutex);
    err =  at_send_command_full_nolock(command, type,
                    responsePrefix, smspdu,
                    timeoutMsec, pp_outResponse);

    pthread_mutex_unlock(& s_commandmutex); } static int  at_send_command_full_nolock (const char *command, ATCommandType type,
                    const char *responsePrefix, const char *smspdu,
                    long long timeoutMsec, ATResponse **pp_outResponse) {     err =  writeline ( command);
     while (sp_response->finalResponse == NULL && s_readerClosed == 0) {
        if (timeoutMsec != 0) {
#ifdef USE_NP
            err = pthread_cond_timeout_np(&s_commandcond, &s_commandmutex, timeoutMsec);
#else
            err = pthread_cond_timedwait(&s_commandcond, &s_commandmutex, &ts);
#endif /*USE_NP*/
        } else {    // this thread will be wake up by  handleFinalResponse()
            err =  pthread_cond_wait(& s_commandcond, & s_commandmutex);
        }
    }
        at_response_free(sp_response); }

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. Android中后台定时任务实现,即时数据同步
  2. macOS中配置Flutter开发环境(使用AndroidS
  3. Android(安卓)View体系(二)实现View滑动的
  4. Android将so库封装到jar包中并加载其中的
  5. Android(安卓)App Daemon
  6. Android的原理-不需要太多的剩余内存
  7. 【Android适配问题集锦-rom类】Android(
  8. [Android]如何做一个崩溃率少于千分之三
  9. android 问题分析解析,有你想要的吗
  10. Android手势源码浅析----手势识别