android下调试3G之自动拨号【转】

来自:   http://blog.csdn.net/hanbo622/article/details/41009037

本章简单讲述下Android实现自动拨号的功能,该功能利用了系统启动的rild的服务来实现,因为rild的服务是杀不死的,所以利用这一点,可以使拨号失败或网络断掉后自动重拨,来增强上网的可靠性。这里只实现拨号功能,把ril库实现的一些功能都去掉了。

一、修改rild程序源码

     把 .../hardware/ril里面的文件全部删掉,创建rild文件夹,把以下面代码放到新建的文件夹下。

      1、rild.c

[cpp]  view plain  copy
  1. #define LOG_TAG "RILD"  
  2. #include <unistd.h>  
  3. #include <pthread.h>  
  4. #include <utils/Log.h>  
  5. #include <sys/types.h>  
  6. #include <sys/stat.h>  
  7. #include "ril_fun.h"  
  8. int main(int argc, char *argv[])  
  9. {  
  10.     int opt;  
  11.     int err;  
  12.     pthread_t tid;  
  13.     char buf[PROPERTY_VALUE_MAX];  
  14.     static int device_fd;  
  15.     static char * device_path = NULL;  
  16.     umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);  
  17.     while ( -1 != (opt = getopt(argc, argv, "d:"))) {//用来分析main函数传递的命令行参数  
  18.         switch (opt) {  
  19.             case 'd':  
  20.                 device_path = optarg;  
  21.                 ALOGD("Opening tty device %s\n", device_path);  
  22.             break;  
  23.             default:  
  24.                 ALOGD("Not tty device");  
  25.                 goto done;  
  26.         }  
  27.     }  
  28.     device_fd = device_open(device_path);//打开设备节点  
  29.     device_init(device_fd);//初始化设备节点  
  30.     property_set("ctl.stop", PPPD_SERVICE_NAME);//设置pppd_gprs属性为停止  
  31.     request_setup_datacall(device_fd);//继续执行拨号  
  32.           
  33.     pthread_create(&tid,NULL,ip_detection,(void *)device_fd);//创建查询IP线程,使断网后重新拨号  
  34. done:  
  35.     while(1){  
  36.         sleep(0x00ffffff);  
  37.     }  
  38.     return 0;  
  39. }  

      2、ril_fun.c

