/* * Waits for the camera * type: 0: Wait until the camera gets ready * 1: Read data from irq * The function stores the readen 8 Bytes in data. * and return 0 on success else -1. */ static int mdc800_usb_readFromIrq (GPPort *port,int type,unsigned char* data,int timeout) { int ret; struct timeval tv; gp_port_set_timeout(port,1); timeout+=10*MDC800_USB_IRQ_INTERVAL; gettimeofday(&tv,NULL); while (timeout>=0) { /* try a read */ ret = gp_port_check_int(port,(char*)data,8); if (ret!=8) { printCError ("(mdc800_usb_readFromIRQ) reading bytes from irq fails (%d)\n",ret); return ret; } if (0) { int i=0; printf ("irq :"); for (i=0; i<8; i++) { printf ("%i ", data [i]); } printf ("\n"); } /* check data */ if (type) { if (!(mdc800_usb_isReady(data)||mdc800_usb_isBusy(data))) { fprintf(stderr,"got data.\n"); /* Data received successfull */ return GP_OK; } } else { if (mdc800_usb_isReady (data)) { fprintf(stderr,"got readiness.\n"); /* Camera response ready */ return GP_OK; } } /* wait the specified time */ if (1) { usleep(MDC800_USB_IRQ_INTERVAL * 1000); timeout-=MDC800_USB_IRQ_INTERVAL; } } /* Timeout */ printCError ("(mdc800_usb_readFromIrq) timeout\n"); return GP_ERROR_IO; }
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 (GP_LOG_DEBUG, "ptp2/usb_event", "reading event an error %d occurred", result); if (result == GP_ERROR_TIMEOUT) return PTP_ERROR_TIMEOUT; return PTP_ERROR_IO; } if (result == 0) { gp_log (GP_LOG_DEBUG, "ptp2/usb_event", "reading event an 0 read occurred, assuming timeout."); return PTP_ERROR_TIMEOUT; } rlen = result; if (rlen < 8) { gp_log (GP_LOG_ERROR, "ptp2/usb_event", "reading event an short read of %ld bytes occurred", 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 (GP_LOG_DEBUG, "ptp2/usb_event","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; }