int irods_reli_md5( const char *host, const char *path, char *digest ) { dataObjInp_t request; int result; char *str = 0; struct irods_server *server = connect_to_host(host); if(!server) return -1; memset(&request,0,sizeof(request)); strcpy(request.objPath,path); debug(D_IRODS,"rcDataObjChksum %s %s",host,path); result = rcDataObjChksum(server->conn,&request,&str); debug(D_IRODS,"= %d",result); if(result<0) { errno = irods_reli_errno(result); return -1; } else { /* rcDataObjChecksum returns the checksum as ASCII */ /* but Parrot is expecting 16 bytes of binary data */ int i; for(i=0;i<16;i++) { digest[i] = hex_to_byte(&str[2*i]); } debug(D_IRODS,"%s",str); free(str); return 0; } }
void WolClient::parseMacAddress(const char* string, uint8_t* target) { uint8_t i = 0; uint8_t j = 0; uint8_t max = 17; // MAC String is 17 characters. while (i < max) { target[j++] = hex_to_byte(string[i], string[i + 1]); i += 3; } }
unsigned http_post_data_part(char *src_text, void *data, unsigned len) // LBS 24.02.2011 { char *d = data; for(int n=0; n<len; ++n) { d[n] = hex_to_byte(&src_text[n<<1]); } return len<<1; }
boost::tribool consume( OutputIterator data, char input ) { switch (state_) { case expecting_backslash: if (input == '\\') { state_ = expecting_x; return boost::indeterminate; } else { return false; } case expecting_x: if (input == 'x') { state_ = nibble_one; return true; } else { return false; } case nibble_one: if (std::isxdigit(input)) { most_sighificant_nibble_ = hex_to_byte(input); state_ = nibble_two; return boost::indeterminate; } else { return false; } case nibble_two: if (std::isxdigit(input)) { *data++ = (hex_to_byte(input) << 4) | most_sighificant_nibble_; state_ = nibble_one; return true; } else { return false; } default: break; } }
void process_cmd(void) { uart_putstr("Processing command: "); uart_putstr(cmdbuf); UART_PUTS("\r\n"); if ((cmdbuf[0] == 'w') && (strlen(cmdbuf) == 5)) { if (enable_write_eeprom) { uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]); uint8_t val = hex_to_uint8((uint8_t *)cmdbuf, 3); UART_PUTF2("Writing data 0x%x to EEPROM pos 0x%x.\r\n", val, adr); eeprom_write_byte((uint8_t *)adr, val); } else { UART_PUTS("Ignoring EEPROM write, since write mode is DISABLED.\r\n"); } } else if ((cmdbuf[0] == 'r') && (strlen(cmdbuf) == 3)) { uint16_t adr = hex_to_byte((uint8_t)cmdbuf[1]) * 16 + hex_to_byte((uint8_t)cmdbuf[2]); uint8_t val = eeprom_read_byte((uint8_t *)adr); UART_PUTF2("EEPROM value at position 0x%x is 0x%x.\r\n", adr, val); } else if ((cmdbuf[0] == 's') && (strlen(cmdbuf) > 4)) { strcpy(sendbuf, cmdbuf + 1); send_data_avail = true; } else { UART_PUTS("Unknown command.\r\n"); } }
struct ether_addr Ethernet::readMAC(const char* buf) { struct ether_addr temp; memset(&temp, 0, sizeof(temp)); unsigned char* start = (unsigned char*)&temp; unsigned char* end = start + sizeof(temp); bool go_next = false; while(start < end) { if(!go_next) { int ret = hex_to_byte(*(buf++)); if(ret == -1) { continue; } unsigned char current = (unsigned char)ret; current = current << 4; *start |= current; go_next = true; } else { int ret = hex_to_byte(*(buf++)); if(ret == -1) { continue; } unsigned char current = (unsigned char)ret; *start |= current; go_next = false; start++; } } return temp; }
void parseCANStr(char *pBuf, OpenLcbCanBuffer *pCAN, uint8_t len) { if( (pBuf[0] == ':') && (pBuf[len-1] == ';') && (len >= 4) && ( (pBuf[1] == 'X') || (pBuf[1] == 'S') ) ) { memset(pCAN, 0, sizeof(tCAN)); if (pBuf[1] == 'X') { pCAN->flags.extended = true ; } else { return; // skip standard frames } char *pEnd; pCAN->id = strtoul(pBuf+2, &pEnd, 16); // If Standard Frame then check to see if Id is in the valid 11-bit range if((pCAN->flags.extended && (pCAN->id > 0x1FFFFFFF)) || (!pCAN->flags.extended && (pCAN->id > 0x07FF))) return; if(*pEnd == 'N') { pEnd++; pCAN->length = 0; while(isxdigit(*pEnd)) { pCAN->data[pCAN->length] = hex_to_byte(pEnd); pCAN->length++; pEnd += 2; } } else if(*pEnd == 'R') { pCAN->flags.rtr = 1; char tChar = *(pEnd+1); if(isdigit(tChar)) pCAN->length = *(pEnd+1) - '0'; } return; } return; }
uint8_t hex_set_to_byte(const char a, const char b) { return ((hex_to_byte(a) << 4) + hex_to_byte(b)); }
static bool tlm_stream_decode(FILE *file, tlm_component *p_comp) { /* Stream is: <Name>:<Var Size in Bytes>:<Array size>:<Type>:<HEX Bytes>\n */ uint32_t exp_byte_cnt = 0; /* expected byte count */ /* Get the header information prior to the hex data */ char header[128] = { 0 }; int i = 0, colon_count = 0; const int colon_count_of_hex_data = 4; for ( ; i < sizeof(header)-1; i++) { int c = fgetc(file); if (c == EOF) { goto decode_error; } if (c == ':' && (++colon_count) >= colon_count_of_hex_data) { break; } header[i] = c; } /* Break the header into pieces */ char *tok_itr = 0; char *tok_name = strtok_r(header, ":", &tok_itr); char *tok_var_size = strtok_r(NULL, ":", &tok_itr); char *tok_arr_size = strtok_r(NULL, ":", &tok_itr); if (NULL != tok_name && NULL != tok_var_size && NULL != tok_arr_size) { exp_byte_cnt = atoi(tok_var_size) * atoi(tok_arr_size); } else { goto decode_error; } /* Decode hex bytes after the header */ const tlm_reg_var_type *reg_var = tlm_variable_get_by_name(p_comp, tok_name); if (NULL != reg_var && (reg_var->elm_size_bytes) * (reg_var->elm_arr_size) == exp_byte_cnt) { char *dst = (char*)(reg_var->data_ptr); int terminator = EOF; for ( ; exp_byte_cnt != 0; --exp_byte_cnt) { char byte1 = fgetc(file); char byte2 = fgetc(file); terminator = fgetc(file); /* could be comma, \n or EOF */ if (EOF == terminator) { goto decode_error; } char hex_bytes[] = { byte1, byte2, 0}; char byte = hex_to_byte(hex_bytes); memcpy(dst, &byte, sizeof(byte)); dst += sizeof(byte); } /* After we decode all hex bytes, the last char should be the * newline character because we still should have the last line * of telemetry stream containing "END:<comp name>" */ if ('\n' != terminator) { goto decode_error; } } else { /* Handle unregistered variable */ } return true; decode_error : return false; }
// ---------------------------------------------------------------------------- bool usbcan_decode_message(char *str, uint8_t length) { can_t msg; uint8_t dlc_pos; bool extended; if (str[0] == 'R' || str[0] == 'T') { extended = true; dlc_pos = 9; } else { extended = false; dlc_pos = 4; } if (length < dlc_pos + 1) return false; // get the number of data-bytes for this message msg.length = str[dlc_pos] - '0'; if (msg.length > 8) return false; // too many data-bytes if (str[0] == 'r' || str[0] == 'R') { msg.flags.rtr = true; if (length != (dlc_pos + 1)) return false; } else { msg.flags.rtr = false; if (length != (msg.length * 2 + dlc_pos + 1)) return false; } // read the messge-identifier if (extended) { uint16_t id; uint16_t id2; id = hex_to_byte(&str[1]) << 8; id |= hex_to_byte(&str[3]); id2 = hex_to_byte(&str[5]) << 8; id2 |= hex_to_byte(&str[7]); msg.id = (uint32_t) id << 16 | id2; } else { uint16_t id; id = char_to_byte(&str[1]) << 8; id |= hex_to_byte(&str[2]); msg.id = id; } msg.flags.extended = extended; // read data if the message is no rtr-frame if (!msg.flags.rtr) { char *buf = str + dlc_pos + 1; uint8_t i; for (i=0; i < msg.length; i++) { msg.data[i] = hex_to_byte(buf); buf += 2; } } // finally try to send the message if (can_send_message( &msg )) return true; else return false; }
void parse_args(const unsigned int argc, char * const argv[]) { struct option long_options[] = {{"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {"recursive", no_argument, 0, 'r'}, {"path", required_argument, 0, 'p'}, {"hex", required_argument, 0, 'n'}, {"string", required_argument, 0, 's'}, {"output", required_argument, 0, 'o'}, {"threads", required_argument, 0, 't'}, {"extension", required_argument, 0, 'e'}, {0, 0, 0, 0}}; int i = 0, c; while (1) { c = getopt_long(argc, argv, "hvrp:n:s:o:t:e:", long_options, &i); if (c == -1) break; switch (c) { case 'h': print_help(); break; case 'v': print_version(); break; case 'r': flags.recursive = 1; break; case 'p': input = optarg; break; case 't': { char *endptr = NULL; flags.threads = strtol(optarg, &endptr, 0); if (errno == ERANGE || *endptr != '\0') { fprintf(stderr, "Invalid or out of range number of threads.\n"); exit(EXIT_FAILURE); } } break; case 'e': flags.extension = optarg; break; case 's': flags.chunkString = optarg; break; case 'o': flags.output = optarg; break; case 'n': flags.chunkString = hex_to_byte(optarg); break; case '?': default: print_help(); } } if (!flags.chunkString) { fprintf(stderr, "The sequence to be identified has to be specified.\n\n"); print_help(); } }
uint16_t hex_to_uint8(uint8_t * buf, uint8_t offset) { return hex_to_byte(buf[offset]) * 16 + hex_to_byte(buf[offset + 1]); }
// Process all bytes in the rxbuffer. This function should be called in the main loop. // It can be interrupted by a UART RX interrupt, so additional bytes can be added into the ringbuffer while this function is running. void process_rxbuf(void) { while (rxbuf_count > 0) { char input; // get one char from the ringbuffer and reduce it's size without interruption through the UART ISR cli(); input = rxbuf[rxbuf_startpos]; rxbuf_startpos = (rxbuf_startpos + 1) % RXBUF_LENGTH; rxbuf_count--; sei(); // process character if (uart_timeout == 0) { bytes_to_read = bytes_pos = 0; } if (bytes_to_read > bytes_pos) { if (input == 13) { bytes_to_read = bytes_pos; } else if (((input >= 48) && (input <= 57)) || ((input >= 65) && (input <= 70)) || ((input >= 97) && (input <= 102))) { cmdbuf[bytes_pos] = input; bytes_pos++; UART_PUTF4("*** Received character %c (ASCII %u) = value 0x%x, %u bytes to go. ***\r\n", input, input, hex_to_byte(input), bytes_to_read - bytes_pos); } else { UART_PUTS("*** Illegal character. Use only 0..9, a..f, A..F. ***\r\n"); } if (bytes_pos == bytes_to_read) { cmdbuf[bytes_pos] = '\0'; process_cmd(); } } else if (input == 'h') { UART_PUTS("*** Help ***\r\n"); UART_PUTS("h.........this help\r\n"); UART_PUTS("rAA.......read EEPROM at hex address AA\r\n"); UART_PUTS("wAAXX.....write EEPROM at hex address AA to hex value XX\r\n"); UART_PUTS("x.........enable writing to EEPROM\r\n"); UART_PUTS("z.........disable writing to EEPROM\r\n"); UART_PUTS("sKKCCXX...Use AES key KK to send a packet with command ID CC and data XX (0..22 bytes).\r\n"); UART_PUTS(" End data with ENTER. Packet number and CRC are automatically added.\r\n"); } else if (input == 'x') { enable_write_eeprom = true; UART_PUTS("*** Writing to EEPROM is now ENABLED. ***\r\n"); } else if (input == 'z') { enable_write_eeprom = false; UART_PUTS("*** Writing to EEPROM is now DISABLED. ***\r\n"); } else if (input == 'r') { UART_PUTS("*** Read from EEPROM. Enter address (2 characters). ***\r\n"); cmdbuf[0] = 'r'; bytes_to_read = 3; bytes_pos = 1; } else if (input == 'w') { UART_PUTS("*** Write to EEPROM. Enter address and data (4 characters). ***\r\n"); cmdbuf[0] = 'w'; bytes_to_read = 5; bytes_pos = 1; } else if (input == 's') { UART_PUTS("*** Enter AES key nr, command ID and data in hex format to send, finish with ENTER. ***\r\n"); cmdbuf[0] = 's'; bytes_to_read = 49; // 's' + 2 characters for key nr + 2 characters for command ID + 2*22 characters for data bytes_pos = 1; } else { UART_PUTS("*** Character ignored. Press h for help. ***\r\n"); } // enable user timeout if waiting for further input uart_timeout = bytes_to_read == bytes_pos ? 0 : 255; } }
// Process all bytes in the UART RX ringbuffer ("rxbuf"). This function should be called in the // main loop. It can be interrupted by a UART RX interrupt, so additional bytes can be added // into the ringbuffer while this function is running. void process_rxbuf(void) { // Only process characters if the cmdbuf is clear to be overwritten. // If not, wait for the main loop to clear it by processing the user "send" command. if (send_data_avail) { return; } while (rxbuf_count > 0) { char input; // get one char from the ringbuffer and reduce its size without interruption through the UART ISR cli(); input = rxbuf[rxbuf_startpos]; rxbuf_startpos = (rxbuf_startpos + 1) % RXBUF_LENGTH; rxbuf_count--; sei(); // process character if (uart_timeout == 0) { bytes_to_read = bytes_pos = 0; } if (bytes_to_read > bytes_pos) { if (input == 13) { bytes_to_read = bytes_pos; } else if (((input >= 48) && (input <= 57)) || ((input >= 65) && (input <= 70)) || ((input >= 97) && (input <= 102))) { cmdbuf[bytes_pos] = input; bytes_pos++; UART_PUTF("*** 0x%x\r\n", hex_to_byte(input)); } else { UART_PUTS("*** Illegal character. Use only 0..9, a..f, A..F. ***\r\n"); } if (bytes_pos == bytes_to_read) { cmdbuf[bytes_pos] = '\0'; //led_dbg(1); process_cmd(); } } else if (input == 'h') { UART_PUTS("*** Help ***\r\n"); UART_PUTS("h..............this help\r\n"); UART_PUTS("rAA............read EEPROM at hex address AA\r\n"); UART_PUTS("wAAXX..........write EEPROM at hex address AA to hex value XX\r\n"); UART_PUTS("x..............enable writing to EEPROM\r\n"); UART_PUTS("z..............disable writing to EEPROM\r\n"); UART_PUTS("sKKTT{D}.......Use AES key KK to send a packet with MessageType TT, followed\r\n"); UART_PUTS(" by all necessary extension header fields and message data D.\r\n"); UART_PUTS(" Fields are: ReceiverID (RRRR), MessageGroup (GG), MessageID (MM)\r\n"); UART_PUTS(" AckSenderID (SSSS), AckPacketCounter (PPPPPP), Error (EE).\r\n"); UART_PUTS(" MessageData (DD) can be 0..17 bytes with bits moved to the left.\r\n"); UART_PUTS(" End data with ENTER. SenderID, PacketCounter and CRC are automatically added.\r\n"); UART_PUTS("sKK00RRRRGGMMDD...........Get\r\n"); UART_PUTS("sKK01RRRRGGMMDD...........Set\r\n"); UART_PUTS("sKK02RRRRGGMMDD...........SetGet\r\n"); UART_PUTS("sKK08GGMMDD...............Status\r\n"); UART_PUTS("sKK09SSSSPPPPPPEE.........Ack\r\n"); UART_PUTS("sKK0ASSSSPPPPPPEEGGMMDD...AckStatus\r\n"); UART_PUTS("cKKTT{D}{CRC}..Same as s..., but a CRC32 checksum of the command has to be appended.\r\n"); UART_PUTS(" If it doesn't match, the command is ignored.\r\n"); } else if (input == 'x') { enable_write_eeprom = true; UART_PUTS("*** Writing to EEPROM is now ENABLED. ***\r\n"); } else if (input == 'z') { enable_write_eeprom = false; UART_PUTS("*** Writing to EEPROM is now DISABLED. ***\r\n"); } else if (input == 'r') { UART_PUTS("*** Read from EEPROM. Enter address (2 characters). ***\r\n"); cmdbuf[0] = 'r'; bytes_to_read = 3; bytes_pos = 1; } else if (input == 'w') { UART_PUTS("*** Write to EEPROM. Enter address and data (4 characters). ***\r\n"); cmdbuf[0] = 'w'; bytes_to_read = 5; bytes_pos = 1; } else if (input == 's') { UART_PUTS("*** Enter data, finish with ENTER. ***\r\n"); cmdbuf[0] = 's'; bytes_to_read = 54; // 2 characters for key nr + 2 characters for MessageType + 16 characters for hdr.ext. + 2*17 characters for data bytes_pos = 1; } else if (input == 'c') { UART_PUTS("*** Enter data, finish with ENTER. ***\r\n"); cmdbuf[0] = 'c'; bytes_to_read = 62; // 2 characters for key nr + 2 characters for MessageType + 16 characters for hdr.ext. + 2*17 characters for data + 8 characters for CRC bytes_pos = 1; } else { UART_PUTS("*** Character ignored. Press h for help. ***\r\n"); } // enable user timeout if waiting for further input uart_timeout = bytes_to_read == bytes_pos ? 0 : 255; } }
/***************************************************************************** * main() * * Parse command line, load patch, start midi_tx, midi_rx, and jack threads. *****************************************************************************/ int main(int argc, char **argv) { char thread_name[16]; char opts[NUM_OPTS * 2 + 1]; struct option *op; char *cp; char *p; char *term; char *tokbuf; int c; int j = 0; int ret = 0; int saved_errno; int argcount = 0; char **argvals = argv; char **envp = environ; char *argvend = (char *)argv; size_t argsize; unsigned char rx_channel; setlocale(LC_ALL, "C"); jamrouter_instance = get_instance_num(); fprintf(stderr, "Starting jamrouter instance %d.\n", jamrouter_instance); /* Start debug thread. debug_class is not set until arguemnts are parsed, so use fprintf() until then. */ if ((ret = pthread_create(&debug_thread_p, NULL, &jamrouter_debug_thread, NULL)) != 0) { fprintf(stderr, "***** ERROR: Unable to start debug thread.\n"); } /* lock down memory (rt hates page faults) */ if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { saved_errno = errno; fprintf(stderr, "Unable to unlock memory: errno=%d (%s)\n", saved_errno, strerror(saved_errno)); } /* init lash client */ #ifndef WITHOUT_LASH for (j = 0; j < argc; j++) { if ((strcmp(argv[j], "-L") == 0) || (strcmp(argv[j], "--disable-lash") == 0) || (strcmp(argv[j], "-h") == 0) || (strcmp(argv[j], "--help") == 0) || (strcmp(argv[j], "-l") == 0) || (strcmp(argv[j], "--list") == 0) || (strcmp(argv[j], "-v") == 0) || (strcmp(argv[j], "--version") == 0) || (strcmp(argv[j], "-D") == 0) || (strcmp(argv[j], "--session-dir") == 0) || (strcmp(argv[j], "-u") == 0) || (strcmp(argv[j], "--uuid") == 0)) { lash_disabled = 1; break; } } if (!lash_disabled) { snprintf(thread_name, 16, "jamrouter%c-lash", ('0' + jamrouter_instance)); pthread_setname_np(pthread_self(), thread_name); if (lash_client_init(&argc, &argv) == 0) { lash_poll_event(); } snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance)); pthread_setname_np(pthread_self(), thread_name); } #endif /* startup initializations */ init_midi_event_queue(); init_jack_audio_driver(); select_midi_driver(NULL, DEFAULT_MIDI_DRIVER); /* save original command line for session handling */ if (jamrouter_cmdline[0] == '\0') { jamrouter_cmdline[0] = '\0'; for (j = 0; j < argc; j++) { strcat(&(jamrouter_cmdline[0]), argv[j]); strcat(&(jamrouter_cmdline[0]), " "); } jamrouter_cmdline[strlen(jamrouter_cmdline) - 1] = '\0'; term = get_color_terminal(); if (term == NULL) { strcpy(jamrouter_full_cmdline, jamrouter_cmdline); } else { snprintf(jamrouter_full_cmdline, 512, "%s -e \"%s \"", term, jamrouter_cmdline); } argcount = argc; argvals = argv; } /* command line args supplied by session manager */ else { argcount = 0; cp = strdup(jamrouter_cmdline); p = cp; while ((p = index(p, ' ')) != NULL) { p++; argcount++; } if ((argvals = malloc(((size_t)(argcount) + 1UL) * (size_t)sizeof(char *))) == NULL) { fprintf(stderr, "Out of Memory!\n"); return -1; } if ((tokbuf = alloca(strlen(jamrouter_cmdline) * 4)) == NULL) { fprintf(stderr, "Out of Memory!\n"); return -1; } while ((p = strtok_r(cp, " ", &tokbuf)) != NULL) { cp = NULL; argvals[j++] = p; } argvals[argcount] = NULL; } /* build the short option string */ cp = opts; for (op = long_opts; op < &long_opts[NUM_OPTS]; op++) { *cp++ = (char) op->val; if (op->has_arg) { *cp++ = ':'; } } /* handle options */ for (;;) { c = getopt_long(argcount, argvals, opts, long_opts, NULL); if (c == -1) { break; } switch (c) { case 'M': /* MIDI driver */ select_midi_driver(optarg, -1); break; case 'D': /* MIDI Rx/Tx port/device */ midi_rx_port_name = strdup(optarg); midi_tx_port_name = strdup(optarg); break; case 'r': /* MIDI Rx port/device */ midi_rx_port_name = strdup(optarg); break; case 't': /* MIDI Tx port/device */ midi_tx_port_name = strdup(optarg); break; case 'x': /* MIDI Rx latency periods */ rx_latency_periods = atoi(optarg); break; case 'X': /* MIDI Tx latency periods */ tx_latency_periods = atoi(optarg); break; case 'g': /* Tx byte guard time in usec */ byte_guard_time_usec = atoi(optarg); break; case 'G': /* Tx event guard time in usec */ event_guard_time_usec = atoi(optarg); break; case 'i': /* JACK MIDI input port */ jack_input_port_name = strdup(optarg); break; case 'o': /* JACK MIDI output port */ jack_output_port_name = strdup(optarg); break; case 'j': /* Jitter correction mode */ jitter_correct_mode = 1; break; case 'z': /* JACK wake phase within MIDI Rx/Tx period */ setting_midi_phase_lock = (timecalc_t)(atof(optarg)); if (setting_midi_phase_lock < (timecalc_t)(0.0625)) { setting_midi_phase_lock = (timecalc_t)(0.0625); } else if (setting_midi_phase_lock > (timecalc_t)(0.9375)) { setting_midi_phase_lock = (timecalc_t)(0.9375); } break; #ifndef WITHOUT_JACK_DLL case '4': /* JACK DLL timing level 4 */ jack_dll_level = 4; break; case '3': /* JACK DLL timing level 3 */ jack_dll_level = 3; break; case '2': /* JACK DLL timing level 2 */ jack_dll_level = 2; break; case '1': /* JACK DLL timing level 1 */ jack_dll_level = 1; break; #endif case 'k': /* key to controller mapping */ if (optarg != NULL) { if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) { jamrouter_shutdown("Out of memory!\n"); } if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) { rx_channel = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { keymap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { keymap_tx_controller[rx_channel] = atoi(p) & 0x7F; } } JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Key --> Controller Map: " "rx_channel=%0d tx_channel=%d tx_cc=%d\n", rx_channel + 1, keymap_tx_channel[rx_channel] + 1, keymap_tx_controller[rx_channel]); } } break; case 'p': /* key to pitchbend translation */ if (optarg != NULL) { if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) { jamrouter_shutdown("Out of memory!\n"); } if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) { rx_channel = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { pitchmap_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { pitchmap_center_note[rx_channel] = atoi(p) & 0x7F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { pitchmap_bend_range[rx_channel] = atoi(p) & 0x7F; } } } JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Key --> Pitchbend Map: " "rx_chan=%0d tx_chan=%d center=%d range=%d\n", rx_channel + 1, pitchmap_tx_channel[rx_channel] + 1, pitchmap_center_note[rx_channel], pitchmap_bend_range[rx_channel]); } } break; case 'q': /* pitchbend to controller translation */ if (optarg != NULL) { if ((tokbuf = alloca(strlen((const char *)optarg) * 4)) == NULL) { jamrouter_shutdown("Out of memory!\n"); } if ((p = strtok_r(optarg, ",", &tokbuf)) != NULL) { rx_channel = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { pitchcontrol_tx_channel[rx_channel] = (atoi(p) - 1) & 0x0F; if ((p = strtok_r(NULL, ",", &tokbuf)) != NULL) { pitchcontrol_controller[rx_channel] = atoi(p) & 0x7F; } } JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Pitchbend --> Controller Map: " "rx_chan=%0d tx_chan=%d controller=%d\n", rx_channel + 1, pitchcontrol_tx_channel[rx_channel] + 1, pitchcontrol_controller[rx_channel]); } } break; #ifndef WITHOUT_JUNO case 'J': /* Juno-106 sysex controller translation */ translate_juno_sysex = 1; break; case 's': /* echo sysex translations back to originator */ echosysex = 1; break; #endif case 'e': /* echo pitchbend and controller translations back to originator */ echotrans = 1; break; case 'T': /* alternate sysex terminator byte */ sysex_terminator = hex_to_byte(optarg); break; case 'U': /* alternate sysex terminator byte */ sysex_extra_terminator = hex_to_byte(optarg); break; case 'A': /* Active-Sensing mode */ if (strcmp(optarg, "on") == 0) { active_sensing_mode = ACTIVE_SENSING_MODE_ON; } else if (strcmp(optarg, "thru") == 0) { active_sensing_mode = ACTIVE_SENSING_MODE_THRU; } else if (strcmp(optarg, "drop") == 0) { active_sensing_mode = ACTIVE_SENSING_MODE_DROP; } break; case 'R': /* Omit running status byte on MIDI Tx */ use_running_status = 1; break; case 'n': /* Note-On Velocity */ note_on_velocity = hex_to_byte(optarg); break; case 'N': /* Note-Off Velocity */ note_off_velocity = hex_to_byte(optarg); break; case 'f': /* Send multiple Note-Off messages as All-Notes-Off */ tx_prefer_all_notes_off = 1; break; case 'F': /* Tx send real Note-Off instead of Velocity-0-Note-On */ tx_prefer_real_note_off = 1; break; case '0': /* Rx queue real Note-Off instead of Velocity-0-Note-On */ rx_queue_real_note_off = 1; break; case 'y': /* MIDI Rx thread priority */ if ((midi_rx_thread_priority = atoi(optarg)) <= 0) { midi_rx_thread_priority = MIDI_RX_THREAD_PRIORITY; } break; case 'Y': /* MIDI Tx thread priority */ if ((midi_tx_thread_priority = atoi(optarg)) <= 0) { midi_tx_thread_priority = MIDI_TX_THREAD_PRIORITY; } break; case 'd': /* debug */ debug = 1; for (j = 0; debug_class_list[j].name != NULL; j++) { if (strcmp(debug_class_list[j].name, optarg) == 0) { debug_class |= debug_class_list[j].id; } } break; case 'v': /* version */ printf("jamrouter-%s\n", PACKAGE_VERSION); return 0; case 'L': /* disable lash */ lash_disabled = 1; break; case 'l': /* list midi devices */ scan_midi(); return 0; case 'u': /* jack session uuid */ jack_session_uuid = strdup(optarg); break; case '?': case 'h': /* help */ default: showusage(argv[0]); return -1; } } /* Rewrite process title */ argcount = argc; argvals = argv; for (j = 0; j <= argcount; j++) { if ((j == 0) || ((argvend + 1) == argvals[j])) { argvend = argvals[j] + strlen(argvals[j]); } else { continue; } } /* steal space from first environment entry */ if (envp[0] != NULL) { argvend = envp[0] + strlen (envp[0]); } /* calculate size we have for process title */ argsize = (size_t)((char *)argvend - (char *)*argvals - 1); memset (*argvals, 0, argsize); /* rewrite process title */ argc = 0; snprintf((char *)*argvals, argsize, "jamrouter%d", jamrouter_instance); /* signal handlers for clean shutdown */ init_signal_handlers(); /* init MIDI system based on selected driver */ JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "Initializing MIDI: driver=%s.\n", midi_driver_names[midi_driver]); init_sync_info(0, 0); init_midi(); /* initialize JACK audio system based on selected driver */ snprintf(thread_name, 16, "jamrouter%c-clnt", ('0' + jamrouter_instance)); pthread_setname_np(pthread_self(), thread_name); init_jack_audio(); while (sample_rate == 0) { JAMROUTER_DEBUG(DEBUG_CLASS_INIT, "JACK did not set sample rate. Re-initializing...\n"); init_jack_audio(); usleep(125000); } /* start the JACK audio system */ start_jack_audio(); /* wait for JACK audio to start before starting midi. */ wait_jack_audio_start(); snprintf(thread_name, 16, "jamrouter%c-main", ('0' + jamrouter_instance)); pthread_setname_np(pthread_self(), thread_name); /* start MIDI Rx/Tx threads. */ start_midi_rx(); wait_midi_rx_start(); start_midi_tx(); wait_midi_tx_start(); /* debug thread not needed once watchdog is running */ debug_done = 1; pthread_join(debug_thread_p, NULL); /* Jamrouter watchdog handles restarting threads on config changes, runs driver supplied watchdog loop iterations, and handles debug output. */ jamrouter_watchdog(); stop_midi_tx(); stop_midi_rx(); stop_jack_audio(); output_pending_debug(); /* Wait for threads created directly by JAMROUTER to terminate. */ if (midi_rx_thread_p != 0) { pthread_join(midi_rx_thread_p, NULL); } if (midi_tx_thread_p != 0) { pthread_join(midi_tx_thread_p, NULL); } output_pending_debug(); return 0; }