コード例 #1
0
ファイル: camera_control.c プロジェクト: tok101/tok101
static int try_get_camera_file(GPParams* gp_params, const char* folder, const char* filename)
{
	int ret = 0;
    CameraFile *file = NULL;
	if ( (ret = gp_file_new (&file)) < 0) {
		LOG_E("gp_file_new failed %d\n", ret);
		return -1;
	}
    if ( (ret = gp_camera_file_get (gp_params->camera, folder, filename, GP_FILE_TYPE_NORMAL,
			  file, gp_params->context)) < 0) {
		LOG_I("gp_camera_file_get: %s\n", gp_port_result_as_string(ret));
	}
	gp_file_unref (file);
	return ret;
}
コード例 #2
0
ファイル: gphoto2-port.c プロジェクト: axxel/libgphoto2
/**
 * \brief Read data from port
 *
 * \param port a #GPPort
 * \param data a pointer to an allocated buffer
 * \param size the number of bytes that should be read
 *
 * Reads a specified number of bytes from the port into the supplied buffer.
 * It returns the number of bytes read or a negative error code.
 *
 * \return a gphoto2 error code or the amount of data read
 **/
int
gp_port_read (GPPort *port, char *data, int size)
{
        int retval;

	gp_log (GP_LOG_DATA, __func__, "Reading %i = 0x%x bytes from port...", size, size);

	C_PARAMS (port);
	CHECK_INIT (port);

	/* Check if we read as many bytes as expected */
	CHECK_SUPP (port, "read", port->pc->ops->read);
	retval = port->pc->ops->read (port, data, size);
	if (retval < 0) {
		GP_LOG_E ("Reading %i = 0x%x bytes from port failed: %s (%d)",
			  size, size, gp_port_result_as_string(retval), retval);
		return retval;
	}
	LOG_DATA (data, retval, size, "Read   ", "from port:");

	return (retval);
}
コード例 #3
0
ファイル: gphoto2-port.c プロジェクト: axxel/libgphoto2
/**
 * \brief Writes a specified amount of data to a port.

 * \param port a #GPPort
 * \param data the data to write to the port
 * \param size the number of bytes to write to the port
 *
 * Writes data to the port. On non-serial ports the amount of data
 * written is returned (and not just GP_OK).
 *
 * \return a negative gphoto2 error code or the amount of data written.
 **/
int
gp_port_write (GPPort *port, const char *data, int size)
{
	int retval;

        gp_log (GP_LOG_DATA, __func__, "Writing %i = 0x%x bytes to port...", size, size);

 	C_PARAMS (port && data);
	CHECK_INIT (port);

	/* Check if we wrote all bytes */
	CHECK_SUPP (port, "write", port->pc->ops->write);
	retval = port->pc->ops->write (port, data, size);
	if (retval < 0) {
		GP_LOG_E ("Writing %i = 0x%x bytes to port failed: %s (%d)",
			  size, size, gp_port_result_as_string(retval), retval);
		return retval;
	}
	LOG_DATA (data, retval, size, "Wrote  ", "to port:");

	return (retval);
}
コード例 #4
0
ファイル: usb.c プロジェクト: msmeissn/libgphoto2
uint16_t
ptp_usb_sendreq (PTPParams* params, PTPContainer* req)
{
	int res, towrite, do_retry = TRUE;
	PTPUSBBulkContainer usbreq;
	Camera *camera = ((PTPData *)params->data)->camera;

	GP_LOG_D ("Sending PTP_OC 0x%0x (%s) request...", req->Code, ptp_get_opcode_name(params, req->Code));

	/* build appropriate USB container */
	usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-
		(sizeof(uint32_t)*(5-req->Nparam)));
	usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);
	usbreq.code=htod16(req->Code);
	usbreq.trans_id=htod32(req->Transaction_ID);
	usbreq.payload.params.param1=htod32(req->Param1);
	usbreq.payload.params.param2=htod32(req->Param2);
	usbreq.payload.params.param3=htod32(req->Param3);
	usbreq.payload.params.param4=htod32(req->Param4);
	usbreq.payload.params.param5=htod32(req->Param5);
	/* send it to responder */
	towrite = PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam));
