Hisilicon 3518C 4G module transplantation and application

    This chapter mainly introduces the use of LTE modules and driver transplantation, pppd dial-up software transplantation, LTE modules mainly use ZTE ME3630 , Wade S600 module, Longshang U9300C module, MeiG SLM730 , Quectel EC20 , Neoway N720 ; the basic AT commands of each module The same, only a few specific commands are different ( 4G signal query command, soft reset command).


1. Pppd porting

   

    This chapter uses the ppp-2.4.4 version, and the development package is ppp-2.4.4.tar.gz ;

Need to modify the content:

1.1. Modify ppp-2.4.4\pppd\ipcp.c

The main reason for modifying this file is that when the dial-up software obtains the network parameter DNS , the tool will not be automatically set to the embedded system, and we need to operate it ourselves.

Add in the ipcp_up function :


char cmd1[100] = {0x00};
    char cmd2[100] = {0x00};
-------
notice("local  IP address %I", go->ouraddr);
notice("remote IP address %I", ho->hisaddr);

	//写入配置脚本
	if (go->dnsaddr[0])
	{
	    notice("primary   DNS address %I", go->dnsaddr[0]);
	    sprintf(cmd1, "echo nameserver %s > /mnt/mtd/resolv_wirless.conf",
                                         ip_ntoa(go->dnsaddr[0]));
	    system(cmd1);
	}
	if (go->dnsaddr[1])
	{
	    notice("secondary DNS address %I", go->dnsaddr[1]);
	    sprintf(cmd2, "echo nameserver %s >> /mnt/mtd/resolv_wirless.conf", 
                                         ip_ntoa(go->dnsaddr[1]));
	    system(cmd2);
	}
    //清除默认网关
	cifdefaultroute(0,0,0);
    //设置新的网关
	SetGateway(ifname,ip_ntoa(ho->hisaddr));

The main reason for setting the gateway is that a wired / wireless automatic switching function is designed in this chapter. In the wired environment, the dial-up software exits (occasionally exits the dial-up connection due to poor signal), and when it needs to switch to wireless, it needs to be cleared . Default gateway, reset the wireless gateway.

Set the gateway function


static  bool 
SetGateway(char* _szInterface, char* _szGateway)
{
	int s32Ret;
	int s32Socketfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(s32Socketfd < 0)
	{
		printf("socket failed by %d", errno);
		return -1;
	}
		
	struct rtentry rt;
	memset(&rt, 0, sizeof(struct rtentry));

	memset(&rt.rt_dst, 0, sizeof(rt.rt_dst));
	rt.rt_dst.sa_family = AF_INET;
	((struct sockaddr_in *)(&rt.rt_dst))->sin_addr.s_addr = inet_addr("0.0.0.0");

	memset(&rt.rt_gateway, 0, sizeof(rt.rt_gateway));
	rt.rt_gateway.sa_family = AF_INET;
	((struct sockaddr_in *)(&rt.rt_gateway))->sin_addr.s_addr = inet_addr(_szGateway);

	memset(&rt.rt_genmask, 0, sizeof(rt.rt_genmask));
	rt.rt_genmask.sa_family = AF_INET;
	((struct sockaddr_in *)(&rt.rt_genmask))->sin_addr.s_addr = 0L;

	rt.rt_dev = _szInterface;
	rt.rt_flags = RTF_GATEWAY;

	s32Ret = ioctl(s32Socketfd, SIOCADDRT, &rt);
	if(s32Ret < 0)
	{
		printf("ioctl SIOCADDRT failed by %d", errno);
		close(s32Socketfd);
		return -1;
	}
	close(s32Socketfd);

	return 0;
}

The above function is to write the dns obtained by dialing into the system file cache, and the application needs to write the cache into the system's dns file ( linux system: /etc/resolv.conf , Android system: it needs to be set through the dnsproxy2 tool Tools will be introduced in another chapter );

 

1.2. Determine whether the dial-up to obtain DNS is correct

Because when the dial-up software performs dial-up, when the signal is very poor, the DNS obtained from the base station will be wrong, so it must be filtered when obtaining DNS .

 

Modify the main.c function:

add function


