Beispiel #1
0
int send_cmd_hdd_file_send_with_offset(libusb_device_handle* fd, __u8 dir, char *path, __u64 offset)
{
    struct tf_packet req;
    __u16 packetSize, pad;
    int pathLen = strlen(path) + 1;
	trace(3, printf("send_cmd_hdd_file_send_with_offset:  %s  [%ld]\n",path,offset));
    if((PACKET_HEAD_SIZE + 1 + 2 + pathLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stdout, "ERROR: Path is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 1 + 2 + pathLen   +8;
	pad =  ((packetSize + 1) & ~1 ) - packetSize;
	//printf("Packet padding: %d\n",pad);
	pad =  0;//((packetSize + 1) & ~1 ) - packetSize;
	//printf("Packet padding: %d\n",pad);



    packetSize +=pad;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_FILE_SEND);
    req.data[0] = dir;
    put_u16(&req.data[1], (__u16) pathLen);
    strcpy((char *) &req.data[3], path);
	put_u64( &req.data[3+pathLen+pad],offset);
    return send_tf_packet(fd, &req);
}
Beispiel #2
0
static byte *
mrt_put_bgp4_hdr(byte *buf, struct bgp_conn *conn, int as4)
{
  struct bgp_proto *p = conn->bgp;

  if (as4)
    {
      put_u32(buf+0, p->remote_as);
      put_u32(buf+4, p->local_as);
      buf+=8;
    }
  else
    {
      put_u16(buf+0, (p->remote_as <= 0xFFFF) ? p->remote_as : AS_TRANS);
      put_u16(buf+2, (p->local_as <= 0xFFFF)  ? p->local_as  : AS_TRANS);
      buf+=4;
    }

  put_u16(buf+0, (p->neigh && p->neigh->iface) ? p->neigh->iface->index : 0);
  put_u16(buf+2, BGP_AF);
  buf+=4;
  buf = put_ipa(buf, conn->sk ? conn->sk->daddr : IPA_NONE);
  buf = put_ipa(buf, conn->sk ? conn->sk->saddr : IPA_NONE);

  return buf;
}
Beispiel #3
0
int send_cmd_hdd_rename(libusb_device_handle* fd, char *src, char *dst)
{
    struct tf_packet req;
    __u16 packetSize;
    __u16 srcLen = strlen(src) + 1;
    __u16 dstLen = strlen(dst) + 1;

	trace(3, printf("send_cmd_hdd_rename: %s : %s\n",src,dst));
    if((PACKET_HEAD_SIZE + 2 + srcLen + 2 + dstLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stdout,
                "ERROR: Combination of source and destination paths is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 2 + srcLen + 2 + dstLen;
    packetSize = (packetSize + 1) & ~1;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_RENAME);
    put_u16(&req.data[0], srcLen);
    strcpy((char *) &req.data[2], src);
    put_u16(&req.data[2 + srcLen], dstLen);
    strcpy((char *) &req.data[2 + srcLen + 2], dst);
    return send_tf_packet(fd, &req);
}
Beispiel #4
0
static void
isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *mlp)
{
	isdn_net_dev *idev;
	struct sk_buff *skb;
	unsigned char *p;

	if (list_empty(&mlp->online)) {
		isdn_BUG();
		return;
	}
	idev = list_entry(mlp->online.next, isdn_net_dev, online);

	skb = isdn_net_ciscohdlck_alloc_skb(idev, 4 + 14);
	if (!skb)
		return;

	p = skb_put(skb, 4 + 14);

	/* cisco header */
	p += put_u8 (p, CISCO_ADDR_UNICAST);
	p += put_u8 (p, CISCO_CTRL);
	p += put_u16(p, CISCO_TYPE_SLARP);

	/* slarp request */
	p += put_u32(p, CISCO_SLARP_REQUEST);
	p += put_u32(p, 0); // address
	p += put_u32(p, 0); // netmask
	p += put_u16(p, 0); // unused

	isdn_net_write_super(idev, skb);
}
Beispiel #5
0
Sophon_Result
sophon_insfile_store (Sophon_VM *vm, Sophon_Module *mod,
			Sophon_IOFunc func, Sophon_Ptr data)
{
	Sophon_U16 i;

	SOPHON_ASSERT(vm && mod && func);

	put_u32(func, data, SOPHON_INSFILE_MAGIC);
	put_u32(func, data, SOPHON_INSFILE_VERSION);

	if (mod->name)
		put_str(vm, func, data, mod->name);
	else
		put_u32(func, data, 0);

	put_u16(func, data, mod->const_count);
	for (i = 0; i < mod->const_count; i++) {
		put_value(vm, func, data, mod->consts[i]);
	}

	put_u16(func, data, mod->func_count);
	for (i = 0; i < mod->func_count; i++) {
		put_func(vm, func, data, mod->funcs[i]);
	}


	return SOPHON_OK;
}
Beispiel #6
0
int
as_path_convert_to_old(struct adata *path, byte *dst, int *new_used)
{
  byte *src = path->data;
  byte *src_end = src + path->length;
  byte *dst_start = dst;
  u32 as;
  int i, n;
  *new_used = 0;

  while (src < src_end)
    {
      n = src[1];
      *dst++ = *src++;
      *dst++ = *src++;

      for(i=0; i<n; i++)
	{
	  as = get_u32(src);
	  if (as > 0xFFFF) 
	    {
	      as = AS_TRANS;
	      *new_used = 1;
	    }
	  put_u16(dst, as);
	  src += 4;
	  dst += 2;
	}
    }

  return dst - dst_start;
}
Beispiel #7
0
/*
 * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
 * by (bits+7)/8 bytes of binary data, msb first.
 */
int
buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
{
	int bits = BN_num_bits(value);
	int bin_size = (bits + 7) / 8;
	u_char *buf = xmalloc(bin_size);
	int oi;
	char msg[2];

	/* Get the value of in binary */
	oi = BN_bn2bin(value, buf);
	if (oi != bin_size) {
		error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
		    oi, bin_size);
		free(buf);
		return (-1);
	}

	/* Store the number of bits in the buffer in two bytes, msb first. */
	put_u16(msg, bits);
	buffer_append(buffer, msg, 2);
	/* Store the binary data. */
	buffer_append(buffer, buf, oi);

	memset(buf, 0, bin_size);
	free(buf);

	return (0);
}
Beispiel #8
0
Datei: mjd.c Projekt: nben/puppy
/* Convert time_t to Topfield MJD date and time structure */
void time_to_tfdt(const time_t t, struct tf_datetime *dt)
{
    int y, m, d, k, mjd;
    struct tm *tm = localtime(&t);

    y = tm->tm_year;
    m = tm->tm_mon + 1;
    d = tm->tm_mday;

    if((m == 1) || (m == 2))
    {
        k = 1;
    }
    else
    {
        k = 0;
    }

    mjd = 14956 + d +
        ((int) ((y - k) * 365.25)) + ((int) ((m + 1 + k * 12) * 30.6001));
    put_u16(&dt->mjd, mjd);
    dt->hour = tm->tm_hour;
    dt->minute = tm->tm_min;
    dt->second = tm->tm_sec;
}
Beispiel #9
0
int send_cmd_reset(libusb_device_handle* fd)
{
    struct tf_packet req;
    trace(3, printf("send_cmd_reset\n"));
    put_u16(&req.length, 8);
    put_u32(&req.cmd, CMD_RESET);
    return send_tf_packet(fd, &req);
}
Beispiel #10
0
int send_cmd_hdd_size(libusb_device_handle* fd)
{
    struct tf_packet req;
    trace(3, printf("send_cmd_hdd_size\n"));
    put_u16(&req.length, 8);
    put_u32(&req.cmd, CMD_HDD_SIZE);
    return send_tf_packet(fd, &req);
}
Beispiel #11
0
/*
 * Stores integers in the buffer, msb first.
 */
