main2.c 12.5 KB
#include <string.h>
#include "libwismart.h"
#include "libwismart_irqs.h" /* implement irq handlers */
#include "lwip/inet.h"
#include "globals.h"
#include "httpClient.h"
#include "callbacks.h"
#include "buffer.h"
#include "i2c.h"
#include "configServer.h"
#include "timer-loop.h"
#include "ntp.h"
#include "sensors.h"

#define WIFI_MODE               WIFI_MODE_CLIENT
#define NETWORK_SSID_AP         "modularsense"
#define NETWORK_KEY_AP          NULL
#define NETWORK_CHANNEL_AP      1

#define HARD_LIMIT_WAIT_TIME 10*1000 //5*60*1000

wismart_registryKey_t geo;


void initLibwismart(void)
{
    wismart_hwif_t hwif = libwismart_GetDefaultHWIF();
    libwismart_Init(hwif);
}

uint8_t connected=0;
uint8_t timeout=0;
uint8_t retries=0;
uint8_t sensors_length=0;
uint8_t registry_opened=0;

module mod;

void update_time(unsigned long *time)
{
    printf("Requesting new NTP time...\r\n");
    unsigned long new_time = getSecsSince1900();
    if(new_time)
    {
        *time = getSecsSince1900();
    }
    printf("Time updated...\r\n");
}

void init_registry(void)
{
    config_params_t config;

    strcpy(config.localization,"none");
    if(!registry_opened)
    {
        libwismart_RegistryCreateKey(&geo, 1, sizeof(config));
        libwismart_RegistryOpen(1);
        registry_opened = 1;
    }
    if(!libwismart_RegistryIsValueEmpty(&geo))
    {
        libwismart_RegistryGet(&geo,&config);
    }

    printf("SSID = %s\r\n",config.ssid);
    printf("Wep key = %s\r\n",config.wepkey);
    printf("Passphrase = %s\r\n", config.passphrase);
    printf("User = %s\r\n",config.user);
    printf("Password = %s\r\n",config.password);
    printf("Encryption type = %d\r\n",config.security);
    printf("Geo Localization = %s\r\n", config.localization);

    strcpy(mod.geoloc,config.localization);
    strcpy(mod.ID,MODULE_ID);
    printf("%s\r\n", mod.geoloc);
    if(config.security == PROFILE_SECURITY_OPEN)
    {
        printf("open detected\r\n");
        libwismart_WiFiConnect(config.ssid,NULL,wifi_connect_result_cb);
    }
    else if(config.security == PROFILE_SECURITY_WPA_WPA2)
    {
        if(!strcmp(config.user,""))
        {
            printf("wpa detected\r\n");
            libwismart_WiFiConnect(config.ssid,config.passphrase,wifi_connect_result_cb);
        }
        else
        {
            printf("wpa Enterprise detected\r\n");
            struct wpa_param wpa;
            wpa.eap_method = WISMART_EAP_METHOD_TTLS;
            wpa.u.ttls.identity = config.user;
            wpa.u.ttls.password = config.password;
			wpa.u.ttls.ca_cert=NULL;
            libwismart_WiFiConnectEnterprise(config.ssid, &wpa, wifi_connect_result_cb);
        }
    }
    else
    {
        printf("wep detected\r\n");
        //Is WEP
        libwismart_WiFiConnect(config.ssid,config.wepkey,wifi_connect_result_cb);
        libwismart_WiFiSetWep(config.wepkey,1);
    }
	while(connected == 0 && timeout != 1  )
    {chThdSleepMilliseconds(500);}

}

void send_data(char** buffers[], uint32_t ind[], uint32_t sizes[], uint8_t sensors[])
{
    int j;
    for(j=0;j<sensors_length;j++)
    {   
        printf(" enviant buffer %d\r\n",j);
        
        // fem servir 085 de prova, però haurem de fer servir sensor_id[j]
        char id[3];
        sprintf(id,"%x",sensors[j]);
        int ok=send(buffers[j],&ind[j],&sizes[j], mod.ID, id);

        if(ok==JSON_COMM_ERROR)
        {
            printf("wismart is not connected\r\n");
        }
        else if( ok==JSON_OTHER_ERROR){
            printf("some error ocurred\r\n");
        }
        else if(ok ==JSON_POST_OK){
            printf(" send OK \r\n");
        }
    }
}