void checkdns  __V((char *fmt, ...))
{
    va_list pvar;
#if defined(__STDC__)
    va_start(pvar, fmt);
#else
    char *fmt;
    va_start(pvar);
    fmt = va_arg(pvar, char *);
#endif

    int n;
    char buf[1024];
    n = vslprintf(buf, sizeof(buf), fmt, pvar);
    va_end(pvar);
	
    //IPCP ConfAck id=0x2 <addr 10.138.113.2> <ms-dns1 210.21.4.130> <ms-dns3 221.5.88.88>
    /*
    *    该段函数是为了防止拨号后获取到错误的DNS后还继续使用该
    *    该参数,解决方案是当获取到配置应答指令后判断是否获取
    *    到IP地址和对于的DNS,如果没获取到DNS则推出该拨号程序。
    */
    char *pu8ConfAck;
    char *pu8addr;
    char *pu8msdns;
    pu8ConfAck = strstr((char*) buf,"ConfAck");
    if(pu8ConfAck != NULL)
    if(strncmp(pu8ConfAck,"ConfAck",strlen("ConfAck")) == 0)
    {
         printf("---ConfAck[%s]\n",pu8ConfAck); 
	  pu8addr = strstr((char*) pu8ConfAck,"addr");
	  if(pu8addr != NULL)
	  if(strncmp(pu8addr,"addr",strlen("addr")) == 0)
	  {
		 printf("---addr[%s]\n",pu8addr);
		 pu8msdns = strstr((char*) pu8addr,"ms-dns");
		 if(pu8msdns == NULL)
		 	exit(1);
		 printf("---msdns[%s]\n",pu8msdns);
	  }		
    }
}