void
buffer_put_short(Buffer *buffer, u_short value)
{
	char buf[2];

	put_u16(buf, value);
	buffer_append(buffer, buf, 2);
}
Beispiel #12
0
/* Converts 'learn' into a "struct nx_action_learn" and appends that action to
 * 'ofpacts'. */
void
learn_to_nxast(const struct ofpact_learn *learn, struct ofpbuf *openflow)
{
    const struct ofpact_learn_spec *spec;
    struct nx_action_learn *nal;
    size_t start_ofs;

    start_ofs = openflow->size;
    nal = ofputil_put_NXAST_LEARN(openflow);
    nal->idle_timeout = htons(learn->idle_timeout);
    nal->hard_timeout = htons(learn->hard_timeout);
    nal->fin_idle_timeout = htons(learn->fin_idle_timeout);
    nal->fin_hard_timeout = htons(learn->fin_hard_timeout);
    nal->priority = htons(learn->priority);
    nal->cookie = htonll(learn->cookie);
    nal->flags = htons(learn->flags);
    nal->table_id = learn->table_id;

    for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; spec++) {
        put_u16(openflow, spec->n_bits | spec->dst_type | spec->src_type);

        if (spec->src_type == NX_LEARN_SRC_FIELD) {
            put_u32(openflow, spec->src.field->nxm_header);
            put_u16(openflow, spec->src.ofs);
        } else {
            size_t n_dst_bytes = 2 * DIV_ROUND_UP(spec->n_bits, 16);
            uint8_t *bits = ofpbuf_put_zeros(openflow, n_dst_bytes);
            bitwise_copy(&spec->src_imm, sizeof spec->src_imm, 0,
                         bits, n_dst_bytes, 0,
                         spec->n_bits);
        }

        if (spec->dst_type == NX_LEARN_DST_MATCH ||
                spec->dst_type == NX_LEARN_DST_LOAD) {
            put_u32(openflow, spec->dst.field->nxm_header);
            put_u16(openflow, spec->dst.ofs);
        }
    }

    if ((openflow->size - start_ofs) % 8) {
        ofpbuf_put_zeros(openflow, 8 - (openflow->size - start_ofs) % 8);
    }

    nal = ofpbuf_at_assert(openflow, start_ofs, sizeof *nal);
    nal->len = htons(openflow->size - start_ofs);
}
Beispiel #13
0
int send_cmd_turbo(libusb_device_handle* fd, int turbo_on)
{
    struct tf_packet req;
    trace(3, printf("send_cmd_turbo\n"));
    put_u16(&req.length, 12);
    put_u32(&req.cmd, CMD_TURBO);
    put_u32(&req.data, turbo_on);
    return send_tf_packet(fd, &req);
}
Beispiel #14
0
static void
store_var (Sophon_VM *vm, Sophon_HashEntry *ent, Sophon_Ptr ptr)
{
	StoreVarParams *p = (StoreVarParams*)ptr;
	Sophon_String *name = (Sophon_String*)ent->key;
	Sophon_U16 id = (Sophon_U16)(Sophon_UIntPtr)ent->value;

	put_str(vm, p->func, p->data, name);
	put_u16(p->func, p->data, id);
}
Beispiel #15
0
ssize_t send_cmd_hdd_size(int fd)
{
    struct tf_packet req;

    trace(2, fprintf(stderr, "%s\n", __func__));

    put_u16(&req.length, 8);
    put_u32(&req.cmd, CMD_HDD_SIZE);
    return send_tf_packet(fd, &req);
}
Beispiel #16
0
bool wav_dump( const char* filename, int bytespersample, int channels, int freq, void const* data, int bytecnt)
{
    // room for file header, fmt chunk and data chunk header
    uint8_t buf[(8+4)+(8+18) + 8];

    uint8_t* p=buf;
    p=put_4CC(p,"RIFF");
    p=put_u32(p,4 + (8+18) + (8+bytecnt));
    p=put_4CC(p,"WAVE");
    // fmt chunk
    p=put_4CC(p,"fmt ");
    p=put_u32(p,18);        // chunksize
    p=put_u16(p,0x0001);    // wFormatTag (WAVE_FORMAT_PCM)
    p=put_u16(p,channels);  // nChannels
    p=put_u32(p,freq);      // nSamplesPerSec
    p=put_u32(p,freq*channels*bytespersample);  // nAvgBytesPerSec
    p=put_u16(p,bytespersample*channels);       // nBlockAlign
    p=put_u16(p,bytespersample*8);              // wBitsPerSample
    p=put_u16(p,0);         // cbSize

    // data chunk (header only)
    p=put_4CC(p,"data");
    p=put_u32(p,bytecnt);

    FILE* fp = fopen(filename,"wb");
    if (!fp)
        return false;

    if (fwrite(buf,sizeof(buf),1,fp) != 1)
    {
        fclose(fp);
        return false;
    }

    if (fwrite(data,bytecnt,1,fp) != 1)
    {
        fclose(fp);
        return false;
    }
    fclose(fp);
    return true;
}
Beispiel #17
0
ssize_t send_cmd_turbo(int fd, int turbo_on)
{
    struct tf_packet req;

    trace(2, fprintf(stderr, "%s\n", __func__));

    put_u16(&req.length, 12);
    put_u32(&req.cmd, CMD_TURBO);
    put_u32(&req.data, turbo_on);
    return send_tf_packet(fd, &req);
}
Beispiel #18
0
/* Given a Topfield protocol packet, this function will calculate the required
 * CRC and send the packet out over a bulk pipe. */