void put_buffers(char** buffers[],uint32_t ind[],uint32_t sizes[],char** cooked, uint8_t* sensors){
    int i;
    for(i=0;i<sensors_length;i++){
        printf("For %d and %d\n\r", ind[i],sizes[i]);
        printf("Putting data: %s\n\r",cooked[i]);
        buffers[i] = put_message(cooked[i], buffers[i] ,&ind[i],&sizes[i]);
        printf("Message put: %s\r\n",buffers[i][ind[i]-1]);
        chHeapFree(cooked[i]);
        printf("Memory freed\n\r");
        printf("Message put (assertion): %s with length %d\r\n",buffers[i][ind[i]-1] ,strlen(buffers[i][ind[i]-1]));
    }

}
char** timestamp_datas(char* value[],unsigned long timestamp, uint8_t* sensors){
    char** cooked_data;
    cooked_data = (char**) chHeapAlloc(NULL,sensors_length * sizeof(char*));
    printf("Data allocated...\r\n");
    Date t=getDate(timestamp);
    int i;
    for(i=0;i<sensors_length;i++){
        printf("Calling timestamp_data...\r\n");
        cooked_data[i]=timestamp_data(value[i], t);
        printf("Finished timestamp_data...\r\n");
        printf("Data is: %s\r\n",cooked_data[i]);
        chHeapFree(value[i]);
        
    }
    printf("Returning timestamped data...\r\n");
    return cooked_data;
}

void wifi_connect(void)
{
    init_registry();
    if(timeout==1)
    {
        printf("Creating AP\r\n");
        //corroborar los parametros del AP
        configServer_start(1);
        libwismart_WiFi_SoftAP_Start(NETWORK_SSID_AP,NETWORK_CHANNEL_AP,NULL,softapMode_apStartedCb, softapMode_clientIndicationCb);
        for(;;)
        {
            chThdSleepMilliseconds(1000);
        }
    }
}

void send_battery_level(unsigned long timestamp)
{
    uint8_t result;
    //char *batt_level = battery_value(get_battery_data());
    char *batt_level = battery_value(3300);
    char *batt_data = timestamp_data(batt_level,getDate(timestamp));
    chHeapFree(batt_level);
    char *statement = prepare_json_observation_statement(&batt_data,1);
    chHeapFree(batt_data);
    char id[3];
    sprintf(id,"%02x",battery.ID);
    result = send_json(statement,strlen(statement),mod.ID,id);
    if(result)
    {
        if(result != 200)
        {
            printf("ERROR: SERVER RETURNED %d\r\n",result);
        }
    }
    else
    {
            printf("ERROR: CONNECTION FAILED\r\n");
    }
    chHeapFree(statement);
}

void wifi_disconnect(void){
    uint8_t res=libwismart_WiFiDisconnect();
     if(res)
        printf("WIFI_DISCONNECT_SUCCESS\r\n");
     else
        printf("WIFI_DISCONNECT_FAILURE\r\n");
}

