This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

LTE TCP socket stability testing

I am trying to design some test cases to check the LTE stability and performance. 

I avoid to use the existing Nordic samples to do this as they are too complicate for the testing purposes. 
Here is a test case I've made to test the LTE TCP communication stability. It borrows the idea from the samples of asset_tracker, at_client and tcp. TCP is the prime feature on which TLS, MQTT are based. The test case does the following things:
  1) start the LTE modem
  2) establish a simple TCP connection to a cloud server
  3) periodically (10s) monitor the modem status
  4) periodically (10s) send 2 bytes of payload to the server
I want to see how long the connection can last. 
To build the code, please replace nrf\samples\nrf9160\asset_tracker\src\main.c with the attached main.c. Then rebuild asset_tracker. 
You can see the log in fail1.log attached.
I've run this testing code in a Nordic board (v.07.0) and our own board. Both of them show similar result.
The testing result is inconsistent. Sometime it ran only a few loops (the attached fail1.log is of such kind). Sometime it ran longer. Usually it wouldn't exceed 100 loops. 
When it started to fail, it was usually stuck at recv() which is used to receive AT commands. recv() has been configured with the non-block mode so supposedly it should always return.
Occasionally, it was stuck at connect() when creating TCP connection at boot up.
My questions:
1) is this a proper test case for testing LTE/network stability?
2) is anything missed in the coding for correctly configuring the modem?
3) does the test result meet your expectation?
4) has Nordic done similar testing?
Best,
Kai
#include <zephyr.h>
#include <stdio.h>
#include <string.h>
#include <gps.h>
#include <sensor.h>
#include <console.h>
#include <nrf_cloud.h>
#include <dk_buttons_and_leds.h>
#include <lte_lc.h>
#include <misc/reboot.h>
#include <bsd.h>
#include "nrf_socket.h"
#include "orientation_detector.h"
#include <net/socket.h>
#include <sys/time.h>


#define TCP_HOST "45.33.53.75"
#define TCP_PORT 9090


#define LC_MAX_READ_LENGTH1 128
#define AT_CMD_SIZE1(x) (sizeof(x) - 1)

static const char subscribe[] = "AT+CEREG=2";
static const char psm_disable[] = "AT+CPSMS=0";
static const char normal[] = "AT+CFUN=1";
static const char success[] = "OK";
static const char status1[] = "+CEREG: 1";
static const char status2[] = "+CEREG:1";
static const char status3[] = "+CEREG: 5";
static const char status4[] = "+CEREG:5";

static int at_cmd1(int fd, const char *cmd, size_t size)
{
	int len;
	u8_t buffer[LC_MAX_READ_LENGTH1];

	printk("====AT send (%d bytes): %s\n", strlen(cmd), cmd);
	len = send(fd, cmd, size, 0);
	if (len != size) {
		printk("***ERROR: AT send: failed, ret=%d.\n", len);
		return -1;
	}

	for (int i=0; i<50; i++)		// wait for 5s
	{
		len = recv(fd, buffer, LC_MAX_READ_LENGTH1, MSG_DONTWAIT);
		if (len > 0)
		{
			printk("====AT receive (%d bytes): %s", strlen(buffer), buffer);
			return 0;
		} 
		k_sleep(K_MSEC(100));
	}
	printk("**********AT receive ERROR.\n");
	return -1;
}

