Android——4.2 - 3G移植之路之usb-modeswitch (二)

在前文 Android——4.2 - 3G移植之路之libusb (一)  中有解析到libusb 这个动态库的移植,目的就是为了 usb-modeswitch 服务。

usb-modeswitch的作用就是转换usb型的设备状态,也是3G 移植中重要的准备工作!


                                                                 撰写不易,转载请注明出处:http://blog.csdn.net/jscese/article/details/39271443


一.Kernel配置:

       usb-modeswitch需要kernel中的驱动支持,需要配置serial驱动,到kernel中 make menuconfig 打开serial中的option模块 :

Device Drivers——>USB support——>USB Serial Converter support——>USB driver for GSM and CDMA modems 选中

也可以到 kernel/drivers/usb/serial/Kconfig 中进行手动修改或者直接修改.config。

关于kernel中的模块编译配置可参考:Kernel 编译配置机制

kernel中的option模块已经添加了很多3G模块的ID,包含的ID数组在 kernel/drivers/usb/serial/option.c 中:

  1. static const struct usb_device_id option_ids[] = {  
  2.     { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },  
  3.     { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },  
  4.     { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },  
  5.   
  6. ...  
  7.   
  8. }  

如果需要的移植的3G模块的ID ,上面的数组没包含进去,就手动加进去!

option不能编译成单独module,所以上面选中即可,编译进kernel中。

最后烧录到机器上 目录:/sys/module/option



二.编译:

     按照前文的地址下载 usb-modeswitch-2.2.0 以及 usb-modeswitch-data-20140529 这两个压缩包,解压,字面意思可以理解后面的 data包 作为usb-modeswitch 服务用的。

linux 下是需要配置交叉编译器以及libusb的动态库位置的,这里在android源码中编译,照例放到 external中,将data 包中的usb_modeswitch.d 解压到 usb-modeswitch中。

添加Android.mk:

  1. # jscese add for 3G - usb-modeswitch driver  
  2.   
  3. LOCAL_PATH := $(call my-dir)  
  4. include $(CLEAR_VARS)  
  5.   
  6. LIBUSBDIR :external/libusb/libusb  \  
  7.              external/lilbusb-compat/libusb  
  8.   
  9. LOCAL_MODULE :usb_modeswitch  
  10. LOCAL_SRC_FILES :usb_modeswitch.c  
  11. LOCAL_MODULE_TAGS :optional  
  12. LOCAL_C_INCLUDES :=$(LIBUSBDIR)  
  13. LOCAL_SHARED_LIBRARIES :libusb libusb-compat  
  14.   
  15. include $(BUILD_EXECUTABLE)  
  16.   
  17. #############cp usb_modeswitch database########  
  18.   
  19. $(shell cp -rf $(LOCAL_PATH)/usb_modeswitch.d $(TARGET_OUT)/etc)  


指定INCLUDES,因为需要libusb的头文件,还需要之前编译的lib,我是直接cp了data包到 etc里面,最后打包进系统!

这里我取巧了,直接用了shell,如果整体初次编译是不行的,正规的做法可参考:Android——编译体系中的【PRODUCT_COPY_FILES】【ALL_PREBUILT】【BUILD_PREBUILT】中的第四部分.


可以看看usb_modeswitch.d包里面的内容,全是 ID 文件,看一款华为的3G  12d1:1446:

  1. # Huawei, newer modems  
  2. TargetVendor=0x12d1  
  3. TargetProductList="1001,1406,140b,140c,1412,141b,1432,1433,1436,14ac,1506,150c,1511"  
  4. HuaweiNewMode=1  

usb-modeswitch 转换的时候就是以上面的为参数。

mmm 编译成android 二进制执行文件,整体make -j* 编译不生成到正确路径的问题可参考:Android——编译安装Module的控制因素



