/* Voice thread message processing */
static enum voice_state voice_message(struct voice_thread_data *td)
{
    if (quiet_counter > 0)
        queue_wait_w_tmo(&voice_queue, &td->ev, HZ/10);
    else
        queue_wait(&voice_queue, &td->ev);

    switch (td->ev.id)
    {
    case Q_VOICE_PLAY:
        LOGFQUEUE("voice < Q_VOICE_PLAY");
        if (quiet_counter == 0)
        {
            /* Boost CPU now */
            trigger_cpu_boost();
        }
        else
        {
            /* Stop any clip still playing */
            voice_stop_playback();
        }

        quiet_counter = QUIET_COUNT;

        /* Copy the clip info */
        td->vi = *(struct voice_info *)td->ev.data;

        /* Be sure audio buffer is initialized */
        audio_restore_playback(AUDIO_WANT_VOICE);

        /* We need nothing more from the sending thread - let it run */
        queue_reply(&voice_queue, 1);

        /* Make audio play more softly and set delay to return to normal
           playback level */
        pcmbuf_soft_mode(true);

        /* Clean-start the decoder */
        td->st = speex_decoder_init(&speex_wb_mode);

        /* Make bit buffer use our own buffer */
        speex_bits_set_bit_buffer(&td->bits, td->vi.start, td->vi.size);
        speex_decoder_ctl(td->st, SPEEX_GET_LOOKAHEAD, &td->lookahead);

        return VOICE_STATE_DECODE;

    case SYS_TIMEOUT:
        if (voice_unplayed_frames())
        {
            /* Waiting for PCM to finish */
            break;
        }

        /* Drop through and stop the first time after clip runs out */
        if (quiet_counter-- != QUIET_COUNT)
        {
            if (quiet_counter <= 0)
                pcmbuf_soft_mode(false);

            break;
        }

        /* Fall-through */
    case Q_VOICE_STOP:
        LOGFQUEUE("voice < Q_VOICE_STOP");
        cancel_cpu_boost();
        voice_stop_playback();
        break;

    /* No default: no other message ids are sent */
    }

