Android 2.1下调试3G模块

曾几何时在Android2.1下调试3G模块,曾几何时模块厂商提供的库不能用,曾几何时只能用自己的库痛苦地调试...这一切的一切都已成往事,昔日的成功在毫无保留下成为浮云,该忘了忘记了,该记得也跟着忘记了。现如今再次调3G模块,却不知道以前如何调试,看来还是要记下来。
我采用的是华为EM770W模块,支持WCDMA网络,由于华为提供的库只支持Android2.2,所以用Android2.1就需要自己修改库源码。
 
 
1.修改linux内核
(1)make menuconfig:
Device Drivers  --->
    <*> OHCI HCD support 
    [*] Network device support  --->
         <*>   PPP (point-to-point protocol) support
         [*]     PPP multilink support (EXPERIMENTAL)
         [*]     PPP filtering
         <*>     PPP support for async serial ports
         <*>     PPP support for sync tty ports
         <*>     PPP Deflate compression
         <*>     PPP BSD-Compress compression
         <*>     PPP MPPE compression (encryption) (EXPERIMENTAL)
         <*>     PPP over Ethernet (EXPERIMENTAL)
         <*>     PPP over L2TP (EXPERIMENTAL)
    [*] USB support  --->
         <*>   USB Serial Converter support  --->
               <*>   USB driver for GSM and CDMA modems
(2)增加EM770W的VID和PID
修改驱动文件drivers/usb/serial/option.c,增加以下代码
#define EM770W_OPTION_VENDOR_ID 0x12d1
#define EM770W_OPTION_PRODUCT_COLT 0x1001
 
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },

{ USB_DEVICE(EM770W_OPTION_VENDOR_ID , EM770W_ OPTION_PRODUCT_COLT) },
}
驱动修改后插上3G模块,kernel运行后可在/dev下出现ttyUSB0、ttyUSB1  、ttyUSB2、ttyUSB3、ttyUSB4、ttyUSB5和ppp设备文件 
 
2.修改RIL代码
(1)在ril/reference-ril/Android.mk添加一行:
LOCAL_CFLAGS += -DHUAWEI_EM770W
(2)在ril/reference-ril/atchannel.c中增加的代码
  1. #include <termios.h>

  2. static int urc_fd = -1; /* fd of the URC channel */
  3. static char s_URCBuffer[MAX_AT_RESPONSE+1];
  4. static char *s_URCBufferCur = s_URCBuffer;
  5. static pthread_t s_tid_reader_urc;
  1. static const char *urc_readline()
  2. {
  3.     ssize_t count;
  4.     char *p_read = NULL;
  5.     char *p_eol = NULL;
  6.     char *ret;

  7.     if (*s_URCBufferCur == '\0') {
  8.         s_URCBufferCur = s_URCBuffer;
  9.         *s_URCBufferCur = '\0';
  10.         p_read = s_URCBuffer;
  11.     } else {
  12.         while (*s_URCBufferCur == '\r' || *s_URCBufferCur == '\n')
  13.             s_URCBufferCur++;
  14.         p_eol = findNextEOL(s_URCBufferCur);
  15.         if (p_eol == NULL) {
  16.             size_t len;
  17.             len = strlen(s_URCBufferCur);
  18.             memmove(s_URCBuffer, s_URCBufferCur, len + 1);
  19.             p_read = s_URCBuffer + len;
  20.             s_URCBufferCur = s_URCBuffer;
  21.         }
  22.     }
  23.     while (p_eol == NULL) {
  24.         if (0 == MAX_AT_RESPONSE - (p_read - s_URCBuffer)) {
  25.             LOGE("ERROR: Input line exceeded buffer\n");
  26.             s_URCBufferCur = s_URCBuffer;
  27.             *s_URCBufferCur = '\0';
  28.             p_read = s_URCBuffer;
  29.         }
  30.         do {
  31.             count = read(urc_fd, p_read, MAX_AT_RESPONSE - (p_read - s_URCBuffer));
  32.         } while (count < 0 && errno == EINTR);
  33.         if (count > 0) {
  34.             AT_DUMP( "<< ", p_read, count );
  35.             s_readCount += count;
  36.             p_read[count] = '\0';
  37.             while (*s_URCBufferCur == '\r' || *s_URCBufferCur == '\n')
  38.                 s_URCBufferCur++;
  39.             p_eol = findNextEOL(s_URCBufferCur);
  40.             p_read += count;
  41.         } else if (count <= 0) {
  42.             if(count == 0) {
  43.                 LOGD("atchannel: EOF reached");
  44.             } else {
  45.                 LOGD("atchannel: read error %s", strerror(errno));
  46.             }
  47.             return NULL;
  48.         }
  49.     }
  50.     ret = s_URCBufferCur;
  51.     *p_eol = '\0';
  52.     s_URCBufferCur = p_eol + 1; 
  53.     LOGD("AT< %s\n", ret);
  54.     return ret;
  55. }

  56. static void *urc_readerLoop(void *arg)
  57. {
  58.     for (;;) {
  59.         const char * line;
  60.         line = urc_readline();
  61.         if (line == NULL) {
  62.             break;
  63.         }
  64.         if(isSMSUnsolicited(line)) {
  65.             char *line1;
  66.             const char *line2;
  67.             line1 = strdup(line);
  68.             line2 = readline();
  69.             if (line2 == NULL) {
  70.                 break;
  71.             }
  72.             if (s_unsolHandler != NULL) {
  73.                 s_unsolHandler (line1, line2);
  74.             }
  75.             free(line1);
  76.         } else {
  77.             processLine(line);
  78.         }
  79.     }
  80.     onReaderClosed();
  81.     return NULL;
  82. }
