在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
就可以了。
至此拨号上网功能已经调通,但是发现无法关闭拨号功能,在网上搜到这篇博文:
参考它的做法就可以实现关闭功能了。
 
                    
                     
                    
                 
                    
                 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号