三.使用:

      编译烧录进系统之后,可在android文件系统/system/bin 找到 usb_modeswitch ,shell终端输入 usb_modeswitch + 回车:

  1. shell@android:/ # usb_modeswitch                                                 
  2.   
  3. Usage: usb_modeswitch [<params>] [-c filename]  
  4.   
  5.  -h, --help                    this help  
  6.  -e, --version                 print version information and exit  
  7.  -j, --find-mbim               return config no. with MBIM interface, exit  
  8.   
  9.  -v, --default-vendor NUM      vendor ID of original mode (mandatory)  
  10.  -p, --default-product NUM     product ID of original mode (mandatory)  
  11.  -V, --target-vendor NUM       target mode vendor ID (optional)  
  12.  -P, --target-product NUM      target mode product ID (optional)  
  13.  -C, --target-class NUM        target mode device class (optional)  
  14.  -b, --bus-num NUM             system bus number of device (for hard ID)  
  15.  -g, --device-num NUM          system device number (for hard ID)  
  16.  -m, --message-endpoint NUM    direct the message transfer there (optional)  
  17.  -M, --message-content <msg>   message to send (hex number as string)  
  18.  -2 <msg>, -3 <msg>            additional messages to send (-n recommended)  
  19.  -n, --need-response           read response to the message transfer (CSW)  
  20.  -r, --response-endpoint NUM   read response from there (optional)  
  21.  -K, --std-eject               send standard EJECT sequence  
  22.  -d, --detach-only             detach the active driver, no further action  
  23.  -H, --huawei-mode             apply a special procedure  
  24.  -J, --huawei-new-mode         apply a special procedure  
  25.  -S, --sierra-mode             apply a special procedure  
  26.  -O, --sony-mode               apply a special procedure  
  27.  -G, --gct-mode                apply a special procedure  
  28.  -N, --sequans-mode            apply a special procedure  
  29.  -A, --mobileaction-mode       apply a special procedure  
  30.  -T, --kobil-mode              apply a special procedure  
  31.  -L, --cisco-mode              apply a special procedure  
  32.  -B, --qisda-mode              apply a special procedure  
  33.  -E, --quanta-mode             apply a special procedure  
  34.  -R, --reset-usb               reset the device after all other actions  
  35.  -Q, --quiet                   don't show progress or error messages  
  36.  -W, --verbose                 print all settings and debug output  
  37.  -D, --sysmode                 specific result and syslog message  
  38.  -s, --success <seconds>       switching result check with timeout  
  39.  -I, --inquire                 retrieve SCSI attributes initially  
  40.   
  41.  -c, --config-file <filename>  load long configuration from file  
  42.   
  43.  -t, --stdinput                read long configuration from stdin  
  44.   
  45.  -f, --long-config <text>      get long configuration from string  
  46.   
  47.  -i, --interface NUM           select initial USB interface (default 0)  
  48.  -u, --configuration NUM       select USB configuration  
  49.  -a, --altsetting NUM          select alternative USB interface setting  
  50.   
  51.   
  52.  * usb_modeswitch: handle USB devices with multiple modes  
  53.  * Version 2.2.0 (C) Josua Dietze 2014  
  54.  * Based on libusb1/libusbx  
  55.   
  56.  ! PLEASE REPORT NEW CONFIGURATIONS !  

参数用法全列出来了,想怎么用,看各人爱好了,usb-modeswitch的data包里面 是有 rules 文件的 40-usb_modeswitch.rules

适用于linux的udev,当kernel监测到设备时,交给udev来处理,此时会根据rules 来执行 usb-modeswitch。

android 用vold 取代了 udev,所以一般都是在vold 里面调用 usb-modeswitch了!

关于 androdi 的 vold 机制可参考 我之前的专栏:Android— 4.2 Vold


这里贴出我的做法:

/system/vold/NetlinkHandler.cpp中的 onEvent 函数中添加:

  1. if (!strcmp(subsys, "usb"))  
  2.     {  
  3.          if(access("/dev/ttyUSB2",0)==0) //check一下是否已经转了,如果已经调用usb-modeswitch 并且成功了的话是会在/dev/下看到ttyUSB* 字样的设备文件的  
  4.          {  
  5.              SLOGW("jscese display in NetlinkHandler::onEvent  already switch  \n");  
  6.             return;  
  7.          }  
  8.      char  *productid = (char *)evt->findParam("PRODUCT");//取event中的 设备ID信息,包含厂商ID,产品ID  
  9.   
  10.       SLOGW("jscese display in NetlinkHandler::onEvent productid ==%s \n",productid);  
  11.         if(productid ==NULL) //过滤kernel发上来的一些事件  
  12.         {  
  13.             return;  
  14.         }  
  15.   
  16.         handledevice(evt,productid);  
  17.   
  18. }  
  19.   
  20. void NetlinkHandler::handledevice(NetlinkEvent *evt,char *str)  
  21. {  
  22.   
  23.     const char *delim = "/";  
  24.     char *save_ptr;  
  25.     char *idVendor =NULL;  
  26.     char *idProduct =NULL;  
  27.   
  28.     if(evt->getAction()==NetlinkEvent::NlActionAdd)  
  29.     {  
  30.   
  31.                 if (!(idVendor = strtok_r(str, delim, &save_ptr))) {//分割保存  
  32.                                 SLOGE("Error parsing idVendor");  
  33.                                 return;  
  34.                   }  
  35.   
  36.                 if (!(idProduct = strtok_r(NULL, delim, &save_ptr))) {  
  37.                                 SLOGE("Error parsing idProduct");  
  38.                                 return;  
  39.                   }  
  40.   
  41.                 char modeswitch_cmd[1024] = {'\0'};  
  42.                 sprintf(modeswitch_cmd, "/system/bin/usb_modeswitch -W -v %s -p %s -c /system/etc/usb_modeswitch.d/%s:%s", idVendor,  
  43.                         idProduct, idVendor, idProduct);  // 准备 执行usb-modeswitch的 命令, 用到了前面的data文件  
  44.                 SLOGW("jscese display modeswitch ==%s \n", modeswitch_cmd);  
  45.                 if (system(modeswitch_cmd) == 0)  //这里就是真正的调用,执行上面的cmd,shell指令成功返回0  
  46.                 {  
  47.                     SLOGW("jscese display system modeswitch success \n");  
  48.   
  49.                 }else  
  50.                 {  
  51.                     SLOGW("jscese display system modeswitch fail \n");  
  52.                 }  
  53.   
  54.     }  
  55.   
  56. }  