ssize_t send_tf_packet(int fd, struct tf_packet *packet)
{
    unsigned int pl = get_u16(&packet->length);
    ssize_t byte_count = (pl + 1) & ~1;

    trace(3, fprintf(stderr, "%s\n", __func__));
    put_u16(&packet->crc, get_crc(packet));
    print_packet(packet, "OUT>");
    swap_out_packet(packet);
    return usb_bulk_write(fd, 0x01, (__u8 *) packet, byte_count,
                          TF_PROTOCOL_TIMEOUT);
}
Beispiel #19
0
int send_cmd_hdd_file_send(libusb_device_handle* fd, __u8 dir, char *path)
{
    struct tf_packet req;
    __u16 packetSize;
    int pathLen = strlen(path) + 1;
	trace(3, printf("send_cmd_hdd_file_send:  %s \n",path));
    if((PACKET_HEAD_SIZE + 1 + 2 + pathLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stdout, "ERROR: Path is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 1 + 2 + pathLen;
    packetSize = (packetSize + 1) & ~1;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_FILE_SEND);
    req.data[0] = dir;
    put_u16(&req.data[1], (__u16) pathLen);
    strcpy((char *) &req.data[3], path);
    return send_tf_packet(fd, &req);
}
Beispiel #20
0
int send_cmd_hdd_create_dir(libusb_device_handle* fd, char *path)
{
    struct tf_packet req;
    __u16 packetSize;
    __u16 pathLen = strlen(path) + 1;

	trace(3, printf("send_cmd_hdd_create_dir: %s\n",path));
    if((PACKET_HEAD_SIZE + 2 + pathLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stdout, "ERROR: Path is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 2 + pathLen;
    packetSize = (packetSize + 1) & ~1;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_CREATE_DIR);
    put_u16(&req.data[0], pathLen);
    strcpy((char *) &req.data[2], path);
    return send_tf_packet(fd, &req);
}
Beispiel #21
0
u8 *translateTree(AST *tree)
{
	FILE *fp = NULL;
	u16 i, j, k;
	u8 *bin = NULL;
	u32 binlen;

	fp = tmpfile();
	if (fp == NULL) return NULL;

	put_u32(0, fp);
	put_u32(0, fp);

	for (i = 0; i < tree->ngames; i++) {
		putFireStr(toFireStr(tree->games[i].s), fp);
		put_u16(tree->games[i].ncheats, fp);

		for (j = 0; j < tree->games[i].ncheats; j++) {
			putFireStr(toFireStr(tree->games[i].cheats[j].s), fp);
			put_u16(tree->games[i].cheats[j].ncodes, fp);

			for (k = 0; k < tree->games[i].cheats[j].ncodes; k++) {
				put_u32(tree->games[i].cheats[j].codes[2 * k], fp);
				put_u32(tree->games[i].cheats[j].codes[(2 * k) + 1], fp);
			}
		}
	}

	put_u32(BIN_MKR_EOF, fp);

	binlen = ftell(fp);
	bin = (u8*) readFromFile(fp, 0, binlen);
	if (bin == NULL) return NULL;
	fclose(fp); // Delete temporary file

	*(u32*) &bin[0] = binlen - 8;
	*(u32*) &bin[4] = get_crc32(bin + 8, binlen - 8);

	return bin;
}
Beispiel #22
0
ssize_t send_cmd_hdd_create_dir(const int fd, const char *path)
{
    struct tf_packet req;
    __u16 packetSize;
    __u16 pathLen = strlen(path) + 1;

    trace(2, fprintf(stderr, "%s\n", __func__));

    if((PACKET_HEAD_SIZE + 2 + pathLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stderr, "ERROR: Path is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 2 + pathLen;
    packetSize = (packetSize + 1) & ~1;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_CREATE_DIR);
    put_u16(&req.data[0], pathLen);
    strcpy((char *) &req.data[2], path);
    return send_tf_packet(fd, &req);
}
Beispiel #23
0
static int
isdn_ciscohdlck_header(struct sk_buff *skb, struct net_device *dev, 
		      unsigned short type,
		      void *daddr, void *saddr, unsigned plen)
{
	unsigned char *p = skb_push(skb, 4);

	p += put_u8 (p, CISCO_ADDR_UNICAST);
	p += put_u8 (p, CISCO_CTRL);
	p += put_u16(p, type);
	
	return 4;
}
Beispiel #24
0
static void
isdn_net_ciscohdlck_slarp_send_reply(isdn_net_dev *idev)
{
	isdn_net_local *mlp = idev->mlp;
	struct sk_buff *skb;
	unsigned char *p;
	struct in_device *in_dev = NULL;
	u32 addr = 0;		/* local ipv4 address */
	u32 mask = 0;		/* local netmask */

	if ((in_dev = mlp->dev.ip_ptr) != NULL) {
		/* take primary(first) address of interface */
		struct in_ifaddr *ifa = in_dev->ifa_list;
		if (ifa != NULL) {
			addr = ifa->ifa_local;
			mask = ifa->ifa_mask;
		}
	}

	skb = isdn_net_ciscohdlck_alloc_skb(idev, 4 + 14);
	if (!skb)
		return;

	p = skb_put(skb, 4 + 14);

	/* cisco header */
	p += put_u8 (p, CISCO_ADDR_UNICAST);
	p += put_u8 (p, CISCO_CTRL);
	p += put_u16(p, CISCO_TYPE_SLARP);

	/* slarp reply, send own ip/netmask; if values are nonsense remote
	 * should think we are unable to provide it with an address via SLARP */
	p += put_u32(p, CISCO_SLARP_REPLY);
	p += put_u32(p, addr);	// address
	p += put_u32(p, mask);	// netmask
	p += put_u16(p, 0);	// unused

	isdn_net_write_super(idev, skb);
}
Beispiel #25
0
ssize_t send_cmd_hdd_file_send(const int fd, __u8 dir, const char *path)
{
    struct tf_packet req;
    __u16 packetSize;
    int pathLen = strlen(path) + 1;

    trace(2, fprintf(stderr, "%s\n", __func__));

    if((PACKET_HEAD_SIZE + 1 + 2 + pathLen) >= MAXIMUM_PACKET_SIZE)
    {
        fprintf(stderr, "ERROR: Path is too long.\n");
        return -1;
    }

    packetSize = PACKET_HEAD_SIZE + 1 + 2 + pathLen;
    packetSize = (packetSize + 1) & ~1;
    put_u16(&req.length, packetSize);
    put_u32(&req.cmd, CMD_HDD_FILE_SEND);
    req.data[0] = dir;
    put_u16(&req.data[1], pathLen);
    strcpy((char *) &req.data[3], path);
    return send_tf_packet(fd, &req);
}
Beispiel #26
0
static void
put_str (Sophon_VM *vm, Sophon_IOFunc func, Sophon_Ptr data,
			Sophon_String *str)
{
	Sophon_Char *cstr;
	Sophon_U32 len;
	Sophon_U16 c;

	cstr = sophon_string_chars(vm, str);
	len  = sophon_string_length(vm, str);

	put_u32(func, data, len);
	while (len--) {
		c = *cstr++;
		put_u16(func, data, c);
	}
}
Beispiel #27
0
/* Given a Topfield protocol packet, this function will calculate the required
 * CRC and send the packet out over a bulk pipe. */
int send_tf_packet(libusb_device_handle* fd, struct tf_packet *packet)
{


    unsigned int pl = get_u16(&packet->length);


    size_t byte_count = (pl + 1) & ~1;

    put_u16(&packet->crc, get_crc(packet));
    if (verbose>2) print_packet(packet, "OUT>");
    swap_out_packet(packet);
	if (fd==0)  return -1;

    return usb_bulk_write(fd, 0x01, (__u8 *) packet, byte_count,
                          default_timeout());
	
}
Beispiel #28
0
static void
put_func (Sophon_VM *vm, Sophon_IOFunc func, Sophon_Ptr data,
			Sophon_Function *f)
{
	StoreVarParams svp;
	Sophon_U16 i;

	SOPHON_ASSERT(!(f->flags & SOPHON_FUNC_FL_NATIVE));

	if (f->name)
		put_str(vm, func, data, f->name);
	else
		put_u32(func, data, 0);

	put_u8(func, data, f->flags);
	put_u8(func, data, f->argc);
	put_u16(func, data, f->varc);
	put_u16(func, data, f->stack_size);
	put_u16(func, data, f->ibuf_size);

	SOPHON_ASSERT(f->var_hash.count == f->varc + f->argc);

	svp.func = func;
	svp.data = data;
	sophon_hash_for_each(vm, &f->var_hash, store_var, &svp);

	func(data, f->f.ibuf, f->ibuf_size);

#ifdef SOPHON_LINE_INFO
	put_u16(func, data, f->lbuf_size);
	for (i = 0; i < f->lbuf_size; i++) {
		put_u16(func, data, f->lbuf[i].line);
		put_u16(func, data, f->lbuf[i].offset);
	}
#endif
}
Beispiel #29
0
static inline void
put_time16(void *p, u16 v)
{
  put_u16(p, v * BABEL_TIME_UNITS);
}
Beispiel #30
0
static int
put_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFile *file,
	       void *data, GPContext *context)
{
	Camera *camera = data;

	/*
	 * Upload the file to the camera. Use gp_file_get_data_and_size etc.
	 */
	int result = -EPROTO;
	time_t startTime = time(NULL);
	enum {
		START,
		DATA,
		END,
		FINISHED
	} state;
	int src = -1;
	int r;
	int update = 0;
	struct stat srcStat;
	__u64 fileSize;
	__u64 byteCount = 0;
	const char *filename;
	char *path;
	struct tf_packet reply;

	if(0 != fstat(src, &srcStat))
	{
		gp_log (GP_LOG_ERROR, "topfield", "ERROR: Can not examine source file: %s\n",
			strerror(errno));
		result = errno;
		goto out;
	}

	fileSize = srcStat.st_size;
	if(fileSize == 0)
	{
		gp_log (GP_LOG_ERROR, "topfield", "ERROR: Source file is empty - not transfering.\n");
		result = -ENODATA;
		goto out;
	}

	path = get_path (camera, folder, filename);
	r = send_cmd_hdd_file_send(camera, PUT, path, context);
	if(r < 0)
		goto out;

	state = START;
	while(0 < get_tf_packet(camera, &reply, context)) {
		update = (update + 1) % 16;
		switch (get_u32(&reply.cmd)) {
		case SUCCESS:
			switch (state) {
			case START: {
				/* Send start */
				struct typefile *tf = (struct typefile *) packet.data;

				put_u16(&packet.length, PACKET_HEAD_SIZE + 114);
				put_u32(&packet.cmd, DATA_HDD_FILE_START);
				time_to_tfdt(srcStat.st_mtime, &tf->stamp);
				tf->filetype = 2;
				put_u64(&tf->size, srcStat.st_size);
				strncpy((char *) tf->name, path, 94);
				tf->name[94] = '\0';
				tf->unused = 0;
				tf->attrib = 0;
				gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_START\n", __func__);
				r = send_tf_packet(camera, &packet, context);
				if(r < 0)
				{
					gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n");
					goto out;
				}
				state = DATA;
				break;
			}

			case DATA: {
				int payloadSize = sizeof(packet.data) - 9;
				ssize_t w = read(src, &packet.data[8], payloadSize);

				/* Detect a Topfield protcol bug and prevent the sending of packets
				   that are a multiple of 512 bytes. */
				if((w > 4) && (((((PACKET_HEAD_SIZE + 8 + w) + 1) & ~1) % 0x200) == 0)) {
					lseek(src, -4, SEEK_CUR);
					w -= 4;
					payloadSize -= 4;
				}

				put_u16(&packet.length, PACKET_HEAD_SIZE + 8 + w);
				put_u32(&packet.cmd, DATA_HDD_FILE_DATA);
				put_u64(packet.data, byteCount);
				byteCount += w;

				/* Detect EOF and transition to END */
				if((w < 0) || (byteCount >= fileSize)) {
					state = END;
				}

				if(w > 0) {
					gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_DATA\n", __func__);
					r = send_tf_packet(camera, &packet, context);
					if(r < w) {
						gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n");
						goto out;
					}
				}

				if(!update && !quiet) {
					progressStats(fileSize, byteCount, startTime);
				}
				break;
			}

			case END:
				/* Send end */
				put_u16(&packet.length, PACKET_HEAD_SIZE);
				put_u32(&packet.cmd, DATA_HDD_FILE_END);
				gp_log (GP_LOG_DEBUG, "topfield", "%s: DATA_HDD_FILE_END\n", __func__);
				r = send_tf_packet(camera, &packet, context);
				if(r < 0) {
					gp_log (GP_LOG_ERROR, "topfield", "ERROR: Incomplete send.\n");
					goto out;
				}
				state = FINISHED;
				break;

			case FINISHED:
				result = 0;
				goto out;
				break;
			}
			break;

		case FAIL:
			gp_log (GP_LOG_ERROR, "topfield", "ERROR: Device reports %s\n", decode_error(&reply));
			goto out;
			break;

		default:
			gp_log (GP_LOG_ERROR, "topfield", "ERROR: Unhandled packet (%d)\n", get_u32(&reply.cmd));
			break;
		}
	}
	finalStats(byteCount, startTime);
out:
	close(src);
	return result;
}