retry:
	res = gp_port_write (camera->port, (char*)&usbreq, towrite);
	if (res != towrite) {
		if (res < 0) {
			GP_LOG_E ("PTP_OC 0x%04x sending req failed: %s (%d)", req->Code, gp_port_result_as_string(res), res);
			if (res == GP_ERROR_IO_WRITE && do_retry) {
				GP_LOG_D ("Clearing halt on OUT EP and retrying once.");
				gp_port_usb_clear_halt (camera->port, GP_PORT_USB_ENDPOINT_OUT);
				do_retry = FALSE;
				goto retry;
			}
		} else
			GP_LOG_E ("PTP_OC 0x%04x sending req failed: wrote only %d of %d bytes", req->Code, res, towrite);
		return PTP_ERROR_IO;
	}
	return PTP_RC_OK;
}
コード例 #5
0
static int
foreach_func (const char *filename, lt_ptr data)
{
	GPPortInfoList *list = data;
	lt_dlhandle lh;
	GPPortLibraryType lib_type;
	GPPortLibraryList lib_list;
	GPPortType type;
	unsigned int j, old_size = list->count;
	int result;

	gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
		_("Called for filename '%s'."), filename );

	lh = lt_dlopenext (filename);
	if (!lh) {
		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("Could not load '%s': '%s'."), filename, lt_dlerror ());
		return (0);
	}

	lib_type = lt_dlsym (lh, "gp_port_library_type");
	lib_list = lt_dlsym (lh, "gp_port_library_list");
	if (!lib_type || !lib_list) {
		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("Could not find some functions in '%s': '%s'."),
			filename, lt_dlerror ());
		lt_dlclose (lh);
		return (0);
	}

	type = lib_type ();
	for (j = 0; j < list->count; j++)
		if (list->info[j].type == type)
			break;
	if (j != list->count) {
		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("'%s' already loaded"), filename);
		lt_dlclose (lh);
		return (0);
	}

	result = lib_list (list);
	lt_dlclose (lh);
	if (result < 0) {
		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("Could not load port driver list: '%s'."),
			gp_port_result_as_string (result));
		return (0);
	}

	for (j = old_size; j < list->count; j++){
		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("Loaded '%s' ('%s') from '%s'."),
			list->info[j].name, list->info[j].path,
			filename);
		strcpy (list->info[j].library_filename, filename);
	}

	return (0);
}
コード例 #6
0
ファイル: usb.c プロジェクト: msmeissn/libgphoto2
static inline uint16_t
ptp_usb_event (PTPParams* params, PTPContainer* event, int wait)
{
	int			result, timeout, fasttimeout;
	unsigned long		rlen;
	PTPUSBEventContainer	usbevent;
	Camera			*camera = ((PTPData *)params->data)->camera;

	if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON)
		fasttimeout = PTP2_FAST_TIMEOUT*2;
	else
		fasttimeout = PTP2_FAST_TIMEOUT;

	PTP_CNT_INIT(usbevent);

	if (event==NULL)
		return PTP_ERROR_BADPARAM;

	switch(wait) {
	case PTP_EVENT_CHECK:
		result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
		if (result <= 0) result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
		break;
	case PTP_EVENT_CHECK_FAST:
		gp_port_get_timeout (camera->port, &timeout);
		gp_port_set_timeout (camera->port, fasttimeout);
		result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
		if (result <= 0) result = gp_port_check_int (camera->port, (char*)&usbevent, sizeof(usbevent));
		gp_port_set_timeout (camera->port, timeout);
		break;
	default:
		return PTP_ERROR_BADPARAM;
	}
	if (result < 0) {
		GP_LOG_E ("Reading PTP event failed: %s (%d)", gp_port_result_as_string(result), result);
		if (result == GP_ERROR_TIMEOUT)
			return PTP_ERROR_TIMEOUT;
		return PTP_ERROR_IO;
	}
	if (result == 0) {
		GP_LOG_E ("Reading PTP event failed: a 0 read occurred, assuming timeout.");
		return PTP_ERROR_TIMEOUT;
	}
	rlen = result;
	if (rlen < 8) {
		GP_LOG_E ("Reading PTP event failed: only %ld bytes read", rlen);
		return PTP_ERROR_IO;
	}

	/* Only do the additional reads for "events". Canon IXUS 2 likes to
	 * send unrelated data.
	 */
	if (	(dtoh16(usbevent.type) == PTP_USB_CONTAINER_EVENT) &&
		(dtoh32(usbevent.length) > rlen)
	) {
		GP_LOG_D ("Canon incremental read (done: %ld, todo: %d)", rlen, dtoh32(usbevent.length));
		gp_port_get_timeout (camera->port, &timeout);
		gp_port_set_timeout (camera->port, PTP2_FAST_TIMEOUT);
		while (dtoh32(usbevent.length) > rlen) {
			result = gp_port_check_int (camera->port, ((char*)&usbevent)+rlen, sizeof(usbevent)-rlen);
			if (result <= 0)
				break;
			rlen += result;
		}
		gp_port_set_timeout (camera->port, timeout);
	}
	/* if we read anything over interrupt endpoint it must be an event */
	/* build an appropriate PTPContainer */
	event->Nparam  = (rlen-12)/4;
	event->Code   = dtoh16(usbevent.code);
	event->SessionID=params->session_id;
	event->Transaction_ID=dtoh32(usbevent.trans_id);
	event->Param1 = dtoh32(usbevent.param1);
	event->Param2 = dtoh32(usbevent.param2);
	event->Param3 = dtoh32(usbevent.param3);
	return PTP_RC_OK;
}
コード例 #7
0
ファイル: usb.c プロジェクト: msmeissn/libgphoto2
uint16_t
ptp_usb_senddata (PTPParams* params, PTPContainer* ptp,
		  uint64_t size, PTPDataHandler *handler
) {
	uint16_t ret = PTP_RC_OK;
	int res, wlen, datawlen;
	PTPUSBBulkContainer usbdata;
	unsigned long bytes_left_to_transfer, written;
	Camera *camera = ((PTPData *)params->data)->camera;
	unsigned char *bytes;
	int progressid = 0;
	int usecontext = (size > CONTEXT_BLOCK_SIZE);
	GPContext *context = ((PTPData *)params->data)->context;

	GP_LOG_D ("Sending PTP_OC 0x%0x (%s) data...", ptp->Code, ptp_get_opcode_name(params, ptp->Code));
	/* build appropriate USB container */
	usbdata.length	= htod32(PTP_USB_BULK_HDR_LEN+size);
	usbdata.type	= htod16(PTP_USB_CONTAINER_DATA);
	usbdata.code	= htod16(ptp->Code);
	usbdata.trans_id= htod32(ptp->Transaction_ID);

	if (params->split_header_data) {
		datawlen = 0;
		wlen = PTP_USB_BULK_HDR_LEN;
	} else {
		unsigned long gotlen;
		/* For all camera devices. */
		datawlen = (size<PTP_USB_BULK_PAYLOAD_LEN_WRITE)?size:PTP_USB_BULK_PAYLOAD_LEN_WRITE;
		wlen = PTP_USB_BULK_HDR_LEN + datawlen;
		ret = handler->getfunc(params, handler->priv, datawlen, usbdata.payload.data, &gotlen);
		if (ret != PTP_RC_OK)
			return ret;
		if (gotlen != datawlen)
			return PTP_RC_GeneralError;
	}
	res = gp_port_write (camera->port, (char*)&usbdata, wlen);
	if (res != wlen) {
		if (res < 0)
			GP_LOG_E ("PTP_OC 0x%04x sending data failed: %s (%d)", ptp->Code, gp_port_result_as_string(res), res);
		else
			GP_LOG_E ("PTP_OC 0x%04x sending data failed: wrote only %d of %d bytes", ptp->Code, res, wlen);
		return PTP_ERROR_IO;
	}
	if (size <= datawlen) { /* nothing more to do */
		written = wlen;
		goto finalize;
	}
	if (usecontext)
		progressid = gp_context_progress_start (context, (size/CONTEXT_BLOCK_SIZE), _("Uploading..."));
	bytes = malloc (4096);
	if (!bytes)
		return PTP_RC_GeneralError;
	/* if everything OK send the rest */
	bytes_left_to_transfer = size-datawlen;
	ret = PTP_RC_OK;
	written = 0;
	while(bytes_left_to_transfer > 0) {
		unsigned long readlen, toread, oldwritten = written;

		toread = 4096;
		if (toread > bytes_left_to_transfer)
			toread = bytes_left_to_transfer;
		ret = handler->getfunc (params, handler->priv, toread, bytes, &readlen);
		if (ret != PTP_RC_OK)
			break;
		res = gp_port_write (camera->port, (char*)bytes, readlen);
		if (res < 0) {
			ret = PTP_ERROR_IO;
			break;
		}
		bytes_left_to_transfer -= res;
		written += res;
		if (usecontext && (oldwritten/CONTEXT_BLOCK_SIZE < written/CONTEXT_BLOCK_SIZE))
			gp_context_progress_update (context, progressid, written/CONTEXT_BLOCK_SIZE);
#if 0 /* Does not work this way... Hmm. */
		if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) {
			ret = ptp_usb_control_cancel_request (params,ptp->Transaction_ID);
			if (ret == PTP_RC_OK)
				ret = PTP_ERROR_CANCEL;
			break;
		}
#endif
	}
	if (usecontext)
		gp_context_progress_stop (context, progressid);
	free (bytes);
finalize:
	if ((ret == PTP_RC_OK) && ((written % params->maxpacketsize) == 0))
		gp_port_write (camera->port, "x", 0);
	if ((ret!=PTP_RC_OK) && (ret!=PTP_ERROR_CANCEL))
		ret = PTP_ERROR_IO;
	return ret;
}