//=================================================================== // // server features // bool LIBCOD_CALL server_isalive( server_t *server ) { clock_t start = clock(); clock_t end = 0; string buff = xmalloc( 2048 ); int err = server_raw_socket( server, "\xff\xff\xff\xffgetstatus", buff, 2048 ); if ( err > 0 ) { xfree( buff ); spawn_error( "Error while running server_isalive", false ); return false; } end = clock(); server->pingdelay = (int) ( ( ( (double) end - (double) start ) / CLOCKS_PER_SEC ) * 1000 ); server->timeout = (int) ( ( server->pingdelay / 1000 ) + 1 ); xfree( buff ); return true; }
string LIBCOD_CALL server_private_rcon_sz( server_t *server, const string command, const size_t size ) { if ( server->lastrconcommand == 0 ) server->lastrconcommand = clock(); clock_t now = clock(); int length = (int) ( ( ( (double) now - (double) server->lastrconcommand ) / CLOCKS_PER_SEC ) * 1000 ); if ( length < server->rcondelay ) msleep( server->rcondelay - length ); string buff = xmalloc( size ); string str = xmalloc( ( strlen( server->rconpassword ) + strlen( command ) + 12 ) ); sprintf( str, "\xff\xff\xff\xffrcon %s %s", server->rconpassword, command ); int err = server_raw_socket( server, str, buff, size ); xfree( str ); if ( err > 0 ) { xfree( buff ); spawn_error( "Error while running server_private_rcon", false ); return NULL; } server->lastrconcommand = clock(); int newlen = strlen( buff ) - indexof( buff, '\n', 0 ); string newbuff = xmalloc( newlen + 1 ); int i = indexof( buff, '\n', 0 ); int j = 0; for ( ; i < strlen( buff ); i++ ) { newbuff[ j ] = buff[ i ]; j++; } newbuff[ j ] = 0; xfree( buff ); trim( newbuff ); return newbuff; }
bool usb_init(programmer_t *pgm, unsigned int vid, unsigned int pid) { libusb_device **devs; libusb_context *ctx = NULL; int r; ssize_t cnt; r = libusb_init(&ctx); if(r < 0) return(false); #ifdef STM8FLASH_LIBUSB_QUIET libusb_set_debug(ctx, 0); #else libusb_set_debug(ctx, 3); #endif cnt = libusb_get_device_list(ctx, &devs); if(cnt < 0) return(false); pgm->dev_handle = libusb_open_device_with_vid_pid(ctx, vid, pid); pgm->ctx = ctx; if (!pgm->dev_handle) spawn_error("Could not open USB device."); // assert(pgm->dev_handle); libusb_free_device_list(devs, 1); //free the list, unref the devices in it if(libusb_kernel_driver_active(pgm->dev_handle, 0) == 1) { //find out if kernel driver is attached int r = libusb_detach_kernel_driver(pgm->dev_handle, 0); assert(r == 0); } #if defined(__APPLE__) || defined(WIN32) r = libusb_claim_interface(pgm->dev_handle, 0); assert(r == 0); #endif return(true); }
void LIBCOD_CALL server_detectversion( server_t *server ) { string buff = xmalloc( 1024 ); int err = server_raw_socket( server, "\xff\xff\xff\xffgetinfo xxx", buff, 1024 ); if ( err > 0 || indexof( buff, '\\', 0 ) < 0 ) { xfree( buff ); spawn_error( "Error while running server_detectversion", false ); return; } string infostring = substring( buff, indexof( buff, '\\', 0 ), strlen( buff ) ); xfree( buff ); string val = Info_ValueForKey( infostring, "protocol" ); int gameversion = UNKNOWN; if ( strcmp( val, "" ) == 0 ) return; int protocol = atoi( val ); switch ( protocol ) { // Call of Duty case 1: gameversion = COD_1_1; break; case 2: gameversion = COD_1_2; break; case 4: gameversion = COD_1_3; break; case 5: gameversion = COD_1_4; break; case 6: gameversion = COD_1_5; break; // Call of Duty: United Offensive case 21: gameversion = CODUO_1_41; break; case 22: gameversion = CODUO_1_51; break; // Call of Duty 2 case 115: gameversion = COD2_1_0; break; case 116: gameversion = COD2_1_01; break; case 117: gameversion = COD2_1_2; break; case 118: gameversion = COD2_1_3; break; // Call of Duty: World at War case 93: gameversion = CODWAW_1_0; break; case 94: gameversion = CODWAW_1_0_1017; break; case 95: gameversion = CODWAW_1_1; break; case 96: gameversion = CODWAW_1_2; break; case 97: gameversion = CODWAW_1_3; break; case 98: gameversion = CODWAW_1_4; break; case 99: gameversion = CODWAW_1_5; break; case 100: gameversion = CODWAW_1_6; break; case 101: gameversion = CODWAW_1_7; break; default: break; } if ( gameversion == UNKNOWN ) { string voice = Info_ValueForKey( infostring, "voice" ); if ( strcmp( voice, "" ) != 0 ) { switch ( protocol ) { // Call of Duty 4 case 0: gameversion = COD4_1_1; break; case 1: gameversion = COD4_1_2; break; case 2: gameversion = COD4_1_3; break; case 3: gameversion = COD4_1_4; break; case 4: gameversion = COD4_1_5; break; case 5: gameversion = COD4_1_6; break; case 6: gameversion = COD4_1_7; break; default: break; } } } xfree( infostring ); server->version = gameversion; server->versionstring = versionstring( gameversion ); }
int main(int argc, char **argv) { unsigned int start; int bytes_count = 0; char filename[256]; memset(filename, 0, sizeof(filename)); // Parsing command line char c; action_t action = NONE; bool start_addr_specified = false, pgm_specified = false, part_specified = false, bytes_count_specified = false; memtype_t memtype = FLASH; int i; programmer_t *pgm = NULL; const stm8_device_t *part = NULL; while((c = getopt (argc, argv, "r:w:v:nc:p:s:b:luV")) != (char)-1) { switch(c) { case 'c': pgm_specified = true; for(i = 0; pgms[i].name; i++) { if(!strcmp(optarg, pgms[i].name)) pgm = &pgms[i]; } break; case 'p': part_specified = true; part = get_part(optarg); break; case 'l': for(i = 0; stm8_devices[i].name; i++) printf("%s ", stm8_devices[i].name); printf("\n"); exit(0); case 'r': action = READ; strcpy(filename, optarg); break; case 'w': action = WRITE; strcpy(filename, optarg); break; case 'v': action = VERIFY; strcpy(filename, optarg); break; case 'u': action = UNLOCK; start = 0x4800; memtype = OPT; strcpy(filename, "Workaround"); break; case 's': // Start addr is depending on MCU type if(strcasecmp(optarg, "flash") == 0) { memtype = FLASH; } else if(strcasecmp(optarg, "eeprom") == 0) { memtype = EEPROM; } else if(strcasecmp(optarg, "ram") == 0) { memtype = RAM; } else if(strcasecmp(optarg, "opt") == 0) { memtype = OPT; } else { // Start addr is specified explicitely memtype = UNKNOWN; int success = sscanf(optarg, "%x", &start); assert(success); start_addr_specified = true; } break; case 'b': bytes_count = atoi(optarg); bytes_count_specified = true; break; case 'V': print_version_and_exit( (bool)0); break; case '?': print_help_and_exit(argv[0], false); default: print_help_and_exit(argv[0], true); } } if(argc <= 1) print_help_and_exit(argv[0], true); if(pgm_specified && !pgm) { fprintf(stderr, "No valid programmer specified. Possible values are:\n"); dump_pgms( (programmer_t *) &pgms); exit(-1); } if(!pgm) spawn_error("No programmer has been specified"); if(part_specified && !part) { fprintf(stderr, "No valid part specified. Use -l to see the list of supported devices.\n"); exit(-1); } if(!part) spawn_error("No part has been specified"); // Try define memory type by address if(memtype == UNKNOWN) { if((start >= 0x4800) && (start < 0x4880)) { memtype = OPT; } if((start >= part->ram_start) && (start < part->ram_start + part->ram_size)) { memtype = RAM; } else if((start >= part->flash_start) && (start < part->flash_start + part->flash_size)) { memtype = FLASH; } else if((start >= part->eeprom_start) && (start < part->eeprom_start + part->eeprom_size)) { memtype = EEPROM; } } if(memtype != UNKNOWN) { // Selecting start addr depending on // specified part and memtype switch(memtype) { case RAM: if(!start_addr_specified) { start = part->ram_start; } if(!bytes_count_specified || bytes_count > part->ram_size) { bytes_count = part->ram_size; } fprintf(stderr, "Determine RAM area\r\n"); break; case EEPROM: if(!start_addr_specified) { start = part->eeprom_start; } if(!bytes_count_specified || bytes_count > part->eeprom_size) { bytes_count = part->eeprom_size; } fprintf(stderr, "Determine EEPROM area\r\n"); break; case FLASH: if(!start_addr_specified) { start = part->flash_start; } if(!bytes_count_specified || bytes_count > part->flash_size) { bytes_count = part->flash_size; } fprintf(stderr, "Determine FLASH area\r\n"); break; case OPT: if(!start_addr_specified) { start = 0x4800; } size_t opt_size = (part->flash_size <= 8*1024 ? 0x40 : 0x80); if(!bytes_count_specified || bytes_count > opt_size) { bytes_count = opt_size; } fprintf(stderr, "Determine OPT area\r\n"); break; } start_addr_specified = true; } if(!action) spawn_error("No action has been specified"); if(!start_addr_specified) spawn_error("No memtype or start_addr has been specified"); if (!strlen(filename)) spawn_error("No filename has been specified"); if(!action || !start_addr_specified || !strlen(filename)) print_help_and_exit(argv[0], true); if(!usb_init(pgm, pgm->usb_vid, pgm->usb_pid)) spawn_error("Couldn't initialize stlink"); if(!pgm->open(pgm)) spawn_error("Error communicating with MCU. Please check your SWIM connection."); FILE *f; if(action == READ) { fprintf(stderr, "Reading %d bytes at 0x%x... ", bytes_count, start); fflush(stderr); int bytes_count_align = ((bytes_count-1)/256+1)*256; // Reading should be done in blocks of 256 bytes unsigned char *buf = malloc(bytes_count_align); if(!buf) spawn_error("malloc failed"); int recv = pgm->read_range(pgm, part, buf, start, bytes_count_align); if(recv < bytes_count_align) { fprintf(stderr, "\r\nRequested %d bytes but received only %d.\r\n", bytes_count_align, recv); spawn_error("Failed to read MCU"); } if(!(f = fopen(filename, "w"))) spawn_error("Failed to open file"); if(is_ext(filename, ".ihx") || is_ext(filename, ".hex")) { fprintf(stderr, "Reading from Intel hex file "); ihex_write(f, buf, start, start+bytes_count); } else if(is_ext(filename, ".s19") || is_ext(filename, ".s8") || is_ext(filename, ".srec")) { printf("Reading from Motorola S-record files are not implemented (yet)\n"); printf("Exiting...\n"); exit(-1); //TODO Remove the above message and exit, and implement reading from S-record. fprintf(stderr, "Reading from Motorola S-record file "); srec_write(f, buf, start, start+bytes_count); } else { fwrite(buf, 1, bytes_count, f); } fclose(f); fprintf(stderr, "OK\n"); fprintf(stderr, "Bytes received: %d\n", bytes_count); } else if (action == VERIFY) { fprintf(stderr, "Verifing %d bytes at 0x%x... ", bytes_count, start); fflush(stderr); int bytes_count_align = ((bytes_count-1)/256+1)*256; // Reading should be done in blocks of 256 bytes unsigned char *buf = malloc(bytes_count_align); if(!buf) spawn_error("malloc failed"); int recv = pgm->read_range(pgm, part, buf, start, bytes_count_align); if(recv < bytes_count_align) { fprintf(stderr, "\r\nRequested %d bytes but received only %d.\r\n", bytes_count_align, recv); spawn_error("Failed to read MCU"); } if(!(f = fopen(filename, "r"))) spawn_error("Failed to open file"); unsigned char *buf2 = malloc(bytes_count); if(!buf2) spawn_error("malloc failed"); int bytes_to_verify; /* reading bytes to RAM */ if(is_ext(filename, ".ihx") || is_ext(filename, ".hex")) { bytes_to_verify = ihex_read(f, buf, start, start + bytes_count); } else { fseek(f, 0L, SEEK_END); bytes_to_verify = ftell(f); if(bytes_count_specified) { bytes_to_verify = bytes_count; } else if(bytes_count < bytes_to_verify) { bytes_to_verify = bytes_count; } fseek(f, 0, SEEK_SET); fread(buf2, 1, bytes_to_verify, f); } fclose(f); if(memcmp(buf, buf2, bytes_to_verify) == 0) { fprintf(stderr, "OK\n"); fprintf(stderr, "Bytes verified: %d\n", bytes_to_verify); } else { fprintf(stderr, "FAILED\n"); exit(-1); } } else if (action == WRITE) { if(!(f = fopen(filename, "r"))) spawn_error("Failed to open file"); int bytes_count_align = ((bytes_count-1)/part->flash_block_size+1)*part->flash_block_size; unsigned char *buf = malloc(bytes_count_align); if(!buf) spawn_error("malloc failed"); memset(buf, 0, bytes_count_align); // Clean aligned buffer int bytes_to_write; /* reading bytes to RAM */ if(is_ext(filename, ".ihx") || is_ext(filename, ".hex")) { fprintf(stderr, "Writing Intel hex file "); bytes_to_write = ihex_read(f, buf, start, start + bytes_count); } else if (is_ext(filename, ".s19") || is_ext(filename, ".s8") || is_ext(filename, ".srec")) { fprintf(stderr, "Writing Motorola S-record file "); bytes_to_write = srec_read(f, buf, start, start + bytes_count); } else { fprintf(stderr, "Writing binary file "); fseek(f, 0L, SEEK_END); bytes_to_write = ftell(f); if(bytes_count_specified) { bytes_to_write = bytes_count; } else if(bytes_count < bytes_to_write) { bytes_to_write = bytes_count; } fseek(f, 0, SEEK_SET); fread(buf, 1, bytes_to_write, f); } fprintf(stderr, "%d bytes at 0x%x... ", bytes_to_write, start); /* flashing MCU */ int sent = pgm->write_range(pgm, part, buf, start, bytes_to_write, memtype); if(pgm->reset) { // Restarting core (if applicable) pgm->reset(pgm); } fprintf(stderr, "OK\n"); fprintf(stderr, "Bytes written: %d\n", sent); fclose(f); } else if (action == UNLOCK) { int bytes_to_write=part->option_bytes_size; if (part->read_out_protection_mode==ROP_UNKNOWN) spawn_error("No unlocking mode defined for this device. You may need to edit the file stm8.c"); unsigned char *buf=malloc(bytes_to_write); if(!buf) spawn_error("malloc failed"); if (part->read_out_protection_mode==ROP_STM8S_STD) { for (int i=0; i<bytes_to_write;i++) { buf[i]=0; if ((i>0)&&((i&1)==0)) buf[i]=0xff; } } /* flashing MCU */ int sent = pgm->write_range(pgm, part, buf, start, bytes_to_write, memtype); if(pgm->reset) { // Restarting core (if applicable) pgm->reset(pgm); } fprintf(stderr, "Unlocked device. Option bytes reset to default state.\n"); fprintf(stderr, "Bytes written: %d\n", sent); } return(0); }