Library for my home monitoring classes and serial communication protocol. It monitors temperature and movement on the mbed application board.

Dependents:   FinalProject

Communication/Communication.cpp

Committer:
groletter
Date:
2013-09-03
Revision:
2:84432add9142
Parent:
1:2f5a62eb52ad

File content as of revision 2:84432add9142:

#include "USBHomeMon.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "Temperature.h"
#include "HomeMonUtils.h"
#include "USBSerial.h"
#include "Motion.h"
#include <sstream>
#include <string>

extern USBSerial serial;

/* ! \fn Gets character from host */
int mon_get() {
    return serial._getc();
}

/// Sends character to the host
int mon_send(char c) {
    return serial._putc(c);
}

/// Waits for the host to ack
bool host_wait() {
	char resp;
	// FIXME - check buffer size before waiting so 
	// we don't block?
    if ((resp = mon_get()) == 'k') {
        return true;
    }
    else {
        return false;
    }
}

/// Listens for connection message from host
bool check_connection() {
    if (serial.available()) {
        if (mon_get() == 'c') {
            send_ack();
            return true;
        }
        else {
            return false;
        }
    }
}

/// Sends actual alert to the host
bool send_alert(alert_type alert) {
    int response;
    mon_send('a'); // Send alert
    // Wait for response
    response = host_wait();
    if (!response) {
        return false;
    }
    switch (alert) {
        case MOTION:
            mon_send('m');
            break;
        case TEMP_LOW:
            mon_send('l');
            break;
        case TEMP_HI:
            mon_send('h');
            break;
    }
    response = host_wait();
    if (!response) {
        return false;
    }
    
    return true;
}

char rec_command() {
   
    char host_msg;

    host_msg = mon_get();

    return host_msg;
}

bool send_sample(double sample) {
	// Somewhat kludgy way of creating a fixed width field so
	// I don't have to worry about parsing.  All samples are always
	// 7 characters wide and will be padded with spaces to ensure it.

    std::string mystring; 
    if (convert_sample(sample, mystring)) {
        for (size_t i=0; i < mystring.size(); ++i) {
		    mon_send(mystring[i]);
	    }
	    return true;
	}
	else {
	    printf("Error with %f\n", sample);
	    send_err();
		return false;
	}
}

bool send_samples(std::vector<std::string> samples) {
	for (size_t i=0; i < samples.size(); ++i) {
		std::string tempstr = samples[i];
		for (size_t j=0; j < tempstr.size(); ++j) {
			mon_send(tempstr[j]);
		}
	}

	// FIXME - need to make sure samples were sent okay and return
	// proper value.
	return true; 
}

double get_sample(void) {
    char char_sample[SAMP_SIZE+1];
	char_sample[SAMP_SIZE] = '\0';
    for (int i=0; i<SAMP_SIZE; ++i) {
        char_sample[i] = mon_get();
    }
	// FIXME - need error checking here on sample.  Try
	// printing it to a string and make sure it will fit in
	// 7 characters or don't allow it to be set.
    // DEBUG printf("Sample = %s\n", char_sample);
    return atof(char_sample);
}

msg_type parse_msg(char msg) {
	switch(msg) {
	case 'z':
		return SET_TEMP_MIN;
		break;
	case 'y':
		return SET_TEMP_MAX;
		break;
	case 'x':
		return SET_TEMP_NUM_SAMPLES;
		break;
	case 'w':
		return SET_MOTION_NUM_SAMPLES;
		break;
	case 'v':
		return SET_PERIOD;
		break;
	case 'u':
		return SET_MOTION_THRESH;
		break;
	case 't':
		return GET_TEMP_SAMPLES;
		break;
	case 's':
		return GET_MOTION_SAMPLES;
		break;
	case 'r':
		return GET_MIN_TEMP;
		break;
	case 'q':
		return GET_MAX_TEMP;
		break;
	case 'p':
		return GET_PERIOD;
		break;
	case 'o':
		return GET_TEMP_NUM_SAMPLES;
		break;
	case 'n':
		return GET_MOTION_NUM_SAMPLES;
		break;
	case 'j':
		return GET_MOTION_THRESH;
		break;
	default:
	    printf("Received unknown command: %c\n", msg);
		return MON_ERROR;
	}
}

void host_command_resp(msg_type msg, Temperature &temp, Motion &motion) {
    double sample, sample2, sample3;
	motion_vec motion_thresh;
    switch (msg) {
        case SET_TEMP_MIN:
            send_ack();
            sample = get_sample();
			// DEBUG printf(" sample = %f\n", sample);
            if(temp.set_min(sample)) {
				send_ack();
			}
			else {
			    printf("Error receiving sample\n");
				send_err();
			}
            break;
        case SET_TEMP_MAX:
            send_ack();
            sample = get_sample();
            if(temp.set_max(sample)) {
				send_ack();
			}
			else {
				send_err();
			}
            break;
        case SET_TEMP_NUM_SAMPLES:
            send_ack();
            sample = get_sample();
            if (temp.change_max_samples((int)sample)) {
				send_ack();
			}
			else {
				send_err();
			}
            break;
        case SET_MOTION_NUM_SAMPLES:
            send_ack();
            sample = get_sample();
            if (motion.change_max_samples((int)sample)) {
				send_ack();
			}
			else {
				send_err();
			}
            break;
		case SET_PERIOD:
            send_ack();
            sample = get_sample();
            if (temp.set_period(sample)) {
                send_ack();
			}
			else {
				send_err();
			}
            break;
		case SET_MOTION_THRESH:
            send_ack();
            sample = get_sample();
			sample2 = get_sample();
			sample3 = get_sample();
			motion_thresh.x = sample;
			motion_thresh.y = sample2;
			motion_thresh.z = sample3;
            if (motion.set_motion_thresh(motion_thresh)) {
                send_ack();
            }
            else {
                send_err();
            }
            break;
        case GET_TEMP_SAMPLES:
            send_ack();
            send_sample(temp.get_max_samples());
			send_samples(temp.get_samples());
            break;
        case GET_MOTION_SAMPLES:
            send_ack();
            send_sample(motion.get_max_samples());
			send_samples(motion.get_samples());
            break;
        case GET_MIN_TEMP:
            send_ack();
			send_sample(temp.get_min());
            break;
        case GET_MAX_TEMP:
            send_ack();
			send_sample(temp.get_max());
            break;
        case GET_PERIOD:
            send_ack();
			send_sample(temp.get_period());
            break;
		case GET_TEMP_NUM_SAMPLES:
            send_ack();
			send_sample((double)temp.get_max_samples());
            break;
		case GET_MOTION_NUM_SAMPLES:
            send_ack();
			send_sample((double)motion.get_max_samples());
            break;
		case GET_MOTION_THRESH:
			send_ack();
			motion_thresh = motion.get_motion_thresh();
			send_sample(motion_thresh.x);
			send_sample(motion_thresh.y);
			send_sample(motion_thresh.z);
            break;
        default:
            printf("Received unkown message type\n");
            send_err();
            break;
    }
}