Skip to content

Commit 039e271

Browse files
author
Maksymilian Wojczuk
committed
DNS Support
Added dns support for downloading files
1 parent 9cf9192 commit 039e271

File tree

5 files changed

+448
-21
lines changed

5 files changed

+448
-21
lines changed

Inc/communication/binary_download.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#define REQUEST_ERROR -4
1818
#define RECEIVE_ERROR -5
1919
#define USB_ERROR -6
20-
20+
#define ERROR_PARSING_URL -7
21+
#define HOST_UNKNOWN_ERROR -8
2122

2223
int startDownload(target_instance_t *targetP);
2324
#endif

Inc/communication/yuarel.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/**
2+
* Copyright (C) 2016 Jack Engqvist Johansson
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
#ifndef INC_YUAREL_H
23+
#define INC_YUAREL_H
24+
25+
#ifdef __cplusplus
26+
extern "C" {
27+
#endif
28+
29+
/**
30+
* The struct where the parsed values will be stored:
31+
*
32+
* scheme ":" [ "//" ] [ username ":" password "@" ] host [ ":" port ] [ "/" ] [ path ] [ "?" query ]
33+
*
34+
* Note: to make sure that no strings are copied, the first slash "/" in the
35+
* path will be used to null terminate the hostname if no port is supplied.
36+
*/
37+
struct yuarel {
38+
char *scheme; /* scheme, without ":" and "//" */
39+
char *username; /* username, default: NULL */
40+
char *password; /* password, default: NULL */
41+
char *host; /* hostname or IP address */
42+
int port; /* port, default: 0 */
43+
char *path; /* path, without leading "/", default: NULL */
44+
char *query; /* query, default: NULL */
45+
char *fragment; /* fragment, default: NULL */
46+
};
47+
48+
/* A struct to hold the query string parameter values. */
49+
struct yuarel_param {
50+
char *key;
51+
char *val;
52+
};
53+
54+
/**
55+
* Parse a URL to a struct.
56+
*
57+
* The URL string should be in one of the following formats:
58+
*
59+
* Absolute URL:
60+
* scheme ":" [ "//" ] [ username ":" password "@" ] host [ ":" port ] [ "/" ] [ path ] [ "?" query ] [ "#" fragment ]
61+
*
62+
* Relative URL:
63+
* path [ "?" query ] [ "#" fragment ]
64+
*
65+
* The following parts will be parsed to the corresponding struct member.
66+
*
67+
* *url: a pointer to the struct where to store the parsed values.
68+
* *url_str: a pointer to the url to be parsed (null terminated). The string
69+
* will be modified.
70+
*
71+
* Returns 0 on success, otherwise -1.
72+
*/
73+
extern int yuarel_parse(struct yuarel *url, char *url_str);
74+
75+
/**
76+
* Split a path into several strings.
77+
*
78+
* No data is copied, the slashed are used as null terminators and then
79+
* pointers to each path part will be stored in **parts. Double slashes will be
80+
* treated as one.
81+
*
82+
* *path: the path to split. The string will be modified.
83+
* **parts: a pointer to an array of (char *) where to store the result.
84+
* max_parts: max number of parts to parse.
85+
*
86+
* Returns the number of parsed items. -1 on error.
87+
*/
88+
extern int yuarel_split_path(char *path, char **parts, int max_parts);
89+
90+
/**
91+
* Parse a query string into a key/value struct.
92+
*
93+
* The query string should be a null terminated string of parameters separated by
94+
* a delimiter. Each parameter are checked for the equal sign character. If it
95+
* appears in the parameter, it will be used as a null terminator and the part
96+
* that comes after it will be the value of the parameter.
97+
*
98+
* No data are copied, the equal sign and delimiters are used as null
99+
* terminators and then pointers to each parameter key and value will be stored
100+
* in the yuarel_param struct.
101+
*
102+
* *query: the query string to parse. The string will be modified.
103+
* delimiter: the character that separates the key/value pairs from eachother.
104+
* *params: an array of (struct yuarel_param) where to store the result.
105+
* max_values: max number of parameters to parse.
106+
*
107+
* Returns the number of parsed items. -1 on error.
108+
*/
109+
extern int yuarel_parse_query(char *query, char delimiter, struct yuarel_param *params, int max_params);
110+
111+
#ifdef __cplusplus
112+
}
113+
#endif
114+
115+
#endif /* INC_YUAREL_H */

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ Src/stm32f4xx_hal_msp.c \
162162
Src/communication/dbgu.c \
163163
Src/communication/term_io.c \
164164
Src/communication/binary_download.c \
165-
Src/communication/wakaama_client/wakaama.c
165+
Src/communication/wakaama_client/wakaama.c \
166+
Src/communication/yuarel.c
166167

167168
# ASM sources
168169
ASM_SOURCES = \

Src/communication/binary_download.c

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,59 @@
33
#include "communication_config.h"
44
#include "binary_download.h"
55
#include "errno.h"
6+
#include "yuarel.h"
7+
#include "FreeRTOS.h"
68

79

