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

How can I post big chuck of data to Contiki Server running on a microcontroller? #138

Open
anesh1992 opened this issue Feb 14, 2019 · 5 comments

Comments

@anesh1992
Copy link

This is my post handler in contiki;

#define MAX_PLUGFEST_BODY    2048
#define MAX_PLUGFEST_PAYLOAD 64 + 1       /* +1 for the terminating zero, which is not transmitted */

static int32_t large_update_size = 0;
static uint8_t large_update_store[MAX_PLUGFEST_BODY] = { 0 };
static unsigned int large_update_ct = TEXT_PLAIN;
EVENT_RESOURCE(res_configuration,
               "title=\"ELEMENT TYPE\"; obs",
		NULL,
		res_post_put_handler_configuration,
	        res_post_put_handler_configuration,
               NULL,
	       NULL
               );

static void
res_post_put_handler_configuration(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset)
{
	coap_packet_t *const coap_req = (coap_packet_t *)request;
	uint8_t *incoming = NULL;
	size_t len = 0;

	unsigned int ct = -1;
	REST.get_header_content_type(request, &ct);
//	if(!REST.get_header_content_type(request, &ct)) {
//		REST.set_response_status(response, REST.status.BAD_REQUEST);
//		const char *error_msg = "NoContentType";
//		REST.set_response_payload(response, error_msg, strlen(error_msg));
//		return;
//	}

	if((len = REST.get_request_payload(request, (const uint8_t **)&incoming))) {
	    if(coap_req->block1_num * coap_req->block1_size + len <= sizeof(large_update_store)) {
	      memcpy(large_update_store + coap_req->block1_num * coap_req->block1_size, incoming, len);
	      large_update_size = coap_req->block1_num * coap_req->block1_size + len;
	      large_update_ct = ct;

	      REST.set_response_status(response, REST.status.CREATED);
	      coap_set_header_block1(response, coap_req->block1_num, 0,
	                             coap_req->block1_size);
	    } else {
	      REST.set_response_status(response, REST.status.REQUEST_ENTITY_TOO_LARGE);
	      REST.set_response_payload(
	        response,
	        buffer,
	        snprintf((char *)buffer, MAX_PLUGFEST_PAYLOAD, "%uB max.",
	                 sizeof(large_update_store)));
	      return;
	    }
	  } else {
	    REST.set_response_status(response, REST.status.BAD_REQUEST);
	    const char *error_msg = "NoPayload";
	    REST.set_response_payload(response, error_msg, strlen(error_msg));
	    return;
	  }
}

Python code;

from coapthon.client.helperclient import HelperClient
import socket, struct, time
import json
from coapthon import defines
import time
from coapthon.resources.resource import Resource
from coapthon.utils import parse_blockwise

conductor_host = "fd00::XXXX:XXXX:XXXX:XXXX"
port = 5683
path ="configure/res_configuration"

client = HelperClient(server=(conductor_host, port))
length = len("{\"CONDUCTOR\":\"0\",\"Device Name\":\"BOH\", \"IPV6\":\"XXXX::XXXX:XXXX:XXXX:XXXX\", \"Element Type ID\":\"17\"}")
value = parse_blockwise(length)
print(value)
response = client.post(path = path, \
	payload = "{\"CONDUCTOR\":\"0\",\"Device Name\":\"BOH\", \"IPV6\":\"fd00::fd00:fd00:49bf:fd00\", \"Element Type ID\":\"17\"}", \
	accept = defines.Content_types["text/plain"],	\
	block1= value)
print (response.pretty_print())

The problem is, complete string is not reaching to microcontroller board running post handler, I am not sure if problem is in microcontroller code or python code. Can somebody please hint me where is the problem? At least, if python test code is correct or not? Thanks!
-Anesh

@Tanganelli
Copy link
Owner

Tanganelli commented Feb 15, 2019 via email

@anesh1992
Copy link
Author

client = HelperClient(server=(conductor_host, port))
response = client.post(path = path, \
	payload = "{\"CONDUCTOR\":\"0\",\"Device Name\":\"BOH\", \"IPV6\":\"fd00::fd00:fd00:49bf:fd00\", \"Element Type ID\":\"17\"}")
print (response.pretty_print())

Is client.post () is taking care of big data? Or do I need to pass any argument to tell post() method that it's a long string? Microcontroller running post handler resource, not recieving NUM, M and SZX as it should.
the size of the block (SZX);
whether more blocks are following (M);
the relative number of the block (NUM) within a sequence of blocks with the given size.

@anesh1992
Copy link
Author

I did something like this and ity's working. But, It seems to me that, this is not a correct way of blockwise transfer. I made M always 1 that means server knows that more data is coming from client, when in last block when no payload is there, i am not changing M to 0, that is why getting bad request (but that is okay for me know).

def post_configuration (host, path, payload):
	lst = list (parse_blockwise(len(payload)))
	lst [1] = 1
	value = tuple(lst)
	client = HelperClient(server=(host, port))
	request = Request()
	request.code = defines.Codes.POST.number
	request.type = defines.Types["CON"]
	request.destination = (host, port)
	request.uri_path = path
	request.content_type = defines.Content_types["text/plain"]
	request.payload = payload
	request.block1 = value
	request._mid = 10
	response = client.send_request(request)
	print (response.pretty_print())
	client.stop()

@anesh1992
Copy link
Author

@Tanganelli In the above code if I will not use parse_blockwise then I will have to hard code as you did in your test code https://github.com/Tanganelli/CoAPthon3/blob/master/coverage_test.py#L452. Is there any API for big data transfer that takes care of request.block1 = value and just I need to call that? Is above code is correct? If not what is wrong? Thanks!

@anesh1992
Copy link
Author

@Tanganelli I am really stuck with this block-wise transfer, With code here #138 (comment) I posted, able to send data and sometimes not, can you please provide example code for block-wise transfer?
This is the payload I want to send, length of payload could change.

"{'0_1|0000_1100': [3, 2, 4, 20.0, 22.22, -0.56, 0.28],'0_1|1100_2400': [3, 2, 4, 20.0, 22.22, -0.56, 0.28],'2_3|0000_2400': [2, 2, 4, 20.0, 22.22, -0.56, 0.56],'4|0000_1400': [2, 2, 4, 20.0, 22.22, -0.56, 0.56],'4|1400_2400': [2, 2, 4, 20.0, 22.22, -0.56, 0.56],'5_6|0000_0900': [2, 2, 4, 20.0, 22.22, -0.56, 0.56],'5_6|0900_1900': [2, 2, 4, 20.0, 22.22, -0.56, 0.56],'5_6|1900_2400': [2, 2, 4, 20.0, 22.22, -0.56, 0.56]}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants