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

nRF9160 DK HTTP POST to my Webserver

Dear , 

I want to use LTE_M of nRF9160 DK to POST to my webserver

Do you have any suggestions?

Thanks, 

Regards

hng

Parents
  • It works, just fixed a little bit: 

    /******************************************"**************************************/
    #define MAXLINE 4096
    #define HTTP_HOST "142.xx.xx.192"  //my webserver
    #define HTTP_PORT 80
    #define HTTP_PATH "/"
    #define TEST_STRING  "Hello from nRF9160 DK"
    
    #define POST_TEMPLATE "POST %s? HTTP/1.1\r\n"\
    		"Host: %s\r\n"\
    		"Connection: keep-alive\r\n"\
    	        "Content-type: application/x-www-form-urlencoded\r\n"\
    		"Content-length: %d\r\n\r\n"\
    		"%s"
    /************************************************************************/
    void app_http_post()
    {  
    	//int err; 
        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;
    
    	      
    	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[MAXLINE + 1];
    	
    	int send_data_len_post = snprintf(send_buf,
    				         500, /*total length should not exceed MTU size*/
    				         POST_TEMPLATE, HTTP_PATH,
    				         HTTP_HOST, strlen(TEST_STRING),
    				         TEST_STRING);
    
    	printk("send err: %d\n\r", send_data_len_post);
    
    
    	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);
            // connect
    	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
    			       sizeof(struct sockaddr_in));
    	printk("connect err: %d\n\r", err);
           //send
        blocking_send(client_fd, send_buf, send_data_len_post, 0);
        k_sleep(1000);
           
    	printk("\n\r HTTP POST Finished. \n\r");
    	close(client_fd);
    
    }

    Thanks so much

    Regards, 

    hng

  • Dear

    I tried to run this http post in a loop

    first, i will check the LTE_M signal "AT+CEREG?"

    It returns:  

    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    +CEREG: 0,5,"765D","0110C303",7
    
    OK
    
    Found the LTE_M signal 
    Closing socket
    
      find LTE_M signal........... 
    Checking LTE_M signal.............
    
    Closing socket
    
     Couldnt find LTE_M signal........... 
    Checking LTE_M signal.............
    
    Closing socket
    
     Couldnt find LTE_M signal........... 
    Checking LTE_M signal.............
    

    After 7times, "AT+CEREG?" return NOTHING!

    Why is the problem, the buffer is full? or something wrong in my code? 

    Plz help me. 

    Thanks so much 

    Regards, 

    hng

  • I believe a bug in the BSD library causes this. I get the "no memory" error when call socket send in a loop without any delay in-between. I have reported this internally. A workaround, for now, is to add a delay between each post request. 

