android ril 代码逻辑分析

基于Android RIL层实现来电拦截的技术原理(一) 引入          目前市面上,Android上的防骚扰类应用非常多,比如腾讯手机管家、360手机卫士、金山手机卫士等。由于受Android OS设计框架,他们的来电拦截实现,都是通过接受com.android.phone进程所发送的广播而实现。具体的实现方案,网上有很多教程,在此不再叙述。      采用上述的方案实现来电拦截,存在一个先天性的技术缺陷——每当有来电时,都会跳 阅读详情
--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_event, s_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_reader, pthread_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);
}
RIL/QCRIL架构及基本流程 通过之前章节的讲述我们已经知道,libril属于Google原生的逻辑,MTK和高通公司都在使用这套原始逻辑,而libril的下层则是各个芯片厂商为了适配各自的芯片而自己开发的一套处理逻辑。QCRil则是高通公司为适配自己的modem芯片而开发的自己消息处理逻辑。里面主要是将请求消息、请求响应及主动上报消息封装成QMI消息进行传递。据高通的说法,使用qmi消息的机制可以传输效率更高,更稳定。 阅读详情

相关推荐

深入了解Android RIL层源码实现

在移动通信设备中,无线接口层(Radio Interface Layer,简称RIL)扮演着至关重要的角色。RIL是移动设备软件架构中的关键组件,它作为中介层,负责协调硬件(如基带处理器)与高级服务(如电话和数据通信服务)之间的通信。RIL的定义主要涉及到它的基本功能和它如何被设计来提供与无线硬件的交互。它抽象化了底层无线通信的复杂性,为上层应用提供了一组简洁明了的接口。因此,无论是操作系统还是应用程序,都可以通过RIL与手机的无线模块进行通信。

weixin_42571280的博客 1630

Telephony业务关键日志

Telephony业务关键日志

cornerOfHeart的博客 327

Quectel Android RIL 驱动开发详解与实战应用

Android RIL(Radio Interface Layer)是Android系统中负责通信控制的核心模块,承担着连接上层Telephony服务与底层Modem硬件之间的桥梁作用。其主要职责包括:接收来自Java层的通信请求(如拨号、短信、数据连接等),通过守护进程RILD(RIL Daemon)将请求转换为Modem可识别的AT指令或厂商私有协议,并将Modem的响应结果回传至上层。

weixin_31419153的博客 1387

RIL层源码分析(原)

写在前面     1、本文从宏观的角度去分析问题,因此忽略了一些非主线的函数。     2、同理,对于函数内部非主要的逻辑部分,也采取了省略。     3、受限于知识的积累和理解能力,文中描述如有分析不妥之处,希望能够得到大家更正。 从Main函数开始的故事     Android的智能机架构是应用处理器+基带芯片,也就是AP+Modem的模式,AP部分相当于CPU,Modem相当于网卡

阿杜的专栏 1万+

深入理解Google Android reference-ril源码

RIL(Radio Interface Layer)即无线接口层,在Android系统中扮演着至关重要的角色。它作为硬件(如手机射频模块)与软件(如Android框架层)之间的桥梁,负责管理所有的无线通信功能,包括但不限于语音通话、短信、移动数据服务等。RIL层是Android通信子系统的核心部分,确保了上层应用可以与底层硬件通信。模块之间的通信依赖于定义良好的接口。RIL库中的接口定义了模块之间传递消息的方式、消息的格式以及期望的行为。

weixin_42451850的博客 599

PaddleOCR 3.x 最新版使用教程(2025)——从安装到实战身份证识别,一步到位!

本文针对PaddleOCR 3.x大版本更新带来的参数变化和兼容性问题,提供从环境配置到实际应用的全流程解决方案。

qq_58607032的博客 9787

java的RIL框架处理modem网络状态改变事件的流程

############################################################################################### PhoneApp收到一个RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED网络状态变化事件。 发送message到注册的handler上。GsmServiceStateTra

好记性不如写博客! 2303

S型速度曲线C程序实现

S型速度曲线C语言程序实现 前言 S型曲线相较于梯形速度曲线具有运行更加平稳的特点,S型曲线共有八种运行情况,感兴趣可以查阅相关文献 代码段 #include <stdio.h> #include <math.h> #define FP64 double int main(void) { /**************************** 定义相关变量(需要映射到PLC寄存器才能进行监控) ***********************/ FP6

