You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

508 lines
12 KiB

// Copyright 2018 Mobvoi Inc. All Rights Reserved.
#define _BSD_SOURCE
#define _DEFAULT_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
//#include <unistd.h>
//#include <termios.h>
//#include <sys/time.h>
#include<windows.h>
#include "Serial8008.h"
enum {
CMD_EXIT = 0,
CMD_ENABLE_BF = 1,
CMD_DISABLE_BF = 2,
CMD_GET_BF_STATUS = 3,
CMD_SET_BF_DIR = 4,
CMD_GET_DOA_DIR = 5,
CMD_GET_BF_DIRS = 6,
CMD_GET_WAKEUP_WORDS = 7,
CMD_SET_LED_ON = 8,
CMD_SET_LED_OFF = 9,
CMD_DUMP_UART_HEX = 98,
CMD_SHOW_UART_LOG = 99,
};
//#define SEND_TEST_COMMAND
#define LOG_TAG "DEMO"
static inline void SerialLog(const char* fmt, ...) {
va_list vl;
char s[1024] = { 0 };
va_start(vl, fmt);
vsprintf(s, fmt, vl);
va_end(vl);
printf("%s: %s",LOG_TAG, s);
}
void Usage() {
SerialLog(
"\nCommand list:\n"
"\t0 : Exit\n"
"\t1 : Enable beamforming\n"
"\t2 : Disable beamforming\n"
"\t3 : Get beamforming status\n"
"\t4 <dir>: Set beamforming direction\n"
"\t5 : Get DOA direction\n"
"\t6 : Get all beamforming directions\n"
"\t7 : Get wakeup words\n"
"\t8 <dir>: Turn on LED\n"
"\t9 : Turn off LED\n"
"\t98 : Switch hex dumpping\n"
"\t99 : Switch showing log from UART\n"
"\tENTER : Repeat last command\n"
);
}
static int exit_flag = 0;
static int show_log = 1;
static int dump_hex = 0;
static int test_mode = 0;
void send_command(void* fd, int argc, int cmd, int param);
#ifdef SEND_TEST_COMMAND
void* send_test_command(void* fd) {
int cmds[] = {4, 5, 6, 7};
while (exit_flag == 0) {
int cmd = cmds[rand() % (sizeof(cmds) / sizeof(cmds[0]))];
int argc = 1;
if (cmd == 4) {
send_command(fd, 2, cmd, rand() % 360);
} else {
send_command(fd, 1, cmd, 0);
}
//sleep(rand() % 10 + 1);
Sleep(rand() % 10 + 1);
}
}
#endif
void* send_commands(void* fd) {
char line[64];
int cmd = 0;
int param = 0;
int argc = 0;
while (exit_flag == 0 && fgets(line, sizeof(line), stdin) != NULL) {
if (line[0] != '\n' || cmd == 0) {
argc = sscanf(line, "%d %d", &cmd, &param);
if (argc < 1) {
Usage();
continue;
}
}
send_command(fd, argc, cmd, param);
}
return NULL;
}
void send_command(void* fd, int argc, int cmd, int param) {
int msg_len = 0;
char msg_buff[MAX_MSG_LEN] = {0};
mob_gs_msg* msg = (mob_gs_msg*) msg_buff;
switch (cmd) {
case CMD_EXIT: {
exit_flag = 1;
SerialLog("Exiting\n");
break;
}
case CMD_ENABLE_BF: {
msg->event = EVENT_FROM_HOST_ENABLE_BF;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_DISABLE_BF: {
msg->event = EVENT_FROM_HOST_DISABLE_BF;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_GET_BF_STATUS: {
msg->event = EVENT_FROM_HOST_GET_BF_STATUS;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_SET_BF_DIR: {
if (argc < 2) {
SerialLog("Parameter error\n");
Usage();
break;
}
msg->event = EVENT_FROM_HOST_SET_BF_DIR;
msg->payload_len = 2;
mob_short2bytes(param, msg->payload_data);
msg_len = sizeof(mob_gs_msg) + msg->payload_len;
break;
}
case CMD_GET_DOA_DIR: {
msg->event = EVENT_FROM_HOST_GET_DOA_DIR;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_GET_BF_DIRS: {
msg->event = EVENT_FROM_HOST_GET_BF_DIR_LIST;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_GET_WAKEUP_WORDS: {
msg->event = EVENT_FROM_HOST_GET_WAKEUP_WORD;
msg->payload_len = 0;
msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_SET_LED_ON: {
if (argc < 2) {
SerialLog("Parameter error\n");
Usage();
break;
}
msg->event = EVENT_FROM_HOST_SET_LED;
msg->payload_len = 2;
short leds = 1 << param;
mob_short2bytes(leds, msg->payload_data);
msg_len = sizeof(mob_gs_msg) + msg->payload_len;
break;
}
case CMD_SET_LED_OFF: {
msg->event = EVENT_FROM_HOST_SET_LED;
msg->payload_len = 2;
short leds = 0;
mob_short2bytes(leds, msg->payload_data);
msg_len = sizeof(mob_gs_msg) + msg->payload_len;
break;
}
case CMD_DUMP_UART_HEX: {
dump_hex = !dump_hex;
SerialLog("Flag of dump is %s\n", dump_hex ? "ON" : "OFF");
break;
}
case CMD_SHOW_UART_LOG: {
show_log = !show_log;
SerialLog("Flag of log is %s\n", show_log ? "ON" : "OFF");
break;
}
default: {
Usage();
break;
}
}
if (msg_len > 0) {
msg->sync_tag[0] = SYNC_TAG[0];
msg->sync_tag[1] = SYNC_TAG[1];
msg->sync_tag[2] = SYNC_TAG[2];
msg->sync_tag[3] = SYNC_TAG[3];
msg->check_bits = 0;
msg->reserved = 0;
#ifdef SEND_TEST_COMMAND
if (test_mode) {
msg_len = 10000;
}
#endif
int ret = write(*(int*)fd, msg, msg_len);
if (ret < 0) {
SerialLog("Wrote %d %d\n", ret, errno);
}
}
}
void process_results(mob_gs_msg* msg) {
SerialLog("Event: 0x%02hhX\n", msg->event);
switch (msg->event) {
case EVENT_TO_HOST_WAKEUP: {
SerialLog("Waked up\n");
break;
}
case EVENT_TO_HOST_WAKEUP_WORDS: {
SerialLog("Wake up words: ");
char* buff = msg->payload_data;
while (buff < (msg->payload_data + msg->payload_len)) {
printf("%s ", buff);
buff += strlen(buff) + 1;
}
printf("\n");
break;
}
case EVENT_TO_HOST_DOA_DIR: {
if (msg->payload_len < sizeof(short)) {
SerialLog("Invalid payload len %d\n", msg->payload_len);
} else {
SerialLog("Doa dir: %d\n", mob_bytes2short(msg->payload_data));
}
break;
}
case EVENT_TO_HOST_BF_DIR_LIST: {
if (msg->payload_len < sizeof(short)) {
SerialLog("Invalid payload len %d\n", msg->payload_len);
} else {
SerialLog("BF dir list:");
for (int i = 0; i < msg->payload_len / sizeof(short); i++) {
printf(" %d",
mob_bytes2short(msg->payload_data + i * sizeof(short)));
}
printf("\n");
}
break;
}
case EVENT_TO_HOST_BF_STATUS: {
if (msg->payload_len < sizeof(short)) {
SerialLog("Invalid payload len %d\n", msg->payload_len);
} else {
SerialLog("BF dir: %d, ", mob_bytes2short(msg->payload_data));
printf("%s\n",
mob_bytes2short(msg->payload_data + 2) ? "enabled" : "disabled");
}
break;
}
default: {
SerialLog("Unknown event: %d\n", msg->event);
break;
}
}
}
void* recv_results(void* fd) {
char msg_buff[MAX_MSG_LEN] = {0};
int last_remain = 0;
while (exit_flag == 0) {
char* buff = msg_buff + last_remain;
int size = read(*(int*)fd, buff, MAX_MSG_LEN - last_remain);
// printf("read out %d, %d\n", size, errno);
if (size <= 0) {
//sleep(1);
Sleep(1);
continue;
}
if (size > 0) {
if (show_log) printf("%s", buff);
if (dump_hex) {
SerialLog("Msg arrived(%d):", size);
for (int i = 0; i < size; i++) {
printf(" %02hhX", buff[i]);
}
printf("\n");
}
}
buff = msg_buff;
size += last_remain;
while (size >= sizeof(mob_gs_msg)) {
if (buff[0] != SYNC_TAG[0] || buff[1] != SYNC_TAG[1] ||
buff[2] != SYNC_TAG[2] || buff[3] != SYNC_TAG[3]) {
buff++;
size--;
// printf("sync failed! discard 1 byte\n");
continue;
}
mob_gs_msg* msg = (mob_gs_msg*) buff;
if ((sizeof(mob_gs_msg) + msg->payload_len) > MAX_MSG_LEN) {
size -= sizeof(mob_gs_msg);
buff += sizeof(mob_gs_msg);
SerialLog("Invalid payload len, discard msg\n");
continue;
}
if (size < (sizeof(mob_gs_msg) + msg->payload_len)) break;
process_results(msg);
int processed = sizeof(mob_gs_msg) + msg->payload_len;
buff += processed;
size -= processed;
}
last_remain = size;
if (size > 0) {
memmove(msg_buff, buff, size);
if (dump_hex) {
SerialLog("Remain data(%d):", size);
for(int i = 0; i < size; i++) {
printf(" %02hhX", msg_buff[i]);
}
printf("\n");
}
}
memset(msg_buff + size, 0, MAX_MSG_LEN - size);
}
return NULL;
}
//////
void createCommandMsg(int argc, int cmd, int param, mob_gs_msg * msg, int * msg_len) {
//int msg_len = 0;
//char msg_buff[MAX_MSG_LEN] = { 0 };
//mob_gs_msg* msg = (mob_gs_msg*)msg_buff;
switch (cmd) {
case CMD_EXIT: {
exit_flag = 1;
SerialLog("Exiting\n");
break;
}
case CMD_ENABLE_BF: {
msg->event = EVENT_FROM_HOST_ENABLE_BF;
msg->payload_len = 0;
*msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_DISABLE_BF: {
msg->event = EVENT_FROM_HOST_DISABLE_BF;
msg->payload_len = 0;
*msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_GET_BF_STATUS: {
msg->event = EVENT_FROM_HOST_GET_BF_STATUS;
msg->payload_len = 0;
*msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_SET_BF_DIR: {
if (argc < 2) {
SerialLog("Parameter error\n");
Usage();
break;
}
msg->event = EVENT_FROM_HOST_SET_BF_DIR;
msg->payload_len = 2;
mob_short2bytes(param, msg->payload_data);
*msg_len = sizeof(mob_gs_msg) + msg->payload_len;
break;
}
case CMD_GET_DOA_DIR: {
msg->event = EVENT_FROM_HOST_GET_DOA_DIR;
msg->payload_len = 0;
*msg_len = sizeof(mob_gs_msg);
break;
}
case CMD_GET_BF_DIRS: {
msg->event = EVENT_FROM_HOST_GET_BF_DIR_LIST;
msg->payload_len = 0;
*msg_len = sizeof(mob_gs_msg);
break;
}
default: {
Usage();
break;
}
}
if (*msg_len > 0) {
msg->sync_tag[0] = SYNC_TAG[0];
msg->sync_tag[1] = SYNC_TAG[1];
msg->sync_tag[2] = SYNC_TAG[2];
msg->sync_tag[3] = SYNC_TAG[3];
msg->check_bits = 0;
msg->reserved = 0;
#ifdef SEND_TEST_COMMAND
if (test_mode) {
*msg_len = 10000;
}
#endif
}
}
void* recv_resultsForTimes(int count, HANDLE hCom ) {
char msg_buff[MAX_MSG_LEN] = { 0 };
int last_remain = 0;
while (( exit_flag == 0) && (count > 0) ) {
count= count-1;
char* buff = msg_buff + last_remain;
DWORD size = 0;
//ͬ����ʽ
DWORD wCount = MAX_MSG_LEN - last_remain; //�ɹ���ȡ�������ֽ���
BOOL bReadStat = ReadFile(hCom, //���ھ���
buff, //�����׵�ַ
wCount, //Ҫ��ȡ�����������ֽ���
&size, //DWORD*,�������շ��سɹ���ȡ�������ֽ���
NULL); //NULLΪͬ�����ͣ�OVERLAPPED*Ϊ�첽����
// printf("read out %d, %d\n", size, errno);
if (size <= 0) {
//sleep(1);
Sleep(1);
continue;
}
if (size > 0) {
if (show_log) printf("%s", buff);
if (dump_hex) {
SerialLog("Msg arrived(%d):", size);
for (int i = 0; i < size; i++) {
printf(" %02hhX", buff[i]);
}
printf("\n");
}
}
buff = msg_buff;
size += last_remain;
while (size >= sizeof(mob_gs_msg)) {
if (buff[0] != SYNC_TAG[0] || buff[1] != SYNC_TAG[1] ||
buff[2] != SYNC_TAG[2] || buff[3] != SYNC_TAG[3]) {
buff++;
size--;
// printf("sync failed! discard 1 byte\n");
continue;
}
mob_gs_msg* msg = (mob_gs_msg*)buff;
if ((sizeof(mob_gs_msg) + msg->payload_len) > MAX_MSG_LEN) {
size -= sizeof(mob_gs_msg);
buff += sizeof(mob_gs_msg);
SerialLog("Invalid payload len, discard msg\n");
continue;
}
if (size < (sizeof(mob_gs_msg) + msg->payload_len)) break;
process_results(msg);
int processed = sizeof(mob_gs_msg) + msg->payload_len;
buff += processed;
size -= processed;
}
last_remain = size;
if (size > 0) {
memmove(msg_buff, buff, size);
if (dump_hex) {
SerialLog("Remain data(%d):", size);
for (int i = 0; i < size; i++) {
printf(" %02hhX", msg_buff[i]);
}
printf("\n");
}
}
memset(msg_buff + size, 0, MAX_MSG_LEN - size);
}
return NULL;
}