int main(void)
{
    initLibwismart();
    libwismart_PowerSave_Enable();
    libwismart_PowerSave_HigherProfile(TRUE);
    libwismart_RegisterDhcpCB(dhcp_connect_result_cb);
    libwismart_WiFiInit();
    libwismart_SetScanRunsForConnTimeout(4); //Edit a 4
	libwismart_EnableBsdSocketAPI();
    
    uint8_t sensors[TOTAL_SENSORS];
    memset (sensors, 0, TOTAL_SENSORS);

    char* valueSensors[TOTAL_SENSORS];
    memset (valueSensors, 0, TOTAL_SENSORS);

    printf("Connecting to wifi...\r\n");
    wifi_connect();

    wakeup_sensors(0xFF);
    printf("Scanning sensors...\r\n");
    //Escanea los sensores -> retorna un vector con las direcciones en cada posición del vector, si la posición del vector retorna un cero -> no existe el sensor
    //Escanea y registra
    I2C_scan(I2C1,sensors);
    sensors_length=strlen((char*)sensors);
    printf("%d sensor detected...\r\n",sensors_length);

    unsigned long time;
    update_time(&time);
    //desconectarwifi
    printf("Disconecting wifi...\r\n");
    wifi_disconnect();

    unsigned long timestamp = 0;
    unsigned long delay = getSystemTime();
    sleep_thread(SHORT_PERIOD - time%SHORT_PERIOD);

    uint32_t ind[TOTAL_SENSORS]={0};
    char** buffers[TOTAL_SENSORS];
    uint32_t sizes[TOTAL_SENSORS]={0};
    int i  = 1;

    while(1){
        if(ind[0])
        {
            printf("Data stored in buffer: %s with index %d and size %d\r\n",buffers[0][ind[0]-1], ind[0],sizes[0]);
        }
        time += getElapsedTime(delay);
        printf("time (absolute):\t%ul\r\ntime mod LONG_PERIOD:\t%ul\r\ntime mod SHORT_PERIOD:\t%ul\r\n",time,time%LONG_PERIOD,time%SHORT_PERIOD);

        delay = getSystemTime();
        /* Collect data from sensors */
        if(ind[0])
        {
            printf("Data stored in buffer: %s with index %d and size %d\r\n",buffers[0][ind[0]-1], ind[0],sizes[0]);
        }
        printf("Collecting data...\r\n");
        collectData(valueSensors, sensors);
        printf("Data collected...\r\n");
        if(ind[0])
        {
            printf("Data stored in buffer: %s with index %d and size %d\r\n",buffers[0][ind[0]-1], ind[0],sizes[0]);
        }
        time += getElapsedTime(delay);
        printf("time (absolute):\t%ul\r\ntime mod LONG_PERIOD:\t%ul\r\ntime mod SHORT_PERIOD:\t%ul\r\n",time,time%LONG_PERIOD,time%SHORT_PERIOD);
        timestamp = time;
        printf("timestamp (absolute):\t%ul\r\ntimestamp mod LONG_PERIOD:\t%ul\r\ntimestamp mod SHORT_PERIOD:\t%ul\r\n",timestamp,timestamp%LONG_PERIOD,timestamp%SHORT_PERIOD);
        delay = getSystemTime();
        printf("Timestamping data...\r\n");
        char** values=timestamp_datas(valueSensors,timestamp,sensors);
        printf("Putting data in buffer...\r\n");
        put_buffers(buffers,ind,sizes,values,sensors);
        printf("Data is now in buffer...\n\r");
        printf("Data stored in buffer: %s with index %d and size %d\r\n",buffers[0][ind[0]-1], ind[0],sizes[0]);
         if (i == LONG_PERIOD/SHORT_PERIOD ){
            printf("Programmed Send cycle...\r\n");
            /* Wi-Fi connect */
            printf("Connecting to wifi...\r\n");
            wifi_connect();
            /* Send data to server, empty the buffer */
            send_data(buffers, ind, sizes, sensors);
            printf("Data sent!\r\n");
            //Now sending battery level
            send_battery_level(timestamp);
            //time = getNTPTime();
            update_time(&time);
            delay = getSystemTime();
            //desconectar wifi
            wifi_disconnect();
            printf("new ntp time (absolute):\t%ul\r\ntime mod LONG_PERIOD:\t%ul\r\ntime mod SHORT_PERIOD:\t%ul\r\n",time,time%LONG_PERIOD,time%SHORT_PERIOD);
            i = 0;
        }

        printf("mirant memoria\r\n");
        int res=check_memory();
        if(res==SOFT_REACHED){
            printf("--------------soft limit-------------\r\n");
            wifi_connect();
            send_data(buffers, ind, sizes, sensors);
            //Now sending battery level
            send_battery_level(timestamp);
            //disconect_wifi()
            wifi_disconnect();
        }
        else if(res==HARD_REACHED){
            printf("--------------hard limit-------------\r\n");
            wifi_connect();
            char id_0[3];
            sprintf(id_0,"%x",sensors[0]);
            while( send(buffers[0],&ind[0],&sizes[0], mod.ID, id_0) != JSON_POST_OK )
            {
                // El servidor no ens sap dir si tenim permisos o no sense registrar una mostra.
                // Intentem enviar un buffer sencer, a veure si ja podem buidar.
                // No podem enviar només una mostra perquè json és rígid en aquest sentit.
            
                printf("hard_reached and unable to sentd.\r\nLa biblia en vers: i Jesús digué: Aixeca't, Llàtzer!!\r\n");
                chThdSleepMilliseconds(HARD_LIMIT_WAIT_TIME);
            }
            int j;
            for(j=1;j<sensors_length;j++)
            {   
                
                printf(" enviant buffer %d\r\n",j);
                char id[3];
                sprintf(id,"%x",sensors[j]);
                int ok=send(buffers[j],&ind[j],&sizes[j], mod.ID, id);
                if(ok==JSON_COMM_ERROR)
                {
                    printf("wismart is not connected\r\n");
                }
                else if( ok==JSON_OTHER_ERROR){
                    printf("some error ocurred\r\n");
                }
                else if(ok ==JSON_POST_OK){
                    printf(" send OK \r\n");
                } 
                
            }
            //Now sending battery level
            send_battery_level(timestamp);
            wifi_disconnect();
        }
        time += getElapsedTime(delay);
        printf("time (absolute):\t%ul\r\ntime mod LONG_PERIOD:\t%ul\r\ntime mod SHORT_PERIOD:\t%ul\r\n",time,time%LONG_PERIOD,time%SHORT_PERIOD);
        
        delay = getSystemTime();
        printf("Time to sleep! for %d seconds\r\n", SHORT_PERIOD - time%SHORT_PERIOD);
        sleep_thread(SHORT_PERIOD - time%SHORT_PERIOD);
        i++;
    }  
}

/*
 * TO-DO
 *
 * - Test all sensors
 * - Test ADC
 * - Test register, data send and battery send
 * - Reset server-related defines
 * - Reset timer-related defines
 */