HL7588 384-second connection timeout with Verizon

Hello,

We are using the HL7588_1104081 over USB to connect to Verizon’s network on Linux (Raspbian). We acquire quickly and can use the connection for around 378 to 384 seconds, after which we always get a drop. The same SIM cards do not give a drop on the USB730L adapter from MiFi. Our tests mainly consist of pings, and we have tried a double-rate ping (every half-second) which gives the same result and also an initial delay of 100 seconds which then allows around 280 seconds of pings (the same total duration). We also tried downloading a file and ran out of data at 7.5MB; this SIM card now refuses to connect at all, meaning the timeout problem is not simply a lack of data loaded on the cards which Verizon initially suspected. Our initialization routine is the series of commands described in “AirPrime_HL75xx_Network_Interface_Configuration_Technical_Note_Rev1_0.pdf” made into a C script. Any help or suggestions would be appreciated.

Arthur

Hi,
Could you help to share your C script? And what firmware is your device using?

Thanks,

Hi Jerdung,

This is the response to “ATI10”:

Modem-Firmware:
RHL75xx.V.3.15.151600.201802071640.x7160_1
HL7588
HL75xx.V.3.15
x7160
FUSED
2018-02-07 17:19:52
r12267

Primary-Boot:
RHL75xx.V.3.15.0202170420.201802071640.x7160_1
2018-02-07 16:40:00
r10909

Secondary-Boot:
RHL75xx.V.3.15.0202170420.201802071640.x7160_1
2018-02-07 16:40:00
r10909

Update-Agent:
RHL75xx.V.3.15.0202170413.201802071640.x7160_1
2018-02-07 16:40:00
r12267

4G-Firmware:
7160.S3.561.34.4.744.04.2769.18265

3G-Firmware:
202.999.423.42-54.35

And this is our C program:

#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>

int issue_at(int port, char *command, char *result, int biggest)
{
  int count=0, len=strlen(command), n=0;

  // Flush any buffered characters
  read(port, result, biggest);

  // Send the AT command over the port
  count=write(port, command, strlen(command));
  if(count<0) {
    result[0]=0x00;
    return -1;
  }

  // Remove the echo
  do {
    count=read(port, result, len);
  } while(count==0);

  // Wait for a response and add a terminating NULL
  do {
    count=read(port, result, biggest-1);
  } while(count==0);
  result[count]=0x00;

  // Remove any leading control characters
  len=0; while(result[len]<0x20) len++;
  if(len>0) {
    for(n=0;n<=(count-len);++n) result[n]=result[n+len];
    count-=len;
  }

  // Remove any trailing control characters
  while((count>0)&&(result[count-1]<0x20)) result[--count]=0x00;

  // Register an "OK" or "ERROR" and delete
  if(count>=2) {
    if((result[count-2]=='O')&&(result[count-1]=='K')) {
      count-=2;
      result[count]=0x00;
    } else if((count>=5)&&(result[count-5]=='E')&&(result[count-4]=='R')&&(result[count-3]=='R')&&(result[count-2]=='O')&&(result[count-1]=='R')) {
      result[0]=0x00;
      return -1;
    }
  }

  // Remove any trailing control characters
  while((count>0)&&(result[count-1]<0x20)) result[--count]=0x00;

  // Return the string length of the remaining result
  return count;
}

int main(void)
{
  char result[256], ip[64], search[]="XDNS: 3", *dns=NULL, dns1[64], dns2[64];
  int i=0, j=0, k=0, at_fd=open("/dev/ttyACM2", O_RDWR|O_NOCTTY|O_SYNC);
  struct termios options;
  FILE *fout=NULL;

  if(at_fd<=0) return -1;

  bzero(&options, sizeof(options));
  options.c_cflag=B9600|CS8|CLOCAL|CREAD|IGNPAR;
  tcflush(at_fd, TCIFLUSH);
  tcsetattr(at_fd, TCSANOW, &options);

  // Flush any buffered characters
  read(at_fd, result, sizeof(result));
  usleep(100000);
  issue_at(at_fd, "AT\r", result, sizeof(result));
  usleep(100000);
  read(at_fd, result, sizeof(result));

  usleep(10000);
  issue_at(at_fd, "AT+CGSN\r", result, sizeof(result));
  printf("IMEI: %s\n", result);

  usleep(10000);
  if(issue_at(at_fd, "AT+CCID\r", result, sizeof(result))>0) {
    printf("ICCID: %s\n", result+7);
  } else {
    printf("[No SIM detected]\n");
    close(at_fd);
    return -1;
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+XDNS=3,1\r", result, sizeof(result))<0) {
    printf("Error with `AT+XDNS=3,1`!\n");
    close(at_fd);
    return -1;
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+CGACT=1,3\r", result, sizeof(result))<0) {
    printf("Error with `AT+CGACT=1,3`!\n");
    close(at_fd);
    return -1;
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+CGPADDR=3\r", result, sizeof(result))<0) {
    printf("Error with `AT+CGPADDR=3`!\n");
    close(at_fd);
    return -1;
  }

  for(i=0;i<strlen(result);++i) if(result[i]=='"') break;
  if(i<strlen(result)) {
    strcpy(ip, result+i+1);
    for(i=0;i<strlen(ip);++i) if(ip[i]=='"') break;
    if(i<strlen(ip)) ip[i]=0x00;
    printf("Found IP: %s\n", ip);
  } else {
    close(at_fd);
    return -1;
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+XDNS?\r", result, sizeof(result))<0) {
    printf("Error with `AT+XDNS?`!\n");
    close(at_fd);
    return -1;
  }

  dns=strstr(result, search);
  if(dns==NULL) {
    printf("Error with `AT+XDNS?`!\n");
    close(at_fd);
    return -1;
  } else {
    i=j=k=dns1[0]=dns2[0]=0;
    while(dns[i]>=0x20) {
      switch(j) {
        case 0:
          if(dns[i]=='"') j=1;
          break;

        case 1:
          if(dns[i]=='"') {
            j=2; k=0;
          } else {
            dns1[k++]=dns[i]; dns1[k]=0x00;
          }
          break;

        case 2:
          if(dns[i]=='"') j=3;
          break;

        case 3:
          if(dns[i]=='"') {
            j=4; k=0;
          } else {
            dns2[k++]=dns[i]; dns2[k]=0x00;
          }
          break;
      }

      i++;
    }

    printf("Found DNS: %s and %s\n", dns1, dns2);
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+XDATACHANNEL=1,1,\"/USBCDC/2\",\"/USBHS/NCM/1\",2,3\r", result, sizeof(result))<0) {
    printf("Error with `AT+XDATACHANNEL=1,1,\"/USBCDC/2\",\"/USBHS/NCM/1\",2,3`!\n");
    close(at_fd);
    return -1;
  }

  usleep(10000);
  if(issue_at(at_fd, "AT+CGDATA=\"M-RAW_IP\",3\r", result, sizeof(result))<0) {
    printf("Error with `AT+CGDATA=\"M-RAW_IP\",3`!\n");
    close(at_fd);
    return -1;
  }

  fout=fopen("/etc/resolv.conf", "wb");
  sprintf(result, "nameserver %s\nnameserver %s\n", dns1, dns2);
  fputs(result, fout);
  fclose(fout);

  sprintf(result, "ifconfig wwan1 %s netmask 255.255.255.0 -arp up", ip);
  system(result);
  system("route add default wwan1");

  printf("Connected on wwan1\n");

  close(at_fd);
  return 0;
}