    return VOICE_STATE_MESSAGE;
}
Example #2
0
static void bluetooth_parse_command(uint8_t len)
{
	uint8_t response = RESPONSE_OK;

	sei();

	if (len == 0) {
		response = RESPONSE_NO_RESPONSE;
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_HELP, len) == 0) {
		uint8_t i = 0;

		for (i = 1; i < sizeof(commands) / sizeof(commands[0]); i ++) {
			uart_puts(commands[i]);

			if ((i % 3) == 0) {
				uart_puts("\r\n");
			} else {
				uint8_t padding = 0, j = 0;
				padding = 26 - strlen(commands[i]);
				for (j = 0; j < padding; j++) {
					uart_putc(' ');
				}
			}
		}

		if (((i - 1) % 3) != 0) {
			uart_puts("\r\n");
		}

		response = RESPONSE_NO_RESPONSE;
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_BATTERY, len) == 0) {
		uint8_t capacity = 0;
		char resp[16];

		capacity = battery_get_capacity();
		itoa(capacity, resp, 10);

		uart_puts(BLUETOOTH_CMD_BATTERY);
		uart_puts(": ");
		uart_puts(resp);
		uart_puts("%\r\n");

		response = RESPONSE_NO_RESPONSE;
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_ECHO, len) == 0) {
		echo = TRUE;
		uart_puts("\r\n");
		response = RESPONSE_NO_RESPONSE;
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_EYES, strlen(BLUETOOTH_CMD_EYES)) == 0) {
		char *param = rxbuff + strlen(BLUETOOTH_CMD_EYES) + 1;

		if (len == strlen(BLUETOOTH_CMD_EYES) + strlen(BLUETOOTH_PARAM_ON) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_ON, strlen(BLUETOOTH_PARAM_ON)) == 0) {
				power_on(EYES);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_EYES) + strlen(BLUETOOTH_PARAM_OFF) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_OFF, strlen(BLUETOOTH_PARAM_OFF)) == 0) {
				power_off(EYES);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_EYES)) {
			uint8_t state = power_state(EYES);

			uart_puts(BLUETOOTH_CMD_EYES);
			uart_puts(": ");

			if (state == POWER_ON) {
				uart_puts(BLUETOOTH_PARAM_ON);
			} else {
				uart_puts(BLUETOOTH_PARAM_OFF);
			}
			uart_puts("\r\n");

			response = RESPONSE_NO_RESPONSE;
		} else {
			response = RESPONSE_ERROR;
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_HELMET, strlen(BLUETOOTH_CMD_HELMET)) == 0) {
		char *param = rxbuff + strlen(BLUETOOTH_CMD_HELMET) + 1;

		if (len == strlen(BLUETOOTH_CMD_HELMET) + strlen(BLUETOOTH_PARAM_OPEN) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_OPEN, strlen(BLUETOOTH_PARAM_OPEN)) == 0) {
				helmet_open();
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_HELMET) + strlen(BLUETOOTH_PARAM_CLOSE) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_CLOSE, strlen(BLUETOOTH_PARAM_CLOSE)) == 0) {
				helmet_close();
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_HELMET)) {
			uint8_t state = helmet_state();

			uart_puts(BLUETOOTH_CMD_HELMET);
			uart_puts(": ");

			if (state == HELMET_OPEN) {
				uart_puts(BLUETOOTH_PARAM_OPEN);
			} else {
				uart_puts(BLUETOOTH_PARAM_CLOSE);
			}
			uart_puts("\r\n");

			response = RESPONSE_NO_RESPONSE;
		} else {
			response = RESPONSE_ERROR;
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_INTENSITY, strlen(BLUETOOTH_CMD_INTENSITY)) == 0) {
		uint8_t device = 0;
		char *param = rxbuff + strlen(BLUETOOTH_CMD_INTENSITY) + 1;

		if (strncmp(param, BLUETOOTH_CMD_EYES, strlen(BLUETOOTH_CMD_EYES)) == 0) {
			if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_EYES) + 3) {
				device = EYES;
			} else if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_EYES) + 1) {
				device = EYES;
				response = RESPONSE_NO_RESPONSE;
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (strncmp(param, BLUETOOTH_CMD_REPULSORS, strlen(BLUETOOTH_CMD_REPULSORS)) == 0) {
			if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_REPULSORS) + 3) {
				device = REPULSORS_POWER;
			} else if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_REPULSORS) + 1) {
				device = REPULSORS_POWER;
				response = RESPONSE_NO_RESPONSE;
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (strncmp(param, BLUETOOTH_CMD_UNIBEAM, strlen(BLUETOOTH_CMD_UNIBEAM)) == 0) {
			if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_UNIBEAM) + 3) {
				device = UNIBEAM;
			} else if (len == strlen(BLUETOOTH_CMD_INTENSITY) + strlen(BLUETOOTH_CMD_UNIBEAM) + 1) {
				device = UNIBEAM;
				response = RESPONSE_NO_RESPONSE;
			} else {
				response = RESPONSE_ERROR;
			}
		} else {
			response = RESPONSE_ERROR;
		}

		if (response == RESPONSE_OK) {
			// convert number in ascii to integer
			uint8_t intensity = rxbuff[len - 1] - '0';

			if ((intensity >= 0) && (intensity <= 9)) {
				power_set_intensity(device, intensity);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (response == RESPONSE_NO_RESPONSE) {
			int8_t intensity = power_get_intensity(device);

			uart_puts(BLUETOOTH_CMD_INTENSITY);
			uart_puts(": ");
			uart_putc('0' + intensity);
			uart_puts("\r\n");
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_QUOTE, len) == 0) {
		if (voice_is_playing()) {
			voice_stop_playback();
		} else {
			voice_play_quote();
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_REBOOT, len) == 0) {
		response = RESPONSE_NO_RESPONSE;

		// stop reporting of battery status
		battery_reporting_stop();

		voice_play_sound(SOUND_SLEEP_0);
		_delay_ms(1000);
		voice_play_sound(SOUND_SLEEP_2);
		voice_play_sound_no_wait(SOUND_POWER_DOWN);

		// turn off all devices
		power_off(ALL);

		// restart mcu
		wdt_reboot();
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_REPULSORS, strlen(BLUETOOTH_CMD_REPULSORS)) == 0) {
		char *param = rxbuff + strlen(BLUETOOTH_CMD_REPULSORS) + 1;

		if (len == strlen(BLUETOOTH_CMD_REPULSORS) + strlen(BLUETOOTH_PARAM_ON) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_ON, strlen(BLUETOOTH_PARAM_ON)) == 0) {
				power_on(REPULSORS_POWER);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_REPULSORS) + strlen(BLUETOOTH_PARAM_OFF) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_OFF, strlen(BLUETOOTH_PARAM_OFF)) == 0) {
				power_off(REPULSORS_POWER);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_REPULSORS)) {
			uint8_t state = power_state(REPULSORS_POWER);

			uart_puts(BLUETOOTH_CMD_REPULSORS);
			uart_puts(": ");

			if (state == POWER_ON) {
				uart_puts(BLUETOOTH_PARAM_ON);
			} else {
				uart_puts(BLUETOOTH_PARAM_OFF);
			}
			uart_puts("\r\n");

			response = RESPONSE_NO_RESPONSE;
		} else {
			response = RESPONSE_ERROR;
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_REPULSOR, strlen(BLUETOOTH_CMD_REPULSOR)) == 0) {
		char *param = rxbuff + strlen(BLUETOOTH_CMD_REPULSOR) + 1;

		if (len == strlen(BLUETOOTH_CMD_REPULSOR) + strlen(BLUETOOTH_PARAM_LEFT) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_LEFT, strlen(BLUETOOTH_PARAM_LEFT)) == 0) {
				power_blast(REPULSOR_LEFT);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_REPULSOR) + strlen(BLUETOOTH_PARAM_RIGHT) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_RIGHT, strlen(BLUETOOTH_PARAM_RIGHT)) == 0) {
				power_blast(REPULSOR_RIGHT);
			} else {
				response = RESPONSE_ERROR;
			}
		} else {
			response = RESPONSE_ERROR;
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_UNIBEAM, strlen(BLUETOOTH_CMD_UNIBEAM)) == 0) {
		char *param = rxbuff + strlen(BLUETOOTH_CMD_UNIBEAM) + 1;

		if (len == strlen(BLUETOOTH_CMD_UNIBEAM) + strlen(BLUETOOTH_PARAM_ON) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_ON, strlen(BLUETOOTH_PARAM_ON)) == 0) {
				power_on(UNIBEAM);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_UNIBEAM) + strlen(BLUETOOTH_PARAM_OFF) + 1) {
			if (strncmp(param, BLUETOOTH_PARAM_OFF, strlen(BLUETOOTH_PARAM_OFF)) == 0) {
				power_off(UNIBEAM);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_UNIBEAM)) {
			uint8_t state = power_state(UNIBEAM);

			uart_puts(BLUETOOTH_CMD_UNIBEAM);
			uart_puts(": ");

			if (state == POWER_ON) {
				uart_puts(BLUETOOTH_PARAM_ON);
			} else {
				uart_puts(BLUETOOTH_PARAM_OFF);
			}
			uart_puts("\r\n");

			response = RESPONSE_NO_RESPONSE;
		} else {
			response = RESPONSE_ERROR;
		}
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_VERSION, len) == 0) {
		uart_puts(BLUETOOTH_RESPONSE_VERSION);
		uart_puts("\r\n");
		response = RESPONSE_NO_RESPONSE;
	} else if (strncmp(rxbuff, BLUETOOTH_CMD_VOLUME, strlen(BLUETOOTH_CMD_VOLUME)) == 0) {
		if (len == strlen(BLUETOOTH_CMD_VOLUME) + 2) {
			// convert number in ascii to integer
			uint8_t volume = rxbuff[len - 1] - '0';

			if ((volume >= 0) && (volume <= 7)) {
				voice_set_volume(SOUND_VOLUME_0 + volume);
			} else {
				response = RESPONSE_ERROR;
			}
		} else if (len == strlen(BLUETOOTH_CMD_VOLUME)) {
			uint8_t volume = voice_get_volume() - SOUND_VOLUME_0;

			uart_puts(BLUETOOTH_CMD_VOLUME);
			uart_puts(": ");
			uart_putc('0' + volume);
			uart_puts("\r\n");

			response = RESPONSE_NO_RESPONSE;
		} else {
			response = RESPONSE_ERROR;
		}
	} else {
		response = RESPONSE_ERROR;
	}

	if (response == RESPONSE_OK) {
		uart_puts(BLUETOOTH_RESPONSE_OK);
		uart_puts("\r\n");
	} else if (response == RESPONSE_ERROR) {
		uart_puts(BLUETOOTH_RESPONSE_ERROR);
		uart_puts("\r\n");
	}

	if (echo) {
		uart_puts(BLUETOOTH_PROMPT);
	}
}