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

HTTP AT

Hello,

i work on nrf9160 dk


I would like to know if it is possible to use an AT firmware to be able to easily switch to LTE-M, NB-IOT, send sms, switch off the modem etc.... and also to make http post as on the example "http sample" which works very well.

I tried the firmware "simple_at" which works well too but by combining the two, nothing works anymore.

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include <zephyr.h>
#include <stdio.h>
#include <drivers/uart.h>
#include <string.h>

#include <zephyr.h>
#include <net/socket.h>

#define HTTP_HOST "google.com"

#define HTTP_PORT 80
#define RECV_BUF_SIZE 1024

char recv_buf[RECV_BUF_SIZE + 1];



/**@brief Recoverable BSD library error. */
void bsd_recoverable_error_handler(uint32_t err)
{
	printk("bsdlib recoverable error: %u\n", err);
}

/**@brief HTTP function */
int blocking_recv(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;

	do {
		err = recv(fd, buf, size, flags);
	} while (err < 0 && errno == EAGAIN);

	return err;
}

int blocking_send(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;

	do {
		err = send(fd, buf, size, flags);
	} while (err < 0 && errno == EAGAIN);

	return err;
}

int blocking_connect(int fd, struct sockaddr *local_addr, socklen_t len)
{
	int err;

	do {
		err = connect(fd, local_addr, len);
	} while (err < 0 && errno == EAGAIN);

	return err;
}




const char *at_commands[] = {
	"AT+CFUN?", "AT+CFUN=1", "AT+CFUN?",
	/* Add more here if needed */
};
void app_socket_start(void)
{
	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);

	printk("Starting simple AT socket application\n\r");

	if (at_socket_fd < 0) {
		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
	}
	for (int i = 0; i < ARRAY_SIZE(at_commands); i++) {
		int bytes_written = send(at_socket_fd, at_commands[i],
					 strlen(at_commands[i]), 0);
		if (bytes_written > 0) {
			int r_bytes =
				blocking_recv(at_socket_fd, recv_buf,
					      sizeof(recv_buf), MSG_DONTWAIT);
			if (r_bytes > 0) {
				printk("%s", recv_buf);
			}
		}
	}
	printk("Closing socket\n\r");

	(void)close(at_socket_fd);
}



void app_http_start(void)
{
    
	struct sockaddr_in local_addr;
	struct addrinfo *res;

	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(0);
	local_addr.sin_addr.s_addr = 0;

	printk("HTTP example\n\r");

	int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);

	printk("getaddrinfo err: %d\n\r", err);
	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);

	char send_buf[] =
		//"GET / HTTP/1.1\r\nHost: www.google.com:80\r\nConnection: close\r\n\r\n";
                "POST / HTTP/1.0\r\nHost: www.google.com:80\r\nContent-Type: application/json\r\nContent-Length: 41\r\n\r\n\{\"payload\": \"trame NBIOT de nrf9160 v01\"\}\x1A";
	int send_data_len = strlen(send_buf);

	int client_fd = socket(AF_INET, SOCK_STREAM, 0);

	printk("client_fd: %d\n\r", client_fd);
	err = bind(client_fd, (struct sockaddr *)&local_addr,
		   sizeof(local_addr));
	printk("bind err: %d\n\r", err);
	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
			       sizeof(struct sockaddr_in));
	printk("connect err: %d\n\r", err);

	int num_bytes = send(client_fd, send_buf, send_data_len, 0);

	printk("send err: %d\n\r", num_bytes);

	int tot_num_bytes = 0;

	do {
		/* TODO: make a proper timeout *
		 * Current solution will just hang 
		 * until remote side closes connection */
		num_bytes =
			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
		tot_num_bytes += num_bytes;

		if (num_bytes <= 0) {
			break;
		}
		printk("%s", recv_buf);
	} while (num_bytes > 0);

	printk("\n\rFinished. Closing socket");
	freeaddrinfo(res);
	err = close(client_fd);
}






void main(void)
{
	printk("The AT \n");
        app_socket_start();
        printk("The AT 1\n");
       // app_http_start();
        printk("The AT Maxime2\n");
        
}

