Пример #1
0
/*
 * Send a load of data
 *
 * P4 is the inter byte gap
 *
 * This does very un-clever half duplex removal, there better not be
 * any outstanding data on the bus (or in the l0 buffers) or this
 * will think it has a half-duplex failure, i.e a bus error
 *
 * Returns 0 on success -1 on failure
 */
int
diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, size_t len, int p4)
{
	int rv = -1;
	int l0flags;
	const struct diag_l0 *dl0 = diag_l0_device_dl0(dl0d);

	/*
	 * If p4 is zero and not in half duplex mode, or if
	 * L1 is a "DOESL2" interface send the whole message to L0
	 * as one write
	 */ 
	l0flags = diag_l1_getflags(dl0d);

	if (   ((p4 == 0) && ((l0flags & DIAG_L1_HALFDUPLEX) == 0)) ||
		(l0flags & DIAG_L1_DOESL2FRAME) || (l0flags & DIAG_L1_DOESP4WAIT) ) {
		/*
		 * Send the lot if we don't need to delay, or collect
		 * the echos
		 */
		rv = (dl0->diag_l0_send)(dl0d, subinterface, data, len);
	} else {
		const uint8_t *dp = (const uint8_t *)data;

		/* Send each byte */
		while (len--) {
			rv = (dl0->diag_l0_send)(dl0d, subinterface, dp, 1);
			if (rv != 0)
				break;

			/*
			 * If half duplex, read back the echo, if
			 * the echo is wrong then this is an error
			 * i.e something wrote on the diag bus whilst
			 * we were writing
			 */
			if (l0flags & DIAG_L1_HALFDUPLEX) {
				uint8_t c;

				c = *dp - 1; /* set it with wrong val */
				if (diag_l1_saferead(dl0d, &c, 1, 1000) < 0) {
					rv=DIAG_ERR_GENERAL;
					break;
				}
				if (c != *dp) {
					if (c == *dp - 1)
						fprintf(stderr,"Half duplex interface not echoing!\n");
					else
						fprintf(stderr,"Bus Error: got 0x%x expected 0x%x\n",
							c&0xff, *dp & 0xff);
					rv = DIAG_ERR_BUSERROR;
					break;
				}
			}
			dp++;

			if (p4)	/* Inter byte gap */
				diag_os_millisleep(p4);
		}
	}

	return rv;
}
Пример #2
0
/*
 * Send a load of data
 *
 * P4 is the inter byte gap
 *
 * This does very un-clever half duplex removal, there better not be
 * any outstanding data on the bus (or in the l0 buffers) or this
 * will think it has a half-duplex failure, i.e a bus error
 *
 * Returns 0 on success
 */
int
diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, size_t len, unsigned int p4) {
	int rv = DIAG_ERR_GENERAL;
	uint32_t l0flags;
	uint8_t duplexbuf[MAXRBUF];

	if (len > MAXRBUF) {
		return diag_iseterr(DIAG_ERR_BADLEN);
	}

	l0flags = diag_l1_getflags(dl0d);

	DIAG_DBGMDATA(diag_l1_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V, data, len,
		FLFMT "_send: len=%d P4=%u l0flags=0x%X; ",
		FL, (int) len, p4, l0flags);

	/*
	 * If p4 is zero and not in half duplex mode, or if
	 * L1 is a "DOESL2" interface, or if L0 takes care of P4 waits,
	 * or if P4==0 and we do per-message duplex removal:
	 * send the whole message to L0 as one write
	 */

	if (   ((p4 == 0) && ((l0flags & DIAG_L1_HALFDUPLEX) == 0)) ||
		(l0flags & DIAG_L1_DOESL2FRAME) || (l0flags & DIAG_L1_DOESP4WAIT) ||
		((p4==0) && (l0flags & DIAG_L1_BLOCKDUPLEX)) ) {
		/*
		 * Send the lot
		 */
		rv = diag_l0_send(dl0d, subinterface, data, len);

		//optionally remove echos
		if ((l0flags & DIAG_L1_BLOCKDUPLEX) && (rv==0)) {
			//try to read the same number of sent bytes; timeout=300ms + 1ms/byte
			//This is plenty OK for typical 10.4kbps but should be changed
			//if ever slow speeds are used.
			if (diag_l0_recv(dl0d, NULL, duplexbuf, len, 300+len) != (int) len) {
				rv=DIAG_ERR_GENERAL;
			}

			//compare to sent bytes
			if ( memcmp(duplexbuf, data, len) !=0) {
				fprintf(stderr,FLFMT "Bus Error: bad half duplex echo!\n", FL);
				rv=DIAG_ERR_BUSERROR;
			}
		}
	} else {
		/* else: send each byte */
		const uint8_t *dp = (const uint8_t *)data;

		while (len--) {
			rv = diag_l0_send(dl0d, subinterface, dp, 1);
			if (rv != 0) {
				break;
			}

			/*
			 * If half duplex, read back the echo, if
			 * the echo is wrong then this is an error
			 * i.e something wrote on the diag bus whilst
			 * we were writing
			 */
			if (l0flags & DIAG_L1_HALFDUPLEX) {
				uint8_t c;

				c = *dp - 1; /* set it with wrong val. */
				if (diag_l0_recv(dl0d, NULL, &c, 1, 200) != 1) {
					rv=DIAG_ERR_GENERAL;
					break;
				}

				if (c != *dp) {
					if (c == *dp - 1) {
						fprintf(stderr,"Half duplex interface not echoing!\n");
					} else {
						fprintf(stderr,
							"Bus Error: got 0x%X "
							"expected 0x%X\n",
							c, *dp);
					}
					rv = DIAG_ERR_BUSERROR;
					break;
				}
			}
			dp++;

			if (p4) { /* Inter byte gap */
				diag_os_millisleep(p4);
			}
		}
	}

	return rv? diag_iseterr(rv):0;
}