LSX312441548的博客 8392

android ril 模拟,Android RIL代码详细分析

RIL代码分析代码位于:android/hardware/ril1 rild.c中的main()函数提供了rild的入口首先,通过main函数的传参,cmdline,内核选项等方式获取rild.libpath和rild.libargs。我们这里主要是:/system/lib/libreference-ril.so。2 RIL_startEventLoop():建立消息队列的机制,开始事件的监听函数...

weixin_39702649的博客 674

Keil MDK编译错误#541解决方案与ARM_Compiler包解析

在嵌入式开发中,编译器工具链的依赖管理是确保项目顺利构建的关键环节。以Keil MDK为例,其软件包依赖机制通过组件化设计实现功能解耦,其中ARM_Compiler包专门处理系统IO重定向等编译器扩展功能。这种架构既提升了模块复用性,也带来了版本兼容性挑战。当出现'Error #541: component missing'报错时,通常是由于中间件组件(如文件系统)在新版本中显式依赖了ARM_Compiler包。开发者需要通过Pack Installer安装该包,并在Run-Time Environment

weixin_32129187的博客 366

Ubuntu安装有线网卡驱动

问题:插入网线后,无法识别有线连接。 原因:主板有线网卡的型号和系统中网卡的驱动不匹配 解决 前提条件: 需要连wifi通网,因为需要安装dkms,和下载驱动。 删除原驱动 1、查看网卡型号 lspci | grep net 我的网卡型号是8125 2、查看网卡驱动 lspci -k 网卡驱动是r8169 3、卸载网卡驱动 找出位置 modinfo r8169 | grep filename 然后删除 rm path/r8169.ko 卸载驱动 rmmod r8169 查看是否卸载成功 lsm

weixin_43932656的博客 1万+

Android RIL模块非启动界面联网实战(二)

原文地址::http://yangyangzhao.blog.163.com/blog/static/17581636620101163758306/   在Android RIL模块非启动界面联网实战(一)中,最后发现只需要调用radiooptions这个程序就可以达到联网的目的了,一切似乎都很简单。 事实上如何呢?在android的shell下调用radiooptions,得到它的usa

xqhrs232的专栏 2332

Halcon 3D点云匹配实战:从预处理到模板创建的完整流程(附代码)

本文详细介绍了Halcon在3D点云匹配中的实战应用,涵盖从预处理到模板创建的完整流程。通过代码示例和实用技巧,帮助开发者掌握点云采样、降噪、三角化等关键技术,并优化匹配参数以提高精度和效率。适用于工业检测、机器人引导等领域。

weixin_33670786的博客 433

android 7.1 RIL 获取SIM卡号

