/* * Read a string of hexadecimal digits and write out bytes to a * string. Returns 0 if there are any non-hex characters, or there are * less than 2*memsize characters in the source null-terminated string. */ int hexstr_to_mem(unsigned char * dest, const char * source, int memsize) { int result = 1; int i = 0; for (i = 0; i < memsize && result; i++) { if (isxdigit(source[2*i]) && isxdigit(source[2*i + 1])) { dest[i] = (hex_to_char(source[2*i]) << 4) | hex_to_char(source[2*i + 1]); } else { result = 0; } } return result; }
/* unescape hex characters and plus in CGI input */ void unescape_cgi_input(char *input) { int x, y; int len; if (input == NULL) return; len = strlen(input); for (x = 0, y = 0; x < len; x++, y++) { if (input[x] == '\x0') break; else if (input[x] == '%') { input[y] = hex_to_char(&input[x+1]); x += 2; // RB 2011-09-08 // convert plus as well that it can bu used in service and host names } else if (input[x] == '+') { input[y] = ' '; } else input[y] = input[x]; } input[y] = '\x0'; return; }
size_t urldecode(char *desc, const char *source, size_t src_len) { if (src_len==0) { src_len=strlen(source); } if (!desc) { return urldecode_size(source, src_len); } size_t ret=0; for(size_t i = 0; i<src_len; i++) { switch(source[i]) { case '+': desc[ret++] = ' '; break; case '%': if(isxdigit(source[i + 1]) && isxdigit(source[i + 2])) { desc[ret++] = hex_to_char(source[i+1], source[i+2]); i += 2; }else { desc[ret++] = '%'; } break; default: desc[ret++] = source[i]; break; } } desc[ret]=0; return ret; }
char* hexString_to_charString(char* s) { int length = 0; char *x; char *y = s; while(*y != '\0') { length += 1; y += 1; } x = (char *) malloc((length / 2 + 1) * sizeof(char)); y = s; for(int i = 0; i < length / 2; ++i) { sprintf(x + i, "%c", hex_to_char(y + 2*i)); } x[length / 2] = '\0'; return x; }
TSTRING cCharEncoderUtil::HexValueToCharString( const TSTRING& str ) { TSTRING strOut; TSTRING::const_iterator at; for( at = str.begin(); at < str.end(); at += TCHAR_AS_HEX__IN_TCHARS ) { strOut += hex_to_char( at, at + TCHAR_AS_HEX__IN_TCHARS ); } return strOut; }
static string url_decode(string in) { int i, pos; string ret; ret = ""; i = 0; while((pos = index_of(i, in, "%")) >= 0) { if(pos) { ret += replace(in[(i?i+1:0)..pos-1], "+", " "); } ret += hex_to_char(in[pos+1..pos+2]); i = pos + 2; } if(i < strlen(in)) { ret += replace(in[(i?i+1:i)..], "+", " "); }
/* unescape hex characters and plus in CGI input */ void unescape_cgi_input(char *input) { int x, y; int len; if (input == NULL) return; len = strlen(input); for (x = 0, y = 0; x < len; x++, y++) { if (input[x] == '\x0') { break; // RB 2013-04-07 // only allow hex conversion if '%' is follow by a valid character } else if (input[x] == '%' && ( // 0 - 9 (input[x+1] >= 48 && input[x+1] <= 57) || // A - F (input[x+1] >= 65 && input[x+1] <= 70) || // a - f (input[x+1] >= 97 && input[x+1] <= 102)) ) { input[y] = hex_to_char(&input[x+1]); x += 2; // RB 2011-09-08 // convert plus as well that it can bu used in service and host names } else if (input[x] == '+') { input[y] = ' '; } else input[y] = input[x]; } input[y] = '\x0'; return; }
/* unescape hex characters in CGI input */ void unescape_cgi_input(char *input) { int x, y; int len; if(input == NULL) return; len = strlen(input); for(x = 0, y = 0; x < len; x++, y++) { if(input[x] == '\x0') break; else if(input[x] == '%') { input[y] = hex_to_char(&input[x + 1]); x += 2; } else input[y] = input[x]; } input[y] = '\x0'; return; }
inline char hex_to_char(char c1, char c2) { return (char)((hex_to_char(c1)<<4) | hex_to_char(c2)); }
/************************************************************************************************** * Handle received HID set feature reports */ void HID_set_feature_report_out(uint8_t *report) { uint8_t response[UDI_HID_REPORT_OUT_SIZE]; response[0] = report[0] | 0x80; response[1] = report[1]; response[2] = report[2]; uint16_t addr; addr = *(uint16_t *)(report+1); switch(report[0]) { // no-op case CMD_NOP: break; // write to RAM page buffer case CMD_RESET_POINTER: page_ptr = 0; return; // read from RAM page buffer case CMD_READ_BUFFER: memcpy(response, &page_buffer[page_ptr], UDI_HID_REPORT_OUT_SIZE); page_ptr += UDI_HID_REPORT_OUT_SIZE; page_ptr &= APP_SECTION_PAGE_SIZE-1; break; // erase entire application section case CMD_ERASE_APP_SECTION: SP_WaitForSPM(); SP_EraseApplicationSection(); return; // calculate application and bootloader section CRCs case CMD_READ_FLASH_CRCS: SP_WaitForSPM(); *(uint32_t *)&response[3] = SP_ApplicationCRC(); *(uint32_t *)&response[7] = SP_BootCRC(); break; // read MCU IDs case CMD_READ_MCU_IDS: response[3] = MCU.DEVID0; response[4] = MCU.DEVID1; response[5] = MCU.DEVID2; response[6] = MCU.REVID; break; // read fuses case CMD_READ_FUSES: response[3] = SP_ReadFuseByte(0); response[4] = SP_ReadFuseByte(1); response[5] = SP_ReadFuseByte(2); response[6] = 0xFF; response[7] = SP_ReadFuseByte(4); response[8] = SP_ReadFuseByte(5); break; // write RAM page buffer to application section page case CMD_WRITE_PAGE: if (addr > (APP_SECTION_SIZE / APP_SECTION_PAGE_SIZE)) // out of range { response[1] = 0xFF; response[2] = 0xFF; break; } SP_WaitForSPM(); SP_LoadFlashPage(page_buffer); SP_WriteApplicationPage(APP_SECTION_START + ((uint32_t)addr * APP_SECTION_PAGE_SIZE)); page_ptr = 0; break; // read application page to RAM buffer and return first 32 bytes case CMD_READ_PAGE: if (addr > (APP_SECTION_SIZE / APP_SECTION_PAGE_SIZE)) // out of range { response[1] = 0xFF; response[2] = 0xFF; } else { memcpy_P(page_buffer, (const void *)(APP_SECTION_START + (APP_SECTION_PAGE_SIZE * addr)), APP_SECTION_PAGE_SIZE); memcpy(&response[3], page_buffer, 32); page_ptr = 0; } break; // erase user signature row case CMD_ERASE_USER_SIG_ROW: SP_WaitForSPM(); SP_EraseUserSignatureRow(); break; // write RAM buffer to user signature row case CMD_WRITE_USER_SIG_ROW: SP_WaitForSPM(); SP_LoadFlashPage(page_buffer); SP_WriteUserSignatureRow(); break; // read user signature row to RAM buffer and return first 32 bytes case CMD_READ_USER_SIG_ROW: if (addr > (USER_SIGNATURES_PAGE_SIZE - 32)) { response[1] = 0xFF; response[2] = 0xFF; } else { memcpy_P(page_buffer, (const void *)(USER_SIGNATURES_START + addr), USER_SIGNATURES_SIZE); memcpy(&response[3], page_buffer, 32); page_ptr = 0; } break; case CMD_READ_SERIAL: { uint8_t i; uint8_t j = 3; uint8_t b; for (i = 0; i < 6; i++) { b = SP_ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0) + i); response[j++] = hex_to_char(b >> 4); response[j++] = hex_to_char(b & 0x0F); } response[j++] = '-'; b = SP_ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0) + 6); response[j++] = hex_to_char(b >> 4); response[j++] = hex_to_char(b & 0x0F); response[j++] = '-'; for (i = 7; i < 11; i++) { b = SP_ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0) + i); response[j++] = hex_to_char(b >> 4); response[j++] = hex_to_char(b & 0x0F); } response[j] = '\0'; break; } case CMD_READ_BOOTLOADER_VERSION: response[3] = BOOTLOADER_VERSION; break; case CMD_RESET_MCU: reset_do_soft_reset(); response[1] = 0xFF; // failed break; case CMD_READ_EEPROM: if (addr > (EEPROM_SIZE - 32)) { response[1] = 0xFF; response[2] = 0xFF; } else { EEP_EnableMapping(); memcpy_P(page_buffer, (const void *)(MAPPED_EEPROM_START + addr), APP_SECTION_PAGE_SIZE); EEP_DisableMapping(); memcpy(&response[3], page_buffer, 32); page_ptr = 0; } break; case CMD_WRITE_EEPROM: if (addr > (EEPROM_SIZE / EEPROM_PAGE_SIZE)) { response[1] = 0xFF; response[2] = 0xFF; } else { EEP_LoadPageBuffer(&report[3], EEPROM_PAGE_SIZE); EEP_AtomicWritePage(addr); } break; // unknown command default: response[0] = 0xFF; break; } udi_hid_generic_send_report_in(response); }