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

uint8_t register_sensor(sensor sens)
{
	DBG_JSON("Registering sensor: %s\r\n",sens.description);
    uint8_t result;
    char *statement;
    if(sens.ID == PRESSURE_ADDR)
    {
    	DBG_JSON("Putting additional info for pressure sensor...\r\n");
    	char *callibration_data = callibration_pressure_data_csv(get_pressure_callibration_data());
    	DBG_JSON("callibration_data is: %s\r\n",callibration_data);
        statement = prepare_json_register_statement(mod,sens,callibration_data);
    	chHeapFree(callibration_data);
    }
    else
    {
    	statement = prepare_json_register_statement(mod,sens,NULL);
    }
	char sensor_ID[3];
	sprintf(sensor_ID,"%02x",sens.ID);
    result = send_json(statement,strlen(statement),mod.ID,NULL);
    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, char *additional_info)
{
	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,"%02X",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(additional_info != NULL)
	{
		DBG_JSON("In prepare_json_register_statement: Detected additional_info\r\n");
		str_aux2 = join_strings(str_aux,"\",\"additionalInfo\":\"",length,20,JOIN_NO_FREE);
		chHeapFree(str_aux);
		length += 20;
		str_aux = join_strings(str_aux2,additional_info,length,strlen(additional_info),JOIN_NO_FREE);
		chHeapFree(str_aux2);
		length += strlen(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;
	int value_length = find_next_index(observation,length,',');
	while(1)
	{
		if(find_next_index(observation+value_length+1,length,','))
		{
			value_length +=  find_next_index(observation+value_length+1,length,',')+1;
		}
		else
		{
			break;
		}
	}
	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,1+strlen(SERVER_HOSTNAME));
		strcpy(URL,SERVER_HOSTNAME);
		#ifdef SERVER_VANILLA
		//VANILLA SERVER (SENTILO)
		DBG_JSON("Server is vanilla\r\n")
		PATH = (char*) chHeapAlloc(NULL,19);
		strcpy(PATH,"/catalog/register");
		#endif
		#ifdef SERVER_LEWIS
		//FUCKING LEWIS...
		DBG_JSON("Server is lewis.upc.es\r\n");
		PATH = (char*) chHeapAlloc(NULL,50);
		strcpy(PATH,"/modularsense/wordpress/opendata/catalog/register");
		#endif
	}
	else //Post data
	{
		URL = (char*) chHeapAlloc(NULL,1+strlen(SERVER_HOSTNAME));
		strcpy(URL,SERVER_HOSTNAME);
		URL[strlen(SERVER_HOSTNAME)] = '\0';
		#ifdef SERVER_VANILLA
		//VANILLA SERVER (SENTILO)
		DBG_JSON("Server is vanilla\r\n")
		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);
		#endif
		#ifdef SERVER_LEWIS
		//FUCKING LEWIS...
		DBG_JSON("Server is lewis.upc.es\r\n");
		PATH = (char*) chHeapAlloc(NULL,54+strlen(provider_ID)+strlen(sensor_ID));
		strcpy(PATH,"/modularsense/wordpress/opendata/data/modularupload/");
		strcpy(PATH+52,provider_ID);
		strcpy(PATH+52+strlen(provider_ID),sensor_ID);
		#endif
	}
	struct httpHeaders server = { put,PATH,strlen(PATH),URL,strlen(URL)};
	response_code = httpRequest(server, statement, length);
	chHeapFree(PATH);
	chHeapFree(URL);
	if(response_code == 200)
	{
		DBG_JSON("Success: %c[1;32mJSON_POST_OK%c[1;00m\r\n",0x1B,0x1B);
		return JSON_POST_OK;
	}
	else if((response_code >= 400) && (response_code < 500))
	{
		
		DBG_JSON("%c[1;31m[ERROR] Communication with server FAILED: JSON_COMM_ERROR%c[1;00m\r\n",0x1B,0x1B);
		return JSON_COMM_ERROR;
	}
	else
	{
		DBG_JSON("%c[1;31m[ERROR] Unspecified error: JSON_ERROR_OTHER%c[1;00m\r\n",0x1B,0x1B);
		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 0;
}

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