Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding HTTP post functionality #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,31 @@ CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y

# Network driver config
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_INIT_STACKS=y

# network configuration
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_TCP=y
CONFIG_NET_ARP=y
CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SHELL=y
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y

# Sockets
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_POLL_MAX=4

# HTTP
CONFIG_HTTP_CLIENT=y

# logging
CONFIG_LOG=y
CONFIG_NET_LOG=y
8 changes: 8 additions & 0 deletions src/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,11 @@ int set_led_state(uint8_t id, bool state);
int periphs_init(void);
int board_init(void);
void start_sensor_values_work(void);

struct kernel_version {
uint8_t major;
uint8_t minor;
uint8_t patch;
};

struct kernel_version get_kernel_version();
46 changes: 46 additions & 0 deletions src/dhcp_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <zephyr.h>
#include <net/net_if.h>
#include <net/net_core.h>
#include <net/net_context.h>
#include <net/net_mgmt.h>
#include <device.h>

static struct net_mgmt_event_callback mgmt_cb;

static void dhcp_handler(struct net_mgmt_event_callback *cb,
uint32_t mgmt_event,
struct net_if *iface){
int i = 0;
if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) {
printk("not listening to right event\n");
return;
}

for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) {
char buf[NET_IPV4_ADDR_LEN];

if (iface->config.ip.ipv4->unicast[i].addr_type != NET_ADDR_DHCP) {
continue;
}

printk("Assigned address: %s\n",
log_strdup(
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->unicast[i].address.in_addr, buf, sizeof(buf))));

printk("Lease time: %u hours\n", iface->config.dhcpv4.lease_time / 60 / 60);
printk("Subnet: %s\n",
log_strdup(
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->netmask, buf, sizeof(buf))));
printk("Gateway: %s\n",
log_strdup(
net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, buf, sizeof(buf))));
}
}

void initialize_dhcp() {
struct net_if *iface;
net_mgmt_init_event_callback(&mgmt_cb, dhcp_handler, NET_EVENT_IPV4_ADDR_ADD);
net_mgmt_add_event_callback(&mgmt_cb);
iface = net_if_get_default();
net_dhcpv4_start(iface);
}
138 changes: 138 additions & 0 deletions src/http_util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include <stdio.h>
#include <zephyr.h>
#include <string.h>

#include <net/socket.h>
#include <net/net_ip.h>
#include <net/http_client.h>
#include <net/tls_credentials.h>
#include <kernel.h>

#define HTTP_PORT 8000
#define HTTP_PROTOCOL "HTTP/1.2"

#define MAX_RECV_BUF_LEN 512
#define REMOTE_SERVER_ADDRESS "192.168.10.10"

static uint8_t recv_buf_ipv4[MAX_RECV_BUF_LEN];

char *http_headers[] = {
"Content-Length: 30\r\n",
"Content-Type: application/json\r\n",
"Authorization: Token 439c3b239670205ec60a0510cabdab6d220da5c2\r\n",
NULL
};

void error(const char *msg) {
printk("%s\n", msg);
}

static int setup_socket(sa_family_t family, const char *server, int port, int *sock,
struct sockaddr *addr, socklen_t addr_len) {
memset(addr, 0, addr_len);

net_sin(addr)->sin_family = AF_INET;
net_sin(addr)->sin_port = htons(port);
inet_pton(family, server, &net_sin(addr)->sin_addr);
*sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
return 0;
}

static int payload_callback(int sock, struct http_request *req, void *user_data) {
(void)send(sock, user_data, strlen(user_data), 0);
return 0;
}

static void response_callback(struct http_response *resp, enum http_final_call final_data, void *user_data){
if (final_data == HTTP_DATA_MORE) {
printk("partial data recieved (%zd bytes)\n", resp->data_len);
} else if (final_data == HTTP_DATA_FINAL) {
printk("All data has been received (%zd bytes), status: %s\n", resp->data_len, resp->http_status);
}

printk("Response to %s\n", (const char *)user_data);
}

static int connect_socket(sa_family_t family, const char *server, int port, int *sock, struct sockaddr *addr, socklen_t addr_len){
int res;
res = setup_socket(family, server, port, sock, addr, addr_len);
if (res < 0 || *sock < 0) {
printk("unable to setup socket\n");
return -1;
}
res = connect(*sock, addr, addr_len);
if (res < 0) {
printk("can not connect to IPv4 remote (%d)\n", -errno);
res = -errno;
}
return res;
}

int ping_http_server() {
struct sockaddr_in addr4;
int sock4 = -1;
int32_t timeout = 3 * MSEC_PER_SEC;
int ret;
int port = HTTP_PORT;

connect_socket(AF_INET, REMOTE_SERVER_ADDRESS, port, &sock4, (struct sockaddr *)&addr4, sizeof(addr4));

if(sock4 < 0) {
printk("cannot create HTTP connection\n");
return -1;
}

struct http_request req;
memset(&req, 0, sizeof(req));

req.method = HTTP_GET;
req.url = "/ping/";
req.host = REMOTE_SERVER_ADDRESS;
req.protocol = HTTP_PROTOCOL;
req.response = response_callback;
req.recv_buf = recv_buf_ipv4;
req.recv_buf_len = sizeof(recv_buf_ipv4);
ret = http_client_req(sock4, &req, timeout, "IPv4 GET");
close(sock4);
return ret;
}

