Dear ,
I want to use LTE_M of nRF9160 DK to POST to my webserver
Do you have any suggestions?
Thanks,
Regards
hng
Dear ,
I want to use LTE_M of nRF9160 DK to POST to my webserver
Do you have any suggestions?
Thanks,
Regards
hng
Hi,
Please see my response here: https://devzone.nordicsemi.com/f/nordic-q-a/46094/how-to-make-http-post-no-libcurl
Regards,
Vidar
Thank Vidar,
I will try it
Regards,
hng
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
Thanks for sharing the solution here.
DearVidar Berg
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.
Dear Vidar Berg
I had 2s delay between
How long should I add ?
Thanks for fast responds,
Regards,
hng
Dear Vidar Berg
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 Vidar Berg
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 Vidar Berg
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); } }
Hi,
The function returns "Not enough space" after a while. Increasing the delay did not help. Maybe you can try to keep the socket open rather than open and close it for every command.
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........... %s \n", strerror(errno));} k_sleep(8000); } }