zoukankan      html  css  js  c++  java
  • Android 2.3 拨号上网调试记录--基于AM3715平台

    在AM3715上调试gprs模块时遇到了一些问题,在这里记录一下,以免日后忘记。

    下面按照遇到的问题先后来做记录:

    使用的是广和通的G510模块,使用的是他们提供的RIL和MUX驱动,根据他们的指导文档,很快就实现了电话、短信功能。

    手动调用pppd call ppp-dial 是可以拨号成功,ifconfig ppp0 可获取IP地址,但是通过勾选“设置”->“无线和网络”->“移动网络”->“已启用网络”

    并不能实现拨号。

    此时发现进入“接入点名称”并没看到任何APN显示出来,新建APN时MCC、MNC为空,将所有信息填完也无法保存,保存时ril log(logcat -b  radio)显示:

    "Failed setting numeric 'null' for the current operator."

    numeric是由MCC、MNC组成的,这个说明系统没有读到SIM卡的MCC和MNC,但是在ril log中可看到

    D/GSM ( 1103): IMSI: 460028xxxxxxx

    说明已经读到了MCC=460,MNC=02,查看/system/etc/apns-conf.xml,发现里面已经含了

    <apn carrier="China Mobile" mcc="460" mnc="02" apn="cmnet" type="default,supl" />

    但是这个APN为什么还是没有显示出来呢?这些情况说明MCC、MNC虽然得到了,但是却没有成功上报给上一层,所以numeric是null。

    还是要从源代码入手:

    D/GSM ( 1103): IMSI: 460028xxxxxxx

    这句来自于frameworks/base/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java, 位于其中的

    public void handleMessage(Message msg)->case EVENT_GET_IMSI_DONE 分句,获取IMSI后,应该就会去更新mncLength,

    if (mncLength == UNKNOWN) {
      // the SIM has told us all it knows, but it didn't know the mnc length.
      // guess using the mcc
      try {
        int mcc = Integer.parseInt(imsi.substring(0,3));
        mncLength = MccTable.smallestDigitsMccForMnc(mcc);
      } catch (NumberFormatException e) {
        mncLength = UNKNOWN;
        Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
      }
    }

    通过添加log语句,可知mncLength在这个if之前是mncLength=UNINITIALIZED (-1), 所以就跳过了这个if里的语句,没有更新

    mncLength,故将条件判断改为

      if ((mncLength == UNKNOWN || mncLength == UNINITIALIZED) && (imsi != null)) 

    这样就能正确更新mncLength为2。

    从case EVENT_GET_IMSI_DONE break出来后,就会调用onRecordLoaded():

    protected void onRecordLoaded() {
      // One record loaded successfully or failed, In either case
      // we need to update the recordsToLoad count
      recordsToLoad -= 1;

       if (recordsToLoad == 0 && recordsRequested == true) {
        onAllRecordsLoaded();
      } else if (recordsToLoad < 0) {
        Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected");
        recordsToLoad = 0;
      }
    }

    其中的onAllRecordsLoaded()函数会调用getSIMOperatorNumeric()去获取numeric,然后设置PROPERTY_ICC_OPERATOR_NUMERIC,

    但是通过在getSIMOperatorNumeric里添加log语句,发现getSIMOperatorNumeric根本就没有被执行过,说明onAllRecordsLoaded也没有

    被执行过,估计是onRecordLoaded里的判断条件没有符合,所以将判断条件去掉,重新编译更新系统,果然能够正常显示已有的APN,新建APN

    也能保存了。

    此时再次勾选“已启用网络”,可见可以开始pppd拨号了,ifconfig ppp0 也返回了IP,但是android屏幕上端的标题仍然没有出现数据连接的图标,

    这个说明pppd拨号虽然通了,但是没有上报给android系统,android系统仍不知有这个连接存在,这是ril的工作,勾选“已启用网络”后,会调用

    hardware/ril/reference-ril/reference-ril.c 里的 requestSetupDataCall()来进行pppd拨号:

    static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
    {
      const char *apn;
      const char *user = NULL;
      const char *password = NULL;
      char *cmd;
      int err;
      int res;
      ATResponse *p_response = NULL;

      apn = ((const char **)data)[2];
      user = ((const char **)data)[3];
      password = ((const char **)data)[4];

      const char *pdp_type;

      /*set data call state in RIL process*/ //by trento
      LOGD("requesting data connection to APN '%s'", apn);

      if (datalen > 6 * sizeof(char *)) {
        pdp_type = ((const char **)data)[6];
      } else {
        pdp_type = "IP";
      }
      asprintf(&cmd, "AT+CGDCONT=1,"%s","%s"",pdp_type, apn);//,,0,0", pdp_type, apn);
      //FIXME check for error here
      err = at_send_command(cmd, NULL);
      free(cmd);

      err = dial_at_modem("ATD*99***1# ");
      if(err != 0)
      {
        LOGE("dial failed");
      }
      err=runPPPD(user, password);//system("pppd call ppp-dial &"); //mod by trento
      if(err !=0){
        goto error;
      }

      at_response_free(p_response);

      return;
    error:
      RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
      at_response_free(p_response);

    }

    发现这里面只进行了pppd拨号,并没有上报的动作,所以在函数里定义

    char *response[3] = { "1", PPP_TTY_PATH, "0.0.0.0"};

    并在runPPPD后添加:

    sleep(5); //wait for establish the connection
    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));

    这样就改动以后,建立连接后就可在android屏幕上看到建立连接的图标了,不过在浏览器里输入www.baidu.com还是打不开,

    后来发现ping IP是成功的,但是ping域名就不行,心想在浏览器里直接输入百度IP是不是可以呢,一试,果然可以!这样应该是

    dns设置的问题了,在网上搜到了解决办法:在init.rc中

    setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680

    下面加上:

    setprop net.dns1 202.96.128.166
    setprop net.dns2 202.96.134.133
    setprop net.dnschange 2

    就可以了。

    至此拨号上网功能已经调通,但是发现无法关闭拨号功能,在网上搜到这篇博文:

    android2.3 添加关闭数据开关功能

    参考它的做法就可以实现关闭功能了。

  • 相关阅读:
    Mac OS X各版本号的历史费用和升级关系
    Openlayers2中统计图的实现
    CentOS下Redisserver安装配置
    最小生成树算法
    机器学习---支持向量机(SVM)
    Android HttpURLConnection源代码分析
    Lighttpd1.4.20源代码分析 笔记 状态机之错误处理和连接关闭
    <html>
    【LeetCode-面试算法经典-Java实现】【059-Spiral Matrix II(螺旋矩阵II)】
    软件开发中的11个系统思维定律
  • 原文地址:https://www.cnblogs.com/Shangzhi/p/3335266.html
Copyright © 2011-2022 走看看