2025-07-09 5:10 PM - edited 2025-07-09 5:19 PM
I am using NucleoH563ZI board with threadx and netxduo.
I have the following code, it makes http requests.
The first completes ok, but the other 2 has a problem where the dns returns with 0xA3, basically can't resolve the host url.
With wireshark i noticed that the url somehow contains one additional character: "firestore.googleapis.comD" and with the second case: "firestore.googleapis.comH"
calloc (or malloc, does not matter which i am using) returns a valid and good pointer then strcpy copies the url string.
In debug I can see that the url is copied succesfully. But after the next calloc suddenly an excess character appears at the end of the string, thus the dns fails to resolve.
It does not matter what I put between the strcpy and the calloc, it always fails the same way.
if I compile the program with only a single request, then it sometimes works.
Any idea what is going on?
//get public IP
char* public_ip_str = calloc(30, 1);
if(public_ip_str == NULL)
{ Error_Handler();}
{
//init
HTTP_RSC_STRUCT input_data;
input_data.server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
input_data.hostURL = calloc(strlen("ipv4.icanhazip.com"), 1);
if(input_data.hostURL == NULL) { Error_Handler();}
strcpy(input_data.hostURL, "ipv4.icanhazip.com");
input_data.resource = calloc(strlen(" "), 1);
if(input_data.resource == NULL) { Error_Handler();}
strcpy(input_data.resource, " ");
input_data.method = NX_WEB_HTTP_METHOD_GET;
//get
status = Http_request(&input_data);
if(status != NX_SUCCESS) { printf("icanhazip.com request not successful, status:%i\n\r", status);}
//process
if(input_data.return_data_p != NULL)
{
printf("__public ip:%s\n\r", input_data.return_data_p);
ipstr_cleanup(public_ip_str, input_data.return_data_p);
printf("clean pub ip:%s\n\r", public_ip_str);
PublicIpAddress = StrIp2Ulong(public_ip_str);
printf("pub ip:%li\n\r", PublicIpAddress);
}
//cleanup
free(input_data.hostURL);
input_data.hostURL = NULL;
free(input_data.resource);
input_data.resource = NULL;
if(input_data.return_data_p != NULL)
{
free(input_data.return_data_p);
input_data.return_data_p = NULL;
}
}
//get stored IP from firebase
{
//init
HTTP_RSC_STRUCT input_data;
input_data.server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
input_data.hostURL = calloc(strlen("firestore.googleapis.com"), 1);
if(input_data.hostURL == NULL) { Error_Handler();}
strcpy(input_data.hostURL, "firestore.googleapis.com");
input_data.resource = calloc(strlen("/v1/projects/testprj-b61e8/databases/(default)/documents/asd"), 1);
if(input_data.resource == NULL) { Error_Handler();}
strcpy(input_data.resource, "/v1/projects/testprj-b61e8/databases/(default)/documents/asd");
input_data.method = NX_WEB_HTTP_METHOD_GET;
//get
status = Http_request(&input_data);
if(status != NX_SUCCESS)
{
printf("firebase get request not successful, status:%i\n\r", status);
}
//process
if(input_data.return_data_p != NULL)
{
printf("__firestore response:%s\n\r", input_data.return_data_p);
//cut out the ip string from the response
char* ip_part_location = strstr(input_data.return_data_p, "stringValue");
if( (ip_part_location != NULL) && (ip_part_location != input_data.return_data_p) )
{
char* stored_ip_str = calloc(30, 1);
char* tmps = calloc(30, 1);
if(stored_ip_str == NULL) { Error_Handler();}
if(tmps == NULL) { Error_Handler();}
printf("location:%s\n\r", ip_part_location);
strncpy(tmps, ip_part_location+15, 16);
printf("substring:%s\n\r", tmps);
ipstr_cleanup(stored_ip_str, tmps);
printf("clean string:%s\n\r", stored_ip_str);
StoredIpAddress = StrIp2Ulong(stored_ip_str);
printf("converted ip:%li\n\r", StoredIpAddress);
free(stored_ip_str);
stored_ip_str = NULL;
free(tmps);
tmps = NULL;
}
else
{
printf("cannot find ip in response\n\r");
StoredIpAddress = 0;
}
}
else
{
StoredIpAddress = 0;
}
//cleanup
free(input_data.hostURL);
input_data.hostURL = NULL;
free(input_data.resource);
input_data.resource = NULL;
if(input_data.return_data_p != NULL)
{
free(input_data.return_data_p);
input_data.return_data_p = NULL;
}
}
//compare public ip and stored ip and if they don't match, call a patch req to firebase
if(StoredIpAddress != IpAddress) && (StoredIpAddress != 0) )
{
//init
HTTP_RSC_STRUCT input_data;
input_data.server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
input_data.hostURL = calloc(strlen("firestore.googleapis.com"), 1);
if(input_data.hostURL == NULL) { Error_Handler();}
strcpy(input_data.hostURL, "firestore.googleapis.com");
input_data.resource = calloc(strlen("/v1/projects/testprj-b61e8/databases/(default)/documents/asd/qwe"), 1);
if(input_data.resource == NULL) { Error_Handler();}
strcpy(input_data.resource, "/v1/projects/testprj-b61e8/databases/(default)/documents/asd/qwe");
//"{\"fields\": {\"slip\": {\"stringValue\": \"000.000.000.000\"}}}"
ULONG part1 = strlen("{\"fields\": {\"tmp\": {\"stringValue\": \"");
ULONG part2 = strlen(public_ip_str);
ULONG part3 = strlen("\"}}}");
input_data.resource_content = calloc(part1+part2+part3, 1);
if(input_data.resource_content == NULL) { Error_Handler();}
strcpy(input_data.resource_content, "{\"fields\": {\"tmp\": {\"stringValue\": \"");
strcpy(input_data.resource_content+part1, public_ip_str);
strcpy(input_data.resource_content+part1+part2, "\"}}}");
input_data.method = NX_WEB_HTTP_METHOD_PATCH;
printf("patch content:%s\n\r", input_data.resource_content);
//patch
status = Http_request(&input_data);
if(status != NX_SUCCESS) { printf("firebase patch request not successful, status:%i\n\r", status);}
else{ printf("patch status:%i\n\r", status);}
//process
//no response expected from patch request
//cleanup
free(input_data.hostURL);
input_data.hostURL = NULL;
free(input_data.resource);
input_data.resource = NULL;
free(input_data.resource_content);
input_data.resource_content = NULL;
if(input_data.return_data_p != NULL)
{
free(input_data.return_data_p);
input_data.return_data_p = NULL;
}
}
free(public_ip_str);
Solved! Go to Solution.
2025-07-09 6:53 PM
Perhaps use a subroutine, so you don't duplicate a lot of code, and make less errors.
char *strcalloc(char *str, size_t x)
{
char *s = calloc(strlen(str)+1, x);
if (s) strcpy(s, str);
return(s);
}
...
input_data.hostURL = strcalloc("ipv4.icanhazip.com", 1);
if(input_data.hostURL == NULL) { Error_Handler();}
2025-07-09 5:28 PM
Don't forget to allocate enough space to hold the NUL character at the end of the string, "hello" takes 6 bytes, not 5
Check the heap size, and the allocator function. Perhaps build something to walk the heap's linked list in your implementation.
2025-07-09 6:12 PM
You are right, strlen does not counts the termitaing 0.
2025-07-09 6:53 PM
Perhaps use a subroutine, so you don't duplicate a lot of code, and make less errors.
char *strcalloc(char *str, size_t x)
{
char *s = calloc(strlen(str)+1, x);
if (s) strcpy(s, str);
return(s);
}
...
input_data.hostURL = strcalloc("ipv4.icanhazip.com", 1);
if(input_data.hostURL == NULL) { Error_Handler();}