[cpp]  view plain  copy
  1. #define LOG_TAG "RIL"  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5. #include <sys/types.h>  
  6. #include <sys/stat.h>  
  7. #include <fcntl.h>  
  8. #include <termios.h>  
  9. #include <sys/select.h>  
  10. #include "ril_fun.h"  
  11.   
  12. #define PPPD_EXIT_CODE      "net.gprs.ppp-exit"  
  13. #define PPP_NET_LOCAL_IP    "net.ppp0.local-ip"  
  14. #define PPP_SYSFS_RETRY     5  
  15. #define PPP_OPERSTATE_PATH  "/sys/class/net/ppp0/operstate"  
  16.   
  17. static int pppd_started = 0;  
  18.   
  19. int device_open(char *device_path)  
  20. {  
  21.     int device_fd = -1;  
  22.     while (device_fd < 0) {   
  23.         if (device_path != NULL) {  
  24.             device_fd = open (device_path, O_RDWR);//打开串口AT模块的设备   
  25.         }  
  26.         if (device_fd < 0) {  
  27.             ALOGD ("opening AT interface. retrying...");  
  28.             sleep(3);  
  29.         }  
  30.     }  
  31.     return device_fd;  
  32. }  
  33. void device_init(int device_fd)  
  34. {  
  35.     struct termios options;  
  36.     tcgetattr(device_fd, &options);//获取串口属性  
  37.       
  38.     cfsetispeed(&options, B115200);//设置接收波特率  
  39.     cfsetospeed(&options, B115200);//设置发送波特率  
  40.   
  41.     options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|IGNCR|ICRNL|IXON);  
  42.   
  43.     options.c_cflag &= ~PARENB; //无奇偶校验位  
  44.     options.c_cflag &= ~CSTOPB; //停止位为1位  
  45.     options.c_cflag &= ~CSIZE;    
  46.     options.c_cflag |= CS8;     //数据位为8位  
  47.       
  48.     options.c_lflag   &=   ~(ICANON   |   ECHO   |   ECHOE   |   ISIG);  
  49.       
  50.     tcsetattr(device_fd,TCSANOW,&options);  
  51. }   
  52. int at_send_command(int device_fd, char *cmd)  
  53. {  
  54.     int ret;      
  55.     ret = write(device_fd, cmd, strlen(cmd));  
  56.     return ret;  
  57. }  
  58. void request_setup_datacall(int device_fd)   
  59. {  
  60.     const char *apn = "cmnet";  
  61.     char *cmd = NULL;  
  62.     int err;  
  63.   
  64.     ALOGD("requesting data connection to APN '%s'", apn);  
  65.   
  66.     if(pppd_started) {  
  67.         ALOGD("Stop existing PPPd before activating PDP");  
  68.         property_set("ctl.stop", PPPD_SERVICE_NAME);//设置pppd_gprs属性为停止  
  69.         pppd_started = 0;  
  70.     }  
  71.   
  72.     err = at_send_command(device_fd, "at$qcpdplt=0");  
  73.   
  74.     asprintf(&cmd, "AT+CGDCONT=1,\"IP\",\"%s\",,0,0", apn);//设置PDP上下文  
  75.     err = at_send_command(device_fd, cmd);  
  76.     free(cmd);  
  77.     if (err < 0 ) {  
  78.         ALOGD("AT Send Command error!");  
  79.     }  
  80.   
  81.     err = property_set(PPPD_EXIT_CODE, "");//设置net.gprs.ppp-exit为空  
  82.     if (err < 0) {  
  83.         ALOGW("Set PPPD_EXIT_CODE failed!");  
  84.         goto ppp_error;  
  85.     }  
  86.     err = property_set(PPP_NET_LOCAL_IP, "");//设置net.ppp0.local-ip为空  
  87.     if (err < 0) {  
  88.         ALOGW("Set PPPD_NET_LOCAL_IP failed!");  
  89.         goto ppp_error;  
  90.     }  
  91.     err = property_set("ctl.start", PPPD_SERVICE_NAME);//设置pppd_gprs属性为启动  
  92.     pppd_started = 1;  
  93.     if (err < 0) {  
  94.         ALOGW("Can not start PPPd");  
  95.         goto ppp_error;  
  96.     }  
  97.     ALOGD("PPPd started");  
  98.   
  99.     return;  
  100. ppp_error:  
  101.     at_send_command(device_fd, "AT+CGACT=0,1");//PDP上下文去激活  
  102.   
  103.     if(pppd_started) {  
  104.         property_set("ctl.stop", PPPD_SERVICE_NAME);  
  105.         pppd_started = 0;  
  106.     }  
  107.   
  108. }  
  109. void *ip_detection(void *arg)   
  110. {  
  111.     int fd;  
  112.     int err;  
  113.     int device_fd = (int)arg;  
  114.     char buffer[20];  
  115.     char exit_code[PROPERTY_VALUE_MAX];  
  116.     static char local_ip[PROPERTY_VALUE_MAX];  
  117.     static int pppd_started = 0;  
  118.   
  119.     sleep(2);  
  120.     while(1){  
  121.         property_get(PPPD_EXIT_CODE, exit_code, "");//获取pppd的退出状态  
  122.         if(strcmp(exit_code, "") != 0) {//检测pppd是否异常退出  
  123.             ALOGW("PPPd exit with code %s", exit_code);  
  124.             request_setup_datacall(device_fd);//继续执行拨号  
  125.             goto done;  
  126.         }  
  127.         fd  = open(PPP_OPERSTATE_PATH, O_RDONLY);//读取/sys/class/net/ppp0/operstate来监控数据网络数据的状态  
  128.         if (fd >= 0)  {  
  129.             buffer[0] = 0;  
  130.             read(fd, buffer, sizeof(buffer));  
  131.             close(fd);  
  132.             ALOGW("buffer = %s", buffer);  
  133.             if(!strncmp(buffer, "up", strlen("up")) || !strncmp(buffer, "unknown", strlen("unknown"))) {  
  134.                 memset(local_ip,'\0',sizeof(local_ip));  
  135.                 err = property_get(PPP_NET_LOCAL_IP, local_ip, "");//获取IP  
  136.                 if (err < 0) {  
  137.                     ALOGW("Get PPPD_NET_LOCAL_IP failed!");  
  138.                 }  
  139.                 if(!strcmp(local_ip, "")) {  
  140.                     ALOGW("PPP link is up but no local IP is assigned. Will retry times after %d seconds",PPP_SYSFS_RETRY);  
  141.                     property_set("ctl.stop", PPPD_SERVICE_NAME);//如果没有IP停止pppd  
  142.                 } else {  
  143.                     ALOGD("PPP link is up with local IP address %s", local_ip);  
  144.                 }  
  145.             } else {  
  146.                 ALOGW("PPP link status in %s is %s. Will retry times after %d seconds", \  
  147.                 PPP_OPERSTATE_PATH, buffer, PPP_SYSFS_RETRY);  
  148.                 property_set("ctl.stop", PPPD_SERVICE_NAME);//如果数据网络数据的状态不对停止pppd  
  149.             }  
  150.         } else {  
  151.             ALOGW("Can not detect PPP state in %s. Will retry  times after %d seconds", \  
  152.             PPP_OPERSTATE_PATH ,PPP_SYSFS_RETRY);  
  153.             request_setup_datacall(device_fd);//继续执行拨号  
  154.         }  
  155. done:  
  156.         sleep(PPP_SYSFS_RETRY);  
  157.     }  
  158.   
  159.     return NULL;  
  160. }  

      3、ril_fun.h

