json.c 5.64 KB
#include "json.h"

uint8_t register_sensor(sensor sens)
{
        uint8_t result;
        if(sens.ID == PRESSURE_ADDR)
        {
                sens.additional_info = callibration_pressure_data_csv(get_pressure_callibration_data());
        }
        char *statement = prepare_json_register_statement(mod,sens);
        chHeapFree(sens.additional_info);
        sens.additional_info = NULL;
	char sensor_ID[3];
	sprintf(sensor_ID,"%d",sens.ID);
        result = send_json(statement,strlen(statement),mod.ID,sensor_ID);
        chHeapFree(statement);
        return result;
}

char* prepare_json_observation_statement(char** data, uint32_t nObservations)
{
	unsigned int i, length, observation_length;
	char *json_statement, *str_aux, *str_aux2;
	length = 17;
	str_aux = join_strings("{\"observations\":[","",length,0,JOIN_NO_FREE);
	for(i = 0; i < nObservations; i++)
	{
		str_aux2 = prepare_observation(data[i],strlen(data[i]));
		observation_length = strlen(str_aux2);
		str_aux = join_strings(str_aux,str_aux2,length,observation_length,JOIN_FREE_MEM);
		length += observation_length;
	}
	length--; //REMOVE LAST ','
	json_statement = join_strings(str_aux,"]}\0",length,3,JOIN_NO_FREE);
	chHeapFree(str_aux);
	return json_statement;
}

char* prepare_json_register_statement(module mod, sensor sens)
{
	unsigned int length;
	char *json_statement, *str_aux, *str_aux2;
	char ID[MODULE_ID_LENGTH+3];
	length = 23;
	strcpy(ID,mod.ID);
	sprintf(ID+MODULE_ID_LENGTH,"%X",sens.ID);
	str_aux = join_strings("{\"sensors\":[{\"sensor\":\"",ID,length,MODULE_ID_LENGTH+2,JOIN_NO_FREE);
	length += MODULE_ID_LENGTH+2;
	str_aux2 = join_strings(str_aux,"\",\"description\":\"",length,17,JOIN_NO_FREE);
	chHeapFree(str_aux);
	length += 17;
	str_aux = join_strings(str_aux2,sens.description,length,strlen(sens.description),JOIN_NO_FREE);
	chHeapFree(str_aux2);
	length += strlen(sens.description);
	str_aux2 = join_strings(str_aux,"\",\"type\":\"",length,10,JOIN_NO_FREE);
	chHeapFree(str_aux);
	length += 10;
	str_aux = join_strings(str_aux2,sens.type,length,strlen(sens.type),JOIN_NO_FREE);
	chHeapFree(str_aux2);
	length += strlen(sens.type);
	str_aux2 = join_strings(str_aux,"\",\"unit\":\"",length,10,JOIN_NO_FREE);
	chHeapFree(str_aux);
	length += 10;
	str_aux = join_strings(str_aux2,sens.unit,length,strlen(sens.unit),JOIN_NO_FREE);
	chHeapFree(str_aux2);
	length += strlen(sens.unit);
	str_aux2 = join_strings(str_aux,"\",\"location\":\"",length,14,JOIN_NO_FREE);
	chHeapFree(str_aux);
	length += 14;
	str_aux = join_strings(str_aux2,mod.geoloc,length,strlen(mod.geoloc),JOIN_NO_FREE);
	chHeapFree(str_aux2);
	length += strlen(mod.geoloc);
	if(sens.additional_info != NULL)
	{
		str_aux2 = join_strings(str_aux,sens.additional_info,length,strlen(sens.additional_info),JOIN_NO_FREE);
		chHeapFree(str_aux2);
		length += strlen(sens.additional_info);
	}
	json_statement = join_strings(str_aux,"\"}]}\0",length,5,JOIN_NO_FREE);
	chHeapFree(str_aux);
	return json_statement;
}