上面的handledevice 为核心函数,不logcat,kernel的打印如下:

  1. [ 3252.717055] ==11==> hub_port_init 1   
  2. [ 3252.720785] Plug in USB Port1  
  3. [ 3252.905058] usb 4-1: new high speed USB device number 4 using Mstar-ehci-1  
  4. [ 3253.343340] usb 4-1: New USB device found, idVendor=12d1idProduct=1446  
  5. [ 3253.350139] usb 4-1: New USB device strings: Mfr=3Product=2SerialNumber=0  
  6. [ 3253.357428] usb 4-1: Product: HUAWEI Mobile  
  7. [ 3253.361713] usb 4-1: Manufacturer: HUAWEI Technology  
  8. [ 3253.371651] scsi6 : usb-storage 4-1:1.0  
  9. [ 3253.379741] scsi 6:0:0:0: CD-ROM            HUAWEI   Mass Storage     2.31 PQ: 0 ANSI: 2  
  10. [ 3253.388333] scsi7 : usb-storage 4-1:1.1  
  11. [ 3253.395767] scsi 7:0:0:0: Direct-Access     HUAWEI   SD Storage       2.31 PQ: 0 ANSI: 2  
  12. [ 3253.410108] sd 7:0:0:0: [sda] Attached SCSI removable disk  
  13. [ 3253.442848] usb 4-1: USB disconnect, device number 4  
  14. [ 3258.683641] root hub reinitial  
  15. [ 3258.692585] Mstar-ehci-1 Mstar-ehci-1.0: force halt; handshake fd204814 0000c000 00000000 -> -110  
  16. [ 3258.969055] ==11==> hub_port_init 1   
  17. [ 3258.972702] Plug in USB Port1  
  18. [ 3259.157042] usb 4-1: new high speed USB device number 5 using Mstar-ehci-1  
  19. [ 3259.595613] usb 4-1: New USB device found, idVendor=12d1idProduct=1436  
  20. [ 3259.602448] usb 4-1: New USB device strings: Mfr=4Product=3SerialNumber=0  
  21. [ 3259.609776] usb 4-1: Product: HUAWEI Mobile  
  22. [ 3259.614050] usb 4-1: Manufacturer: HUAWEI Technology  
  23. [ 3259.629199] option 4-1:1.0: GSM modem (1-port) converter detected  
  24. [ 3259.638958] usb 4-1: GSM modem (1-port) converter now attached to ttyUSB0  
  25. [ 3259.650087] option 4-1:1.3: GSM modem (1-port) converter detected  
  26. [ 3259.658538] usb 4-1: GSM modem (1-port) converter now attached to ttyUSB1  
  27. [ 3259.666610] option 4-1:1.4: GSM modem (1-port) converter detected  
  28. [ 3259.674883] usb 4-1: GSM modem (1-port) converter now attached to ttyUSB2  
  29. [ 3259.683800] scsi10 : usb-storage 4-1:1.5  
  30. [ 3259.690925] scsi11 : usb-storage 4-1:1.6  
  31. [ 3259.695228] scsi 10:0:0:0: CD-ROM            HUAWEI   Mass Storage     2.31 PQ: 0 ANSI: 2  
  32. [ 3259.706845] scsi 11:0:0:0: Direct-Access     HUAWEI   SD Storage       2.31 PQ: 0 ANSI: 2  
  33. [ 3259.722956] sd 11:0:0:0: [sda] Attached SCSI removable disk  

可以看到 厂商ID 和产品ID 分别为: idVendor=12d1, idProduct=1446  

并且生成了 ttyUSB0 ~ttyUSB2 三个设备文件在/dev下


还需要保证这三个设备文件的权限,以备后续使用,设置权限:

关于设备文件的权限设置,android默认是放在 /system/core/rootdir/ueventd.rc中:

添加ttyUSB0 ~ttyUSB2读写权限:

  1. # jscese add for 3G  
  2. /dev/ttyUSB0                 0666   radio      radio  
  3. /dev/ttyUSB1                 0666   radio      radio  
  4. /dev/ttyUSB2                 0666   radio      radio 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值