8-
static void download_error(target_instance_t *targetP, int err, int socket) {
10+
11+
static void download_error(target_instance_t *targetP, int err, int socket, char *url_str) {
912
targetP->download_state = DOWNLOAD_ERROR;
1013
targetP->download_error = err;
11-
if(err != SOCKET_ERROR){
14+
if(err != SOCKET_ERROR && err != ERROR_PARSING_URL){
1215
lwip_close(socket);
1316
}
17+
lwm2m_free(url_str);
1418
vTaskDelete(NULL);
1519
}
1620

1721
int startDownload(target_instance_t *targetP) {
18-
22+
struct yuarel url;
23+
char *url_str = lwm2m_strdup(targetP->firmware_url);
24+
if(yuarel_parse(&url, url_str) != 0) {
25+
printf("Error parsing URL\r\n");
26+
download_error(targetP, ERROR_PARSING_URL, 0, url_str);
27+
}
1928
int socket;
2029
socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
2130
if (socket < 0 ) {
2231
printf("cannot create socket: %d\r\n", errno);
23-
download_error(targetP, SOCKET_ERROR, socket);
32+
download_error(targetP, SOCKET_ERROR, socket, url_str);
33+
}
34+
35+
ip_addr_t *addr = NULL;
36+
if (netconn_gethostbyname(url.host, &addr) != ERR_OK) {
37+
printf("cannot resolve hostname\r\n");
38+
download_error(targetP, HOST_UNKNOWN_ERROR, socket, url_str);
2439
}
2540

26-
struct sockaddr_in clientAddress;
27-
clientAddress.sin_family = AF_INET;
28-
clientAddress.sin_port = htons(80);
29-
clientAddress.sin_addr.s_addr = inet_addr(SERVER_IP);
41+
struct sockaddr_in clientAddressv4;
42+
clientAddressv4.sin_family = AF_INET;
43+
clientAddressv4.sin_port = htons(80);
44+
clientAddressv4.sin_addr.s_addr = addr;
3045

31-
int result = lwip_connect(socket, (struct sockaddr *) &clientAddress, sizeof (clientAddress));
46+
int result = lwip_connect(socket, (struct sockaddr *) &clientAddressv4, sizeof (struct sockaddr_in));
3247
if (result < 0) {
3348
printf("cannot connect to server, err: %d\r\n", result);
3449
lwip_close(socket);
35-
download_error(targetP,CONNECTION_ERROR, socket);
50+
download_error(targetP,CONNECTION_ERROR, socket, url_str);
3651
}
3752

3853
char message[200];
39-
sprintf(message, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n Connection: keep-alive\r\n\r\n Keep-Alive: 300\r\n", targetP->firmware_url, SERVER_IP);
54+
sprintf(message, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n Connection: keep-alive\r\n\r\n Keep-Alive: 300\r\n", url.path, url.host);
4055

4156
if( lwip_send(socket , message , strlen(message) , 0) < 0) {
4257
printf("Send failed\r\n");
43-
download_error(targetP,REQUEST_ERROR, socket);
58+
download_error(targetP,REQUEST_ERROR, socket, url_str);
4459
}
4560

4661
int server_response_length = 300;
@@ -52,7 +67,7 @@ int startDownload(target_instance_t *targetP) {
5267
int received_len = lwip_recv(socket, server_reply , sizeof server_reply - 1, 0);
5368
if( received_len < 0 ){
5469
printf("recv failed\r\n");
55-
download_error(targetP,RECEIVE_ERROR, socket);
70+
download_error(targetP,RECEIVE_ERROR, socket, url_str);
5671
}
5772

5873
if(!lwm2m_strncmp(server_reply, "HTTP/1.1 200 OK", 15) == 0){
@@ -61,10 +76,10 @@ int startDownload(target_instance_t *targetP) {
6176
asd = server_reply + 9;
6277
if(xatoi(&asd, &response_code) != 1) {
6378
printf("Error reading Server response code\r\n");
64-
download_error(targetP,UNKNOWN_ERROR, socket);
79+
download_error(targetP,UNKNOWN_ERROR, socket, url_str);
6580
}
66-
printf("Server Response status:%d\r\n", response_code);
67-
download_error(targetP, response_code, socket);
81+
printf("Server Response status:%ld\r\n", response_code);
82+
download_error(targetP, response_code, socket, url_str);
6883
}
6984
printf("Server responded with 200!\r\n");
7085
for(int i = 15 ; i < received_len ; i++) {
@@ -73,7 +88,7 @@ int startDownload(target_instance_t *targetP) {
7388
asd = server_reply + i + 15;
7489
if (xatoi(&asd, &payload_len) != 1) {
7590
printf("Error reading Content-Length\r\n");
76-
download_error(targetP, UNKNOWN_ERROR, socket);
91+
download_error(targetP, UNKNOWN_ERROR, socket, url_str);
7792
}
7893
break;
7994
}
@@ -84,7 +99,7 @@ int startDownload(target_instance_t *targetP) {
8499

85100
if( received_len < 0 ){
86101
printf("recv failed\r\n");
87-
download_error(targetP, RECEIVE_ERROR, socket);
102+
download_error(targetP, RECEIVE_ERROR, socket, url_str);
88103
}
89104

90105

@@ -96,7 +111,7 @@ int startDownload(target_instance_t *targetP) {
96111
if(get_usb_ready()) {
97112
usb_write(server_reply, targetP->binary_filename, received_len);
98113
} else {
99-
download_error(targetP, USB_ERROR, socket);
114+
download_error(targetP, USB_ERROR, socket, url_str);
100115
}
101116

102117
if( total_received_len >= payload_len ){
@@ -108,6 +123,7 @@ int startDownload(target_instance_t *targetP) {
108123
targetP->download_progress = 100;
109124
targetP->download_error = NO_ERROR;
110125
lwip_close(socket);
126+
lwm2m_free(url_str);
111127
vTaskDelete();
112128

113129
}

0 commit comments

Comments
 (0)