int post_sensor_data(char *data) {
struct sockaddr_in addr4;
int sock4 = -1;
int32_t timeout = 3 * MSEC_PER_SEC;
int ret;
int port = HTTP_PORT;

connect_socket(AF_INET, REMOTE_SERVER_ADDRESS, port, &sock4, (struct sockaddr *)&addr4, sizeof(addr4));

if(sock4 < 0) {
printk("cannot create HTTP connection\n");
return -1;
}

struct http_request req;
memset(&req, 0, sizeof(req));

struct http_request request;
memset(&request, 0, sizeof(request));

request.method = HTTP_POST;
request.url = "/api/remote/upload/";
request.host = REMOTE_SERVER_ADDRESS;
request.protocol = HTTP_PROTOCOL;
request.content_type_value = "application/json";
request.payload = data;
request.payload_len = strlen(data);
request.response = response_callback;
request.recv_buf = recv_buf_ipv4;
request.recv_buf_len = sizeof(recv_buf_ipv4);
char content_length[30];
sprintf(content_length, "Content-Length: %d\r\n", strlen(data));
http_headers[0] = content_length;

request.header_fields = http_headers;
ret = http_client_req(sock4, &request, timeout, "IPv4 POST");
close(sock4);
return ret;
}
2 changes: 2 additions & 0 deletions src/http_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
int ping_http_server();
int post_sensor_data(char *data);
4 changes: 3 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "mesh.h"
#include "board.h"
#include "dhcp_config.h"

static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
Expand Down Expand Up @@ -192,8 +193,9 @@ static void bt_ready(int err)

void main(void)
{
initialize_dhcp();

int err;

err = board_init();
if (err) {
printk("board init failed (err %d)\n", err);
Expand Down
19 changes: 12 additions & 7 deletions src/mesh_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "mesh_app.h"
#include "mesh.h"
#include "http_util.h"

// ======================================== CONST Configurations ======================================== //

Expand All @@ -21,7 +22,7 @@ const float PROXIMITY_TO_METER = MAX_PROXIMITY_DISTANCE / 235;

const int ENVIRONMENTAL_FACTOR = 2 * 10;

#define POST_DATA_INTERVAL K_MINUTES(1)
#define POST_DATA_INTERVAL K_MINUTES(5)

// ======================================== Global Variables ======================================== //

Expand Down Expand Up @@ -286,7 +287,7 @@ void get_self_node_message(char *buffer)

strcpy(self_node_data.neighbor_distances, neighbor_distances);

sprintf(buffer, "%s,%.1f,%d;%s",
sprintf(buffer, "\"%s,%.1f,%d,%s\"",
self_node_data.name,
self_node_data.temperature,
self_node_data.humidity,
Expand Down Expand Up @@ -357,7 +358,7 @@ void update_node_data(uint16_t address, int rssi, char* message_string)

void encode_node_data(struct node_data n, char* buffer)
{
sprintf(buffer, "%04x,%.1f,%d;%s",
sprintf(buffer, "%04x,%.1f,%d,%s",
n.address,
n.temperature,
n.humidity,
Expand All @@ -376,7 +377,8 @@ void get_mesh_summary(char* buffer)

encode_node_data(self_node_data, node_buffer);
strcat(buffer, node_buffer);
strcat(buffer, "\n");
if (current_nodes > 1) strcat(buffer, "\n");
else strcat(buffer, "0");

for (int i = 0; i < current_nodes; i++)
{
Expand Down Expand Up @@ -404,9 +406,12 @@ void post_data()

get_mesh_summary(data);

// Boss' code will go here..


char *payload = k_malloc(100);
char *values = "\"%s\"";
sprintf(payload, values, data);
printk("%s\n", payload);
post_sensor_data(payload);
k_free(payload);

// Repeat the work
k_delayed_work_submit(&post_data_work, POST_DATA_INTERVAL);
Expand Down
11 changes: 11 additions & 0 deletions src/reel_board.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <drivers/flash.h>
#include <storage/flash_map.h>
#include <drivers/sensor.h>
#include <kernel_version.h>

#include <string.h>
#include <stdio.h>
Expand Down Expand Up @@ -763,3 +764,13 @@ int board_init(void)

return 0;
}

struct kernel_version get_kernel_version(){
uint32_t _kernel_info = sys_kernel_version_get();
struct kernel_version version = {
.major = (_kernel_info >> (8*3)) & 0xff,
.minor = (_kernel_info >> (8*2)) & 0xff,
.patch = (_kernel_info >> (8*1)) & 0xff,
};
return version;
}