Parents Reply Children
  • CONFIG_BSD_LIBRARY=y
    CONFIG_GPIO=n
    CONFIG_SERIAL=y
    CONFIG_STDOUT_CONSOLE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_TEST_RANDOM_GENERATOR=y
    CONFIG_NETWORKING=y
    CONFIG_NET_BUF_USER_DATA_SIZE=1
    CONFIG_NET_SOCKETS_OFFLOAD=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    CONFIG_NET_RAW_MODE=y
    CONFIG_TRUSTED_EXECUTION_NONSECURE=y
    CONFIG_LOG=n
    CONFIG_LOG_DEFAULT_LEVEL=4
    CONFIG_HEAP_MEM_POOL_SIZE=1024
    # LTE link control
    //CONFIG_LTE_LINK_CONTROL=y
    CONFIG_MAIN_STACK_SIZE=4096

    I'm trying to make a code that:
    1- Modem OFF
    2- Modem ON + http post
    3-Modem OFF

    I make sure that CONFIG_LTE_LINK_CONTROL = y is not present in the prj.conf file to be able to turn ON and OFF the modem with AT + CFUN = 4/1

    But I have the impression that the problem comes from CFUN = 4

    Currently, I just changed branches (github.com/.../http) and my code:

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    #include <zephyr.h>
    #include <net/socket.h>
    #include <stdio.h>
    #include <uart.h>
    #include <string.h>
    
    #define HTTP_HOST "lp.fr"
    #define HTTP_PORT 80
    #define RECV_BUF_SIZE 8192
    
    char recv_buf[RECV_BUF_SIZE + 1];
    
    /**@brief Recoverable BSD library error. */
    void bsd_recoverable_error_handler(uint32_t err)
    {
    	printk("bsdlib recoverable error: %u\n", err);
    }
    
    int blocking_recv(int fd, u8_t *buf, u32_t size, u32_t flags)
    {
    	int err;
    
    	do {
    		err = recv(fd, buf, size, flags);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    int blocking_send(int fd, u8_t *buf, u32_t size, u32_t flags)
    {
    	int err;
    
    	do {
    		err = send(fd, buf, size, flags);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    int blocking_connect(int fd, struct sockaddr *local_addr, socklen_t len)
    {
    	int err;
    
    	do {
    		err = connect(fd, local_addr, len);
    	} while (err < 0 && errno == EAGAIN);
    
    	return err;
    }
    
    
    
    const char *at_commands[] = {
    	"AT+CFUN=4","AT%XSYSTEMMODE=1,0,0,0","AT+CFUN?", "AT+CFUN=1", "AT+CFUN?","AT+CEREG?",
    	/* Add more here if needed */
    };
    void app_socket_start(void)
    {
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
    
    	printk("Starting simple AT socket application\n\r");
    
    	if (at_socket_fd < 0) {
    		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
    	}
    	for (int i = 0; i < ARRAY_SIZE(at_commands); i++) {
    		int bytes_written = send(at_socket_fd, at_commands[i],
    					 strlen(at_commands[i]), 0);
    		if (bytes_written > 0) {
    			int r_bytes =
    				blocking_recv(at_socket_fd, recv_buf,
    					      sizeof(recv_buf), MSG_DONTWAIT);
    			if (r_bytes > 0) {
    				printk("%s", recv_buf);
    			}
    		}
    	}
    	printk("Closing socket\n\r");
    
    	(void)close(at_socket_fd);
    }
    
    
    
    
    
    void app_http_start(void)
    {
    	struct sockaddr_in local_addr;
    	struct addrinfo *res;
    
    	local_addr.sin_family = AF_INET;
    	local_addr.sin_port = htons(0);
    	local_addr.sin_addr.s_addr = 0;
    
    	printk("HTTP example\n\r");
    
    	int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);
    
    	printk("getaddrinfo err: %d\n\r", err);
    	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);
    
    	char send_buf[] =
    		//"GET / HTTP/1.1\r\nHost: www.google.com:80\r\nConnection: close\r\n\r\n";
                    "POST / HTTP/1.0\r\nHost: laposte.insgroup.fr\r\nContent-Type: application/json\r\nContent-Length: 41\r\n\r\n\{\"payload\": \"trame NBIOT de nrf9160 v01\"\}\x1A";
    	int send_data_len = strlen(send_buf);
    
    	int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    
    	printk("client_fd: %d\n\r", client_fd);
    	err = bind(client_fd, (struct sockaddr *)&local_addr,
    		   sizeof(local_addr));
    	printk("bind err: %d\n\r", err);
    	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
    			       sizeof(struct sockaddr_in));
    	printk("connect err: %d\n\r", err);
    
    	int num_bytes = send(client_fd, send_buf, send_data_len, 0);
    
    	printk("send err: %d\n\r", num_bytes);
    
    	int tot_num_bytes = 0;
    
    	do {
    		/* TODO: make a proper timeout *
    		 * Current solution will just hang 
    		 * until remote side closes connection */
    		num_bytes =
    			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
    		tot_num_bytes += num_bytes;
    
    		if (num_bytes <= 0) {
    			break;
    		}
    		printk("%s", recv_buf);
    	} while (num_bytes > 0);
    
    	printk("\n\rFinished. Closing socket");
    	freeaddrinfo(res);
    	err = close(client_fd);
    }
    
    int main(void)
    {
            app_socket_start();
    	//app_http_start();
    
    }
    


    but same result if CONFIG_LTE_LINK_CONTROL = y present and start at command with CFUN=4
    or CONFIG_LTE_LINK_CONTROL = y non present and start at command with CFUN=1 etc..

    (11:44:51.028) ***** Booting Zephyr OS build v2.0.99-ncs1-rc1-11-g9be97c63368a *****
    (11:44:54.524) Starting simple AT socket application
    (11:44:54.534) <CR>OK<CR>
    (11:44:55.965) OK<CR>
    (11:44:55.965) +CFUN: 4<CR>
    (11:44:55.965) OK<CR>
    (11:44:55.990) OK<CR>
    (11:44:55.990) +CFUN: 1<CR>
    (11:44:56.025) OK<CR>
    (11:44:56.025) +CEREG: 0,0,"61A0","01189806",7<CR>
    (11:44:56.025) OK<CR>
    (11:44:56.025) Closing socket
    (11:44:56.025) <CR>HTTP example
    (11:44:56.025) <CR>getaddrinfo err: 51
    

    Kind regards

  • Hi Max, 

    From what I see, you're not waiting for the network connection. Between each switch of  LTE-M and NB-IoT, you need to verify the connection. In NCS this is handled in nrf\lib\lte_link_control\lte_lc.c, more specific the w_lte_lc_connect(). Have a look at the do{}while loop. 

    Kind regards,
    Øyvind

  • Hello,

    Thank's for your answer.

    I solved this problem with this function:

    /****************************************************************************************************
    *name: 
    *to do:  Repete AT+CEREG jusqu'à avoir du reseau
    *return: 
    ****************************************************************************************************/
    void Wait_connection(void) {
      char recv_buf1[50];
      char *bufatest;
      int event = 0;
    
      const char *at_commandsOFF[] =
          {
              "AT+CEREG?", /* Retour d'état de connexion( PSM activé, Connecté au reseau etc...) */
          };
      int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
      if (at_socket_fd < 0) {
        printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
      }
    
      /* On attend que le modem se connect a la station de base */
      while (event != 8) {
        switch (event) {
    
        case 0: {
    
          for (int i = 0; i < ARRAY_SIZE(at_commandsOFF); i++) {
            int bytes_written = send(at_socket_fd, at_commandsOFF[i],
                strlen(at_commandsOFF[i]), 0);
            if (bytes_written > 0) {
              int r_bytes =
                  blocking_recv(at_socket_fd, recv_buf1,
                      sizeof(recv_buf1), MSG_DONTWAIT);
              if (r_bytes > 0) {
                printk("%s", recv_buf1);
              }
            }
          }
          event = 1;
        }
    
        case 1: {
          bufatest = strstr(recv_buf1, "+CEREG: 0,1,");
          if (bufatest != NULL) {
            event = 8;
          } else {
            printk("wait");
            k_sleep(K_MSEC(1000));
            event = 0;
          }
        }
        }
      }
      (void)close(at_socket_fd);
    }

    I think to use "w_lte_lc_connect" is better but do you have some example for this ? Because i can't replace and use my function with your function like that..

    Thank's for your help

    Max

  • Hi Max,

    w_lte_lc_connect() is called within lte_lc_init_and_connect(). This is used by several of our samples, e.g. https_client

    Kind regards,
    Øyvind

Related