// option handler function definitions #include "stdafx.h" #include "HAMConsole.h" #include #include #include #include #include #include #include #include #include using namespace std; std::wstring s2ws(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } // HAMConsole constructor HAMConsole::HAMConsole() { } // offloads device's data writing to text file void HAMConsole::offload_data(void) { // Detect com port device is recognized on // Allow user to input the path to which the output file will be written // run script to create text file containing COM port assignment for HAMonitor /*"chgport | findstr \"VCP0\" > C:\\Users\\cterndru\\Desktop\\com_assignment.txt"*/ char error_buffer[128]; char *path_tokens[MAX_PATH]; char *backslash_path_tokens[MAX_PATH]; int k = 0; string raw_path, line; // Read in the user's desired file path cout << "Enter path to output text file containing activity data:" << endl; cin.ignore(255,'\n'); getline(cin,raw_path); //cout << raw_path << endl; // copy file path into buffer and append null character char *copy_buffer = (char *)malloc((raw_path.length()+1)*sizeof(char)); raw_path.copy(copy_buffer,raw_path.length(),0); copy_buffer[raw_path.length()] = '\0'; //cout << copy_buffer << endl; char *next_token1; // tokenize string by ... path_tokens[k] = strtok_s(copy_buffer,"\\",&next_token1); while (path_tokens[k] != NULL) { //cout << path_tokens[k] << endl; ++k; path_tokens[k] = strtok_s(NULL,"\\",&next_token1); } if (path_tokens[0] == NULL) return; // insert backslash escapes between tokens string backslash = "\\\\"; string path_with_backslashes(path_tokens[0]); k = 1; while (path_tokens[k] != NULL) { path_with_backslashes.append(backslash); path_with_backslashes.append(path_tokens[k]); ++k; } free(copy_buffer); char *copy_buffer2 = (char *)malloc((path_with_backslashes.length()+1)*sizeof(char)); path_with_backslashes.copy(copy_buffer2,path_with_backslashes.length(),0); copy_buffer2[path_with_backslashes.length()] = '\0'; // tokenize string by spaces char *next_token2; k = 0; backslash_path_tokens[k] = strtok_s(copy_buffer2," ",&next_token2); while (backslash_path_tokens[k] != NULL) { //cout << backslash_path_tokens[l] << endl; ++k; backslash_path_tokens[k] = strtok_s(NULL," ",&next_token2); } // insert space characters between tokens string space_char = "\x20"; string path(backslash_path_tokens[0]); k = 1; while (backslash_path_tokens[k] != NULL) { path.append(space_char); path.append(backslash_path_tokens[k]); ++k; } //cout << path << endl; // break up string and later append to correctly interpret whitespace string command = "MODE.COM | findstr COM > "; //string command2 = "\"E:/Senior Design/com_assignment.txt\""; string command_path = "\""; command_path.append(path); command_path.append("\""); command.append(command_path); if (system(command.c_str()) < 0){ strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); // unsuccessful process termination } // text file containing COM port assignment FILE *com_file; // break up string and later append to correctly interpret whitespace //string path1 = "E:/Senior\x20"; //string path2 = "Design/com_assignment.txt"; //path1.append(path2); if (fopen_s(&com_file,path.c_str(),"r") != 0) { strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); } // Read text file // Get second line of text, first line contains COM1 which is reserved char COM_string[60]; if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } // close text file if (fclose(com_file) != 0){ std::cout << "error in closing com_file\n"; return; //exit(1); // unsuccesful process termination } // tokenize string to obtain COM port char *com_port_string; char *next_string; com_port_string = strtok_s(COM_string," :\t\n",&next_string); int m; for (m=0; m<4; m++){ com_port_string = strtok_s(NULL, " :M\t\n",&next_string); } // Check if COM number is greater than 10 // Modify string accordingly string com_temp = com_port_string; if (stoi(com_port_string,nullptr,10) > 9){ com_temp = com_temp.insert(0,"\\\\.\\COM"); } else { com_temp = com_temp.insert(0,"COM"); } // convert string to appriate type to be passed to CreateFile() wstring stemp = s2ws(com_temp); LPCWSTR com_name = stemp.c_str(); wcout << "Device is on " << com_name << endl; // open the com port the device is connected to HANDLE com_port = CreateFile(L"\\\\.\\COM12",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (com_port == INVALID_HANDLE_VALUE){ std::cout << "error: invalid handle value\n"; return; //exit(1); // unsuccessful process termination } // create text file to write data from device to FILE *output_file; if (fopen_s(&output_file,path.c_str(),"w+") != 0){ std::cout << strerror_s(error_buffer,60,errno) << endl; return; //exit(1); // unsuccessful process termination } // Initialize the DCB structure. DCB dcb; BOOL fSuccess; SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); // Build on the current configuration by first retrieving all current // settings. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // Fill in some DCB values and set the com state: // 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_9600; // baud rate dcb.ByteSize = 8; // data size, xmit and rcv dcb.Parity = NOPARITY; // parity bit dcb.StopBits = ONESTOPBIT; // stop bit fSuccess = SetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return; //exit(3); } // Get the comm config again. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // set comm timeouts LPCOMMTIMEOUTS comm_timeouts = (LPCOMMTIMEOUTS)malloc(sizeof(DWORD)*5); comm_timeouts->ReadIntervalTimeout = 1000; // 1 second comm_timeouts->ReadTotalTimeoutConstant = 0; comm_timeouts->ReadTotalTimeoutMultiplier = 10; comm_timeouts->WriteTotalTimeoutConstant = 0; comm_timeouts->WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(com_port,comm_timeouts) == 0){ std::cout << "error: setting timeouts failed\n"; return; //exit(1); } // amount of data sent by the microcontroller per request // can change to multiple of 11 int bytes_per_read = 1023; // Read buffer // buffer size should be multiple of 11 plus 1 char buffer[1024]; LPDWORD bytes_read; bytes_read = (LPDWORD)malloc(sizeof(long)); BOOL readFileVal; BOOL writeFileVal; char writeBuffer[1024]; writeBuffer[0] = 'B'; LPDWORD bytes_written = (LPDWORD)malloc(sizeof(long)); // Send microcontroller 'B' to initiate communication to tell // microcontroller how many bytes to send at a time // writeFileVal = WriteFile(com_port,writeBuffer,1,bytes_written,NULL); if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; exit(1); // unsuccessful process termination } // Wait until an 'B' is received from the microcontroller do { if (ReadFile(com_port,buffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'B'" << endl; } while(buffer[0] != 'B'); // 'B' for next // Send microcontroller the number of bytes to read at a time writeBuffer[0] = bytes_per_read; writeFileVal = WriteFile(com_port,writeBuffer,1,bytes_written,NULL); if (writeFileVal == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until 'S' received from microcontroller do { if (ReadFile(com_port,buffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'S'" << endl; } while(buffer[0] != 'S'); // 'S' for start // Send 'W' to tell microcontroller it may begin sending data writeBuffer[0] = 'W'; writeFileVal = WriteFile(com_port,writeBuffer,1,bytes_written,NULL); if (writeFileVal == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Receiving data over COM port int total_bytes_sent = 4096; int total_bytes_read = 0; int loop_limit; if (total_bytes_sent % bytes_per_read != 0){ loop_limit = (total_bytes_sent/bytes_per_read)+1; } else { loop_limit = total_bytes_sent/bytes_per_read; } int i; for(i = 0; i < loop_limit; i++){ do{ readFileVal = ReadFile(com_port,buffer,bytes_per_read,bytes_read,NULL); total_bytes_read += *bytes_read; if (readFileVal == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } else { int i = 0; while (i < *bytes_read){ // print new line and carriage return if current byte is multiple of 11 // (11 bytes are recorded for each sample) if ((total_bytes_read - *bytes_read + i) % 11 == 0){ fprintf(output_file,"\n\r"); cout << endl; } // omits comma if last character to be printed on a line /*else if ((total_bytes_read - *bytes_read + i + 1) % 11 == 0){ printf("%d",buffer[i]); cout << ','; fprintf(output_file,"%d",buffer[i]); } else { printf("%d",buffer[i]); cout << ','; fprintf(output_file,"%d, ",buffer[i]); }*/ if ((total_bytes_read - *bytes_read + i) % 11 == 5) { char xl = buffer[i]; char xh = buffer[i+1]; int x = (buffer[i+1] << 4) | buffer[i]; printf("%f",x*0.0078); std::cout << ','; fprintf(output_file,"%f, ",x*0.0078); ++i; ++i; } else if ((total_bytes_read - *bytes_read + i) % 11 == 7) { char yl = buffer[i]; char yh = buffer[i+1]; int y = (buffer[i+1] << 4) | buffer[i]; printf("%f",y*0.0078); std::cout << ','; fprintf(output_file,"%f, ",y*0.0078); ++i; ++i; } else if ((total_bytes_read - *bytes_read + i) % 11 == 9){ char zl = buffer[i]; char zh = buffer[i+1]; int z = (buffer[i+1] << 4) | buffer[i]; printf("%f",z*0.0078); std::cout << ','; fprintf(output_file,"%f, ",z*0.0078); ++i; ++i; } else { // change back to %d printf("%d",buffer[i]); std::cout << ','; fprintf(output_file,"%d, ",buffer[i]); ++i; } } } if (bytes_per_read+total_bytes_read > total_bytes_sent){ bytes_per_read = total_bytes_sent - total_bytes_read; } } while(*bytes_read <= 0); // acknowledge to MCU byte received writeFileVal = WriteFile(com_port,writeBuffer,1,bytes_written,NULL); } std::cout << endl; std::cout << "Total bytes received: " << total_bytes_read << endl; std::free(bytes_read); std::free(bytes_written); if (CloseHandle(com_port) == 0){ std::cout << "error in closing the com_port\n"; return; //exit(1); // unsuccessful process termination } else { std::cout << "com_port closed successfully\n"; } if (fclose(output_file) != 0){ std::cout << "error in closing the output file\n"; return; //exit(1); // unsuccesful process termination } else { std::cout << "output file closed successfully\n"; } std::cout << endl; return; } // set device's internal time void HAMConsole::set_device_time(void){ // get path for TEMP environment variable LPCTSTR envar = L"TEMP"; LPTSTR temp_buffer = (LPTSTR)malloc(sizeof(long)*32767); DWORD chars_written = GetEnvironmentVariable(envar,temp_buffer,32767); string temp = CW2A(temp_buffer); temp.append("\\com_assignment.txt"); // break up string and later append to correctly interpret whitespace string command = "MODE.COM | findstr COM > "; //string command2 = "\"E:/Senior Design/com_assignment.txt\""; string command_path = "\""; command_path.append(temp.c_str()); command_path.append("\""); command.append(command_path.c_str()); // find com port device is connected on char error_buffer[128]; if (system(command.c_str()) < 0){ strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); // unsuccessful process termination } // text file containing COM port assignment FILE *com_file; // break up string and later append to correctly interpret whitespace //string path1 = "E:/Senior\x20"; //string path2 = "Design/com_assignment.txt"; //path1.append(path2); if (fopen_s(&com_file,temp.c_str(),"r") != 0) { strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); } // Read text file // Get second line of text, first line contains COM1 which is reserved char COM_string[60]; if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } // close text file if (fclose(com_file) != 0){ std::cout << "error in closing com_file\n"; return; //exit(1); // unsuccesful process termination } // tokenize string to obtain COM port char *com_port_string; char *next_string; com_port_string = strtok_s(COM_string," :\t\n",&next_string); int m; for (m=0; m<4; m++){ com_port_string = strtok_s(NULL, " :M\t\n",&next_string); } // Check if COM number is greater than 10 // Modify string accordingly string com_temp = com_port_string; if (stoi(com_port_string,nullptr,10) > 9){ com_temp = com_temp.insert(0,"\\\\.\\COM"); } else { com_temp = com_temp.insert(0,"COM"); } // convert string to appriate type to be passed to CreateFile() wstring stemp = s2ws(com_temp); LPCWSTR com_name = stemp.c_str(); wcout << "Device is on " << com_name << endl; // open the com port the device is connected to HANDLE com_port = CreateFile(com_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (com_port == INVALID_HANDLE_VALUE){ std::cout << "error: invalid handle value\n"; return; //exit(1); // unsuccessful process termination } // Initialize the DCB structure. DCB dcb; BOOL fSuccess; SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); // Build on the current configuration by first retrieving all current // settings. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // Fill in some DCB values and set the com state: // 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_9600; // baud rate dcb.ByteSize = 8; // data size, xmit and rcv dcb.Parity = NOPARITY; // parity bit dcb.StopBits = ONESTOPBIT; // stop bit fSuccess = SetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return; //exit(3); } // Get the comm config again. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // set comm timeouts LPCOMMTIMEOUTS comm_timeouts = (LPCOMMTIMEOUTS)malloc(sizeof(DWORD)*5); comm_timeouts->ReadIntervalTimeout = 1000; // 1 second comm_timeouts->ReadTotalTimeoutConstant = 0; comm_timeouts->ReadTotalTimeoutMultiplier = 10; comm_timeouts->WriteTotalTimeoutConstant = 0; comm_timeouts->WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(com_port,comm_timeouts) == 0){ std::cout << "error: setting timeouts failed\n"; return; //exit(1); } cin.clear(); cin.ignore(255,'\n'); int hours, minutes, seconds; // accept time from user while(1){ string time_line; cout << "Enter time (hh:mm:ss) to set device's real-time clock" << endl; cout << "(if no time entered, system time will be used): "; getline(cin,time_line); // tokenize time into hours, minutes, seconds char *token_buffer[3]; char *next; int i = 0; char *copy_buffer = (char *)malloc((time_line.length()+1)*sizeof(char)); time_line.copy(copy_buffer,time_line.length(),0); copy_buffer[time_line.length()] = '\0'; token_buffer[i] = strtok_s(copy_buffer,":",&next); //if (token_buffer[i] == NULL) continue; for (i=1; i < 3 /*&& token_buffer[i] !=NULL*/; i++) { token_buffer[i] = strtok_s(NULL,":",&next); } try { hours = stoi(token_buffer[0],nullptr,10); minutes = stoi(token_buffer[1],nullptr,10); seconds = stoi(token_buffer[2],nullptr,10); } catch (...) { //char error_string[256]; //strerror_s(error_string,256,error); cout << "Enter integers for hours, minutes, seconds" << endl; free(copy_buffer); continue; } if ((hours >= 0 && hours <= 23) && (minutes >= 0 && minutes <= 59) && (seconds >= 0 && seconds <= 59)) { cout << "Hours: " << hours << " Minutes: " << minutes << " Seconds: " << seconds << endl; free(copy_buffer); break; } cout << "Enter a valid time" << endl; free(copy_buffer); } // send 'T' to initiate memory clear char writeBuffer[8]; char readBuffer[8]; LPDWORD bytes_written = (LPDWORD)malloc(sizeof(long));; LPDWORD bytes_read = (LPDWORD)malloc(sizeof(long));; writeBuffer[0] = 'T'; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'T' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'T'" << endl; } while(readBuffer[0] != 'T'); // 'T' for next // send time to microcontroller writeBuffer[0] = hours; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'T' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'T'" << endl; } while(readBuffer[0] != 'S'); // 'T' for next writeBuffer[0] = minutes; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'T' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'T'" << endl; } while(readBuffer[0] != 'S'); // 'T' for next writeBuffer[0] = seconds; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'T' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'T'" << endl; } while(readBuffer[0] != 'S'); // 'T' for next //TEST /*do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'T'" << endl; } while(readBuffer[0] != 'X'); // 'T' for next*/ if (CloseHandle(com_port) == 0){ std::cout << "error in closing the com_port\n"; return; //exit(1); // unsuccessful process termination } else { std::cout << "com_port closed successfully\n"; } std::cout << endl; return; } // set device's id void HAMConsole::set_device_id(void){ // get path for TEMP environment variable LPCTSTR envar = L"TEMP"; LPTSTR temp_buffer = (LPTSTR)malloc(sizeof(long)*32767); DWORD chars_written = GetEnvironmentVariable(envar,temp_buffer,32767); string temp = CW2A(temp_buffer); temp.append("\\com_assignment.txt"); // break up string and later append to correctly interpret whitespace string command = "MODE.COM | findstr COM > "; //string command2 = "\"E:/Senior Design/com_assignment.txt\""; string command_path = "\""; command_path.append(temp.c_str()); command_path.append("\""); command.append(command_path.c_str()); // find com port device is connected on char error_buffer[128]; if (system(command.c_str()) < 0){ strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); // unsuccessful process termination } // text file containing COM port assignment FILE *com_file; // break up string and later append to correctly interpret whitespace //string path1 = "E:/Senior\x20"; //string path2 = "Design/com_assignment.txt"; //path1.append(path2); if (fopen_s(&com_file,temp.c_str(),"r") != 0) { strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); } // Read text file // Get second line of text, first line contains COM1 which is reserved char COM_string[60]; if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } // close text file if (fclose(com_file) != 0){ std::cout << "error in closing com_file\n"; return; //exit(1); // unsuccesful process termination } // tokenize string to obtain COM port char *com_port_string; char *next_string; com_port_string = strtok_s(COM_string," :\t\n",&next_string); int m; for (m=0; m<4; m++){ com_port_string = strtok_s(NULL, " :M\t\n",&next_string); } // Check if COM number is greater than 10 // Modify string accordingly string com_temp = com_port_string; if (stoi(com_port_string,nullptr,10) > 9){ com_temp = com_temp.insert(0,"\\\\.\\COM"); } else { com_temp = com_temp.insert(0,"COM"); } // convert string to appriate type to be passed to CreateFile() wstring stemp = s2ws(com_temp); LPCWSTR com_name = stemp.c_str(); wcout << "Device is on " << com_name << endl; // open the com port the device is connected to HANDLE com_port = CreateFile(com_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (com_port == INVALID_HANDLE_VALUE){ std::cout << "error: invalid handle value\n"; return; //exit(1); // unsuccessful process termination } // Initialize the DCB structure. DCB dcb; BOOL fSuccess; SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); // Build on the current configuration by first retrieving all current // settings. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // Fill in some DCB values and set the com state: // 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_9600; // baud rate dcb.ByteSize = 8; // data size, xmit and rcv dcb.Parity = NOPARITY; // parity bit dcb.StopBits = ONESTOPBIT; // stop bit fSuccess = SetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return; //exit(3); } // Get the comm config again. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // set comm timeouts LPCOMMTIMEOUTS comm_timeouts = (LPCOMMTIMEOUTS)malloc(sizeof(DWORD)*5); comm_timeouts->ReadIntervalTimeout = 1000; // 1 second comm_timeouts->ReadTotalTimeoutConstant = 0; comm_timeouts->ReadTotalTimeoutMultiplier = 10; comm_timeouts->WriteTotalTimeoutConstant = 0; comm_timeouts->WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(com_port,comm_timeouts) == 0){ std::cout << "error: setting timeouts failed\n"; return; //exit(1); } // send 'D' to initiate memory clear char writeBuffer[8]; char readBuffer[8]; LPDWORD bytes_written = (LPDWORD)malloc(sizeof(long));; LPDWORD bytes_read = (LPDWORD)malloc(sizeof(long));; writeBuffer[0] = 'D'; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'D' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'D'" << endl; } while(readBuffer[0] != 'D'); // 'D ' for next // send device ID string line; unsigned int dev_ID; do { cout << "Enter a device ID to associate with the connected device (0 to 255): "; cin >> dev_ID; cout << endl; } while (dev_ID < 0 || dev_ID > 255); writeBuffer[0] = dev_ID; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'S' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'S'" << endl; } while(readBuffer[0] != 'S'); // 'S' for next // close open files, ports, etc. // free dynamically allocated memory free(bytes_read); free(bytes_written); if (CloseHandle(com_port) == 0){ std::cout << "error in closing the com_port\n"; return; //exit(1); // unsuccessful process termination } else { std::cout << "com_port closed successfully\n"; } std::cout << endl; return; } // erase device's flash memory contents void HAMConsole::clear_memory(void){ // get path for TEMP environment variable LPCTSTR envar = L"TEMP"; LPTSTR temp_buffer = (LPTSTR)malloc(sizeof(long)*32767); DWORD chars_written = GetEnvironmentVariable(envar,temp_buffer,32767); string temp = CW2A(temp_buffer); temp.append("\\com_assignment.txt"); // break up string and later append to correctly interpret whitespace string command = "MODE.COM | findstr COM > "; //string command2 = "\"E:/Senior Design/com_assignment.txt\""; string command_path = "\""; command_path.append(temp.c_str()); command_path.append("\""); command.append(command_path.c_str()); // find com port device is connected on char error_buffer[128]; if (system(command.c_str()) < 0){ strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); // unsuccessful process termination } // text file containing COM port assignment FILE *com_file; // break up string and later append to correctly interpret whitespace //string path1 = "E:/Senior\x20"; //string path2 = "Design/com_assignment.txt"; //path1.append(path2); if (fopen_s(&com_file,temp.c_str(),"r") != 0) { strerror_s(error_buffer,128,errno); std::cout << error_buffer << endl; return; //exit(1); } // Read text file // Get second line of text, first line contains COM1 which is reserved char COM_string[60]; if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } if (fgets(COM_string,60,com_file) == NULL){ std::cout << strerror_s(error_buffer,128,errno) << endl; return; //exit(1); // unsuccessful process termination } // close text file if (fclose(com_file) != 0){ std::cout << "error in closing com_file\n"; return; //exit(1); // unsuccesful process termination } // tokenize string to obtain COM port char *com_port_string; char *next_string; com_port_string = strtok_s(COM_string," :\t\n",&next_string); int m; for (m=0; m<4; m++){ com_port_string = strtok_s(NULL, " :M\t\n",&next_string); } // Check if COM number is greater than 10 // Modify string accordingly string com_temp = com_port_string; if (stoi(com_port_string,nullptr,10) > 9){ com_temp = com_temp.insert(0,"\\\\.\\COM"); } else { com_temp = com_temp.insert(0,"COM"); } // convert string to appriate type to be passed to CreateFile() wstring stemp = s2ws(com_temp); LPCWSTR com_name = stemp.c_str(); wcout << "Device is on " << com_name << endl; // open the com port the device is connected to HANDLE com_port = CreateFile(com_name,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (com_port == INVALID_HANDLE_VALUE){ std::cout << "error: invalid handle value\n"; return; //exit(1); // unsuccessful process termination } // Initialize the DCB structure. DCB dcb; BOOL fSuccess; SecureZeroMemory(&dcb, sizeof(DCB)); dcb.DCBlength = sizeof(DCB); // Build on the current configuration by first retrieving all current // settings. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // Fill in some DCB values and set the com state: // 57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_9600; // baud rate dcb.ByteSize = 8; // data size, xmit and rcv dcb.Parity = NOPARITY; // parity bit dcb.StopBits = ONESTOPBIT; // stop bit fSuccess = SetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return; //exit(3); } // Get the comm config again. fSuccess = GetCommState(com_port, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return; //exit(2); } // set comm timeouts LPCOMMTIMEOUTS comm_timeouts = (LPCOMMTIMEOUTS)malloc(sizeof(DWORD)*5); comm_timeouts->ReadIntervalTimeout = 1000; // 1 second comm_timeouts->ReadTotalTimeoutConstant = 0; comm_timeouts->ReadTotalTimeoutMultiplier = 10; comm_timeouts->WriteTotalTimeoutConstant = 0; comm_timeouts->WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(com_port,comm_timeouts) == 0){ std::cout << "error: setting timeouts failed\n"; return; //exit(1); } // send 'C' to initiate memory clear char writeBuffer[8]; char readBuffer[8]; LPDWORD bytes_written = (LPDWORD)malloc(sizeof(long));; LPDWORD bytes_read = (LPDWORD)malloc(sizeof(long));; writeBuffer[0] = 'C'; if (WriteFile(com_port,writeBuffer,1,bytes_written,NULL) == 0){ std::cout << "error: WriteFile() failed\n"; return; //exit(1); // unsuccessful process termination } // Wait until an 'C' is received from the microcontroller do { if (ReadFile(com_port,readBuffer,1,bytes_read,NULL) == 0){ std::cout << "error: ReadFile() failed\n"; return; //exit(1); // unsuccessful process termination } //cout << "waiting for 'C'" << endl; } while(readBuffer[0] != 'C'); // 'C' for next // close open files, ports, etc. // free dynamically allocated memory free(bytes_read); free(bytes_written); if (CloseHandle(com_port) == 0){ std::cout << "error in closing the com_port\n"; return; //exit(1); // unsuccessful process termination } else { std::cout << "com_port closed successfully\n"; } std::cout << endl; return; } // prints instructions for using each option void HAMConsole::help(void) { std::cout << "DESCRIPTION OF OPTIONS" << endl; std::cout << "1. Offload data from device memory" << endl; std::cout << '\t' << "offload's activity data from device's flash memory and writes to text file" << endl; std::cout << '\t' << "Be sure to enter valid file path when prompted" << endl; std::cout << "2. Set device time" << endl; std::cout << '\t' << "set's the device's internal time using real-time clock" << endl; std::cout << '\t' << "time format: hh:mm:ss (e.g. 17:15:01)" << endl; std::cout << '\t' << "default time is computer system time" << endl; std::cout << "3. Enter device ID" << endl; std::cout << '\t' << "sets device id to differentiate between many devices" << endl; std::cout << "4. Clear memory contents" << endl; std::cout << '\t' << "erases device's flash memory" << endl; std::cout << "5. Help" << endl; std::cout << "6. Exit" << endl; std::cout << '\t' << "terminates ACTIVITY MONITOR DATA OFFLOAD PROGRAM" << endl; std::cout << endl; }