char* prepare_observation(char* observation, uint32_t length)
{
	char *json_data, *str_aux, *str_aux2;
	/* TOPKEK
	 *
	 * ¿Gestión de errores?
	 * ¿PA QUÉ?
	 *
	 * --le trole
	 */
	int value_length = find_next_index(observation,length,','); //EXPECTS FORMATTING!!!
	int timestamp_length = length - (value_length + 1);
	char *value = (char*) chHeapAlloc(NULL,value_length+1);
	char *timestamp = (char*) chHeapAlloc(NULL,timestamp_length+1);
	strncpy(value,observation,value_length);
	strncpy(timestamp,observation+(value_length+1),timestamp_length);
	value[value_length] = '\0';
	timestamp[timestamp_length] = '\0';
	str_aux = join_strings("{\"value\":\"",value,10,value_length,JOIN_NO_FREE);
	str_aux2 = join_strings(str_aux,"\",\"timestamp\":\"",10+value_length,15,JOIN_NO_FREE);
	str_aux2 = join_strings(str_aux2,timestamp,25+value_length,timestamp_length,JOIN_FREE_MEM);
	json_data = join_strings(str_aux2,"\"},",25+value_length+timestamp_length,3,JOIN_NO_FREE);
	chHeapFree(str_aux);
	chHeapFree(str_aux2);
	chHeapFree(value);
	return json_data;
}

uint8_t send_json(char* statement, uint32_t length, char* provider_ID, char* sensor_ID)
{
	int connectivity, response_code;
	char *URL, *PATH;
	connectivity = libwismart_IsConnected();
	if(connectivity != WISMART_CONNECTED)
	{
		return JSON_COMM_ERROR;
	}
	if(sensor_ID == NULL) //Register sensor
	{
		URL = (char*) chHeapAlloc(NULL,8+strlen(SERVER_HOSTNAME));
		strcpy(URL,SERVER_HOSTNAME);
		PATH = (char*) chHeapAlloc(NULL,10+strlen(provider_ID));
		strcpy(PATH,"/catalog/");
		strcpy(PATH+9,provider_ID);
	}
	else //Post data
	{
		URL = (char*) chHeapAlloc(NULL,1+strlen(SERVER_HOSTNAME));
		strcpy(URL,SERVER_HOSTNAME);
		URL[strlen(SERVER_HOSTNAME)] = '\0';
		PATH = (char*) chHeapAlloc(NULL,22+strlen(provider_ID)+strlen(sensor_ID));
		strcpy(PATH,"/data/modularupload/");
		strcpy(PATH+20,provider_ID);
		strcpy(PATH+20+strlen(provider_ID),sensor_ID);
		PATH[21+strlen(provider_ID)+strlen(sensor_ID)] = '\0';
	}
	struct httpHeaders server = { put,PATH,strlen(PATH),URL,strlen(URL)};
	response_code = httpRequest(server, statement, length);
	chHeapFree(PATH);
	chHeapFree(URL);
	if(response_code == 200)
	{
		return JSON_POST_OK;
	}
	else if((response_code >= 400) && (response_code < 500))
	{
		return JSON_COMM_ERROR;
	}
	else
	{
		return JSON_OTHER_ERROR;
	}
}

uint32_t find_next_index(char* string, uint32_t length, char delimiter)
{
	unsigned int i;
	for(i = 0; i < length; i++)
	{
		if(string[i] == delimiter)
		{
			return i;
		}
	}
	return -1;
}

char* join_strings(char* str1, char* str2, uint32_t len1, uint32_t len2, uint8_t free_mem)
{
	char* str = (char*) chHeapAlloc(NULL,len1+len2+1);
	strncpy(str,str1,len1);
	str[len1] = '\0';
	strncat(str,str2,len2);
	if(free_mem)
	{
		chHeapFree(str1);
		chHeapFree(str2);
	}
	return str; 
}