1 /**********************************************************************
2 *       Minolta Dimage V digital camera communication library         *
3 *               Copyright 2000,2001 Gus Hartmann                      *
4 *                                                                     *
5 *    This program is free software; you can redistribute it and/or    *
6 *    modify it under the terms of the GNU General Public License as   *
7 *    published by the Free Software Foundation; either version 2 of   *
8 *    the License, or (at your option) any later version.              *
9 *                                                                     *
10 *    This program is distributed in the hope that it will be useful,  *
11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of   *
12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
13 *    GNU General Public License for more details.                     *
14 *                                                                     *
15 *    You should have received a copy of the GNU General Public        *
16 *    License along with this program; if not, write to the            *
17 *    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 *    Boston, MA  02110-1301  USA
19 *                                                                     *
20 **********************************************************************/
21 
22 /* $Id$ */
23 
24 #include "config.h"
25 
26 #include "dimagev.h"
27 
28 #define GP_MODULE "dimagev"
29 
dimagev_put_file(dimagev_t * dimagev,CameraFile * file)30 int dimagev_put_file(dimagev_t* dimagev, CameraFile *file) {
31 	unsigned char total_packets= (unsigned char) 0, sent_packets= (unsigned char) 0;
32 	int left_to_send=0;
33 	const char *data;
34 	unsigned long int size;
35 
36 	dimagev_packet *p;
37 	unsigned char char_buffer, command_buffer[3], *packet_buffer;
38 
39 	if ( dimagev == NULL ) {
40 		GP_DEBUG( "dimagev_put_file::null camera device");
41 		return GP_ERROR_BAD_PARAMETERS;
42 	}
43 
44 	if ( dimagev->data->host_mode != (unsigned char) 1 ) {
45 
46 		dimagev->data->host_mode = (unsigned char) 1;
47 
48 		if ( dimagev_send_data(dimagev) < GP_OK ) {
49 			GP_DEBUG( "dimagev_put_file::unable to set host mode");
50 			return GP_ERROR_IO;
51 		}
52 	}
53 
54 	gp_file_get_data_and_size (file, &data, &size);
55 
56 	/* First make the command packet. */
57 	command_buffer[0] = 0x0e;
58 	if ( ( p = dimagev_make_packet(command_buffer, 1, 0) ) == NULL ) {
59 		GP_DEBUG( "dimagev_put_file::unable to allocate command packet");
60 		return GP_ERROR_NO_MEMORY;
61 	}
62 
63 	if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) {
64 		GP_DEBUG( "dimagev_put_file::unable to send command packet");
65 		free(p);
66 		return GP_ERROR_IO;
67 	} else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) {
68 		GP_DEBUG( "dimagev_put_file::no response from camera");
69 		free(p);
70 		return GP_ERROR_IO;
71 	}
72 
73 	free(p);
74 
75 	switch ( char_buffer ) {
76 		case DIMAGEV_ACK:
77 			break;
78 		case DIMAGEV_NAK:
79 			GP_DEBUG( "dimagev_put_file::camera did not acknowledge transmission");
80 			/* Since we haven't sent anything, keep trying until we get a cancel. */
81 			return dimagev_put_file(dimagev, file);
82 /*			return GP_ERROR_IO;*/
83 		case DIMAGEV_CAN:
84 			GP_DEBUG( "dimagev_put_file::camera cancels transmission");
85 			return GP_ERROR_IO;
86 		default:
87 			GP_DEBUG( "dimagev_put_file::camera responded with unknown value %x", char_buffer);
88 			return GP_ERROR_IO;
89 	}
90 
91 	/* Now start chopping up the picture and sending it over. */
92 
93 	total_packets = ( size / 993 ) +1;
94 
95 	/* The first packet is a special case. */
96 	if ( ( packet_buffer = malloc((size_t)993)) == NULL ) {
97 		GP_DEBUG( "dimagev_put_file::unable to allocate packet buffer");
98 		return GP_ERROR_NO_MEMORY;
99 	}
100 
101 	packet_buffer[0]= total_packets;
102 	memcpy(&(packet_buffer[1]), data, (size_t) 992);
103 
104 	if ( ( p = dimagev_make_packet(packet_buffer, 993, 0) ) == NULL ) {
105 		GP_DEBUG( "dimagev_put_file::unable to allocate command packet");
106 		free(packet_buffer);
107 		return GP_ERROR_NO_MEMORY;
108 	}
109 
110 	free(packet_buffer);
111 
112 	if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) {
113 		GP_DEBUG( "dimagev_put_file::unable to send data packet");
114 		free(p);
115 		return GP_ERROR_IO;
116 	} else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) {
117 		GP_DEBUG( "dimagev_put_file::no response from camera");
118 		free(p);
119 		return GP_ERROR_IO;
120 	}
121 
122 	free(p);
123 
124 	switch ( char_buffer ) {
125 		case DIMAGEV_ACK:
126 			break;
127 		case DIMAGEV_NAK:
128 			GP_DEBUG( "dimagev_put_file::camera did not acknowledge transmission");
129 			return GP_ERROR_IO;
130 		case DIMAGEV_CAN:
131 			GP_DEBUG( "dimagev_put_file::camera cancels transmission");
132 			return GP_ERROR_IO;
133 		default:
134 			GP_DEBUG( "dimagev_put_file::camera responded with unknown value %x", char_buffer);
135 			return GP_ERROR_IO;
136 	}
137 
138 	left_to_send = ( size - 992 );
139 
140 	for ( sent_packets = (unsigned char) 1 ; sent_packets < total_packets ; sent_packets++ ) {
141 		if ( left_to_send > 993 ) {
142 			if ( ( p = dimagev_make_packet((unsigned char *)&(data[(sent_packets * 993) - 1]),
143 						       993, sent_packets) ) == NULL ) {
144 				GP_DEBUG( "dimagev_put_file::unable to allocate data packet");
145 				free(p);
146 				return GP_ERROR_NO_MEMORY;
147 			}
148 			left_to_send-=993;
149 		} else {
150 			if ( ( p = dimagev_make_packet((unsigned char *)&(data[((sent_packets * 993) - 1)]),
151 						       left_to_send, sent_packets) ) == NULL ) {
152 				GP_DEBUG( "dimagev_put_file::unable to allocate data packet");
153 				return GP_ERROR_NO_MEMORY;
154 			}
155 		}
156 
157 		if ( gp_port_write(dimagev->dev, (char *)p->buffer, p->length) < GP_OK ) {
158 			GP_DEBUG( "dimagev_put_file::unable to send data packet");
159 			free(p);
160 			return GP_ERROR_IO;
161 		} else if ( gp_port_read(dimagev->dev, (char *)&char_buffer, 1) < GP_OK ) {
162 			GP_DEBUG( "dimagev_put_file::no response from camera");
163 			free(p);
164 			return GP_ERROR_IO;
165 		}
166 
167 		free(p);
168 
169 		switch ( char_buffer ) {
170 			case DIMAGEV_ACK:
171 				break;
172 			case DIMAGEV_NAK:
173 				GP_DEBUG( "dimagev_put_file::camera did not acknowledge transmission");
174 				return GP_ERROR_IO;
175 			case DIMAGEV_CAN:
176 				GP_DEBUG( "dimagev_put_file::camera cancels transmission");
177 				return GP_ERROR_IO;
178 			default:
179 				GP_DEBUG( "dimagev_put_file::camera responded with unknown value %x", char_buffer);
180 				return GP_ERROR_IO;
181 		}
182 	}
183 
184 
185 
186 	return GP_OK;
187 }
188