Ejemplo n.º 1
0
/* send an ack packet back to the tty */
static int gsp_send_ack(struct garmin_data *garmin_data_p, __u8 pkt_id)
{
	__u8 pkt[10];
	__u8 cksum = 0;
	__u8 *ptr = pkt;
	unsigned  l = 0;

	dbg("%s - pkt-id: 0x%X.", __func__, 0xFF & pkt_id);

	*ptr++ = DLE;
	*ptr++ = ACK;
	cksum += ACK;

	*ptr++ = 2;
	cksum += 2;

	*ptr++ = pkt_id;
	cksum += pkt_id;

	if (pkt_id == DLE)
		*ptr++ = DLE;

	*ptr++ = 0;
	*ptr++ = 0xFF & (-cksum);
	*ptr++ = DLE;
	*ptr++ = ETX;

	l = ptr-pkt;

	send_to_tty(garmin_data_p->port, pkt, l);
	return 0;
}
Ejemplo n.º 2
0
static void garmin_read_process(struct garmin_data *garmin_data_p,
				 unsigned char *data, unsigned data_length,
				 int bulk_data)
{
	unsigned long flags;

	if (garmin_data_p->flags & FLAGS_DROP_DATA) {
		/* abort-transfer cmd is actice */
		dev_dbg(&garmin_data_p->port->dev, "%s - pkt dropped\n", __func__);
	} else if (garmin_data_p->state != STATE_DISCONNECTED &&
		garmin_data_p->state != STATE_RESET) {

		/* if throttling is active or postprecessing is required
		   put the received data in the input queue, otherwise
		   send it directly to the tty port */
		if (garmin_data_p->flags & FLAGS_QUEUING) {
			pkt_add(garmin_data_p, data, data_length);
		} else if (bulk_data ||
			   getLayerId(data) == GARMIN_LAYERID_APPL) {

			spin_lock_irqsave(&garmin_data_p->lock, flags);
			garmin_data_p->flags |= APP_RESP_SEEN;
			spin_unlock_irqrestore(&garmin_data_p->lock, flags);

			if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
				pkt_add(garmin_data_p, data, data_length);
			} else {
				send_to_tty(garmin_data_p->port, data,
						data_length);
			}
		}
		/* ignore system layer packets ... */
	}
}
Ejemplo n.º 3
0
static void priv_status_resp(struct usb_serial_port *port)
{
	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
	__le32 *pkt = (__le32 *)garmin_data_p->privpkt;

	pkt[0] = __cpu_to_le32(GARMIN_LAYERID_PRIVATE);
	pkt[1] = __cpu_to_le32(PRIV_PKTID_INFO_RESP);
	pkt[2] = __cpu_to_le32(12);
	pkt[3] = __cpu_to_le32(VERSION_MAJOR << 16 | VERSION_MINOR);
	pkt[4] = __cpu_to_le32(garmin_data_p->mode);
	pkt[5] = __cpu_to_le32(garmin_data_p->serial_num);

	send_to_tty(port, (__u8 *)pkt, 6 * 4);
}
Ejemplo n.º 4
0
/*
 * Sends the next queued packt to the tty port (garmin native mode only)
 * and then sets a timer to call itself again until all queued data
 * is sent.
 */
static int garmin_flush_queue(struct garmin_data *garmin_data_p)
{
	unsigned long flags;
	struct garmin_packet *pkt;

	if ((garmin_data_p->flags & FLAGS_THROTTLED) == 0) {
		pkt = pkt_pop(garmin_data_p);
		if (pkt != NULL) {
			send_to_tty(garmin_data_p->port, pkt->data, pkt->size);
			kfree(pkt);
			mod_timer(&garmin_data_p->timer, (1)+jiffies);

		} else {
			spin_lock_irqsave(&garmin_data_p->lock, flags);
			garmin_data_p->flags &= ~FLAGS_QUEUING;
			spin_unlock_irqrestore(&garmin_data_p->lock, flags);
		}
	}
	return 0;
}
Ejemplo n.º 5
0
/*
 * Sends a usb packet to the tty
 *
 * Assumes, that all packages and at an usb-packet boundary.
 *
 * return <0 on error, 0 if packet is incomplete or > 0 if packet was sent
 */
static int gsp_send(struct garmin_data *garmin_data_p,
		    const unsigned char *buf, int count)
{
	struct device *dev = &garmin_data_p->port->dev;
	const unsigned char *src;
	unsigned char *dst;
	int pktid = 0;
	int datalen = 0;
	int cksum = 0;
	int i = 0;
	int k;

	dev_dbg(dev, "%s - state %d - %d bytes.\n", __func__,
		garmin_data_p->state, count);

	k = garmin_data_p->outsize;
	if ((k+count) > GPS_OUT_BUFSIZ) {
		dev_dbg(dev, "packet too large\n");
		garmin_data_p->outsize = 0;
		return -4;
	}

	memcpy(garmin_data_p->outbuffer+k, buf, count);
	k += count;
	garmin_data_p->outsize = k;

	if (k >= GARMIN_PKTHDR_LENGTH) {
		pktid  = getPacketId(garmin_data_p->outbuffer);
		datalen = getDataLength(garmin_data_p->outbuffer);
		i = GARMIN_PKTHDR_LENGTH + datalen;
		if (k < i)
			return 0;
	} else {
		return 0;
	}

	dev_dbg(dev, "%s - %d bytes in buffer, %d bytes in pkt.\n", __func__, k, i);

	/* garmin_data_p->outbuffer now contains a complete packet */

	usb_serial_debug_data(&garmin_data_p->port->dev, __func__, k,
			      garmin_data_p->outbuffer);

	garmin_data_p->outsize = 0;

	if (GARMIN_LAYERID_APPL != getLayerId(garmin_data_p->outbuffer)) {
		dev_dbg(dev, "not an application packet (%d)\n",
				getLayerId(garmin_data_p->outbuffer));
		return -1;
	}

	if (pktid > 255) {
		dev_dbg(dev, "packet-id %d too large\n", pktid);
		return -2;
	}

	if (datalen > 255) {
		dev_dbg(dev, "packet-size %d too large\n", datalen);
		return -3;
	}

	/* the serial protocol should be able to handle this packet */

	k = 0;
	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
	for (i = 0; i < datalen; i++) {
		if (*src++ == DLE)
			k++;
	}

	src = garmin_data_p->outbuffer+GARMIN_PKTHDR_LENGTH;
	if (k > (GARMIN_PKTHDR_LENGTH-2)) {
		/* can't add stuffing DLEs in place, move data to end
		   of buffer ... */
		dst = garmin_data_p->outbuffer+GPS_OUT_BUFSIZ-datalen;
		memcpy(dst, src, datalen);
		src = dst;
	}

	dst = garmin_data_p->outbuffer;

	*dst++ = DLE;
	*dst++ = pktid;
	cksum += pktid;
	*dst++ = datalen;
	cksum += datalen;
	if (datalen == DLE)
		*dst++ = DLE;

	for (i = 0; i < datalen; i++) {
		__u8 c = *src++;
		*dst++ = c;
		cksum += c;
		if (c == DLE)
			*dst++ = DLE;
	}

	cksum = 0xFF & -cksum;
	*dst++ = cksum;
	if (cksum == DLE)
		*dst++ = DLE;
	*dst++ = DLE;
	*dst++ = ETX;

	i = dst-garmin_data_p->outbuffer;

	send_to_tty(garmin_data_p->port, garmin_data_p->outbuffer, i);

	garmin_data_p->pkt_id = pktid;
	garmin_data_p->state  = STATE_WAIT_TTY_ACK;

	return i;
}