Пример #1
0
Файл: pcl.c Проект: hwstar/pbl
static int packet_rx(serioStuff *s, void *p, size_t size, int timeout)
{

	if(!flags.hanmode){
		return  serio_read(s, p, size, timeout);

	}
	else{
		int res;
		u8 b[2];
		int xfrcount = 0;

		do{
			res = serio_read(s, b, 1, timeout);
		}
		while((res == 1) && (b[0] != STX));


		for(xfrcount = 0; (res == 1); xfrcount++){
			res = serio_read(s, b, 1, timeout);

			if(res != 1){
				break;
			}

			if(b[0] == ETX){
				break;
			}

			else if(b[0] == SUBST){
				res = serio_read(s, b, 1, timeout);

				if(res != 1){
					break;
				}
			}
			if(xfrcount < size)
				((u8 *) p)[xfrcount] = b[0];
		}
		return (res < 0) ? res : xfrcount;
	}

}
Пример #2
0
int serio_nb_line_readcr(serioStuffPtr_t serio)
{
	char c;
	int res;
	
	if(!serio)
		return -1;

	do{
		res = serio_read(serio, &c, 1);	
		if(serio->eof){
			return TRUE;
		}
		else if(res < 0){	
			if((errno != EAGAIN) && (errno != EWOULDBLOCK)){
				debug(DEBUG_UNEXPECTED, "Read error on fd %d: %s", serio->fd, strerror(errno));
				serio->pos = 0;
				return ERROR;
			}
			return FALSE;
		}
		else if(res == 1){
			/* debug(DEBUG_ACTION,"Byte received"); */
			if(c == '\r') /* Ignore return */
				continue;
			if(c != '\n'){
				if(serio->pos < (SERIO_MAX_LINE - 1))
					serio->line[serio->pos++] = c;
				else
					debug(DEBUG_UNEXPECTED,"End of line buffer reached!");

			}
			else{
				debug(DEBUG_ACTION, "Line received");
				serio->line[serio->pos] = 0;
				serio->pos = 0;
				return TRUE;
			}
		}
	} while(TRUE);

	return ERROR;
}
Пример #3
0
/*-----------------------------------------------------------------------
 Receive a packet via the serial port.
 Caller must put size of buffer in len before calling.
 Packets larger than buffer will be silently ignored.
 On failure, returns
 	ser_RES_BAD if *len looked bogus, or buf was NULL,
				 or packet was too big to fit in buffer, or 0 size.
	ser_RES_EMPTY if no good packet was availible.
 On success,
 	returns ser_RES_OK,
	sets *len to the packet length,

 Can only recieve from ser_HDL_YOU, so no source adr need be returned.

 CRC errors cause ser_RES_EMPTY rather than ser_RES_BAD, since 
 ser_RES_BAD is reserved for caller brain damage errors.

 Strategy:
   Read ser_READSIZE bytes at a time from the serial port into ser->rbuf.
   ser->len is number of bytes in ser->rbuf.
   ser->head is the index of the next byte to get out of ser->rbuf.
   Accumulate next good packet in ser->pkt.
   ser->got is the number of good bytes gotten so far.
   If anything goes wrong, just clear ser->got, and life keeps on humming.
-----------------------------------------------------------------------*/
ser_result_t ser_get(ser_t *ser, void *buf, size_t *len)
{
    for (;;) {
		int c;
		assert((0 <= ser->got) && (ser->got < sizeof(ser->pkt)));

		//DPRINT(("ser_get: top: got = %d\n", ser->got));
		// Fill small input buffer if empty.
		if (ser->head >= ser->len) {
			size_t n_received;
			serio_res_t err;
			//DPRINT(("ser_get: calling serio_read\n"));
			err = serio_read(&ser->serio, ser->rbuf, ser_READSIZE, &n_received);
			if ((err != serio_RES_OK) && (err != serio_RES_EMPTY)) {
				DPRINT(("ser_get: serio_read failed %d\n", err));
			} else if ((n_received == 0) || (err == serio_RES_EMPTY)) {
				DPRINT(("ser_get: returning EMPTY\n"));
				return ser_RES_EMPTY;
			}
			ser->head = 0;
			ser->len = n_received;
			/* check if got a modem not connected signal */
			{	unsigned char *p = &ser->rbuf[0];
				int pos = ser->sigpos;
				for ( ; n_received--; p++) {
					if (*p == SIGNAL_HANGUP[pos])  {
						DPRINT(("ser_get: matched SH[%d]=%c; pos now %d\n", pos, *p, pos+1));
						pos++;
						if (pos >= sizeof(SIGNAL_HANGUP)) {
							DPRINT(("ser_get: returning NO_RESPONSE\n"));
							return ser_RES_NO_RESPONSE;
						}
					} else if (pos) {
						DPRINT(("ser_get: cleared pos\n"));
						pos = 0;
						if (*p == SIGNAL_HANGUP[pos]) {
							DPRINT(("ser_get: matched SH[%d]=%c; pos now %d\n", pos, *p, pos+1));
							pos++;
						}
					}
				}
				ser->sigpos = pos;
			}
		}
		// Continue accumulating bytes of packet.
		c = ser->rbuf[ser->head++];
		((unsigned char *)&ser->pkt)[ser->got++] = c;

		DPRINT(("ser_get: got char 0x%x, got now %d\n", c, ser->got));
		// Do header processing.
		if        (ser->got == 1) {
			// Does 1st byte of header match?
			if (c != ser_HDR_FRAME0)
				ser->got = 0;			// no, just start over.
		} else if (ser->got == 2) {
			// Does 2nd byte of header match?
			if (c != ser_HDR_FRAME1)
				ser->got = 0;			// no, just start over.
		} else if (ser->got == 4) {
			// Is header Checksum valid?
			if (c != ((ser_HDR_FRAME0 + ser_HDR_FRAME1 + ser->pkt.hdr.bodylen) & 0xff))
				ser->got = 0;			// no, just start over.
		} else if ((size_t)(ser->got) >= sizeof(ser_hdr_t) + ser->pkt.hdr.bodylen) {
			int c = crc(ser->pkt.body, ser->pkt.hdr.bodylen);
			ser->got = 0;
			// Done with packet.  Does crc match?
			DPRINT(("ser_get: bodycrc %4x, len %d, first 2 bytes %02x %02x, last 5 bytes %02x %02x %02x %02x %02x\n",
				ser->pkt.hdr.bodycrc,
				ser->pkt.hdr.bodylen,
				ser->pkt.body[0],
				ser->pkt.body[1],
				ser->pkt.body[ser->pkt.hdr.bodylen-5],
				ser->pkt.body[ser->pkt.hdr.bodylen-4],
				ser->pkt.body[ser->pkt.hdr.bodylen-3],
				ser->pkt.body[ser->pkt.hdr.bodylen-2],
				ser->pkt.body[ser->pkt.hdr.bodylen-1]));
			if (c != ser->pkt.hdr.bodycrc) {
				DPRINT(("ser_get: returning EMPTY; bad crc. last 4 bytes %02x %02x %02x %02x\n",
					ser->pkt.body[ser->pkt.hdr.bodylen-4],
					ser->pkt.body[ser->pkt.hdr.bodylen-3],
					ser->pkt.body[ser->pkt.hdr.bodylen-2],
					ser->pkt.body[ser->pkt.hdr.bodylen-1]));
				return ser_RES_EMPTY;
			}
			// Is user buffer big enough to fit this packet?
			if (ser->pkt.hdr.bodylen > *len) {
				DPRINT(("ser_get: returning FULL\n"));
				return ser_RES_FULL;	// no, packet too big to fit, fail
			} else {
				// Yes.  Copy packet to user, prepare for next packet.
				memcpy(buf, ser->pkt.body, ser->pkt.hdr.bodylen);
				*len = ser->pkt.hdr.bodylen;
				DPRINT(("ser_get: returning OK\n"));
				return ser_RES_OK;
			}
		}
	}
	DPRINT(("ser_get: bug: unreachable code reached\n"));
	return ser_RES_EMPTY;
}
Пример #4
0
ser_result_t ser_get(ser_t *ser, void *buf, size_t *len)
{
	DWORD	dwErrorFlags;
	DWORD	dwReadLength;
	BOOL	bContinue = TRUE;
	DWORD	start_tmp;

	while (bContinue) {
		if (LOOKING_FOR_HDR == ser->state) {
			if (RBUF_DATA(ser) >= sizeof(ser_hdr_t)) {
				/* printbytes((void *)(&(ser->rbuf[ser->start])), "ser_get:hdr:", sizeof(ser_hdr_t)); */
				if (ser_HDR_FRAME0 != ser->rbuf[ser->start]) {
					RBUF_INCREMENT_START(ser, 1); continue;
				}
				RBUF_INCREMENT_START(ser, 1);
				if (ser_HDR_FRAME1 != ser->rbuf[ser->start]) {
					RBUF_INCREMENT_START(ser, 1); continue;
				}
				RBUF_INCREMENT_START(ser, 1);
				ser->length = (ser->rbuf[RBUF_OFFSET(ser, 0)] & 0xff);
				if (((ser_HDR_FRAME0 + ser_HDR_FRAME1 + ser->length) & 0xff) != ser->rbuf[RBUF_OFFSET(ser, 1)]) {
					/* DPRINT(("ser_get:got ser->rbuf[RBUF_OFFSET(ser,1)] incorrect\n")); */
					continue;
				}
				ser->crc = ser->rbuf[RBUF_OFFSET(ser, 2)];
				ser->state = LOOKING_FOR_BODY;
			}
			else {
				/* DPRINT(("ser_get: RBUF_DATA len:%d is smaller than %d\n", RBUF_DATA(ser), sizeof(ser_hdr_t))); */
				bContinue = FALSE;
			}
		}
		if (LOOKING_FOR_BODY == ser->state) {
			if (RBUF_DATA(ser) >= ser->length + 3) {
				start_tmp = ser->start; RBUF_INCREMENT_START(ser, 3);
				if (RBUF_CRC(ser) == ser->crc) {
					if (ser->length > *len) {
						/* DPRINT(("ser_get: ser->length=%d > *len=%d\n", ser->length, *len)); */
						*len = (ser->length & 0xff); return ser_RES_FULL;
					} else {
						*len = (ser->length & 0xff);
						if (ser->start + ser->length <= ser->rbufsize) {
							memcpy(buf, ser->rbuf + ser->start, ser->length);
						} else {
							memcpy(buf, ser->rbuf + ser->start, ser->rbufsize - ser->start);
							memcpy((char *) buf + ser->rbufsize - ser->start, ser->rbuf, ser->length - (ser->rbufsize - ser->start));
						}
						/* printbytes(buf, "ser_get:buf:", ser->length); */
						RBUF_INCREMENT_START(ser, ser->length);
						ser->state = LOOKING_FOR_HDR;
						return ser_RES_OK;
					}
				} else {
					ser->start = start_tmp;
					ser->state = LOOKING_FOR_HDR; continue;
				}
			} else {
				/* DPRINT(("ser_get: RBUF_DATA len:%d is smaller than ser->len+3=%d\n", RBUF_DATA(ser), ser->length + 3)); */
				bContinue = FALSE;
			}
		}
		dwReadLength = RBUF_EMPTY(ser);
		if (dwReadLength > 0) {
			serio_res_t err;
			err = serio_read(&ser->serio, &ser->rbuf[ser->end], dwReadLength, &dwReadLength);
			if ((err != serio_RES_OK) && (err != serio_RES_EMPTY)) {
				DPRINT(("ser_get: serio_read failed %d\n", err));
			} else {
				/* check if got a modem not connected signal */
				{	DWORD i;
					int pos;
					unsigned char *p;
					pos = ser->sigpos;
					for (i = 1, p = &(ser->rbuf[ser->end]); i <= dwReadLength; i++, p++) {
						if (*p == SIGNAL_HANGUP[pos])  {
							pos++;
							if (pos >= sizeof(SIGNAL_HANGUP))
								return ser_RES_NO_RESPONSE;
						} else if (pos) {
							pos = 0;
							if (*p == SIGNAL_HANGUP[pos]) 
								pos++;
						}
					}
					ser->sigpos = pos;
				}
#if 0
				DPRINT(("ser_get: read %d bytes\n", dwReadLength));
				printbytes((void *)(&(ser->rbuf[ser->end])), "ser_get:readbuf:", dwReadLength);
#endif
				RBUF_INCREMENT_END(ser, dwReadLength); bContinue = TRUE;
			}
		}
	}
	return ser_RES_EMPTY;
}
Пример #5
0
Файл: pcl.c Проект: hwstar/pbl
static int send_command(serioStuff *s, u8 cmd, u16 param, void *payload)
{
	int retries, res;
	int bytes_sent, bytes_received;
	u8 ack,nak;
	unsigned char resp = 0x55; 
	static u16 seqno = 0;


	packet_init();

	if(flags.hanmode){
		packet.han.pkttype = HDC;
		packet.han.addr = (u8) hannodeaddr; 
		packet.han.cmd = cmd;
		packet.han.param = param;
		packet.han.seq = seqno;
		ack = HDC_ACK;
		nak = HDC_NAK;
		
	}
	else{
		packet.pbl.cmd = cmd;
		packet.pbl.param = param;
		packet.pbl.seq = seqno;
		ack = ACK;
		nak = NAK;
	}
	if(payload)
		memcpy((flags.hanmode) ? packet.han.payload : packet.pbl.payload, payload, LOADER_PAYLOAD);
	packet_finalize();
	debug(DEBUG_ACTION,"Command: 0x%02X Sequence Number: %d, CRC: 0x%04X", cmd, seqno, (flags.hanmode)? packet.han.crc16 : packet.pbl.crc16);

	if(!flags.handisrunning){ // Hand not running?
		serio_flush_input(s);
		for(retries = PACKET_RETRIES;;){
			if((bytes_sent = packet_tx(s, packet.buffer, packet_size, 5000000)) < 0){
				debug(DEBUG_ACTION, "Command Packet Write Error");
				return FAIL;
			}
			debug(DEBUG_ACTION, "Bytes Sent: %d", bytes_sent);
			if(bytes_sent != packet_size){
				debug(DEBUG_ACTION, "Command Packet Write Incomplete");
				return FAIL;
			}

			for(;;){
				bytes_received = serio_read(s, &resp, 1, 5000000);
				if(bytes_received < 0){
					if(errno != EAGAIN){
						debug(DEBUG_UNEXPECTED, "Response Read Error: %s", strerror(errno));
						return FAIL;
					}
					else{
						continue;
					}
				}
				else{
					break;
				}
			}
	
			if(bytes_received != 1){
				debug(DEBUG_ACTION, "Read Timeout Error");
				return FAIL;
			}

			if((resp == ack)||(resp == nak)){
				debug(DEBUG_ACTION, "Response: %s",(resp == ack)?"ACK":"NAK");
			}
			else{
				debug(DEBUG_ACTION, "Response: 0x%02X", (unsigned int) resp);
			}

			if((cmd == BC_CHECK_APP) && (resp == STX)){
				debug(DEBUG_UNEXPECTED, "Check App Failed");
				return FAIL;
			}

			if((resp != ack)){				
				debug(DEBUG_ACTION, "Did not get ACK");
				if((resp == nak) && (retries--)){
					debug(DEBUG_UNEXPECTED, "***Retrying packet***");
					usleep(100000);
					continue;
				}
				return FAIL; // Retries used up or didn't get ACK or NAK. Fail.
			}
			break;
		}
	}
	else{ // Hand is running
		for(retries = 0; retries < PACKET_RETRIES; retries++){
			client_command.cmd.raw.txlen = packet_format(client_command.cmd.raw.txbuffer, &packet.han, packet_size);
			client_command.cmd.raw.rxexpectlen = 1;
			client_command.cmd.raw.txtimeout = 100000;
			client_command.cmd.raw.rxtimeout = 1000000;
			client_command.request = HAN_CCMD_RAW_PACKET;
			res = hanclient_send_command_return_res(&client_command);
			bytes_received = 0;
			if(!res)
				bytes_received = client_command.cmd.raw.rxexpectlen;
			if(bytes_received == 1){
				resp = client_command.cmd.raw.rxbuffer[0];
				if((resp == ack)||(resp == nak)){
					debug(DEBUG_ACTION, "Response: %s",(resp == ack)?"ACK":"NAK");
				}
				else{
					debug(DEBUG_ACTION, "Response: 0x%02X", (unsigned int) resp);
				}

				if((cmd == BC_CHECK_APP) && (resp == STX)){
					debug(DEBUG_UNEXPECTED, "Check App Failed");
					return FAIL;
				}

				if((resp != ack)){				
					debug(DEBUG_ACTION, "Did not get ACK");
					if(resp == nak){
						debug(DEBUG_UNEXPECTED, "***Retrying packet***, try = %d", retries);
						usleep(100000);
						continue;
					}
				}
				else
					break; // Success
			}
			debug(DEBUG_UNEXPECTED,"Received invalid or no response, try = %d", retries);
			usleep(100000);
		}
		if(retries == PACKET_RETRIES){
			debug(DEBUG_EXPECTED, "Too many packet retries!");
			return FAIL;
		}
	}

	seqno++;
	return PASS;
}