Thanks for any insight!

Arthur

Hi,
I used with the same FW but don’t see that issue.
Could you help to try connection manually, don’t use C script.

64 bytes from 1.1.1.1: icmp_seq=522 ttl=50 time=60.5 ms
^C
— 1.1.1.1 ping statistics —
522 packets transmitted, 522 received, 0% packet loss, time 522437ms

Thanks,

Hi Jerdung,

It does the same thing without the C script, by doing the commands manually instead. It appears that Verizon is dropping the connection after this delay time - do we have to get some sort of special approval for our IMEI?

Arthur

Hi,
As I know, there is not special approval for device IMEI.
To define the timeout is come from network or device or Raspbian. Could you help to open ttyACM0 and enable CEREG=1 during testing?
When the data connection is dropped, check on ttyACM0 to see the connection is disconnected or not.
If it is disconnected (CEREG=0) it means that Verizon network dropped your connection.
If it is still connected (CEREG=1) maybe network interface on Raspbian is automatically downed.

Thanks,

Hi Jerdung,

In general, my response would be that we get a “NO CARRIER” printout as soon as the connection drops. We have tried both “/dev/ttyACM0” and “/dev/ttyACM2” while adjusting the “XDATACHANNEL” command appropriately, and both seem to do the same thing. Here is an example of the end of “dmesg”:

[  204.030399] cdc_ncm 1-1.2:1.8 wwan1: 480 mbit/s downlink 480 mbit/s uplink
[  204.038298] cdc_ncm 1-1.2:1.8 wwan1: network connection: connected
[  586.966287] cdc_ncm 1-1.2:1.8 wwan1: network connection: disconnected
[  661.918295] cdc_ncm 1-1.2:1.8 wwan1: 480 mbit/s downlink 480 mbit/s uplink
[  661.926300] cdc_ncm 1-1.2:1.8 wwan1: network connection: connected
[ 1040.206293] cdc_ncm 1-1.2:1.8 wwan1: network connection: disconnected
[ 1065.846301] cdc_ncm 1-1.2:1.8 wwan1: 480 mbit/s downlink 480 mbit/s uplink
[ 1065.854299] cdc_ncm 1-1.2:1.8 wwan1: network connection: connected
[ 1445.662310] cdc_ncm 1-1.2:1.8 wwan1: network connection: disconnected
[ 2151.790294] cdc_ncm 1-1.2:1.8 wwan1: 480 mbit/s downlink 480 mbit/s uplink
[ 2151.798298] cdc_ncm 1-1.2:1.8 wwan1: network connection: connected
[ 2533.110299] cdc_ncm 1-1.2:1.8 wwan1: network connection: disconnected

The exact operation of “CEREG” is somewhat more nuanced and we can detail this if necessary, but “NO CARRIER” seems like a Verizon disconnect. Thanks for any thoughts!

Arthur

Hi Arthur,
Please make sure the APN that you are using correctly. If NO CARRIER is returned, it can be network issue or device issue.
Please use AT&F command and reconfigure APN and then retest again.
If this issue is still happening you can contact technical support, they will guide you to collect device logs to define what is this issue.

BRs,
jerdung

Hi Jerdung,

We were finally able to get our problem solved. Verizon was indeed dropping the connection, but it was because we were sending DHCP discover requests occasionally, and since those come from a 0.0.0.0 IP address, they appear as spoofing which they do not like. They apparently have some “two-minute sliding window” and somehow this translated into the six-minute timeout. We were able to add “denyinterfaces wwan1” to the end of “/etc/dhcpcd.conf” and this fixed the problem. Thanks for your help in getting the “NO CARRIER” message, because this was important for debugging. All the best!

Arthur

1 Like