[cpp]  view plain  copy
  1. #ifndef _RIL_FUN_H_  
  2. #define _RIL_FUN_H_  
  3.   
  4. #include <unistd.h>  
  5. #include <utils/Log.h> //ALOG*()  
  6. #include <cutils/properties.h> //property_set()  
  7.   
  8. #define PPPD_SERVICE_NAME "pppd_gprs"  
  9.   
  10. /************************************************************* 
  11. * 功能:   打开串口设备文件 
  12. * 参数:   device_path: 串口设备文件名 
  13. * 返回值:  串口设备文件描述符 
  14. **************************************************************/  
  15. int device_open(char *device_path);  
  16. /************************************************************* 
  17. * 功能:   初始化设备节点 
  18. * 参数:   device_fd: 串口设备文件描述符           
  19. * 返回值:  无 
  20. **************************************************************/  
  21. void device_init(int device_fd);  
  22. /************************************************************* 
  23. * 功能:   发送AT指令函数 
  24. * 参数:   device_fd: 串口设备文件描述符 
  25. *           cmd:AT命令           
  26. * 返回值:  ret:状态 
  27. **************************************************************/  
  28. int at_send_command(int device_fd, char *cmd);  
  29. /************************************************************* 
  30. * 功能:   建立拨号函数 
  31. * 参数:   device_fd: 串口设备文件描述符           
  32. * 返回值:  无 
  33. **************************************************************/  
  34. void request_setup_datacall(int device_fd);  
  35. /************************************************************* 
  36. * 功能:   创建查询IP线程 
  37. * 参数:   arg: void类型指针          
  38. * 返回值:  NULL 
  39. **************************************************************/  
  40. void *ip_detection(void *arg);  
  41.   
  42. #endif  

      4、Android.mk

[cpp]  view plain  copy
  1. LOCAL_PATH:= $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_SRC_FILES:= \  
  5.     rild.c \  
  6.     ril_fun.c  
  7.   
  8.   
  9. LOCAL_SHARED_LIBRARIES := \  
  10.     libcutils \  
  11.     libdl  
  12.   
  13. LOCAL_LDLIBS += -lpthread  
  14. LOCAL_MODULE:= rild  
  15. LOCAL_MODULE_TAGS := optional  
  16.   
  17. include $(BUILD_EXECUTABLE)  

      上述文件添加好后,进行编译,在编译前如果之前编译过要进行清理,执行make  clean

二、把下面的脚本放到板子的/etc/ppp下

      1、init.gprs-pppd

[cpp]  view plain  copy
  1. #!/system/bin/sh  
  2. # An unforunate wrapper script   
  3. # so that the exit code of pppd may be retrieved  
  4.   
  5. PPPD_PID=  
  6.   
  7. /system/bin/setprop "net.gprs.ppp-exit" "" #设置net.gprs.ppp-exit为空  
  8. /system/bin/log -t pppd "Starting pppd"  
  9.   
  10. /system/bin/pppd connect 'chat -v -s -r "/var/log/chat.log" -f "/etc/ppp/3gdata_call.conf"' disconnect \  
  11. 'chat -r "/var/log/chat.log" -t 30 -e -v "" +++ATH "NO CARRIER"' /dev/ttyUSB3 115200 mru 1280 mtu 1280 \  
  12. nodetach debug dump defaultroute usepeerdns novj novjccomp crtscts user card password card noipdefault ipcp-accept-local  \  
  13. ipcp-accept-remote linkname ppp0  
  14.   
  15. PPPD_EXIT=$? #获得执行命令后的返回值  
  16. PPPD_PID=$!  #最后运行的后台进程的PID  
  17.   
  18. /system/bin/log -t pppd "pppd exited with $PPPD_EXIT"   
  19. /system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT" #把返回值设置给net.gprs.ppp-exit  

      注:脚本中的/dev/ttyUSB3为模块USB串口的Modem口。

      2、3gdata_call.conf

[cpp]  view plain  copy
  1. ABORT "NO CARRIER"  
  2. ABORT "NO DIALTONE"  
  3. ABORT "ERROR"  
  4. ABORT "NO ANSWER"  
  5. ABORT "BUSY"  
  6. TIMEOUT 120  
  7. "" at  
  8. OK atd*99***1#  
  9. CONNECT  

 

三、修改ini.rc脚本 

      打开 .../device/fsl/imx6/etc/init.rc按照如下红色框进行修改

      

      添加修改新加入文件权限的语句。

      

      注:/dev/ttyUSB2是模块USB串口的AT口。

到此,就可以进行打包 make  snod ,烧写镜像进行测试了。

可以用命令:logcat  -b  radio 查看rild 输出的信息进行调试。如果一切正常会打印出IP(或用命令 necfg 查看IP),有IP后用命令 ping  202.108.22.5 (百度IP)看下网络是否能ping通。如果能ping通证明自动拨号已经成功。此时用命令 ps查看rild和pppd进程号,用命令kill  -9  <进程号> 杀死随便一个进程,在5s之后看看是不是该进程又运行了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值