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

Current HTTPS status.

Hi;

I am trying to send a Telegram message using Telegram Bot API. As the documentation shows: "All queries to the Telegram Bot API must be served over HTTPS". I have tried using Rallares's HTTP example, and I have successfully modified it to send a Telegram message. However, when I make the request I get an "HTTP error 301 - moved permanently" error because I don't use HTTPS.

So I am stuck because I need HTTPS and I can't find any working example on the repositories. I have read in other questions that HTTPS is already implemented or will be implemented soon.

So I wonder if actually is possible to use it. If not, do you know any other way to send a Telegram message using an NFR9160? Maybe I can do something with an HTTPS server code...

I will post my code here if useful:

#include <zephyr.h>
#include <stdio.h>
#include <string.h>
#include <gps.h>
#include <sensor.h>
#include <console.h>
#include <dk_buttons_and_leds.h>
#include <lte_lc.h>
#include <misc/reboot.h>
#include <net/bsdlib.h>
#include <net/socket.h>

#define HTTP_HOST "api.telegram.org"
#define HTTP_PORT 80
#define RECV_BUF_SIZE 8192

char recv_buf[RECV_BUF_SIZE + 1];

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;
}

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;
}

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;
}

void app_http_start(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 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 /botMYBOTTOKEN/sendMessage?chat_id=MYCHATID&text=test HTTP/1.1\r\nHost: api.telegram.org\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);

	int tot_num_bytes = 0;

	do {
		/* TODO: make a proper timeout *
		 * Current solution will just hang 
		 * until remote side closes connection */
		num_bytes =
			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
		tot_num_bytes += num_bytes;

		if (num_bytes <= 0) {
			break;
		}
		printk("\n\nhere:%s\n\n", recv_buf);
	} while (num_bytes > 0);

	printk("\n\rFinished. Closing socket\n");
	freeaddrinfo(res);
	err = close(client_fd);
}

static void modem_configure(void)
{
	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
		/* Do nothing, modem is already turned on and connected. */
	} else {
		int err;

		printk("Establishing LTE link (this may take some time) ...\n");
		err = lte_lc_init_and_connect();
		__ASSERT(err == 0, "LTE link could not be established.");
		printk("LTE connection established.\n");
	}
}


void main(void)
{
	int err;
	printk("Application started\n");
    k_sleep(2000);
    modem_configure();
    app_http_start();
	k_sleep(2000);
	if ( (err = lte_lc_offline() ) )
	{
	    printk( "Failure turning off Modem: %d\n", err );
	}
	else{
	    printk("Modem turned off.\n");
}


}

Thanks a lot.

Parents
  • The SDK 16.0.0 includes nrf_tls. The mqtt examples seem to use TLS. Note: HTTPS is HTTP over TLS.

    Not sure if this is enough, modern HTTPS servers may require some advanced features like SNI (Server Name Indication). Certificate handling would be a real pain on the limited space in an NRF device.

    You really don't want to terminate the SSL connection on the small device but on whatever is connected via blueooth (or USB/UART).

Reply
  • The SDK 16.0.0 includes nrf_tls. The mqtt examples seem to use TLS. Note: HTTPS is HTTP over TLS.

    Not sure if this is enough, modern HTTPS servers may require some advanced features like SNI (Server Name Indication). Certificate handling would be a real pain on the limited space in an NRF device.

    You really don't want to terminate the SSL connection on the small device but on whatever is connected via blueooth (or USB/UART).

Children
No Data
Related