Reply Children
  • Dear

    I had 2s delay between

    How long should I add ?

    Thanks for fast responds, 

    Regards, 

    hng

  • A 2-second delay should be sufficient. Can you try to increase the stack sizes in your project *.conf file?

    e.g.,

    CONFIG_MAIN_STACK_SIZE= 8192

    CONFIG_HEAP_MEM_POOL_SIZE=8192

  • Dear

    I tried, the same thing happened  

    int nRF_LTE_check(void)
    {
        int err;
        const char *ATREG="AT+CEREG?"; 
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
        printk("Checking LTE_M signal.............\n\r");
    
    	if (at_socket_fd < 0) {
    		err = 1; 
    	}
        else {
        int bytes_written = send(at_socket_fd, ATREG, strlen(ATREG), 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);
        if (recv_buf== LTEfound) 
           {
          err = 0; 
          printk("Found LTE_M signal \n");
            }
        else {
           printk("Couldnt find the LTE_M signal \n");
           err =1;
            }
     }
      }
              }
    	printk("Closing socket\n\r");
        (void)close(at_socket_fd);
        return err; 
    }

    my loop: 

    #include <zephyr.h>
    #include <net/socket.h>
    #include <misc/printk.h>
    #include <zephyr/types.h>
    #include <math.h>
    #include <uart.h>
    #include <soc.h>
    #include <gpio.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>     /* atof */
    #include <autoconf.h>
    
    void main (void)
    {
      printk("Test is starting \n"); 
    
       
        
        while(1){
    
       
          int lte_err= nRF_LTE_check();
          if(lte_err==0){ printk("  find LTE_M signal........... \n"); }
          else{ printk(" Couldnt find LTE_M signal........... \n");}
          k_sleep(2000);
       
        }
       
    }

    and my prj.conf

    CONFIG_SERIAL=y
    CONFIG_TRUSTED_EXECUTION_NONSECURE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_UART_1_NRF_UARTE=y
    CONFIG_UART_2_NRF_UARTE=y
    
    CONFIG_GPIO=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_BSD_LIBRARY=y
    
    
    CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_TEST_RANDOM_GENERATOR=y
    
    CONFIG_LOG=n
    CONFIG_LOG_DEFAULT_LEVEL=4
    #CONFIG_HEAP_MEM_POOL_SIZE=1024
    CONFIG_MAIN_STACK_SIZE= 8192
    CONFIG_HEAP_MEM_POOL_SIZE=8192
    
    
    # LTE link control
    #CONFIG_LTE_LINK_CONTROL=y
    CONFIG_UART_2_NRF_TX_BUFFER_SIZE=1024

  • Can you upload your entire project directory here so I can try to debug it? Some of the variable definitions are missing from the code snippets above. 

  • Dear

    Sorry for snippers, it missed the LTEfound

    #include <zephyr.h>
    #include <net/socket.h>
    #include <misc/printk.h>
    #include <zephyr/types.h>
    #include <math.h>
    #include <soc.h>
    #include <gpio.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>     /* atof */
    
    #include <autoconf.h>
    
    
    
    #define AT_MAX_CMD_LEN 4096
    #define INVALID_DESCRIPTOR -1
    
    #define UART_RX_BUF_SIZE 4096 
    
    #define CMD_STATE 0
    #define RESPOND_STATE 1
    
    #define UART_BUF_SIZE           1024
    #define RECV_BUF_SIZE 1024
    
    char recv_buf[RECV_BUF_SIZE + 1];
    
    const char *at_commands[] = {
    	"AT+CGMM", "AT+CGDCONT?", "AT%XCBAND=?", "AT+CGSN=1",
    	"AT+CESQ",
    	// Add more here if needed 
    };
    
    /****************************************************************************************************
    *name: 
    *to do:  SPLIT the String with pattern()
    *return: 
    ****************************************************************************************************/
    void stringsplit(char *str)
    {
    	//char str[] = "strtok needs to be called several times to split a string";
    	int init_size = strlen(str);
    	char delim[] = " ";
    
    	char *ptr = strtok(str, delim);
    
    	while(ptr != NULL)
    	{
    		printf("'%s'\n", ptr);
    		ptr = strtok(NULL, delim);
    	}
    
    	/* This loop will show that there are zeroes in the str after tokenizing */
    	for (int i = 0; i < init_size; i++)
    	{
    		printf("%d ", str[i]); /* Convert the character to integer, in this case
    							   the character's ASCII equivalent */
    	}
    	printf("\n");
    
    	return 0;
    }
    /****************************************************************************************************
    *name: 
    *to do:  SPLIT the String with pattern()
    *return: 
    ****************************************************************************************************/
    void split_string_ltepos(char *str, char splitStrings[10][10])
    {
       // char str[100];
         //can store 10 words of 10 characters
        int i,j,cnt;
        j=0; cnt=0;
        for(i=0;i<=(strlen(str));i++)
        {
            // if space or NULL found, assign NULL into splitStrings[cnt]
            if(str[i]=='"'||str[i]=='\0')
            {
                splitStrings[cnt][j]='\0';
                cnt++;  //for next word
                j=0;    //for next word, init index to 0
            }
            else
            {
                splitStrings[cnt][j]=str[i];
                j++;
            }
        }
        printk("\nOriginal String is: %s",str);
        /*
        printk("\nStrings (words) after split by space:\n");
        for(i=0;i < cnt;i++)
            printk("%s\n",splitStrings[i]);
        */
       // return splitStrings;
    }
    
    /****************************************************************************************************
    *name:  blocking_recv()
    *to do: receive data 
    *return: 
    ****************************************************************************************************/
    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;
    }
    /****************************************************************************************************
    *name:  blocking_send
    *todo:  send data 
    *return: 
    ****************************************************************************************************/
    
    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;
    }
    
    /****************************************************************************************************
    *name:  blocking_connect
    *todo:  connect block()
    *return: 
    ****************************************************************************************************/
    
    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;
    }
    
    /****************************************************************************************************
    *name:  nRF_LTE_check
    *todo:  check nRF LTE connect
    *return: return at_commands[]
    ****************************************************************************************************/
    int nRF_LTE_check(void)
    {
            int err;
            const char *ATREG="AT+CEREG?"; 
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
            //printk("LTE socket is: %d \n",at_socket_fd); 
    
    	printk("Checking LTE_M signal.............\n\r");
    
    	if (at_socket_fd < 0) {
    		err = 1; 
    	}
            else {
                err = 0;
                int bytes_written2 = send(at_socket_fd, ATREG, strlen(ATREG), 0);
                k_sleep(5000);
                if (bytes_written2 > 0) {
    		int r_bytes2 = blocking_recv(at_socket_fd, recv_buf,sizeof(recv_buf), MSG_DONTWAIT);
    		if (r_bytes2 > 0) {
    				printk("%s", recv_buf);
                                    char splitStringstac[10][10]; 
                                    split_string_ltepos(recv_buf,splitStringstac); 
                                    if (splitStringstac[0] == 0) 
                                      {
                                        err = 1; 
                                        printk("Cant find LTE_M signal \n");
                                      }
                                     else {
                                        printk("Found the LTE_M signal \n");
                                        err =0;
                                     }
    
    	                       }
                              }
              }
    	printk("Closing socket\n\r");
    	//(void)close(at_socket_fd);
            return err; 
    }
    /****************************************************************************************************
    *name:  app_socket_start
    *todo:  send the const char *at_commands[]
    *return: return at_commands[]
    ****************************************************************************************************/
    void app_socket_start(void)
    {
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
            printk("LTE socket is: %d \n",at_socket_fd); 
    
    	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);
    }
    
    /****************************************************************************************************
    *name:  LTE_socket_com
    *todo:  send AT command
    * use:   LTE_socket_com("AT"); 
             LTE_socket_com("AT+CPIN?"); 
    *return: 
    ****************************************************************************************************/
    void LTE_socket_com(const char *lte_at_cmd )
    {
    	int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
            printk("LTE socket is: %d \n",at_socket_fd); 
    
    	//printk("Starting simple AT socket application\n\r");
            printk("AT cmd: %s \n\r",lte_at_cmd);
    
    	if (at_socket_fd < 0) {
    		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
    	}
    	//for (int i = 0; i < ARRAY_SIZE(lte_at_cmd); i++) {
            
    	int bytes_written = send(at_socket_fd, lte_at_cmd, strlen(lte_at_cmd), 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);
    }
    
    
    /****************************************************************************************************
    *name:  LTE_AT_position
    *todo:  find GMS position
    *return: MCCMNC / LAC / CID
      * MCC � a Mobile Country Code
      * MNC - a Mobile Network Code
      * LAC - Location Area Code
      * CID : CellID 
    ****************************************************************************************************/
    void LTE_AT_position(char *mccmnc,char *lac, char *cid )
     {
    	const char *ATCOPS="AT+COPS?"; 
            const char *ATREG2="AT+CEREG=2"; 
            const char *ATREG="AT+CEREG?"; 
            
            int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
           // printk("LTE socket is: %d \n",at_socket_fd); 
    	
    	if (at_socket_fd < 0) {
    		printk("Socket err: %d, errno: %d\r\n", at_socket_fd, errno);
    	}
    	/*
            * find MNC and MCC
            */
            int bytes_written0 = send(at_socket_fd, ATCOPS, strlen(ATCOPS), 0);
    	if (bytes_written0 > 0) {
    			int r_bytes =
    				blocking_recv(at_socket_fd, recv_buf,
    					      sizeof(recv_buf), MSG_DONTWAIT);
    			if (r_bytes > 0) {
    				//printk("%s", recv_buf);
                                    char splitStringsmcc[10][10]; 
                                     split_string_ltepos(recv_buf,splitStringsmcc);
                                     memcpy(mccmnc,splitStringsmcc[1],sizeof(splitStringsmcc[1]));
                                    
                                     // printk("MCC&MNC: %s\n",mccmnc);
    			              }
    		
    	}
            int bytes_written1 = send(at_socket_fd, ATREG2, strlen(ATREG2), 0);
            if (bytes_written1 > 0) {
    		blocking_recv(at_socket_fd, recv_buf,sizeof(recv_buf), MSG_DONTWAIT);
    			
    	}
            /*************************************
            * find LAC and CID 
            ***************************************/
            int bytes_written2 = send(at_socket_fd, ATREG, strlen(ATREG), 0);
            if (bytes_written2 > 0) {
    		int r_bytes2 = blocking_recv(at_socket_fd, recv_buf,sizeof(recv_buf), MSG_DONTWAIT);
    		if (r_bytes2 > 0) {
    				printk("%s", recv_buf);
                                    char splitStringstac[10][10]; 
                                    split_string_ltepos(recv_buf,splitStringstac); 
                                    memcpy(lac,splitStringstac[1],sizeof(splitStringstac[1]));
                                    memcpy(cid,splitStringstac[3],sizeof(splitStringstac[3]));
    
    	                       }
                              }
    	//printk("Closing socket\n\r");
    	(void)close(at_socket_fd);
    }
    
    /******************************************"**************************************/
    #define MAXLINE 4096
    #define HTTP_HOST "142.93.37.192"
    #define HTTP_PORT 7000
    #define HTTP_PATH "/"
    #define TEST_STRING  "Hello from nRF9160 DK"
    
    #define POST_TEMPLATE "POST %s? HTTP/1.1\r\n"\
    		"Host: %s\r\n"\
    		"Connection: keep-alive\r\n"\
    	        "Content-type: application/x-www-form-urlencoded\r\n"\
    		"Content-length: %d\r\n\r\n"\
    		"%s"
    /****************************************************************************************************
    *name:  app_http_get:
    *todo:    HTTP GET from webserver: http://142.93.37.192
    *return: return from HTTP GET
    *use:     app_http_get(); 
    ****************************************************************************************************/
    void app_http_get(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 GET  http://142.93.37.192  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: http://142.93.37.192:80\r\nConnection: close\r\n\r\n";
    	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);
    
    	
    	num_bytes = blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
    		
    	printk("%s", recv_buf);
    	
    	//printk("\n\rFinished. Closing socket");
    	//err = close(client_fd);
    }
    
    
    /****************************************************************************************************
    *name:  app_http_post_bk
    *todo:  HTTP POST PostString[] to webserver http://142.93.37.192
    *return: 
    * use:
    ****************************************************************************************************/
    
    void app_http_post(char *PostString)
    {  
    	//int err; 
            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;
    
    	    
    	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[MAXLINE + 1];
    	
    	int send_data_len_post = snprintf(send_buf,
    				         500, /*total length should not exceed MTU size*/
    				         POST_TEMPLATE, HTTP_PATH,
    				         HTTP_HOST, strlen(PostString),
    				         PostString);
    
    	printk("send err: %d\n\r", send_data_len_post);
    
    
    	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);
            // connect
    	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
    			       sizeof(struct sockaddr_in));
    	printk("connect err: %d\n\r", err);
           //send
            blocking_send(client_fd, send_buf, send_data_len_post, 0);
            k_sleep(1000);
           
    	printk("\n\r HTTP POST Finished. \n\r");
    	close(client_fd);
    
           
    }
    
    
    
    /****************************************************************************************************
    *name:  nRF_LTE_check
    *todo:  check nRF LTE connect
    *return: return at_commands[]
    ****************************************************************************************************/
    int nRF_LTE_CLOSE(void)
    {
            int err;
            int at_socket_fd = socket(AF_LTE, 0, NPROTO_AT);
            
            err = close(at_socket_fd);
            printk("Close the socket LTE_M \n");
    	return err; 
    }
    #include <zephyr.h>
    #include <net/socket.h>
    #include <misc/printk.h>
    #include <zephyr/types.h>
    #include <math.h>
    #include <uart.h>
    #include <soc.h>
    #include <gpio.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>     
    #include <autoconf.h>
    
    
    #include "lte_post_get.c"
    
    
    
    /********************************************/
    void main (void)
    {
      printk("Test is starting \n"); 
    
       
        
        while(1){
    
        //CyCo_Hot_GSM_Handle();
          int lte_err= nRF_LTE_check();
          if(lte_err==0){ printk("  find LTE_M signal........... \n"); }
          else{ printk(" Couldnt find LTE_M signal........... \n");}
          k_sleep(2000);
       
        }
       
    }
    

Related