microcom-2012.06.0/0000755000175000017500000000000011766331477011751 5ustar arearemicrocom-2012.06.0/commands.c0000644000175000017500000000474111766331477013724 0ustar areare#include #include "microcom.h" static int cmd_speed(int argc, char *argv[]) { int speed; speed_t flag; if (argc < 2) { printf("current speed: %d\n", current_speed); return 0; } speed = strtoul(argv[1], NULL, 0); flag = baudrate_to_flag(speed); if (flag < 0) { printf("invalid speed %d\n", speed); return 1; } current_speed = speed; ios->set_speed(ios, flag); return 0; } static int cmd_flow(int argc, char *argv[]) { char *flow; if (argc < 2) { switch (current_flow) { default: case FLOW_NONE: flow = "none"; break; case FLOW_SOFT: flow = "soft"; break; case FLOW_HARD: flow = "hard"; break; } printf("current flow: %s\n", flow); return 0; } switch (*argv[1]) { case 'n': current_flow = FLOW_NONE; break; case 's': current_flow = FLOW_SOFT; break; case 'h': current_flow = FLOW_HARD; break; default: printf("unknown flow type \"%s\"\n", argv[1]); return 1; } ios->set_flow(ios, current_flow); return 0; } static int cmd_exit(int argc, char *argv[]) { return MICROCOM_CMD_START; } static int cmd_break(int argc, char *argv[]) { ios->send_break(ios); return MICROCOM_CMD_START; } static int cmd_quit(int argc, char *argv[]) { microcom_exit(0); return 0; } static int cmd_help(int argc, char *argv[]) { struct cmd *cmd; if (argc == 1) { for_each_command(cmd) { if (cmd->info) printf("%s - %s\n", cmd->name, cmd->info); else printf("%s\n", cmd->name); } } else { microcom_cmd_usage(argv[1]); } return 0; } static int cmd_execute(int argc, char *argv[]) { if (argc < 2) return MICROCOM_CMD_USAGE; return do_script(argv[1]); } static int cmd_comment(int argc, char *argv[]) { return 0; } static struct cmd cmds[] = { { .name = "speed", .fn = cmd_speed, .info = "set terminal speed", .help = "speed " }, { .name = "exit", .fn = cmd_exit, .info = "exit from command processing", }, { .name = "flow", .fn = cmd_flow, .info = "set flow control", .help = "flow hard|soft|none", }, { .name = "break", .fn = cmd_break, .info = "send break", }, { .name = "quit", .fn = cmd_quit, .info = "quit microcom", }, { .name = "help", .fn = cmd_help, .info = "show help", }, { .name = "x", .fn = cmd_execute, .info = "execute a script", .help = "x ", }, { .name = "#", .fn = cmd_comment, .info = "comment", }, }; void commands_init(void) { int i; for (i = 0; i < ARRAY_SIZE(cmds); i++) register_command(&cmds[i]); } microcom-2012.06.0/serial.c0000644000175000017500000001045111766331477013375 0ustar areare/****************************************************************** ** File: serial.c ** Description: the serial part for microcom project ** ** Copyright (C)1999 Anca and Lucian Jurubita . ** All rights reserved. **************************************************************************** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details at www.gnu.org **************************************************************************** ** Rev. 1.0 - Feb. 2000 ** Rev. 1.01 - March 2000 ** Rev. 1.02 - June 2000 ****************************************************************************/ #include #include #include "microcom.h" static struct termios pots; /* old port termios settings to restore */ static char *lockfile; static void init_comm(struct termios *pts) { /* some things we want to set arbitrarily */ pts->c_lflag &= ~ICANON; pts->c_lflag &= ~(ECHO | ECHOCTL | ECHONL); pts->c_cflag |= HUPCL; pts->c_iflag |= IGNBRK; pts->c_cc[VMIN] = 1; pts->c_cc[VTIME] = 0; /* Standard CR/LF handling: this is a dumb terminal. * Do no translation: * no NL -> CR/NL mapping on output, and * no CR -> NL mapping on input. */ pts->c_oflag &= ~ONLCR; pts->c_iflag &= ~ICRNL; } static int serial_set_speed(struct ios_ops *ios, speed_t speed) { struct termios pts; /* termios settings on port */ tcgetattr(ios->fd, &pts); cfsetospeed(&pts, speed); cfsetispeed(&pts, speed); tcsetattr(ios->fd, TCSANOW, &pts); return 0; } static int serial_set_flow(struct ios_ops *ios, int flow) { struct termios pts; /* termios settings on port */ tcgetattr(ios->fd, &pts); switch (flow) { case FLOW_NONE: /* no flow control */ pts.c_cflag &= ~CRTSCTS; pts.c_iflag &= ~(IXON | IXOFF | IXANY); break; case FLOW_HARD: /* hardware flow control */ pts.c_cflag |= CRTSCTS; pts.c_iflag &= ~(IXON | IXOFF | IXANY); break; case FLOW_SOFT: /* software flow control */ pts.c_cflag &= ~CRTSCTS; pts.c_iflag |= IXON | IXOFF | IXANY; break; } tcsetattr(ios->fd, TCSANOW, &pts); return 0; } static int serial_send_break(struct ios_ops *ios) { tcsendbreak(ios->fd, 0); return 0; } /* unlink the lockfile */ static void serial_unlock() { if (lockfile) unlink(lockfile); } /* restore original terminal settings on exit */ static void serial_exit(struct ios_ops *ios) { tcsetattr(ios->fd, TCSANOW, &pots); close(ios->fd); free(ios); serial_unlock(); } struct ios_ops * serial_init(char *device) { struct termios pts; /* termios settings on port */ struct ios_ops *ops; int fd; char *substring; long pid; ops = malloc(sizeof(*ops)); if (!ops) return NULL; lockfile = malloc(PATH_MAX); if (!lockfile) return NULL; ops->set_speed = serial_set_speed; ops->set_flow = serial_set_flow; ops->send_break = serial_send_break; ops->exit = serial_exit; /* check lockfile */ substring = strrchr(device, '/'); if (substring) substring++; else substring = device; sprintf(lockfile, "/var/lock/LCK..%s", substring); fd = open(lockfile, O_RDONLY); if (fd >= 0 && !opt_force) { close(fd); main_usage(3, "lockfile for port exists", device); } if (fd >= 0 && opt_force) { close(fd); printf("lockfile for port exists, ignoring\n"); serial_unlock(); } fd = open(lockfile, O_RDWR | O_CREAT, 0444); if (fd < 0 && opt_force) { printf("cannot create lockfile. ignoring\n"); lockfile = NULL; goto force; } if (fd < 0) main_usage(3, "cannot create lockfile", device); /* Kermit wants binary pid */ pid = getpid(); write(fd, &pid, sizeof(long)); close(fd); force: /* open the device */ fd = open(device, O_RDWR); ops->fd = fd; if (fd < 0) { serial_unlock(); main_usage(2, "cannot open device", device); } /* modify the port configuration */ tcgetattr(fd, &pts); memcpy(&pots, &pts, sizeof (pots)); init_comm(&pts); tcsetattr(fd, TCSANOW, &pts); printf("connected to %s\n", device); return ops; } microcom-2012.06.0/.gitignore0000644000175000017500000000003311766331477013735 0ustar areare*.o *~ .gitignore microcom microcom-2012.06.0/commands_fsl_imx.c0000644000175000017500000002727611766331477015455 0ustar areare#include #include #include #include #include "microcom.h" static int available(int fd) { fd_set rfds; struct timeval tv = { .tv_sec = 0, .tv_usec = 1 }; int ret; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(fd, &rfds); ret = select(fd + 1, &rfds, NULL, NULL, &tv); if (ret == -1) { perror("select"); return -EINVAL; } if (ret) return 1; else return 0; } static int get_ack(int fd) { unsigned char expect[] = { 0x56, 0x78, 0x78, 0x56 }; int i, ret; unsigned char r; for (i = 0; i < sizeof(expect); i++) { ret = read(ios->fd, &r, 1); if (ret == -1) { perror("read failed\n"); return -1; } if (r != expect[i]) return -1;; } return 0; } static int sync_com(int fd) { unsigned char buf = 0x1; int ret, i; for (i = 0; i < 16; i++) { while (1) { printf("wr %d\n", i++); ret = write(ios->fd, &buf, 1); if (ret < 0) perror("write"); usleep(100000); if (available(fd)) break; } ret = get_ack(fd); if (!ret) return ret; printf("no ack. try again\n"); } printf("failed to connect\n"); return -EINVAL; } static int read_mem(int fd, uint32_t address, void *_buf, int size, int accesssize) { unsigned char buf[] = {0x1, 0x1, /* read command */ 0x0, 0x0, 0x0, 0x0, /* address */ 0x20, /* data size */ 0x0, 0x0, 0x0, 0x0, /* count */ 0x0, 0x0, 0x0, 0x0, 0x0}; /* fill */ int i = 0, ret; uint8_t *buf8 = _buf; uint16_t *buf16 = _buf; uint32_t *buf32 = _buf; buf[2] = (address >> 24) & 0xff; buf[3] = (address >> 16) & 0xff; buf[4] = (address >> 8) & 0xff; buf[5] = (address >> 0) & 0xff; switch (accesssize) { case 8: case 16: case 32: buf[6] = accesssize; break; default: return -EINVAL; } size -= 1; buf[7] = (size >> 24) & 0xff; buf[8] = (size >> 16) & 0xff; buf[9] = (size >> 8) & 0xff; buf[10] = (size >> 0) & 0xff; for (i = 0; i < sizeof(buf); i++) { ret = write(ios->fd, &buf[i], 1); if (ret < 0) { perror("write"); return -EINVAL; } } usleep(100000); ret = get_ack(fd); if (ret) return ret; i = 0; while (i < size) { uint8_t temp; switch (accesssize) { case 8: ret = read(fd, buf8, 1); if (ret < 0) return -EINVAL; buf8++; i++; break; case 16: ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf16 = temp; ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf16 |= temp << 8; buf16++; i += 2; break; case 32: ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf32 = temp; ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf32 |= temp << 8; ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf32 |= temp << 16; ret = read(fd, &temp, 1); if (ret < 0) return -EINVAL; *buf32 |= temp << 24; buf32++; i += 4; break; } } return 0; } #define DISP_LINE_LEN 16 static int memory_display(char *addr, unsigned long offs, unsigned long nbytes, int size) { unsigned long linebytes, i; unsigned char *cp; /* Print the lines. * * We buffer all read data, so we can make sure data is read only * once, and all accesses are with the specified bus width. */ do { char linebuf[DISP_LINE_LEN]; uint *uip = (uint *)linebuf; ushort *usp = (ushort *)linebuf; u_char *ucp = (u_char *)linebuf; uint count = 52; printf("%08lx:", offs); linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; for (i = 0; i < linebytes; i += size) { if (size == 4) { count -= printf(" %08x", (*uip++ = *((uint *)addr))); } else if (size == 2) { count -= printf(" %04x", (*usp++ = *((ushort *)addr))); } else { count -= printf(" %02x", (*ucp++ = *((u_char *)addr))); } addr += size; offs += size; } while(count--) printf(" "); cp = (unsigned char *)linebuf; for (i = 0; i < linebytes; i++) { if ((*cp < 0x20) || (*cp > 0x7e)) printf("."); else printf("%c", *cp); cp++; } printf("\n"); nbytes -= linebytes; } while (nbytes > 0); return 0; } static int md(int argc, char *argv[]) { void *buf; uint32_t addr; int accesssize = 32; int size = 256; int ret = 0; if (argc < 2) return 1; addr = strtoul(argv[1], NULL, 0); buf = malloc(size); ret = read_mem(ios->fd, addr, buf, size, accesssize); if (ret) goto out; memory_display(buf, 0x0, size, accesssize >> 3); out: free(buf); return ret; } static int write_mem(uint32_t address, uint32_t val, int accesssize) { unsigned char buf[] = { 0x2, 0x2, /* write command */ 0x0, 0x0, 0x0, 0x0, /* address */ 0x0, /* data size */ 0x0, 0x0, 0x0, 0x0, /* fill */ 0x0, 0x0, 0x0, 0x0, /* value */ 0x0, /* fill */ }; unsigned char expect[] = {0x12, 0x8a, 0x8a, 0x12}; int i, ret; unsigned char r; buf[2] = (address >> 24) & 0xff; buf[3] = (address >> 16) & 0xff; buf[4] = (address >> 8) & 0xff; buf[5] = (address >> 0) & 0xff; switch (accesssize) { case 8: buf[11] = val & 0xff; buf[6] = accesssize; break; case 16: buf[11] = (val >> 8) & 0xff; buf[12] = val & 0xff; buf[6] = accesssize; break; case 32: buf[11] = (val >> 24) & 0xff; buf[12] = (val >> 16) & 0xff; buf[13] = (val >> 8) & 0xff; buf[14] = (val >> 0) & 0xff; buf[6] = accesssize; break; default: return -EINVAL; } for (i = 0; i < ARRAY_SIZE(buf); i++) { ret = write(ios->fd, &buf[i], 1); if (ret < 0) { perror("write"); return -EINVAL; } } ret = get_ack(ios->fd); if (ret) return ret; for (i = 0; i < sizeof(expect); i++) { ret = read(ios->fd, &r, 1); if (ret == -1) { perror("read failed\n"); return -1; } if (r != expect[i]) return -1;; } return 0; } static int mw(int argc, char *argv[]) { uint32_t addr, val; int accesssize = 32; if (argc < 3) return 1; if (!strcmp(argv[0], "mwb")) accesssize = 8; if (!strcmp(argv[0], "mwh")) accesssize = 16; addr = strtoul(argv[1], NULL, 0); val = strtoul(argv[2], NULL, 0); write_mem(addr, val, accesssize); return 0; } static int do_header(uint32_t addr) { int i, ret; unsigned char buf[] = { 0x20, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; buf[0] = (addr >> 0) & 0xff; buf[1] = (addr >> 8) & 0xff; buf[2] = (addr >> 16) & 0xff; buf[3] = (addr >> 24) & 0xff; for (i = 0; i < ARRAY_SIZE(buf); i++) { ret = write(ios->fd, &buf[i], 1); if (ret < 0) { perror("write"); return -EINVAL; } } return 0; } static int upload_file(uint32_t address, char *name, unsigned char type) { uint32_t size; int upfd, ret, i; unsigned char buf[] = { 0x4, 0x4, /* upload command */ 0x0, 0x0, 0x0, 0x0, /* address */ 0x0, /* fill */ 0x0, 0x0, 0x0, 0x0, /* filesize */ 0x0, 0x0, 0x0, 0x0, /* fill */ 0xaa, /* filetype */ }; struct stat stat; upfd = open(name, O_RDONLY); if (upfd < 0) { perror("open"); return 1; } ret = fstat(upfd, &stat); if (ret) { perror("stat"); return 1; } size = stat.st_size; size += 0x20; buf[2] = (address >> 24) & 0xff; buf[3] = (address >> 16) & 0xff; buf[4] = (address >> 8) & 0xff; buf[5] = (address >> 0) & 0xff; buf[7] = (size >> 24) & 0xff; buf[8] = (size >> 16) & 0xff; buf[9] = (size >> 8) & 0xff; buf[10] = (size >> 0) & 0xff; for (i = 11; i < 16; i++) buf[i] = type; for (i = 0; i < ARRAY_SIZE(buf); i++) { ret = write(ios->fd, &buf[i], 1); if (ret < 0) { perror("write"); return -EINVAL; } } ret = get_ack(ios->fd); if (ret) { printf("no ack\n"); return ret; } do_header(address + 0x20); for (i = 0; i < size - 0x20; i++) { unsigned char tmp; ret = read(upfd, &tmp, 1); if (ret != 1) { perror("read"); goto out; } ret = write(ios->fd, &tmp, 1); if (ret != 1) { perror("write"); goto out; } if (!(i % 65536)) printf("\n "); if (!((i + 1) % 1024)) printf("#"); fflush(stdout); } printf("\n"); out: return 0; } static int upload(int argc, char *argv[]) { uint32_t address; unsigned char buf[] = { 0x5, 0x5, /* status command */ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, }; int i, ret, type = 0; if (argc < 3) return 1; if (argc > 3) { type = strtoul(argv[3], NULL, 0); printf("image type: 0x%02x\n", type); } address = strtoul(argv[1], NULL, 0); upload_file(address, argv[2], type); for (i = 0; i < ARRAY_SIZE(buf); i++) { ret = write(ios->fd, &buf[i], 1); if (ret < 0) { perror("write"); return -EINVAL; } } if (type == 0xaa) return MICROCOM_CMD_START; return 0; } static int fsl_connect(int argc, char *argv[]) { int ret; printf("trying to connect...\n"); ret = sync_com(ios->fd); if (ret) { printf("connect failed\n"); return -11; } printf("done\n"); return 0; } static void fsl_sniff_memwrite(void) { unsigned char buf[15]; int i; uint32_t addr, val; printf("mw "); for (i = 0; i < 15; i++) { read(ios->fd, &buf[i], 1); } addr = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0); val = (buf[10] << 24)| (buf[11] << 16) | (buf[12] << 8) | (buf[13] << 0); printf("0x%08x 0x%08x\n", addr, val); } static void fsl_sniff_6(void) { unsigned char buf[15]; int i; printf("cmd6\n"); for (i = 0; i < 15; i++) { read(ios->fd, &buf[i], 1); printf("%02x ", buf[i]); } printf("\n"); } static void fsl_sniff_sts(void) { unsigned char buf[15]; int i; printf("cmd get status\n"); for (i = 0; i < 15; i++) { read(ios->fd, &buf[i], 1); printf("%02x ", buf[i]); } printf("\n"); } static void fsl_sniff_memread(void) { printf("md (not implemented)\n"); } static void fsl_sniff_upload(void) { unsigned char buf[15]; uint32_t addr, size; int i; printf("upload "); for (i = 0; i < 15; i++) { read(ios->fd, &buf[i], 1); } addr = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | (buf[4] << 0); size = (buf[6] << 24) | (buf[7] << 16) | (buf[8] << 8) | (buf[9] << 0); printf(" adr: 0x%08x size: 0x%08x type 0x%02x ", addr, size, buf[14]); switch(buf[14]) { case 0xaa: printf("(application)\n"); break; case 0xee: printf("(dcd)\n"); break; default: printf("(unknown)\n"); break; } for (i = 0; i < size; i++) { unsigned char tmp; read(ios->fd, &tmp, 1); printf("%02x ", tmp); if (!((i + 1) % 32)) printf("\n"); } printf("\n"); } static int fsl_sniff(int argc, char *argv[]) { while (1) { unsigned char cmd; read(ios->fd, &cmd, 1); switch (cmd) { case 0x2: fsl_sniff_memwrite(); break; case 0x1: fsl_sniff_memread(); break; case 0x4: fsl_sniff_upload(); break; case 0x5: fsl_sniff_sts(); break; case 0x6: fsl_sniff_6(); break; default: printf("unknown cmd 0x%02x\n", cmd); break; }; } return 0; } static struct cmd cmds[] = { { .name = "md", .fn = md, .info = "Display memory (i.MX specific)", .help = "md
", }, { .name = "mw", .fn = mw, .info = "write memory (i.MX specific)", .help = "mw
", }, { .name = "mwb", .fn = mw, .info = "write memory byte (i.MX specific)", .help = "mwb
", }, { .name = "mwh", .fn = mw, .info = "write memory 2 byte (i.MX specific)", .help = "mwh
", }, { .name = "upload", .fn = upload, .info = "upload image (i.MX specific)", .help = "upload
[]\n" "use imagetype = 0xaa for application images", }, { .name = "connect", .fn = fsl_connect, .info = "sync communication to Processor (i.MX specific)", .help = "connect", }, { .name = "sniff", .fn = fsl_sniff, .info = "sniff and dissect communication from ATK (i.MX specific)", .help = "sniff", }, }; void commands_fsl_imx_init(void) { int i; for (i = 0; i < ARRAY_SIZE(cmds); i++) register_command(&cmds[i]); } microcom-2012.06.0/can.c0000644000175000017500000001161611766331477012663 0ustar areare/* * Description: the can part for microcom project * * Copyright (C) 2010 by Marc Kleine-Budde * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details at www.gnu.org * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "microcom.h" enum socket_local_enum { SOCKET_CANSIDE, SOCKET_TERMSIDE, SOCKET_MAX, }; struct can_data { int socket_can; int socket_local[SOCKET_MAX]; int can_id; }; static struct can_data data; static pthread_t can_thread; static int can_set_speed(struct ios_ops *ios, speed_t speed) { return 0; } static int can_set_flow(struct ios_ops *ios, int flow) { return 0; } static int can_send_break(struct ios_ops *ios) { return 0; } static void can_exit(struct ios_ops *ios) { shutdown(ios->fd, SHUT_RDWR); close(ios->fd); pthread_join(can_thread, NULL); free(ios); } static void *can_thread_fun(void *_data) { struct can_data *data = _data; struct can_frame to_can = { .can_id = data->can_id, }; struct can_frame from_can; fd_set ready; int ret, fd_max; fd_max = max(data->socket_can, data->socket_local[SOCKET_CANSIDE]); fd_max++; while (1) { FD_ZERO(&ready); FD_SET(data->socket_can, &ready); FD_SET(data->socket_local[SOCKET_CANSIDE], &ready); ret = select(fd_max, &ready, NULL, NULL, NULL); if (ret == -1) { if (errno == EINTR) continue; goto exit; } /* CAN -> TERMINAL */ if (FD_ISSET(data->socket_can, &ready)) { ret = read(data->socket_can, &from_can, sizeof(from_can)); if ((ret == -1 && errno != EINTR) || ret != sizeof(from_can)) goto exit; ret = write(data->socket_local[SOCKET_CANSIDE], from_can.data, from_can.can_dlc); if ((ret == -1 && errno != EINTR) || ret != from_can.can_dlc) goto exit; } /* TERMINAL -> CAN */ if (FD_ISSET(data->socket_local[SOCKET_CANSIDE], &ready)) { ret = read(data->socket_local[SOCKET_CANSIDE], to_can.data, sizeof(to_can.data)); if ((ret == -1 && errno != EINTR) || ret == 0) goto exit; to_can.can_dlc = ret; ret = write(data->socket_can, &to_can, sizeof(to_can)); if ((ret == -1 && errno != EINTR) || ret != sizeof(to_can)) goto exit; } } exit: shutdown(data->socket_local[SOCKET_CANSIDE], SHUT_RDWR); close(data->socket_local[SOCKET_CANSIDE]); close(data->socket_can); return NULL; } struct ios_ops *can_init(char *interface_id) { struct ios_ops *ios; struct ifreq ifr; struct can_filter filter[] = { { .can_mask = CAN_SFF_MASK, }, }; struct sockaddr_can addr = { .can_family = PF_CAN, }; char *interface = interface_id; char *id_str = NULL; ios = malloc(sizeof(*ios)); if (!ios) return NULL; ios->set_speed = can_set_speed; ios->set_flow = can_set_flow; ios->send_break = can_send_break; ios->exit = can_exit; /* * the string is supposed to be formated this way: * interface:rx:tx */ if (interface_id) id_str = strchr(interface, ':'); if (id_str) { *id_str = 0x0; id_str++; filter->can_id = strtol(id_str, NULL, 16) & CAN_SFF_MASK; id_str = strchr(id_str, ':'); } else { filter->can_id = DEFAULT_CAN_ID; } if (id_str) { *id_str = 0x0; id_str++; data.can_id = strtol(id_str, NULL, 16) & CAN_SFF_MASK; } else { data.can_id = filter->can_id; } if (!interface || *interface == 0x0) interface = DEFAULT_CAN_INTERFACE; /* no cleanups on failure, we exit anyway */ data.socket_can = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (data.socket_can < 0) { perror("socket"); return NULL; } if (setsockopt(data.socket_can, SOL_CAN_RAW, CAN_RAW_FILTER, filter, sizeof(filter))) { perror("setsockopt"); return NULL; } strcpy(ifr.ifr_name, interface); if (ioctl(data.socket_can, SIOCGIFINDEX, &ifr)) { printf("%s: %s\n", interface, strerror(errno)); return NULL; } addr.can_ifindex = ifr.ifr_ifindex; if (bind(data.socket_can, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); return NULL; } if (socketpair(AF_UNIX, SOCK_STREAM, 0, data.socket_local) < 0) { perror("socketpair"); return NULL; } if (pthread_create(&can_thread, NULL, can_thread_fun, &data) != 0) return NULL; ios->fd = data.socket_local[SOCKET_TERMSIDE]; printf("connected to %s (rx_id=%x, tx_id=%x)\n", interface, filter->can_id, data.can_id); return ios; } microcom-2012.06.0/gitlog2changelog.py0000755000175000017500000001020211766331477015540 0ustar areare#!/usr/bin/python # Copyright 2008 Marcus D. Hanwell # Distributed under the terms of the GNU General Public License v2 or later import string, re, os # Execute git log with the desired command line options. fin = os.popen('git log --summary --stat --no-merges --date=short', 'r') # Create a ChangeLog file in the current directory. fout = open('ChangeLog', 'w') # Set up the loop variables in order to locate the blocks we want authorFound = False dateFound = False messageFound = False filesFound = False message = "" messageNL = False files = "" prevAuthorLine = "" # The main part of the loop for line in fin: # The commit line marks the start of a new commit object. if string.find(line, 'commit') >= 0: # Start all over again... authorFound = False dateFound = False messageFound = False messageNL = False message = "" filesFound = False files = "" continue # Match the author line and extract the part we want elif re.match('Author:', line) >=0: authorList = re.split(': ', line, 1) author = authorList[1] author = author[0:len(author)-1] authorFound = True # Match the date line elif re.match('Date:', line) >= 0: dateList = re.split(': ', line, 1) date = dateList[1] date = date[0:len(date)-1] dateFound = True # The svn-id lines are ignored elif re.match(' git-svn-id:', line) >= 0: continue # The sign off line is ignored too elif re.search('Signed-off-by', line) >= 0: continue # Extract the actual commit message for this commit elif authorFound & dateFound & messageFound == False: # Find the commit message if we can if len(line) == 1: if messageNL: messageFound = True else: messageNL = True elif len(line) == 4: messageFound = True else: if len(message) == 0: message = message + line.strip() else: message = message + " " + line.strip() # If this line is hit all of the files have been stored for this commit elif re.search('files changed', line) >= 0: filesFound = True continue # Collect the files for this commit. FIXME: Still need to add +/- to files elif authorFound & dateFound & messageFound: fileList = re.split(' \| ', line, 2) if len(fileList) > 1: if len(files) > 0: files = files + ", " + fileList[0].strip() else: files = fileList[0].strip() # All of the parts of the commit have been found - write out the entry if authorFound & dateFound & messageFound & filesFound: # First the author line, only outputted if it is the first for that # author on this day authorLine = date + " " + author if len(prevAuthorLine) == 0: fout.write(authorLine + "\n") elif authorLine == prevAuthorLine: pass else: fout.write("\n" + authorLine + "\n") # Assemble the actual commit message line(s) and limit the line length # to 80 characters. commitLine = "* " + files + ": " + message.strip() i = 0 commit = "" while i < len(commitLine): if len(commitLine) < i + 78: commit = commit + "\n " + commitLine[i:len(commitLine)] break index = commitLine.rfind(' ', i, i+78) if index > i: commit = commit + "\n " + commitLine[i:index] i = index+1 else: commit = commit + "\n " + commitLine[i:78] i = i+79 # Write out the commit line fout.write(commit + "\n") #Now reset all the variables ready for a new commit block. authorFound = False dateFound = False messageFound = False messageNL = False message = "" filesFound = False files = "" prevAuthorLine = authorLine # Close the input and output lines now that we are finished. fin.close() fout.close() microcom-2012.06.0/microcom.h0000644000175000017500000001030211766331477013726 0ustar areare/*************************************************************************** ** File: microcom.h ** Description: the main header file for microcom project ** ** Copyright (C)1999 Anca and Lucian Jurubita . ** All rights reserved. **************************************************************************** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details at www.gnu.org **************************************************************************** ** Rev. 1.0 - Feb. 2000 ** Rev. 1.02 - June 2000 ****************************************************************************/ #ifndef MICROCOM_H #define MICROCOM_H #include #include #include #include #include #include #include #include #include #include #include #define DEFAULT_BAUDRATE 115200 #define DEFAULT_DEVICE "/dev/ttyS0" #define DEFAULT_CAN_INTERFACE "can0" #define DEFAULT_CAN_ID (0x200) struct ios_ops { int (*set_speed)(struct ios_ops *, speed_t speed); #define FLOW_NONE 0 #define FLOW_SOFT 1 #define FLOW_HARD 2 int (*set_flow)(struct ios_ops *, int flow); int (*send_break)(struct ios_ops *); void (*exit)(struct ios_ops *); int fd; }; void mux_loop(struct ios_ops *); /* mux.c */ void init_terminal(void); void restore_terminal(void); struct ios_ops *telnet_init(char *hostport); struct ios_ops *serial_init(char *dev); struct ios_ops *can_init(char *interfaceid); void microcom_exit(int signal); void microcom_cmd_usage(char *str); void main_usage(int exitcode, char *str, char *dev); int flag_to_baudrate(speed_t speed); speed_t baudrate_to_flag(int speed); extern struct ios_ops *ios; extern int debug; extern int dolog; extern FILE *flog; extern int opt_force; struct cmd { char *name; int(*fn)(int argc, char *argv[]); struct cmd *next; char *info; char *help; }; int register_command(struct cmd *cmd); #define MICROCOM_CMD_START 100 #define MICROCOM_CMD_USAGE 101 extern struct cmd *commands; #define for_each_command(cmd) for (cmd = commands; cmd; cmd = cmd->next) void commands_init(void); void commands_fsl_imx_init(void); #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) /* * min()/max()/clamp() macros that also do * strict type-checking.. See the * "unnecessary" pointer comparison. */ #define min(x, y) ({ \ typeof(x) _min1 = (x); \ typeof(y) _min2 = (y); \ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) #define max(x, y) ({ \ typeof(x) _max1 = (x); \ typeof(y) _max2 = (y); \ (void) (&_max1 == &_max2); \ _max1 > _max2 ? _max1 : _max2; }) extern int current_speed; extern int current_flow; int do_commandline(void); int do_script(char *script); #define dprintf(fmt,args...) ({ if (debug) printf (fmt ,##args); }) /* RFC2217 */ #define COM_PORT_OPTION 44 #define SET_BAUDRATE_CS 1 #define SET_DATASIZE_CS 2 #define SET_PARITY_CS 3 #define SET_STOPSIZE_CS 4 #define SET_CONTROL_CS 5 #define NOTIFY_LINESTATE_CS 6 #define NOTIFY_MODEMSTATE_CS 7 #define FLOWCONTROL_SUSPEND_CS 8 #define FLOWCONTROL_RESUME_CS 9 #define SET_LINESTATE_MASK_CS 10 #define SET_MODEMSTATE_MASK_CS 11 #define PURGE_DATA_CS 12 #define SET_BAUDRATE_SC 101 #define SET_DATASIZE_SC 102 #define SET_PARITY_SC 103 #define SET_STOPSIZE_SC 104 #define SET_CONTROL_SC 105 #define NOTIFY_LINESTATE_SC 106 #define NOTIFY_MODEMSTATE_SC 107 #define FLOWCONTROL_SUSPEND_SC 108 #define FLOWCONTROL_RESUME_SC 109 #define SET_LINESTATE_MASK_SC 110 #define SET_MODEMSTATE_MASK_SC 111 #define PURGE_DATA_SC 112 #endif /* MICROCOM_H */ microcom-2012.06.0/mux.c0000644000175000017500000001315411766331477012732 0ustar areare/*************************************************************************** ** File: mux.c ** Description: the main program loop ** ** Copyright (C)1999 Anca and Lucian Jurubita . ** All rights reserved. **************************************************************************** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details at www.gnu.org **************************************************************************** ** Rev. 1.0 - Feb. 2000 ****************************************************************************/ #include "microcom.h" #include #include #define BUFSIZE 1024 static int do_com_port_option(unsigned char *buf, int len) { int i = 0; while (i < len) { switch (buf[i]) { case IAC: dprintf("IAC "); return i + 1; case SET_BAUDRATE_CS: dprintf("SET_BAUDRATE_CS "); break; case SET_DATASIZE_CS: dprintf("SET_DATASIZE_CS "); break; case SET_PARITY_CS: dprintf("SET_PARITY_CS "); break; case SET_STOPSIZE_CS: dprintf("SET_STOPSIZE_CS "); break; case SET_CONTROL_CS: dprintf("SET_CONTROL_CS "); break; case NOTIFY_LINESTATE_CS: dprintf("NOTIFY_LINESTATE_CS "); break; case NOTIFY_MODEMSTATE_CS: dprintf("NOTIFY_MODEMSTATE_CS "); break; case FLOWCONTROL_SUSPEND_CS: dprintf("FLOWCONTROL_SUSPEND_CS "); break; case FLOWCONTROL_RESUME_CS: dprintf("FLOWCONTROL_RESUME_CS "); break; case SET_LINESTATE_MASK_CS: dprintf("SET_LINESTATE_MASK_CS "); break; case SET_MODEMSTATE_MASK_CS: dprintf("SET_MODEMSTATE_MASK_CS "); break; case PURGE_DATA_CS: dprintf("PURGE_DATA_CS "); break; case SET_BAUDRATE_SC: dprintf("SET_BAUDRATE_SC %d ", ntohl(*(int *)&buf[i + 1])); i += 4; break; case SET_DATASIZE_SC: dprintf("SET_DATASIZE_SC "); break; case SET_PARITY_SC: dprintf("SET_PARITY_SC "); break; case SET_STOPSIZE_SC: dprintf("SET_STOPSIZE_SC "); break; case SET_CONTROL_SC: i++; dprintf("SET_CONTROL_SC 0x%02x ", buf[i]); break; case NOTIFY_LINESTATE_SC: dprintf("NOTIFY_LINESTATE_SC "); break; case NOTIFY_MODEMSTATE_SC: i++; dprintf("NOTIFY_MODEMSTATE_SC 0x%02x ", buf[i]); break; case FLOWCONTROL_SUSPEND_SC: dprintf("FLOWCONTROL_SUSPEND_SC "); break; case FLOWCONTROL_RESUME_SC: dprintf("FLOWCONTROL_RESUME_SC "); break; case SET_LINESTATE_MASK_SC: dprintf("SET_LINESTATE_MASK_SC "); break; case SET_MODEMSTATE_MASK_SC: dprintf("SET_MODEMSTATE_MASK_SC "); break; case PURGE_DATA_SC: dprintf("PURGE_DATA_SC "); break; default: dprintf("%d ", buf[i]); break; } i++; } return len; } static int do_subneg(unsigned char *buf, int len) { int i = 0; while (i < len) { switch (buf[i]) { case COM_PORT_OPTION: dprintf("COM_PORT_OPTION "); return do_com_port_option(&buf[i + 1], len - i) + 1; case IAC: dprintf("IAC "); return len - i; default: dprintf("%d ", buf[i]); break; } i++; } return len; } static int handle_command(unsigned char *buf, int len) { int i = 0; while (i < len) { switch (buf[i]) { case SB: dprintf("SB "); i += do_subneg(&buf[i+1], len - i); break; case IAC: dprintf("IAC "); break; case COM_PORT_OPTION: dprintf("COM_PORT_OPTION "); break; case SE: dprintf("SE "); break; case WILL: dprintf("WILL "); break; case WONT: dprintf("WILL "); break; case DO: dprintf("WILL "); break; case DONT: dprintf("WILL "); break; default: dprintf("%d ", buf[i]); break; } i++; } dprintf("\n"); return len; } /* handle escape characters, writing to output */ static void cook_buf(struct ios_ops *ios, unsigned char *buf, int num) { int current = 0; while (current < num) { /* big while loop, to process all the charactes in buffer */ /* look for the next escape character '~' */ while ((current < num) && (buf[current] != 28)) current++; /* and write the sequence befor esc char to the comm port */ if (current) write(ios->fd, buf, current); if (current < num) { /* process an escape sequence */ /* found an escape character */ do_commandline(); return; } /* if - end of processing escape sequence */ num -= current; buf += current; current = 0; } /* while - end of processing all the charactes in the buffer */ return; } /* main program loop */ void mux_loop(struct ios_ops *ios) { fd_set ready; /* used for select */ int i = 0, len; /* used in the multiplex loop */ int done = 0; unsigned char buf[BUFSIZE]; do { /* forever */ FD_ZERO(&ready); FD_SET(STDIN_FILENO, &ready); FD_SET(ios->fd, &ready); select(ios->fd + 1, &ready, NULL, NULL, NULL); if (FD_ISSET(ios->fd, &ready)) { i = 0; /* pf has characters for us */ len = read(ios->fd, buf, BUFSIZE); if (len > 0) { if (*buf == IAC) i = handle_command(buf, len); write(STDOUT_FILENO, buf + i, len - i); if (dolog) { fwrite(buf + i , 1, len - i , flog); fflush(flog); } } else done = 1; } if (FD_ISSET(STDIN_FILENO, &ready)) { /* standard input has characters for us */ i = read(STDIN_FILENO, buf, BUFSIZE); if (i > 0) cook_buf(ios, buf, i); else done = 1; } } while (!done); } microcom-2012.06.0/ChangeLog0000644000175000017500000001046611766331477013532 0ustar areare2012-06-14 Marc Kleine-Budde * Makefile: release 2012.06.0 2012-02-18 Jonas Zetterberg * serial.c: Remove lockfile on open serial failure Since the lockfile is created before the serial device is opened, if the serial device can not be opened the lockfile needs to be removed. 2010-08-29 Marc Kleine-Budde * ChangeLog: update changelog 2010-08-28 Marc Kleine-Budde * Makefile, can.c, microcom.c, microcom.h: add simple CAN terminal support 2010-08-27 Marc Kleine-Budde * microcom.h: microcom: borrow min/max defines from the linux kernel 2010-08-28 Marc Kleine-Budde * microcom.c: cmd line parser: fail on unknown options 2010-08-27 Marc Kleine-Budde * microcom.c, serial.c, telnet.c: make functions and vars static * serial.c: serial: remove write only var crnl_mapping * microcom.c: microcom: remove unused var pf * microcom.c: microcom: make var telnet non global 2010-08-29 Marc Kleine-Budde * microcom.c: microcom: remove init of static variables with zero * microcom.h: microcom: remove unused definitions 2010-08-27 Marc Kleine-Budde * mux.c: mux: remove unused SCRIPT_DELAY * commands_fsl_imx.c: commands_fsl_imx: fsl_sniff: add missing return 2010-08-11 Marc Kleine-Budde * .gitignore: gitignore; added *~ * ChangeLog: update changelog 2010-06-10 Sascha Hauer * commands.c: reconnect after sending a break 2010-04-15 Sascha Hauer * commands_fsl_imx.c: fsl commands: update help texts 2010-04-15 Marc Kleine-Budde * ChangeLog: update changelog 2010-04-15 Sascha Hauer * commands_fsl_imx.c: fsl commands: commands seem to be only 16 byte. Now works on i.MX27 * commands_fsl_imx.c: fsl commands: add loop arounf connect 2010-04-14 Sascha Hauer * commands.c, microcom.h, parser.c: fixup help * Makefile, commands_fsl_imx.c, microcom.c: add initial support for starting i.MX SoCs via UART * Makefile, commands.c, help.c, microcom.c, microcom.h, mux.c, parser.c: implement a cli for microcom * .gitignore: add ignore file * microcom.c, microcom.h, serial.c: add a -f option to ignore existing lockfiles 2009-09-24 Jan Weitzel * ChangeLog, mux.c: [microcom] fix log data Log complete buffer as shown on STOUT (without commands) into logfile, not only the commands [mkl: improved short description, fixed coding style] 2009-09-17 Uwe Kleine-König * help.c, microcom.h, serial.c, telnet.c: Implement break for rfc2217 mode 2009-07-08 Marc Kleine-Budde * ChangeLog, microcom.c: [microcom] clean up propperly on exit 2009-06-12 Marc Kleine-Budde * ChangeLog, gitlog2changelog.py: added ChangeLog and gitlog2changelog.py the latter one is a changelog generator \o/ * serial.c, telnet.c: add forgotten license headers to files * microcom.c: fix compiler warning (uninitialized variable hostport) microcom.c:152: warning: 'hostport' may be used uninitialized in this function * Makefile, microcom.c: add version string * Makefile: add -O2 to CFLAGS 2009-01-16 Wolfram Sang * serial.c: * locking: adapt to kermit 2009-01-14 Sascha Hauer * serial.c: remove trailing whitespaces 2009-01-14 Wolfram Sang * serial.c: * check for and create lockfiles for serial ports 2008-09-01 Sascha Hauer * serial.c, telnet.c: 2008-08-28 Sascha Hauer * Makefile, help.c, microcom.c, microcom.h, mux.c: duett und datt * microcom.c: resolve hostnames * help.c, microcom.c, microcom.h, mux.c: implement telnet rfc2217 mode (experimental), update help 2007-05-15 Sascha Hauer * help.c: allow q for quit * microcom.c: ignore break 2006-05-10 Sascha Hauer * mux.c: fflush log * microcom.c: change CR/NL mapping 2006-05-05 Sascha Hauer * Makefile, help.c, microcom.c, microcom.h, mux.c: initial microcom-2012.06.0/microcom.c0000644000175000017500000001510511766331477013727 0ustar areare/****************************************************************** ** File: microcom.c ** Description: the main file for microcom project ** ** Copyright (C)1999 Anca and Lucian Jurubita . ** All rights reserved. **************************************************************************** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details at www.gnu.org **************************************************************************** ** Rev. 1.0 - Feb. 2000 ** Rev. 1.01 - March 2000 ** Rev. 1.02 - June 2000 ****************************************************************************/ #include "microcom.h" #include #include #include #include #include #include #include int dolog; /* log active flag */ FILE *flog; /* log file */ static struct termios sots; /* old stdout/in termios settings to restore */ struct ios_ops *ios; int debug; void init_terminal(void) { struct termios sts; memcpy(&sts, &sots, sizeof (sots)); /* to be used upon exit */ /* again, some arbitrary things */ sts.c_iflag &= ~BRKINT; sts.c_iflag |= IGNBRK; sts.c_lflag &= ~ISIG; sts.c_cc[VMIN] = 1; sts.c_cc[VTIME] = 0; sts.c_lflag &= ~ICANON; /* no local echo: allow the other end to do the echoing */ sts.c_lflag &= ~(ECHO | ECHOCTL | ECHONL); tcsetattr(STDIN_FILENO, TCSANOW, &sts); } void restore_terminal(void) { tcsetattr(STDIN_FILENO, TCSANOW, &sots); } speed_t baudrate_to_flag(int speed) { switch(speed) { case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400; default: printf("unknown speed: %d\n",speed); return -1; } } int flag_to_baudrate(speed_t speed) { switch(speed) { case B50: return 50; case B75: return 75; case B110: return 110; case B134: return 134; case B150: return 150; case B200: return 200; case B300: return 300; case B600: return 600; case B1200: return 1200; case B1800: return 1800; case B2400: return 2400; case B4800: return 4800; case B9600: return 9600; case B19200: return 19200; case B38400: return 38400; case B57600: return 57600; case B115200: return 115200; case B230400: return 230400; default: printf("unknown speed: %d\n",speed); return -1; } } void microcom_exit(int signal) { printf("exiting\n"); /* close the log file first */ if (dolog) { fflush(flog); fclose(flog); } ios->exit(ios); tcsetattr(STDIN_FILENO, TCSANOW, &sots); exit(0); } /******************************************************************** Main functions ******************************************************************** static void help_usage(int exitcode, char *error, char *addl) help with running the program - exitcode - to be returned when the program is ended - error - error string to be printed - addl - another error string to be printed static void cleanup_termios(int signal) signal handler to restore terminal set befor exit int main(int argc, char *argv[]) - main program function ********************************************************************/ void main_usage(int exitcode, char *str, char *dev) { fprintf(stderr, "Usage: microcom [options]\n" " [options] include:\n" " -p devfile use the specified serial port device (%s);\n" " -s speed use specified baudrate (%d)\n" " -t host:port work in telnet (rfc2217) mode\n" " -c interface:rx_id:tx_id work in CAN mode\n" " default: (%s:%x:%x)\n" "microcom provides session logging in microcom.log file\n", DEFAULT_DEVICE, DEFAULT_BAUDRATE, DEFAULT_CAN_INTERFACE, DEFAULT_CAN_ID, DEFAULT_CAN_ID); fprintf(stderr, "Exitcode %d - %s %s\n\n", exitcode, str, dev); exit(exitcode); } int opt_force = 0; int current_speed = DEFAULT_BAUDRATE; int current_flow = FLOW_NONE; int main(int argc, char *argv[]) { struct sigaction sact; /* used to initialize the signal handler */ int opt; char *hostport = NULL; int telnet = 0, can = 0; char *interfaceid = NULL; char *device = DEFAULT_DEVICE; speed_t flag; struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "port", required_argument, 0, 'p'}, { "speed", required_argument, 0, 's'}, { "telnet", required_argument, 0, 't'}, { "can", required_argument, 0, 'c'}, { "debug", no_argument, 0, 'd' }, { "force", no_argument, 0, 'f' }, { 0, 0, 0, 0}, }; while ((opt = getopt_long(argc, argv, "hp:s:t:c:df", long_options, NULL)) != -1) { switch (opt) { case 'h': case '?': main_usage(1, "", ""); exit(0); case 'p': device = optarg; break; case 's': current_speed = strtoul(optarg, NULL, 0); break; case 't': telnet = 1; hostport = optarg; break; case 'c': can = 1; interfaceid = optarg; break; case 'f': opt_force = 1; break; case 'd': debug = 1; } } commands_init(); commands_fsl_imx_init(); if (telnet && can) main_usage(1, "", ""); if (telnet) ios = telnet_init(hostport); else if (can) ios = can_init(interfaceid); else ios = serial_init(device); if (!ios) exit(1); flag = baudrate_to_flag(current_speed); if (flag < 0) exit(1); current_flow = FLOW_NONE; ios->set_speed(ios, flag); ios->set_flow(ios, current_flow); printf("Escape character: Ctrl-\\\n"); printf("Type the escape character followed by c to get to the menu or q to quit\n"); /* Now deal with the local terminal side */ tcgetattr(STDIN_FILENO, &sots); init_terminal(); /* set the signal handler to restore the old * termios handler */ sact.sa_handler = µcom_exit; sigaction(SIGHUP, &sact, NULL); sigaction(SIGINT, &sact, NULL); sigaction(SIGPIPE, &sact, NULL); sigaction(SIGTERM, &sact, NULL); /* run thhe main program loop */ mux_loop(ios); microcom_exit(0); return 0; } microcom-2012.06.0/Makefile0000644000175000017500000000310411766331477013407 0ustar areare#/****************************************************************** #** File: Makefile #** Description: the makefile for microcom project #** #** Copyright (C)1999 Anca and Lucian Jurubita . #** All rights reserved. #**************************************************************************** #** This program is free software; you can redistribute it and/or #** modify it under the terms of the GNU General Public License #** as published by the Free Software Foundation; either version 2 #** of the License, or (at your option) any later version. #** #** This program is distributed in the hope that it will be useful, #** but WITHOUT ANY WARRANTY; without even the implied warranty of #** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #** GNU General Public License for more details at www.gnu.org #**************************************************************************** #** Rev. 0.9 - Sept. 1999 #** Rev. 0.91 - Jan. 2000 - minor fixes, compiled under Mandrake 6.0 #****************************************************************************/ CFLAGS += -Wall -O2 -g LDFLAGS += -lreadline -lpthread CPPFLAGS += -DPKG_VERSION="\"2012.06.0\"" -DPF_CAN=29 -DAF_CAN=PF_CAN microcom: microcom.o mux.o serial.o telnet.o can.o commands.o parser.o commands_fsl_imx.o mux.o: mux.c microcom.h microcom.o: microcom.c microcom.h serial.o: serial.c microcom.h telnet.o: telnet.c microcom.h can.o: can.c microcom.h commands.o: telnet.o microcom.h parser.o: parser.c microcom.h commands_fsl_imx.o: commands_fsl_imx.c microcom.h clean: rm -f *.o microcom microcom-2012.06.0/parser.c0000644000175000017500000000631311766331477013414 0ustar areare#include #include #include #include "microcom.h" #define MAXARGS 64 static int parse_line(char *_line, int *argc, char *argv[]) { char *line = _line; int nargs = 0; if (!line) goto out; while (nargs < MAXARGS) { /* skip any white space */ while (*line == ' ' || *line == '\t') ++line; if (*line == '\0' || *line == ';') /* end of line, no more args */ goto out; argv[nargs] = line; /* begin of argument string */ if (*line == '\"') { line++; argv[nargs] = line; while (*line && *line != '\"') line++; if (!*line) { printf("could not find matching '\"'\n"); return -EINVAL; } else *line++ = '\0'; } else { /* find end of string */ while (*line && *line != ' ' && *line != '\t' && *line != ';') ++line; } nargs++; if (*line == '\0') /* end of line, no more args */ goto out; if (*line == ';') { *line = '\0'; goto out; } *line++ = '\0'; /* terminate current arg */ } printf("Too many args (max. %d)\n", MAXARGS); out: argv[nargs] = NULL; *argc = nargs; return line - _line + 1; } struct cmd *commands; int register_command(struct cmd *cmd) { struct cmd *tmp; cmd->next = NULL; if (!commands) { commands = cmd; return 0; } tmp = commands; while (tmp->next) tmp = tmp->next; tmp->next = cmd; return 0; } void microcom_cmd_usage(char *command) { struct cmd *cmd; for_each_command(cmd) { if (!strcmp(command, cmd->name)) { char *str = NULL; if (cmd->info) str = cmd->info; if (cmd->help) str = cmd->help; if (!str) str = "no help available\n"; printf("usage:\n%s\n", str); return; } } printf("no such command\n"); } static int __do_commandline(const char *prompt) { char *cmd; char *argv[MAXARGS + 1]; int argc = 0, ret = 0, n, len; while (1) { struct cmd *command; cmd = readline(prompt); if (!cmd) { ret = MICROCOM_CMD_START; break; } if (!strlen(cmd)) goto done; if (prompt) add_history(cmd); len = strlen(cmd); n = 0; while (n < len) { int handled = 0; ret = parse_line(cmd + n, &argc, argv); if (ret < 0) break; n += ret; if (!argv[0]) continue; for_each_command(command) { if (!strcmp(argv[0], command->name)) { ret = command->fn(argc, argv); if (ret == MICROCOM_CMD_START) { free(cmd); return ret; } if (ret == MICROCOM_CMD_USAGE) microcom_cmd_usage(argv[0]); handled = 1; break; } } if (!handled) printf("unknown command \'%s\', try \'help\'\n", argv[0]); } done: free(cmd); } if (cmd) free(cmd); return ret; } int do_commandline(void) { int ret; restore_terminal(); printf("\nEnter command. Try \'help\' for a list of builtin commands\n"); do { ret = __do_commandline("-> "); } while (ret != MICROCOM_CMD_START); printf("\n----------------------\n"); init_terminal(); return 0; } int do_script(char *script) { int fd = open(script, O_RDONLY); int stdin = dup(1); int ret; if (fd < 0) { printf("could not open %s: %s\n", script, strerror(errno)); return -1; } dup2(fd, 0); ret = __do_commandline(NULL); dup2(stdin, 0); return ret; } microcom-2012.06.0/telnet.c0000644000175000017500000000637611766331477013424 0ustar areare/****************************************************************** ** File: telnet.c ** Description: the telnet part for microcom project ** ** Copyright (C) 2008, 2009 Sascha Hauer . ** All rights reserved. **************************************************************************** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details at www.gnu.org ****************************************************************************/ #include #include #include #include #include #include "microcom.h" static int telnet_set_speed(struct ios_ops *ios, speed_t speed) { // unsigned char buf1[] = {IAC, WILL , COM_PORT_OPTION}; unsigned char buf2[] = {IAC, SB, COM_PORT_OPTION, SET_BAUDRATE_CS, 0, 0, 0, 0, IAC, SE}; int *speedp = (int *)&buf2[4]; // write(fd, buf1, 3); *speedp = htonl(flag_to_baudrate(speed)); write(ios->fd, buf2, 10); return 0; } static int telnet_set_flow(struct ios_ops *ios, int flow) { unsigned char buf2[] = {IAC, SB, COM_PORT_OPTION, SET_CONTROL_CS, 0, IAC, SE}; switch (flow) { case FLOW_NONE: /* no flow control */ buf2[4] = 1; break; case FLOW_SOFT: /* software flow control */ buf2[4] = 2; break; case FLOW_HARD: /* hardware flow control */ buf2[4] = 3; break; } write(ios->fd, buf2, sizeof(buf2)); return 0; } static int telnet_send_break(struct ios_ops *ios) { unsigned char buf2[] = {IAC, BREAK}; write(ios->fd, buf2, sizeof(buf2)); return 0; } static void telnet_exit(struct ios_ops *ios) { close(ios->fd); free(ios); } struct ios_ops *telnet_init(char *hostport) { int sock; struct sockaddr_in server_in; char *host = hostport; char *portstr; int port = 23; struct hostent *hp; struct ios_ops *ios; ios = malloc(sizeof(*ios)); if (!ios) return NULL; ios->set_speed = telnet_set_speed; ios->set_flow = telnet_set_flow; ios->send_break = telnet_send_break; ios->exit = telnet_exit; portstr = strchr(hostport, ':'); if (portstr) { *portstr = 0; portstr++; port = atoi(portstr); } hp = gethostbyname(host); if (!hp) { perror("gethostbyname"); return NULL; } host = inet_ntoa(*(struct in_addr*)(hp->h_addr_list[0])); memset(&server_in, 0, sizeof(server_in)); /* Zero out structure */ server_in.sin_family = AF_INET; /* Internet address family */ server_in.sin_addr.s_addr = inet_addr(host); /* Server IP address */ server_in.sin_port = htons(port); /* Server port */ sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) { printf("socket() failed\n"); return NULL; } /* Establish the connection to the echo server */ if (connect(sock, (struct sockaddr *) &server_in, sizeof(server_in)) < 0) { perror("connect"); return NULL; } ios->fd = sock; printf("connected to %s (port %d)\n", host, port); return ios; }