⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpsflash.c

📁 gpsd, a popular GPS daemon.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: gpsflash.c 4471 2007-12-08 08:02:57Z ckuethe $ *//* * This is the GPS-type-independent part of the gpsflash program. * *//* * Copyright (c) 2005-2007 Chris Kuethe <chris.kuethe@gmail.com> * Copyright (c) 2005-2007 Eric S. Raymond <esr@thyrsus.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */#include <sys/types.h>#include <stdarg.h>#include <string.h>#include "gpsd_config.h"#include "gpsd.h"#include "gpsflash.h"/* block size when writing to the serial port. related to FIFO size */#define WRBLK 128static char *progname;static int verbosity = 0;static bool srec_check(const char *data);void gpsd_report(int errlevel, const char *fmt, ... )/* assemble command in printf(3) style, use stderr or syslog */{    if (errlevel <= verbosity) {	char buf[BUFSIZ];	va_list ap;	(void)strlcpy(buf, progname, BUFSIZ);	(void)strlcat(buf, ": ", BUFSIZ);	va_start(ap, fmt) ;	(void)vsnprintf(buf + strlen(buf), sizeof(buf)-strlen(buf), fmt, ap);	va_end(ap);	(void)fputs(buf, stdout);    }}static voidusage(void){    fprintf(stderr, "Usage: %s [-v d] [-n] [-l <loader_file>] -f <firmware_file> {<tty>}\n", progname);}intserialSpeed(int pfd, struct termios *term, int speed){	int rv;	int r = 0;	switch(speed){#ifdef B115200	case 115200:		speed = B115200;		break;#endif#ifdef B57600	case 57600:		speed = B57600;		break;#endif	case 38400:		speed = B38400;		break;#ifdef B28800	case 28800:		speed = B28800;		break;#endif	case 19200:		speed = B19200;		break;#ifdef B14400	case 14400:		speed = B14400;		break;#endif	case 9600:		speed = B9600;		break;	case 4800:		speed = B9600;		break;	default:		errno = EINVAL;		return -1;	}	/* set UART speed */	(int)tcgetattr(pfd, term);	/*@ ignore @*/	cfsetispeed(term, speed);	cfsetospeed(term, speed);	/*@ end @*/	while (((rv = tcsetattr(pfd, TCSAFLUSH, term)) == -1) && \	    (errno == EINTR) && (r < 3)) {		/* retry up to 3 times on EINTR */		(void)usleep(1000);		r++;	}	if(rv == -1)		return -1;	else		return 0;}intserialConfig(int pfd, struct termios *term, int speed){	int rv;	int r = 0;	/* get the current terminal settings */	(void)tcgetattr(pfd, term);	/* set the port into "raw" mode. */	/*@i@*/cfmakeraw(term);	term->c_lflag &=~ (ICANON);	/* Enable serial I/O, ignore modem lines */	term->c_cflag |= (CLOCAL | CREAD);	/* No output postprocessing */	term->c_oflag &=~ (OPOST);	/* 8 data bits */	term->c_cflag |= CS8;	term->c_iflag &=~ (ISTRIP);	/* No parity */	term->c_iflag &=~ (INPCK);	term->c_cflag &=~ (PARENB | PARODD);	/* 1 Stop bit */	term->c_cflag &=~ (CSIZE | CSTOPB);	/* No flow control */	term->c_iflag &=~ (IXON | IXOFF);#if defined(CCTS_OFLOW) && defined(CRTS_IFLOW) && defined(MDMBUF)	term->c_oflag &=~ (CCTS_OFLOW | CRTS_IFLOW | MDMBUF);#endif#if defined(CRTSCTS)	term->c_oflag &=~ (CRTSCTS);#endif	/* we'd like to read back at least 2 characters in .2sec */	/*@i@*/term->c_cc[VMIN] = 2;	/*@i@*/term->c_cc[VTIME] = 2;	/* apply all the funky control settings */	while (((rv = tcsetattr(pfd, TCSAFLUSH, term)) == -1) && \	    (errno == EINTR) && (r < 3)) {		/* retry up to 3 times on EINTR */		(void)usleep(1000);		r++;	}	if(rv == -1)		return -1;		/* and if that all worked, try change the UART speed */	return serialSpeed(pfd, term, speed);}intbinary_send(int pfd, char *data UNUSED , size_t ls){	unsigned char *msg;	size_t nbr, nbs, nbx;	ssize_t r;	static int count;	double start = timestamp();	/*@ -compdef @*/	if((msg = malloc(ls+10)) == NULL){		return -1; /* oops. bail out */	}	fprintf(stderr, "gpsflash: transferring binary... \010");	count = 0;	nbr = ls+10; nbs = WRBLK ; nbx = 0;	while(nbr){		if(nbr > WRBLK )			nbs = WRBLK ;		else			nbs = nbr;r0:		if((r = write(pfd, msg+nbx, nbs)) == -1){			if (errno == EAGAIN){ /* retry */				(void)tcdrain(pfd); /* wait a moment */				errno = 0; /* clear errno */				nbr -= r; /* number bytes remaining */				nbx += r; /* number bytes sent */				goto r0;			} else {			        (void)free(msg);				return -1; /* oops. bail out */			}		}		nbr -= r;		nbx += r;		(void)fputc("-/|\\"[count % 4], stderr);		(void)fputc('\010', stderr);		(void)fflush(stdout);	}	/*@ +compdef @*/	(void)fprintf(stderr, "...done (%2.2f sec).\n", timestamp()-start);	(void)free(msg);	return 0;}intsrecord_send(int pfd, char *data, size_t len){	int r, i;	size_t tl;	char sendbuf[85], recvbuf[8];	static int count;	double start = timestamp();	/* srecord loading is interactive. send line, get reply */	/* when sending S-records, check for SA/S5 or SE */	fprintf(stderr, "gpsflash: transferring S-records... \010");	count = 0;	memset(recvbuf, 0, 8);	i = 0;	while(strlen(data)){		/* grab a line of firmware, ignore line endings */		if ((r = (int)strlen(data))){			memset(sendbuf,0,85);			if((r = sscanf(data, "%80s", sendbuf)) == EOF)				return 0;			tl = strlen(sendbuf);			if ((tl < 1) || (tl > 80))				return -1;			data += tl;			len -= tl;			while((data[0] != 'S') && (data[0] != '\0'))				data++;			sendbuf[tl] = '\r';			sendbuf[tl+1] = '\n';			tl += 2;			if ((++i % 1000) == 0)				printf ("%6d\n", i);			(void)tcflush(pfd, TCIFLUSH);			if((r = (int)write(pfd, sendbuf, tl+2)) != (int)tl+2)				return -1; /* oops. bail out */			(void)tcdrain(pfd);			if((r = (int)read(pfd, recvbuf, 7)) == -1)				return -1; /* oops. bail out */			if (!((recvbuf[0] == 'S') && ((recvbuf[1] == 'A') || (recvbuf[1] == '5'))))				return -1; /* oops. bail out */		}		(void)fputc("-/|\\"[count % 4], stderr);		(void)fputc('\010', stderr);		(void)fflush(stdout);	}	(void)fprintf(stderr, "...done (%2.2f sec).\n", timestamp()-start);	return 0;}bool expect(int pfd, const char *str, size_t len, time_t timeout)/* keep reading till we see a specified expect string or time out */{    size_t got = 0;    char ch;    double start = timestamp();    gpsd_report(LOG_PROG, "expect(%s, %d)\n", 		gpsd_hexdump((char *)str, len),		timeout);    for (;;) {	if (read(pfd, &ch, 1) != 1)	    return false;		/* I/O failed */	gpsd_report(LOG_RAW, "I see %d: %02x\n", got, (unsigned)(ch & 0xff));	if (timestamp() - start > (double)timeout)	    return false;		/* we're timed out */	else if (got == len)	    return true;		/* we're done */	else if (ch == str[got])	    got++;			/* match continues */	else	    got = 0;			/* match fails, retry */    }}#if defined(SIRF_ENABLE) && defined(BINARY_ENABLE)/* add new types by adding pointers to their driver blocks to this list *//*@ -nullassign @*/static struct flashloader_t *types[] = {&sirf_type, NULL};/*@ +nullassign @*/#else/* add new types by adding pointers to their driver blocks to this list *//*@ -nullassign @*/static struct flashloader_t *types[] = {NULL, NULL};/*@ +nullassign @*/#endifintmain(int argc, char **argv){	int ch;	int lfd, ffd, pfd;	size_t ls,  fs;	bool fflag = false, lflag = false, nflag = false;	struct stat sb;	struct flashloader_t *gpstype, **gp;	char *fname = NULL;	char *lname = NULL;	char *port = NULL;	char *warning;	struct termios term;	sigset_t sigset;	char *firmware = NULL;	char *loader = NULL;	char *version = NULL;	progname = argv[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -