<commit_before>/* pdc700.c
 *
 * Copyright (C) 2001 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * 2001/08/31 <NAME> <<EMAIL>>
 *
 * I cannot test this stuff - I simply don't have this camera. If you have
 * one, please contact me so that we can get this stuff up and running.
 */

#include <config.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <gphoto2-library.h>
#include <gphoto2-port-log.h>

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

#define GP_MODULE "pdc700"

#define PDC700_INIT	0x01
#define PDC700_INFO	0x02

#define PDC700_BAUD	0x04
#define PDC700_PICINFO	0x05
#define PDC700_THUMB	0x06
#define PDC700_PIC	0x07


#define PDC700_FIRST	0x00
#define PDC700_DONE	0x01
#define PDC700_LAST	0x02

typedef struct _PDCDate PDCDate;
struct _PDCDate {
	unsigned char year, month, day;
	unsigned char hour, minute, second;
};

typedef struct _PDCInfo PDCInfo;
struct _PDCInfo {
	unsigned int num_taken, num_free;
	char version[6];
	PDCDate date;
};

typedef struct _PDCPicInfo PDCPicInfo;
struct _PDCPicInfo {
	char version[6];
	unsigned int pic_size, thumb_size;
	unsigned char flash;
};

#define CHECK_RESULT(result) {int r = (result); if (r < 0) return (r);}

/*
 * Every command sent to the camera begins with 0x40 followed by two bytes
 * indicating the number of following bytes. Then follows the byte that
 * indicates the command (see above defines), perhaps some parameters. The
 * last byte is the checksum, the sum of all bytes between length bytes
 * (3rd one) and the last one (checksum).
 */
static int
calc_checksum (unsigned char *cmd, int len)
{
	int i;
	unsigned char checksum;

	for (checksum = 0, i = 0; i < len; i++)
		checksum += cmd[i];

	return (checksum);
}

static int
pdc700_send (Camera *camera, unsigned char *cmd, int cmd_len)
{
	/* Finish the command and send it */
	cmd[0] = 0x40;
	cmd[1] = (cmd_len - 3) >> 8;
	cmd[2] = (cmd_len - 3) & 0xff;
	cmd[cmd_len - 1] = calc_checksum (cmd + 3, cmd_len - 1 - 3);
	CHECK_RESULT (gp_port_write (camera->port, cmd, cmd_len));

	return (GP_OK);
}

static int
pdc700_read (Camera *camera, unsigned char *cmd,
	     unsigned char *b, int *b_len,
	     char *status, char *sequence_number)
{
	unsigned char header[3], checksum;
	unsigned int i;

	/*
	 * Read the header (0x40 plus 2 bytes indicating how many bytes
	 * will follow)
	 */
	CHECK_RESULT (gp_port_read (camera->port, header, 3));
	if (header[0] != 0x40)
		return (GP_ERROR_CORRUPTED_DATA);
	*b_len = (header[2] << 8) | header [1];

	/* Read the remaining bytes */
	CHECK_RESULT (gp_port_read (camera->port, b, *b_len));

	/*
	 * The first byte indicates if this the response for our command.
	 */
	if (b[0] != (0x80 | cmd[3])) {
		gp_camera_set_error (camera, _("Received unexpected response"));
		return (GP_ERROR_CORRUPTED_DATA);
	}

	/* Will other packets follow? */
	*status = b[1];

	/* Then follows the sequence number (number of next packet if any)
	 * only in case of picture transmission */
	if (sequence_number)
		*sequence_number = b[2];

	/* Check the checksum */
	for (checksum = i = 0; i < *b_len - 1; i++)
		checksum += b[i];
	if (checksum != b[*b_len - 1]) {
		gp_camera_set_error (camera, _("Checksum error"));
		return (GP_ERROR_CORRUPTED_DATA);
	}

	/* Preserve only the actual data */
	*b_len -= (sequence_number ? 4 : 3);
	memmove (b, b + (sequence_number ? 3 : 2), *b_len);

	return (GP_OK);
}

static int
pdc700_transmit (Camera *camera, unsigned char *cmd, int cmd_len,
		 unsigned char *buf, unsigned int *buf_len)
{
	unsigned char status, b[2048], sequence_number;
	unsigned int b_len;
	unsigned int target = *buf_len;

	CHECK_RESULT (pdc700_send (camera, cmd, cmd_len));
	CHECK_RESULT (pdc700_read (camera, cmd, b, &b_len, &status,
			(cmd[4] == PDC700_FIRST) ? &sequence_number : NULL));

	/* Copy over the data */
	*buf_len = b_len;
	memcpy (buf, b, b_len);

	if (status != PDC700_DONE) {
		while (status != PDC700_LAST) {
			cmd[4] = PDC700_DONE;
			cmd[5] = sequence_number;
			GP_DEBUG ("Fetching sequence %i...", sequence_number);
			CHECK_RESULT (pdc700_send (camera, cmd, 7));
			CHECK_RESULT (pdc700_read (camera, cmd, b, &b_len,
						&status, &sequence_number));

			/*
			 * Sanity check: We should never read more bytes than
			 * targeted
			 */
			if (*buf_len + b_len > target) {
				gp_camera_set_error (camera, _("The camera "
					"sent more bytes than expected (%i)"),
					target);
				return (GP_ERROR_CORRUPTED_DATA);
			}

			/* Copy over the data */
			memcpy (buf + *buf_len, b, b_len);
			*buf_len += b_len;
			gp_camera_progress (camera,
					    (float) *buf_len / (float) target);
		}

		/* Acknowledge last packet */<commit_msg>And again a bug less...<commit_after>/* pdc700.c
 *
 * Copyright (C) 2001 <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * 2001/08/31 <NAME> <<EMAIL>>
 *
 * I cannot test this stuff - I simply don't have this camera. If you have
 * one, please contact me so that we can get this stuff up and running.
 */

#include <config.h>

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <gphoto2-library.h>
#include <gphoto2-port-log.h>

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

#define GP_MODULE "pdc700"

#define PDC700_INIT	0x01
#define PDC700_INFO	0x02

#define PDC700_BAUD	0x04
#define PDC700_PICINFO	0x05
#define PDC700_THUMB	0x06
#define PDC700_PIC	0x07


#define PDC700_FIRST	0x00
#define PDC700_DONE	0x01
#define PDC700_LAST	0x02

typedef struct _PDCDate PDCDate;
struct _PDCDate {
	unsigned char year, month, day;
	unsigned char hour, minute, second;
};

typedef struct _PDCInfo PDCInfo;
struct _PDCInfo {
	unsigned int num_taken, num_free;
	char version[6];
	PDCDate date;
};

typedef struct _PDCPicInfo PDCPicInfo;
struct _PDCPicInfo {
	char version[6];
	unsigned int pic_size, thumb_size;
	unsigned char flash;
};

#define CHECK_RESULT(result) {int r = (result); if (r < 0) return (r);}

/*
 * Every command sent to the camera begins with 0x40 followed by two bytes
 * indicating the number of following bytes. Then follows the byte that
 * indicates the command (see above defines), perhaps some parameters. The
 * last byte is the checksum, the sum of all bytes between length bytes
 * (3rd one) and the last one (checksum).
 */
static int
calc_checksum (unsigned char *cmd, int len)
{
	int i;
	unsigned char checksum;

	for (checksum = 0, i = 0; i < len; i++)
		checksum += cmd[i];

	return (checksum);
}

static int
pdc700_send (Camera *camera, unsigned char *cmd, int cmd_len)
{
	/* Finish the command and send it */
	cmd[0] = 0x40;
	cmd[1] = (cmd_len - 3) >> 8;
	cmd[2] = (cmd_len - 3) & 0xff;
	cmd[cmd_len - 1] = calc_checksum (cmd + 3, cmd_len - 1 - 3);
	CHECK_RESULT (gp_port_write (camera->port, cmd, cmd_len));

	return (GP_OK);
}

static int
pdc700_read (Camera *camera, unsigned char *cmd,
	     unsigned char *b, int *b_len,
	     char *status, char *sequence_number)
{
	unsigned char header[3], checksum;
	unsigned int i;

	/*
	 * Read the header (0x40 plus 2 bytes indicating how many bytes
	 * will follow)
	 */
	CHECK_RESULT (gp_port_read (camera->port, header, 3));
	if (header[0] != 0x40)
		return (GP_ERROR_CORRUPTED_DATA);
	*b_len = (header[2] << 8) | header [1];

	/* Read the remaining bytes */
	CHECK_RESULT (gp_port_read (camera->port, b, *b_len));

	/*
	 * The first byte indicates if this the response for our command.
	 */
	if (b[0] != (0x80 | cmd[3])) {
		gp_camera_set_error (camera, _("Received unexpected response"));
		return (GP_ERROR_CORRUPTED_DATA);
	}

	/* Will other packets follow? */
	*status = b[1];

	/* Then follows the sequence number (number of next packet if any)
	 * only in case of picture transmission */
	if (sequence_number)
		*sequence_number = b[2];

	/* Check the checksum */
	for (checksum = i = 0; i < *b_len - 1; i++)
		checksum += b[i];
	if (checksum != b[*b_len - 1]) {
		gp_camera_set_error (camera, _("Checksum error"));
		return (GP_ERROR_CORRUPTED_DATA);
	}

	/* Preserve only the actual data */
	*b_len -= (sequence_number ? 4 : 3);
	memmove (b, b + (sequence_number ? 3 : 2), *b_len);

	return (GP_OK);
}

static int
pdc700_transmit (Camera *camera, unsigned char *cmd, int cmd_len,
		 unsigned char *buf, unsigned int *buf_len)
{
	unsigned char status, b[2048], sequence_number;
	unsigned int b_len;
	unsigned int target = *buf_len;

	CHECK_RESULT (pdc700_send (camera, cmd, cmd_len));
	CHECK_RESULT (pdc700_read (camera, cmd, b, &b_len, &status,
			(cmd[4] == PDC700_FIRST) ? &sequence_number : NULL));

	/* Copy over the data */
	*buf_len = b_len;
	memcpy (buf, b, b_len);

	/* Check if other packets are to follow */
	if (cmd[4] == PDC700_FIRST) {

		/* Get those other packets */
		while (status != PDC700_LAST) {
			cmd[4] = PDC700_DONE;
			cmd[5] = sequence_number;
			GP_DEBUG ("Fetching sequence %i...", sequence_number);
			CHECK_RESULT (pdc700_send (camera, cmd, 7));
			CHECK_RESULT (pdc700_read (camera, cmd, b, &b_len,
						&status, &sequence_number));

			/*
			 * Sanity check: We should never read more bytes than
			 * targeted
			 */
			if (*buf_len + b_len > target) {
				gp_camera_set_error (camera, _("The camera "
					"sent more bytes than expected (%i)"),
					target);
				return (GP_ERROR_CORRUPTED_DATA);
			}

			/* Copy over the data */
			memcpy (buf + *buf_len, b, b_len);
			*buf_len += b_len;
			gp_camera_progress (camera,
					    (float) *buf_len / (float) target);
		}

		/* Acknowledge last packet */
{'fraction_non_alphanumeric': 0.11805318786225708, 'fraction_numerical': 0.03077054210705762, 'mean_word_length': 3.8583850931677017, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4520759', 'n_tokens_mistral': 4536, 'n_tokens_neox': 4062, 'n_words': 1405}