void main(void)
{
	printk("Application started\n");

	int err;
	int at_socket_fd;
	u8_t buffer[LC_MAX_READ_LENGTH1];


	// create AT socket
	at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);

	// start modem
	at_cmd1(at_socket_fd, subscribe, AT_CMD_SIZE1(subscribe));
	at_cmd1(at_socket_fd, psm_disable, AT_CMD_SIZE1(psm_disable));
	at_cmd1(at_socket_fd, normal, AT_CMD_SIZE1(normal));

	// wait for LET connection ready
	printk("LTE connecting ...\n");
	while (true) {
		int bytes;
		bytes = recv(at_socket_fd, buffer, LC_MAX_READ_LENGTH1, 0);
		if (bytes) {
			buffer[bytes] = 0;
			printk("====AT receive (%d bytes): %s", bytes, buffer);
			if (!memcmp(status1, buffer, AT_CMD_SIZE1(status1)) ||
			    !memcmp(status2, buffer, AT_CMD_SIZE1(status2)) ||
			    !memcmp(status3, buffer, AT_CMD_SIZE1(status3)) ||
			    !memcmp(status4, buffer, AT_CMD_SIZE1(status4))) {
				break;
			}
		}
	}
	printk("\nLTE connected\n\n");


	// get server IP address
	struct addrinfo * server_addr;
	err = getaddrinfo(TCP_HOST, NULL, NULL, &server_addr);
	if (err != 0)
	{
		printk("***ERROR: failed to get server IP address\n");
		return 0;
	}

	// print server IP address
	{
		u8_t * p2 = &(((struct sockaddr_in *)server_addr->ai_addr)->sin_addr.s_addr);
		printk("server IP addr=%d.%d.%d.%d\n", p2[0], p2[1], p2[2], p2[3]);
	}

	// set server TCP listening port
	((struct sockaddr_in *)server_addr->ai_addr)->sin_port = htons(TCP_PORT);

	// create & bind TCP socket
	int tcp_socket_fd;
	{
		tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0);

		struct sockaddr_in local_addr;
		local_addr.sin_family = AF_INET;
		local_addr.sin_port = htons(0);
		local_addr.sin_addr.s_addr = 0;
		err = bind(tcp_socket_fd, (struct sockaddr *)&local_addr, sizeof(local_addr));
		if (err != 0)
		{
			printk("TCP sokcet bind err: %d\n\r", err);
			return;
		}
	}

	// connect to server
	while(1) 
	{
		printk("\nTCP connect()...\n");
		err = connect(tcp_socket_fd, (struct sockaddr *)server_addr->ai_addr, sizeof(struct sockaddr_in));
		if (err == 0)
		{
			printk("TCP connect() succeeded\n\n");
			break;
		}
		k_sleep(K_MSEC(1000));	// delay 1s
	} 

	// check modem status; send TCP data to server

	int loop = 1;
	while(1) 
	{
		// read AT socket to see if there is any data; with non-block mode read
		while (true) 
		{
			int bytes;
			bytes = recv(at_socket_fd, buffer, LC_MAX_READ_LENGTH1, MSG_DONTWAIT );
			if (bytes <= 0) 
				break;
			buffer[bytes] = 0;
			printk("====AT receive (%d bytes): %s", bytes, buffer);
		}

		printk("---------------------------------------- %d\n", loop++);

		// send AT command to check modem status
//		at_cmd1(at_socket_fd, "AT%XCBAND", AT_CMD_SIZE1("AT%XCBAND"));
		at_cmd1(at_socket_fd, "AT+CESQ", AT_CMD_SIZE1("AT+CESQ"));
		at_cmd1(at_socket_fd, "AT+CEREG?", AT_CMD_SIZE1("AT+CEREG?"));
		at_cmd1(at_socket_fd, "AT+CGDCONT?", AT_CMD_SIZE1("AT+CGDCONT?"));

		// send TCP data to server
#if 1
		static char buf[] = {"a"};
		static int len = sizeof(buf);
		err = send(tcp_socket_fd, buf, len, 0);
		if (err != len)
			printk("**********TCP send: error=%d.\n", err);
		else
			printk("====TCP send (%d bytes)\n", len);
#endif

		// sleep 10s
		k_sleep(K_MSEC(10000));
	}

	close(at_socket_fd);
	return 0;
}

***** Booting Zephyr OS v1.13.99-ncs2 *****
Secure Boot: configure flash
Secure Boot: SPU: set region 0 as Secure
Secure Boot: SPU: set region 1 as Secure
Secure Boot: SPU: set region 2 as Secure
Secure Boot: SPU: set region 3 as Secure
Secure Boot: SPU: set region 4 as Secure
Secure Boot: SPU: set region 5 as Secure
Secure Boot: SPU: set region 6 as Secure
Secure Boot: SPU: set region 7 as Secure
Secure Boot: SPU: set Flash region 8 as Non-Secure
Secure Boot: SPU: set Flash region 9 as Non-Secure
Secure Boot: SPU: set Flash region 10 as Non-Secure
Secure Boot: SPU: set Flash region 11 as Non-Secure
Secure Boot: SPU: set Flash region 12 as Non-Secure
Secure Boot: SPU: set Flash region 13 as Non-Secure
Secure Boot: SPU: set Flash region 14 as Non-Secure
Secure Boot: SPU: set Flash region 15 as Non-Secure
Secure Boot: SPU: set Flash region 16 as Non-Secure
Secure Boot: SPU: set Flash region 17 as Non-Secure
Secure Boot: SPU: set Flash region 18 as Non-Secure
Secure Boot: SPU: set Flash region 19 as Non-Secure
Secure Boot: SPU: set Flash region 20 as Non-Secure
Secure Boot: SPU: set Flash region 21 as Non-Secure
Secure Boot: SPU: set Flash region 22 as Non-Secure
Secure Boot: SPU: set Flash region 23 as Non-Secure
Secure Boot: SPU: set Flash region 24 as Non-Secure
Secure Boot: SPU: set Flash region 25 as Non-Secure
Secure Boot: SPU: set Flash region 26 as Non-Secure
Secure Boot: SPU: set Flash region 27 as Non-Secure
Secure Boot: SPU: set Flash region 28 as Non-Secure
Secure Boot: SPU: set Flash region 29 as Non-Secure
Secure Boot: SPU: set Flash region 30 as Non-Secure
Secure Boot: SPU: set Flash region 31 as Non-Secure
Secure Boot: configure SRAM
Secure Boot: SPU: set SRAM region 0 as Secure
Secure Boot: SPU: set SRAM region 1 as Secure
Secure Boot: SPU: set SRAM region 2 as Secure
Secure Boot: SPU: set SRAM region 3 as Secure
Secure Boot: SPU: set SRAM region 4 as Secure
Secure Boot: SPU: set SRAM region 5 as Secure
Secure Boot: SPU: set SRAM region 6 as Secure
Secure Boot: SPU: set SRAM region 7 as Secure
Secure Boot: SPU: set SRAM region 8 as Non-Secure
Secure Boot: SPU: set SRAM region 9 as Non-Secure
Secure Boot: SPU: set SRAM region 10 as Non-Secure
Secure Boot: SPU: set SRAM region 11 as Non-Secure
Secure Boot: SPU: set SRAM region 12 as Non-Secure
Secure Boot: SPU: set SRAM region 13 as Non-Secure
Secure Boot: SPU: set SRAM region 14 as Non-Secure
Secure Boot: SPU: set SRAM region 15 as Non-Secure
Secure Boot: SPU: set SRAM region 16 as Non-Secure
Secure Boot: SPU: set SRAM region 17 as Non-Secure
Secure Boot: SPU: set SRAM region 18 as Non-Secure
Secure Boot: SPU: set SRAM region 19 as Non-Secure
Secure Boot: SPU: set SRAM region 20 as Non-Secure
Secure Boot: SPU: set SRAM region 21 as Non-Secure
Secure Boot: SPU: set SRAM region 22 as Non-Secure
Secure Boot: SPU: set SRAM region 23 as Non-Secure
Secure Boot: SPU: set SRAM region 24 as Non-Secure
Secure Boot: SPU: set SRAM region 25 as Non-Secure
Secure Boot: SPU: set SRAM region 26 as Non-Secure
Secure Boot: SPU: set SRAM region 27 as Non-Secure
Secure Boot: SPU: set SRAM region 28 as Non-Secure
Secure Boot: SPU: set SRAM region 29 as Non-Secure
Secure Boot: SPU: set SRAM region 30 as Non-Secure
Secure Boot: SPU: set SRAM region 31 as Non-Secure
Secure Boot: configure peripherals
Secure Boot: MSP_NS 20029828
Secure Boot: prepare to jump to Non-Secure image
***** Booting Zephyr OS v1.13.99-ncs2 *****
Application started
====AT send (10 bytes): AT+CEREG=2
====AT receive (4 bytes): OK
====AT send (10 bytes): AT+CPSMS=0
====AT receive (4 bytes): OK
====AT send (9 bytes): AT+CFUN=1
====AT receive (4 bytes): OK
LTE connecting ...
====AT receive (32 bytes): +CEREG: 2,"2005","00803103",7
====AT receive (32 bytes): +CEREG: 1,"2005","00803103",7