平台 RK3288 + Android 7.1 + EC20 流程 获取手机号代码: TelephonyManager telMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); if (telMgr != null) { String num = telMgr.getLine1Nu...

ansondroider的博客 2143

YoloV8改进策略:轻量级的CloFormer助力Yolov8在速度和精度上实现双双提升

CloFormer是清华大学在今年发表的轻量级主干网络,引入了AttnConv,一种attention风格的卷积算子。所提出的AttnConv使用共享权重来聚合局部信息,并配置精心设计的上下文感知权重来增强局部特征。AttnConv和普通attention的结合使用池化来减少CloFormer中的FLOPs,使模型能够感知高频和低频信息。这篇文章主要向大家讲解如何将CloFormer加入到YoloV8中。论文链接:https://arxiv.org/abs/2303.17803v5。

m0_47867638的博客 4311

无需Python环境!纯C#上位机+OpenCVSharp4+ONNX Runtime实现YOLOv8摄像头实时流检测,工业级稳定

摘要 工业自动化C#开发中,传统Python方案实现视觉检测功能存在环境依赖、内存泄漏和性能不稳定等问题。本文提出基于.NET 8+OpenCVSharp4+ONNX Runtime的纯C#方案,通过实际案例验证其优势: 零Python依赖,支持离线部署 内存稳定(380MB/72h),检测延迟<80ms 检测精度达漏检率<0.1%,误检率<0.5% 保留原有业务逻辑代码,3天完成适配 方案采用分层架构设计,支持多种硬件平台和操作系统,提供从模型导出到部署的全流程指导,为工业视觉检测提供高

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 196

Android RIL框架分析

1.RIL框架 RIL,Radio Interface Layer。本层为一个协议转换层,提供Android Telephony与无线通信设备之间的抽象层。 Android RIL位于Telephony Frameworks之下,Modem之上的,根据源码,RIL可以分为两个部分:Frameworks 框架层中的java程序,简称RILJ。HAL层中C/C++程序,简称RILC,RILC具体的又包括LibRIL、Rild和Reference-RIL这三个部分。 Andr...

专注无线 2524

Echarts - 去掉图表上的横线和竖线

效果图 默认效果: 变为如下图所示效果: 实现方法 官方配置文档:https://echarts.apache.org/zh/option.html#radar.splitLine 在 xAxis yAxis 配置中分别加入以下代码: splitLine: { show:false }

🏆 前端领域优质创作者 1万+

Android RIL学习

Android RIL学习tomorrow.cyz@gmail.com 1.Android RIL概念Android RIL是基于telephony 服务和raido 硬件层的抽象层。Android的rild库是介于HAL接口与baseband modem之间,它提供了语音、数据、短信、SIM卡管理以及STK应用的功能。它把标准的 GSM27.007中常用的如dial这些做主动请求

红心地瓜的专栏 8975

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Android RIL 流程

文章目录1. RIL 建立消息队列(基于 Android O 原生)1.1 主要流程1.2 需注意的细节2. RIL 建立数据连接2.1 主要流程2.2 需注意的点 1. RIL 建立消息队列(基于 Android O 原生) 1.1 主要流程 主要流程可以归纳为以下: 开机时 rild 启动,调用 main 函数 在 main 函数中使用 dlopen 打开 so库(vendor实现库) 调用...

谈谈1974 1763

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

android ril.java_Android RIL学习

1.Android RIL概念Android RIL是基于telephony服务和raido硬件层的抽象层。Android的rild库是介于HAL接口与baseband modem之间,它提供了语音、数据、短信、SIM卡管理以及STK应用的功能。它把标准的GSM27.007中常用的如dial这些做主动请求的操作称之为request,一共75个;另外一类GSM模块主动上报的例如信号强度、基站信息等,...

weixin_39987847的博客 390

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android中RIL层详细分析:深入理解无线接口层工作原理

Android中RIL层详细分析:深入理解无线接口层工作原理 【下载地址】Android中RIL层详细分析 这份文档深入剖析了Android系统中的RIL(无线接口层),为开发者提供了全面而详细的分析。从RIL的框架介绍到与WindowsMobile RIL的对比,再到移植和Java框架的解析,内容涵盖广泛且深入。无论是...

gitblog_06742的博客 783

Android RIL 调试问题分析 ——数据频繁断开

Android RIL 调试问题分析 ——数据频繁断开1. 问题描述2. 问题分析2.1 RIL初分析 1. 问题描述 在使用SDX55模组和对应支持NSA/SA网络的RIL时,出现数据业务频繁断开重连现象,用户体验较差。 2. 问题分析 2.1 RIL初分析 从ril log中初步分析,可以得到数据频繁断开原因均一致,原因见以下log段: ......

四儿家的小祖宗的博客 1221

RIL层源码分析

写在前面     1、本文从宏观的角度去分析问题,因此忽略了一些非主线的函数。     2、同理,对于函数内部非主要的逻辑部分,也采取了省略。     3、受限于知识的积累和理解能力,文中描述如有分析不妥之处,希望能够得到大家更正。 从Main函数开始的故事     Android的智能机架构是应用处理器+基带芯片,也就是AP+Modem的模式,AP部分相当于CPU,Modem相当于网卡

tronteng的专栏 1904

Android——RIL 机制源码分析

Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP。AP与BP之间有两种通信方式: 1.Solicited Response:Ap向Bp发送请求,Bp给Ap发送回复,该类型的AT指令及其回调函数以数组的形式存放在Ril_commands.h文件中:     {数组中的索引号,请

jscese 1万+
上一篇: read()函数1
下一篇: ITRON系统使用方法
ecjtuync
博客等级 码龄20年 157粉丝 164原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值