static void
get_input()
{
    -----------------
    dump_packet("rcvd", p, len);
    //-------edw------------------------//
    checkdns( "%P", p, len);
//------end-------------------------//


At this point, the basic modification of the basic dial-up software is completed.

 

Note : For android system porting, the Android sdk comes with the pppd tool ( under the external\ppp directory), the modification content is basically the same as the above, only the difference is in setting dns , and the Android system uses the command " setprop net.dnsx " to set DNS .

 

1.3. Compiler

Generate makefile ;

compile make CC=arm-hisiv100nptl-linux-gcc

 

Get pppd chat

 

1.4. Operator connection point

Unicom node wcdma

mobile node cnmet

telecom node evdo

content:

debug
nodetach
/dev/ttyUSB2
115200
usepeerdns
noauth
noipdefault
novj
novjccomp
noccp
defaultroute
ipcp-accept-local
ipcp-accept-remote
connect '/system/bin/chat -s -v -f /etc/ppp/peers/chat-wcdma-connect'
disconnect '/system/bin/chat -s -v -f/etc/ppp/peers/chat-disconnect'

The contents of the three node files are similar, only the connection point is different: chat-wcdma-connect .

 

Unicom connection point mode chat-wcdma-connect

content:

ABORT 'NO CARRIER'
ABORT 'ERROR'
ABORT 'NO DIALTONE'
ABORT 'BUSY'
ABORT 'NO ANSWER'
'' AT
OK ATZ
OK AT+CGDCONT=1,\"IP\",\"3gnet\",,0,0
OK AT+CFUN=1
OK ATDT*99#
CONNECT ''

Mobile connection point mode chat-cnmet-connect

ABORT 'NO CARRIER'
ABORT 'ERROR'
ABORT 'NO DIALTONE'
ABORT 'BUSY'
ABORT 'NO ANSWER'
'' AT
OK ATZ
OK AT+CGDCONT=1,\"IP\",\"cmnet\",,0,0
OK AT+CFUN=1
OK ATDT*98*1#
CONNECT ''

Telecom connection point mode chat-evdo-connect

ABORT 'NO CARRIER'
ABORT 'ERROR'
ABORT 'NO DIALTONE'
ABORT 'BUSY'
ABORT 'NO ANSWER'
'' AT
OK ATZ
OK AT+CGDCONT=1,\"IP\",\"ctlte\",,0,0
OK AT+CFUN=1
OK ATDT*99#
CONNECT ''

1.5. Start dialing

Unicom operator: pppd call wcdma&

Mobile operator: pppd call cnmet&

Telecom operator: pppd call evdo&

 

2. Driver transplantation

http://blog.csdn.net/skdkjzz/article/details/22206949

stty -F /dev/ttyUSB0 raw speed 9600 min 0 time 10

Use Longshang 4G module, modify the driver:

1.  Add the USB serial driver and USB network card driver to the kernel . You can choose to program them directly into the kernel, or compile them into modules to be loaded when the kernel starts. In short, make sure that after the Linux kernel is started, these two drivers are running on in the kernel.

Usually, configuring the kernel is through the command make menuconfig , after executing the command:

Add USB serial port driver:

device drivers-->

  usb support-->

usb serial converter support-->

  USB driver for GSM and CDMA modems

 

lAdd  USB NIC driver

devices drivers-->

  Network device support-->

usb Network Adapters-->

  Mulil-purpose USB Networking Framework

 

* Note: If your kernel structure is inconsistent with the above, you may need to choose under other paths. In short, just make sure that option.c and its related parts ( USB serial port driver), cdc_ether.c and its related parts in the source file ( USB network card driver) just participate in the compilation

 

2.  Add PPP components to the kernel

Usually, configuring the kernel is through the command make menuconfig , after executing the command:

devices drivers-->

Network device support-->

  ppp support-->

    ppp filtering

ppp support for async serial ports

ppp support for sync tty ports

ppp deflate compression

ppp BSD-compress compression

3.  Add ZTE module-related information in the kernel driver source file : The USB network card driver can automatically recognize the ZTE module, so there is no need to add anything to the corresponding cdc_ether.c file. However, the USB serial port driver cannot be automatically identified, and the device information of the ZTE module must be added to the source file option.c .

File path: /kernel/drivers/usb/serial/option.c

 

Add the VID and PID information of the USB port , see the blue part below. Here 0x0199 is the PID of the ME3860 module and ME3760_V2 module , and 0x1476 is the PID of the ME3620 module . If you are using other modules, just replace the PID value with the corresponding value.

static const struct usb_device_id option_ids[] = {

+{ USB_DEVICE(0x19d2, 0x1476) },   //add  me3630

+{ USB_DEVICE(0x19d2, 0x0016) },   //add  me3630

+{ USB_DEVICE(0x1c9e, 0x9b05) },   //add  8300

+{ USB_DEVICE(0x1c9e, 0x9b3c) },   //add  9300

+{ USB_DEVICE(0x05C6, 0x9025) },   //add  S600

+{ USB_DEVICE(0x05C6, 0xf601) },   //add  slm730

+{ USB_DEVICE(0x2c7c, 0x0125) },   //add  yiyuan

+{ USB_DEVICE(0x05C6, 0x9008) }, //add  n720……

}

The above ID can be entered into the system, through the command " lsusb ", to view the module ID .

 

lAdd  blacklist information, the module information added above is only the VID and PID of the device , without any additional port information, which will cause the network card of the device to be loaded as a USB serial port. The following is a similar blacklist In the list method, in the option_probe function, add the port corresponding to the network card to the blacklist to prevent the USB network card from being loaded as a USB serial port.

For ME3860 and ME3760_V2 , the corresponding ports of the network card are 0 and 1 , and for the ME3620 , the corresponding ports of the network card are 3 and 4 . Please add the following code to the option_probe function

printk("idVendor=%x, idProduct=%x, bInterfaceNumber =%d\r\n", 
serial->dev->descriptor.idVendor, 
serial->dev->descriptor.idProduct,
serial->interface->cur_altsetting->desc. bInterfaceNumber);

   if (serial->dev->descriptor.idVendor == 0x19d2 &&
           serial->dev->descriptor.idProduct == 0x1476 &&
           serial->interface->cur_altsetting->desc. bInterfaceNumber == 3)
           return -ENODEV;
	if (serial->dev->descriptor.idVendor == 0x19d2 &&
                serial->dev->descriptor.idProduct == 0x1476 &&
                serial->interface->cur_altsetting->desc. bInterfaceNumber == 4)
                return -ENODEV;
	if (serial->dev->descriptor.idVendor == 0x19d2 &&
                serial->dev->descriptor.idProduct == 0x0199 &&
                serial->interface->cur_altsetting->desc. bInterfaceNumber == 0)
                return -ENODEV;
	if (serial->dev->descriptor.idVendor == 0x19d2 &&
                serial->dev->descriptor.idProduct == 0x0199 &&
                serial->interface->cur_altsetting->desc. bInterfaceNumber == 1)
                return -ENODEV;

if (serial->dev->descriptor.idVendor == 0x1c9e&& //龙尚
           serial->dev->descriptor.idProduct == 0x9b05&&
           serial->interface->cur_altsetting->desc. bInterfaceNumber == 3)
           return -ENODEV;

* Note: The printk on the first line is printed for the convenience of debugging. Although it has no actual effect, it is best to bring it. The following if statements respectively determine the port numbers that need to be added to the blacklist. If you are using modules other than ME3860 , ME3760_V2 and ME3620 , the judgment conditions in the above if statements should be modified accordingly.

 

 

If you need to load other modules after loading the driver, you can load them with the command:

echo "19d2 1476" >/sys/bus/usb-serial/drivers/option1/new_id

 

Note: The kernel patch will be obtained in the HiSilicon 3518C 4G module porting file;


Guess you like

Origin blog.csdn.net/edw200/article/details/72457684