(3)修改ril/reference-ril/atchannel.c中的at_open函数,增加HUAWEI_EM770W宏控制的代码
  1.     pthread_attr_init (&attr);
  2.     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

  3. #ifdef HUAWEI_EM770W
  4.     int fd2 = -1;
  5.     while(fd2 < 0) {
  6.         fd2 = open ("/dev/ttyUSB2", O_RDWR);
  7.         if (fd2 < 0) {
  8.             perror ("opening URC interface. retrying...");
  9.             sleep(10);
  10.         }
  11.     }
  12.     if(fd2 > 0) {
  13.         urc_fd = fd2;
  14.         struct termios ios;
  15.         tcgetattr( fd2, &ios );
  16.         ios.c_lflag = 0;
  17.         tcsetattr( fd2, TCSANOW, &ios );
  18.     }
  19.     ret = pthread_create(&s_tid_reader_urc, &attr, urc_readerLoop, &attr);
  20.     if (ret < 0) {
  21.         perror ("pthread_create");
  22.         return -1;
  23.     }
  24. #endif

  25.     ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr);

(4)在ril/reference-ril/reference-ril.c中修改的代码

  1. +#include <cutils/properties.h>

  2. -#define PPP_TTY_PATH "/dev/omap_csmi_tty1"
  3. +#define PPP_TTY_PATH "/dev/ppp0"

  4. - /* Not muted */
  5. - at_send_command("AT+CMUT=0", NULL);
  6. + /* Set muted */
  7. + at_send_command("AT+CMUT=1", NULL);

  8. - if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
  9. + if ( fd >= 0) {

  10.      /*    
  11.      asprintf(&cmd, "AT+CGDCONT=1,\"IP\",\"%s\",,0,0", apn);
  12.      //FIXME check for error here
  13.      err = at_send_command(cmd, NULL);
  14.      free(cmd);
  15.      // Set required QoS params to default
  16.      err = at_send_command("AT+CGQREQ=1", NULL);
  17.      // Set minimum QoS params to default
  18.      err = at_send_command("AT+CGQMIN=1", NULL);
  19.      // packet-domain event reporting
  20.      err = at_send_command("AT+CGEREP=1,0", NULL);
  21.      // Hangup anything that's happening there now
  22.      err = at_send_command("AT+CGACT=1,0", NULL);
  23.      // Start data on PDP context 1
  24.      err = at_send_command("ATD*99***1#", &p_response);
  25.      if (err < 0 || p_response->success == 0) {
  26.          goto error;
  27.      }
  28.      */

  29.    + property_set("ctl.start","pppd_gprs");
  30.    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
  31.    at_response_free(p_response);
(5)在ril/rild/rild.c中修改的代码
  1. +#if 0
  2.      /* special override when in the emulator */
  3. -#if 1
  4.      {
  5.          static char* arg_overrides[3];
  6.          static char arg_device[32];

  7.  //switchUser();


前面讲到了如何让修改kernel驱动和ril层代码,接下来还需要增加ppp拨号以及设备文件和服务属性。
1.修改init.gprs-pppd属性
对应文件:system/core/include/private/Android_filesystem_config.h
 
在static struct fs_path_config android_files[]中增加:
+   { 00777, AID_ROOT,      AID_SHELL,     "system/etc/init.gprs-pppd" },
 
2.修改ttyUSB设备属性
对应文件:system/core/init/devices.c
在static struct perms_ devperms[]中增加:
+   { "/dev/ttyUSB0",       0777,   AID_RADIO,      AID_RADIO,      0 }, 
+   { "/dev/ttyUSB1",       0777,   AID_RADIO,      AID_RADIO,      0 },
+   { "/dev/ttyUSB2",       0777,   AID_RADIO,      AID_RADIO,      0 },
+   { "/dev/ttyUSB3",       0777,   AID_RADIO,      AID_RADIO,      0 },
+   { "/dev/ttyUSB4",       0777,   AID_RADIO,      AID_RADIO,      0 },
+   { "/dev/ttyUSB5",       0777,   AID_RADIO,      AID_RADIO,      0 },
 
3.修改pppd_gprs服务属性
对应文件:system/core/init/property_service.c
在property_perms[]中增加:
+   { "net.ppp0.",        AID_RADIO,    0 },
在control_perms[]中增加:
+   { "pppd_gprs",AID_RADIO, AID_LOG },
 
4.修改init.rc文件
service ril-daemon /system/bin/rild -l libreference-ril.so -- -d /dev/ttyUSB2
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
    user root
    group radio cache inet misc
 
service pppd_gprs /etc/ppp/init.gprs-pppd /dev/ttyUSB0
    user root
    group radio cache inet misc
    disabled
 
现在3G模块上电后就可以注册上网络,并能实现电话功能,接下来还要实现gprs拨号上网功能

1.init.gprs-pppd
  1. #!/system/bin/sh
  2. # An unforunate wrapper script
  3. PPPD_PID=
  4. /system/bin/setprop "net.gprs.ppp-exit" ""
  5. /system/bin/log -t pppd "Starting pppd"
  6. /system/bin/pppd call gprs $*
  7. PPPD_EXIT=$?
  8. PPPD_PID=$!
  9. /system/bin/log -t pppd "pppd exited with $PPPD_EXIT"
  10. /system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT"
  11. exit $PPPD_EXIT

2.gprs-connect-chat

  1. ABORT 'BUSY'
  2. ABORT 'NO CARRIER'
  3. ABORT 'ERROR'
  4. ABORT '+CME ERROR: 100'
  5. "" AT
  6. OK AT+CGDCONT=1,"IP","CMNET"
  7. OK AT+CGEQREQ=1,2,128,384,0,0,0,0,"0E0","0E0",,0,0
  8. OK AT
  9. OK AT
  10. OK ATS0=0
  11. OK AT
  12. OK AT
  13. OK ATDT*98*1#
  14. CONNECT
3.gprs-disconnect-chat
  1. ABORT OK
  2. ABORT BUSY
  3. ABORT DELAYED
  4. ABORT "NO ANSWER"
  5. ABORT "NO CARRIER"
  6. ABORT "NO DIALTONE"
  7. ABORT VOICE
  8. ABORT ERROR
  9. ABORT RINGING
  10. TIMEOUT 12
  11. "" \\k\\k\\k\\d+++ATH
  12. "NO CARRIER-AT-OK" ""
4.ip-up
  1. #!/system/bin/sh
  2. /system/bin/setprop "net.interfaces.defaultroute" "gprs"
  3. /system/bin/setprop "net.gprs.dns1" "$DNS1"
  4. /system/bin/setprop "net.gprs.dns2" "$DNS2"
  5. /system/bin/setprop "net.gprs.local-ip" "$IPLOCAL"
  6. /system/bin/setprop "net.gprs.remote-ip" "$IPREMOTE"
  7. exit 0
5.ip-down
  1. #!/system/bin/sh
  2. case $1 in
  3.     ppp1)
  4.   echo 0 > /proc/sys/net/ipv4/ip_forward;
  5.   ;;
  6. esac
  7. rm /etc/ppp/ppp*.pid
  8. # Use interface name if linkname is not available
  9. NAME=${LINKNAME:-"$1"}
  10. #/system/bin/setprop "net.dns1" ""
  11. #/system/bin/setprop "net.dns2" ""
  12. /system/bin/setprop "net.$NAME.local-ip" ""
  13. /system/bin/setprop "net.$NAME.remote-ip" ""

6.peers/gprs

  1. # This is pppd script, used Huawei EM770W3G Module
  2. # Usage: root>pppd call gprs
  3. /dev/ttyUSB0
  4. 115200
  5. crtscts
  6. modem
  7. debug
  8. nodetach
  9. usepeerdns
  10. noipdefault
  11. defaultroute
  12. user "cmnet"
  13. 0.0.0.0:0.0.0.0
  14. connect '/system/bin/chat -s -v -f /etc/ppp/gprs-connect-chat'
  15. #disconnect '/bin/chat -v -f /etc/ppp/gprs-disconnect-chat'

文件创建好后只要在Android启动后进入"Settings(设置)"->"Wireless controls(无线网络)"->"Mobile networks(移动网络)"->"Access Points Name(接入点)",按Menu键弹出界面选择"New APN(新接入点)",一般情况下只要填写"Name(名称)"和"APN"两项即可,"MCC"和"MNC"会随着运行商网络注册成功后自动生成,最后保存。现在就可以通过gprs上网了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值