上·志

上下求索,志在千里。

导航

Android 2.3 拨号上网调试记录--基于AM3715平台

Posted on 2013-09-25 16:10  Shangzhi  阅读(866)  评论(0编辑  收藏  举报

在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#\r");
  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 添加关闭数据开关功能

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