LTE connected

server IP addr=45.33.53.75

TCP connect()...
TCP connect() succeeded

---------------------------------------- 1
====AT send (7 bytes): AT+CESQ
====AT receive (33 bytes): +CESQ: 99,99,255,255,255,51
OK
====AT send (9 bytes): AT+CEREG?
====AT receive (37 bytes): +CEREG: 2,1,"2005","00803103",7
OK
====AT send (11 bytes): AT+CGDCONT?
====AT receive (101 bytes): +CGDCONT: 0,"IPV4V6","vzwinternet","100.88.205.249 2600:1010:B007:C50D:0000:0057:158A:9F01",0,0
OK
====TCP send (2 bytes)
---------------------------------------- 2
====AT send (7 bytes): AT+CESQ
====AT receive (33 bytes): +CESQ: 99,99,255,255,255,51
OK
====AT send (9 bytes): AT+CEREG?
====AT receive (37 bytes): +CEREG: 2,1,"2005","00803103",7
OK
====AT send (11 bytes): AT+CGDCONT?
====AT receive (101 bytes): +CGDCONT: 0,"IPV4V6","vzwinternet","100.88.205.249 2600:1010:B007:C50D:0000:0057:158A:9F01",0,0
OK
====TCP send (2 bytes)
---------------------------------------- 3
====AT send (7 bytes): AT+CESQ
====AT receive (33 bytes): +CESQ: 99,99,255,255,255,51
OK
====AT send (9 bytes): AT+CEREG?
====AT receive (37 bytes): +CEREG: 2,1,"2005","00803103",7
OK
====AT send (11 bytes): AT+CGDCONT?
====AT receive (101 bytes): +CGDCONT: 0,"IPV4V6","vzwinternet","100.88.205.249 2600:1010:B007:C50D:0000:0057:158A:9F01",0,0
OK
====TCP send (2 bytes)
---------------------------------------- 4
====AT send (7 bytes): AT+CESQ
  • Hi Kai,

    1) is this a proper test case for testing LTE/network stability?

     Yes, I don't see anything wrong with the test description.

    2) is anything missed in the coding for correctly configuring the modem?

    I don't see anything wrong in your code. You can see how we configure the modem in the lte_link_control driver here. When it comes to TCP, you can find a sample for that in this fork.

    3) does the test result meet your expectation?

     No, the instability you are seeing is not expected behavior.

    4) has Nordic done similar testing?

     I'm running the code you attached, and I have not been able to reproduce the issue. I have been running the test for almost 2 hours now, and the loop counter is now at ~700. I will let the test run overnight.

    I tested with modem fw: mfw-m1_nrf9160_0.6.8-30.alpha

    What version of the modem fw are you using for the test?

    Best regards,

    Sigurd

  • hi Sigurd,

    Here are my board information:

      1) modem fw is mfw-m1_nrf9160_0.6.8-30.alpha.

      2) board version is 0.7.0

      3) carrier is Verizon. The signal strength is about -80db ~ -90db.

    We have another board in China. It has the same problem. Its information:

      1) nRF9160-NB-MFW_030_12_prealpha

      2) board version is 0.8.2

      3) carrier is China Mobile. The signal strength is about -85db ~ -95db.

    Could the problem be related to the carrier registration? I guess, maybe some registration procedure is missed for my board or SIM card? 

    Best,

    Kai

  • Hi,

    Are you testing with the iBasis sim card? If yes, did you register them at nrfcloud.com ?

    It could be that you are getting a error returned from the bsdlib. Please add the error-handlers and printing of error codes to your main.c file. You can do it like this:

    #include <zephyr.h>
    #include <stdio.h>
    #include <string.h>
    #include <gps.h>
    #include <sensor.h>
    #include <console.h>
    #include <nrf_cloud.h>
    #include <dk_buttons_and_leds.h>
    #include <lte_lc.h>
    #include <misc/reboot.h>
    #include <bsd.h>
    #include "nrf_socket.h"
    #include "orientation_detector.h"
    #include <net/socket.h>
    #include <sys/time.h>
    
    
    #define TCP_HOST "45.33.53.75"
    #define TCP_PORT 9090
    
    
    #define LC_MAX_READ_LENGTH1 128
    #define AT_CMD_SIZE1(x) (sizeof(x) - 1)
    
    static const char subscribe[] = "AT+CEREG=2";
    static const char psm_disable[] = "AT+CPSMS=0";
    static const char normal[] = "AT+CFUN=1";
    static const char success[] = "OK";
    static const char status1[] = "+CEREG: 1";
    static const char status2[] = "+CEREG:1";
    static const char status3[] = "+CEREG: 5";
    static const char status4[] = "+CEREG:5";
    
    /* Interval in microseconds between each time LEDs are updated when indicating
     * that an error has occurred.
     */
    #define LEDS_ERROR_UPDATE_INTERVAL      250000
    
    
    enum error_type {
    	ERROR_NRF_CLOUD,
    	ERROR_BSD_RECOVERABLE,
    	ERROR_BSD_IRRECOVERABLE,
    	ERROR_LTE_LC
    };
    
    
    
    static int at_cmd1(int fd, const char *cmd, size_t size)
    {
    	int len;
    	u8_t buffer[LC_MAX_READ_LENGTH1];
    
    	printk("====AT send (%d bytes): %s\n", strlen(cmd), cmd);
    	len = send(fd, cmd, size, 0);
    	if (len != size) {
    		printk("***ERROR: AT send: failed, ret=%d.\n", len);
    		return -1;
    	}
    
    	for (int i=0; i<50; i++)		// wait for 5s
    	{
    		len = recv(fd, buffer, LC_MAX_READ_LENGTH1, MSG_DONTWAIT);
    		if (len > 0)
    		{
    			printk("====AT receive (%d bytes): %s", strlen(buffer), buffer);
    			return 0;
    		} 
    		k_sleep(K_MSEC(100));
    	}
    	printk("**********AT receive ERROR.\n");
    	return -1;
    }
    
    /**@brief error handler. */
    void error_handler(enum error_type err_type, int err_code)
    {
    
    
    //#if !defined(CONFIG_DEBUG)
    //	sys_reboot(SYS_REBOOT_COLD);
    //#else
    	u8_t led_pattern;
    
    	switch (err_type) {
    	case ERROR_NRF_CLOUD:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 4, 2 and 3)
    		 * if there is an application error.
    		 */
    		led_pattern = DK_LED1_MSK | DK_LED4_MSK;
    		printk("Error of type ERROR_NRF_CLOUD: %d\n", err_code);
    	break;
    	case ERROR_BSD_RECOVERABLE:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 3, 2 and 4)
    		 * if there is a recoverable error.
    		 */
    		led_pattern = DK_LED1_MSK | DK_LED3_MSK;
    		printk("Error of type ERROR_BSD_RECOVERABLE: %d\n", err_code);
    	break;
    	case ERROR_BSD_IRRECOVERABLE:
    		/* Blinking all LEDs ON/OFF if there is an
    		 * irrecoverable error.
    		 */
    		led_pattern = DK_ALL_LEDS_MSK;
    		printk("Error of type ERROR_BSD_IRRECOVERABLE: %d\n",
    								err_code);
    								EINVAL;
    
    	break;
    	default:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 2, 3 and 4)
    		 * undefined error.
    		 */
    		led_pattern = DK_LED1_MSK | DK_LED2_MSK;
    		printk("Unknown error type: %d err_code: %d\n",
    			err_type, err_code);
    	break;
    	}
    
    	while (true) {
    		dk_set_leds(led_pattern & 0x0f);
    		k_busy_wait(LEDS_ERROR_UPDATE_INTERVAL);
    		dk_set_leds(~led_pattern & 0x0f);
    		k_busy_wait(LEDS_ERROR_UPDATE_INTERVAL);
    	}
    //#endif /* CONFIG_DEBUG */
    }
    
    
    /**@brief Recoverable BSD library error. */
    void bsd_recoverable_error_handler(uint32_t err)
    {
    	error_handler(ERROR_BSD_RECOVERABLE, (int)err);
    }
    
    /**@brief Irrecoverable BSD library error. */
    void bsd_irrecoverable_error_handler(uint32_t err)
    {
    	error_handler(ERROR_BSD_IRRECOVERABLE, (int)err);
    }
    
    
    
    void main(void)
    {
    	printk("Application started\n");
    
    	int err;
    	int at_socket_fd;
    	u8_t buffer[LC_MAX_READ_LENGTH1];
    
    
    	// create AT socket
    	at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
    
    	// start modem
    	at_cmd1(at_socket_fd, subscribe, AT_CMD_SIZE1(subscribe));
    	at_cmd1(at_socket_fd, psm_disable, AT_CMD_SIZE1(psm_disable));
    	at_cmd1(at_socket_fd, normal, AT_CMD_SIZE1(normal));
    
    	// wait for LET connection ready
    	printk("LTE connecting ...\n");
    	while (true) {
    		int bytes;
    		bytes = recv(at_socket_fd, buffer, LC_MAX_READ_LENGTH1, 0);
    		if (bytes) {
    			buffer[bytes] = 0;
    			printk("====AT receive (%d bytes): %s", bytes, buffer);
    			if (!memcmp(status1, buffer, AT_CMD_SIZE1(status1)) ||
    			    !memcmp(status2, buffer, AT_CMD_SIZE1(status2)) ||
    			    !memcmp(status3, buffer, AT_CMD_SIZE1(status3)) ||
    			    !memcmp(status4, buffer, AT_CMD_SIZE1(status4))) {
    				break;
    			}
    		}
    	}
    	printk("\nLTE connected\n\n");
    
    
    	// get server IP address
    	struct addrinfo * server_addr;
    	err = getaddrinfo(TCP_HOST, NULL, NULL, &server_addr);
    	if (err != 0)
    	{
    		printk("***ERROR: failed to get server IP address\n");
    		return 0;
    	}
    
    	// print server IP address
    	{
    		u8_t * p2 = &(((struct sockaddr_in *)server_addr->ai_addr)->sin_addr.s_addr);
    		printk("server IP addr=%d.%d.%d.%d\n", p2[0], p2[1], p2[2], p2[3]);
    	}
    
    	// set server TCP listening port
    	((struct sockaddr_in *)server_addr->ai_addr)->sin_port = htons(TCP_PORT);
    
    	// create & bind TCP socket
    	int tcp_socket_fd;
    	{
    		tcp_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    		struct sockaddr_in local_addr;
    		local_addr.sin_family = AF_INET;
    		local_addr.sin_port = htons(0);
    		local_addr.sin_addr.s_addr = 0;
    		err = bind(tcp_socket_fd, (struct sockaddr *)&local_addr, sizeof(local_addr));
    		if (err != 0)
    		{
    			printk("TCP sokcet bind err: %d\n\r", err);
    			return;
    		}
    	}
    
    	// connect to server
    	while(1) 
    	{
    		printk("\nTCP connect()...\n");
    		err = connect(tcp_socket_fd, (struct sockaddr *)server_addr->ai_addr, sizeof(struct sockaddr_in));
    		if (err == 0)
    		{
    			printk("TCP connect() succeeded\n\n");
    			break;
    		}
    		k_sleep(K_MSEC(1000));	// delay 1s
    	} 
    
    	// check modem status; send TCP data to server
    
    	int loop = 1;
    	while(1) 
    	{
    		// read AT socket to see if there is any data; with non-block mode read
    		while (true) 
    		{
    			int bytes;
    			bytes = recv(at_socket_fd, buffer, LC_MAX_READ_LENGTH1, MSG_DONTWAIT );
    			if (bytes <= 0) 
    				break;
    			buffer[bytes] = 0;
    			printk("====AT receive (%d bytes): %s", bytes, buffer);
    		}
    
    		printk("---------------------------------------- %d\n", loop++);
    
    		// send AT command to check modem status
    //		at_cmd1(at_socket_fd, "AT%XCBAND", AT_CMD_SIZE1("AT%XCBAND"));
    		at_cmd1(at_socket_fd, "AT+CESQ", AT_CMD_SIZE1("AT+CESQ"));
    		at_cmd1(at_socket_fd, "AT+CEREG?", AT_CMD_SIZE1("AT+CEREG?"));
    		at_cmd1(at_socket_fd, "AT+CGDCONT?", AT_CMD_SIZE1("AT+CGDCONT?"));
    
    		// send TCP data to server
    #if 1
    		static char buf[] = {"a"};
    		static int len = sizeof(buf);
    		err = send(tcp_socket_fd, buf, len, 0);
    		if (err != len)
    			printk("**********TCP send: error=%d.\n", err);
    		else
    			printk("====TCP send (%d bytes)\n", len);
    #endif
    
    		// sleep 10s
    		k_sleep(K_MSEC(10000));
    	}
    
    	close(at_socket_fd);
    	return 0;
    }
    
    

  • enum error_type {
    	ERROR_BSD_RECOVERABLE,
    	ERROR_BSD_IRRECOVERABLE
    };
    
    static void error_handler(enum error_type err_type, int err)
    {
    	while (1) 
    	{
    		switch (err_type) {
    		case ERROR_BSD_RECOVERABLE:
    			printk("BSD ERROR: RECOVERABLE: %d\n", err);
    			break;
    		case ERROR_BSD_IRRECOVERABLE:
    			printk("BSD ERROR: IRRECOVERABLE: %d\n", err);
    			break;
    		default:
    			break;
    		}
    		k_busy_wait(1000000*2);		// 2s
    	}
    }
    
    void bsd_recoverable_error_handler(uint32_t err)
    {
    	error_handler(ERROR_BSD_RECOVERABLE, (int)err);
    }
    
    void bsd_irrecoverable_error_handler(uint32_t err)
    {
    	error_handler(ERROR_BSD_IRRECOVERABLE, (int)err);
    }
    

    hi,

    I've added the above code in main.c. The error behavior has changed a bit. When the error occurs, instead of being hung there, it resets the whole board. -- what does this behavior change mean?

    My card is a Verizon SIM coming with older board (v.0.7.0). No sure if it has been activated or not.

    Best,

    Kai

  • I've added the above code in main.c. The error behavior has changed a bit. When the error occurs, instead of being hung there, it resets the whole board. -- what does this behavior change mean?

    Please try to add "CONFIG_DEBUG=y" in the prj.conf, and see if that stops the reboot.

Related