int l_init (GPPort *p, GPContext *c) { unsigned int i; int result = GP_OK; CHECK_NULL (p); CHECK (gp_port_set_timeout (p, DEFAULT_TIMEOUT)); for (i = 0; i < 3; i++) { result = l_ping (p, c); if (result != GP_ERROR_TIMEOUT) break; } return (result); }
int l_init (GPPort *p, GPFsErr *c) { unsigned int i; int result = 0; CHECK_NULL (p); CHECK (gp_port_set_timeout (p, DEFAULT_TIMEOUT)); for (i = 0; i < 3; i++) { result = l_ping (p, c); if (result != -1) break; } return (result); }
static int l_esc_read (GPPort *p, unsigned char *c) { CHECK_NULL (p && c); CHECK (gp_port_read (p, c, 1)); /* * STX, ETX, ENQ, ACK, XOFF, XON, NACK, and ETB have to be masked by * ESC. If we receive one of those (except ETX and ETB) without mask, * we will not report an error, as it will be recovered automatically * later. If we receive ETX or ETB, we reached the end of the packet * and report a transmission error, so that the error can be * recovered. * If the camera sends us ESC (the mask), we will not count this byte * and read a second one. This will be reverted and processed. It * then must be one of STX, ETX, ENQ, ACK, XOFF, XON, NACK, ETB, or * ESC. As before, if it is not one of those, we'll not report an * error, as it will be recovered automatically later. */ /* The HP PhotoSmart does not escape every special code, only * some and it gets confused if we do this checks. By relaxing * these, it now downloads images etc. */ #ifndef LESSER_ESCAPES if ((*c == STX ) || (*c == ETX) || (*c == ENQ ) || (*c == ACK) || (*c == XOFF) || (*c == XON) || (*c == NACK) || (*c == ETB)) { #else /* LESSER_ESCAPES */ if ((*c == STX ) || (*c == XOFF) || (*c == XON)) { #endif /* LESSER_ESCAPES */ GP_DEBUG ("Wrong ESC masking!"); if ((*c == ETX) || (*c == ETB)) return (GP_ERROR_CORRUPTED_DATA); } else if (*c == ESC) { CHECK (gp_port_read (p, c, 1)); *c = (~*c & 0xff); if ((*c != STX ) && (*c != ETX ) && (*c != ENQ) && (*c != ACK ) && (*c != XOFF) && (*c != XON) && (*c != NACK) && (*c != ETB ) && (*c != ESC)) GP_DEBUG ("Wrong ESC masking!"); } return (GP_OK); } static int l_send (GPPort *p, GPContext *context, unsigned char *send_buffer, unsigned int send_buffer_size) { unsigned char c; unsigned char checksum; /**********************************************************************/ /* sb: A pointer to the buffer that we will send. */ /* sbs: Its size. */ /**********************************************************************/ unsigned char *sb; unsigned int sbs; int i = 0; CHECK_NULL (p && send_buffer); /* We need to ping the camera first */ CHECK (l_ping (p, context)); /********************************************************/ /* We will write: */ /* - STX */ /* - low order byte of (send_buffer_size + 5) */ /* - high order byte of (send_buffer_size + 5) */ /* - 'send_buffer_size' bytes data plus ESC quotes */ /* - ETX */ /* - 1 byte for checksum plus ESC quotes */ /* */ /* The checksum covers all bytes after STX and before */ /* the checksum byte(s). */ /********************************************************/ sbs = send_buffer_size + 5; sb = malloc (sizeof (char) * sbs); sb[0] = STX; sb[1] = send_buffer_size; sb[2] = send_buffer_size >> 8; checksum = sb[1]; checksum += sb[2]; for (i = 3; i < (sbs - 2); i++) { checksum += *send_buffer; if ( (*send_buffer == STX ) || (*send_buffer == ETX ) || (*send_buffer == ENQ ) || (*send_buffer == ACK ) || (*send_buffer == XOFF) || (*send_buffer == XON ) || (*send_buffer == NACK) || (*send_buffer == ETB ) || (*send_buffer == ESC )) { sb = realloc (sb, ++sbs * sizeof (char)); sb[ i] = ESC; sb[++i] = ~*send_buffer; } else sb[ i] = *send_buffer; send_buffer++; } sb[sbs - 2] = ETX; checksum += ETX; if ( (checksum == STX ) || (checksum == ETX ) || (checksum == ENQ ) || (checksum == ACK ) || (checksum == XOFF) || (checksum == XON ) || (checksum == NACK) || (checksum == ETB ) || (checksum == ESC )) { sb = realloc (sb, ++sbs * sizeof (char)); sb[sbs - 2] = ESC; sb[sbs - 1] = ~checksum; } else sb[sbs - 1] = checksum; for (i = 0; ; i++) { /* Write data as above. */ CHECK_FREE (gp_port_write (p, sb, sbs), sb); CHECK_FREE (gp_port_read (p, &c, 1), sb); switch (c) { case ACK: /* ACK received. We can proceed. */ free (sb); /* Write EOT. */ c = EOT; CHECK (gp_port_write (p, &c, 1)); return (GP_OK); case NACK: /* NACK received. We'll try up to three times. */ if (i == 2) { free (sb); return (GP_ERROR_CORRUPTED_DATA); } else break; default: /* Should not happen. */ return (GP_ERROR_CORRUPTED_DATA); } } }