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 <stdio.h>
27 
28 #include "dimagev.h"
29 
30 #define GP_MODULE "dimagev"
31 
32 /* This is the parent function, who calls most of the functions below.
33    It returns GP_ERROR if it cannot get the camera data, and GP_OK otherwise.
34    The subroutines will print out more detained information should they fail.
35 */
dimagev_get_camera_data(dimagev_t * dimagev)36 int dimagev_get_camera_data(dimagev_t *dimagev) {
37 	dimagev_packet *p, *raw;
38 	unsigned char char_buffer;
39 
40 	/* Check the device. */
41 	if ( dimagev->dev == NULL ) {
42 		GP_DEBUG( "dimagev_get_camera_data::device not valid");
43 		return GP_ERROR_BAD_PARAMETERS;
44 	}
45 
46 	/* Let's say hello and get the current status. */
47 	if ( ( p = dimagev_make_packet(DIMAGEV_GET_DATA, 1, 0)) == NULL ) {
48 		GP_DEBUG( "dimagev_get_camera_data::unable to allocate packet");
49 		return GP_ERROR_NO_MEMORY;
50 	}
51 
52 	if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
53 		GP_DEBUG( "dimagev_get_camera_data::unable to write packet");
54 		free(p);
55 		return GP_ERROR_IO;
56 	} else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
57 		GP_DEBUG( "dimagev_get_camera_data::no response from camera");
58 		free(p);
59 		return GP_ERROR_IO;
60 	}
61 
62 	free(p);
63 
64 	switch ( char_buffer ) {
65 		case DIMAGEV_ACK:
66 			break;
67 		case DIMAGEV_NAK:
68 			GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission");
69 			return GP_ERROR_IO;
70 		case DIMAGEV_CAN:
71 			GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission");
72 			return GP_ERROR_IO;
73 		default:
74 			GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer);
75 			return GP_ERROR_IO;
76 	}
77 
78 	if ( ( p = dimagev_read_packet(dimagev) ) == NULL ) {
79 		GP_DEBUG( "dimagev_get_camera_data::unable to read packet");
80 		return GP_ERROR_IO;
81 	}
82 
83 	char_buffer = DIMAGEV_EOT;
84 	if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
85 		GP_DEBUG( "dimagev_get_camera_data::unable to send EOT");
86 		free(p);
87 		return GP_ERROR_IO;
88 	}
89 
90 	if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
91 		GP_DEBUG( "dimagev_get_camera_data::no response from camera");
92 		free(p);
93 		return GP_ERROR_IO;
94 	}
95 
96 	switch ( char_buffer ) {
97 		case DIMAGEV_ACK:
98 			break;
99 		case DIMAGEV_NAK:
100 			GP_DEBUG( "dimagev_get_camera_data::camera did not acknowledge transmission");
101 			free(p);
102 			return GP_ERROR_IO;
103 		case DIMAGEV_CAN:
104 			GP_DEBUG( "dimagev_get_camera_data::camera cancels transmission");
105 			free(p);
106 			return GP_ERROR_IO;
107 		default:
108 			GP_DEBUG( "dimagev_get_camera_data::camera responded with unknown value %x", char_buffer);
109 			free(p);
110 			return GP_ERROR_IO;
111 	}
112 
113 	if ( ( raw = dimagev_strip_packet(p) ) == NULL ) {
114 		GP_DEBUG( "dimagev_get_camera_data::unable to strip data packet");
115 		free(p);
116 		return GP_ERROR;
117 	}
118 
119 	if ( ( dimagev->data = dimagev_import_camera_data(raw->buffer)) == NULL ) {
120 		GP_DEBUG( "dimagev_get_camera_data::unable to read camera data");
121 		free(raw);
122 		free(p);
123 		return GP_ERROR;
124 	}
125 
126 	/* Sure it *should* get freed automagically, but why take the risk? */
127 	free(p);
128 	free(raw);
129 
130 	return GP_OK;
131 }
132 
133 /* This function sends the contents of a dimagev_data_t to the current camera.
134    This allows many changes to be made (e.g. entering host mode and record
135    mode) while only sending a single set_data command.
136 */
dimagev_send_data(dimagev_t * dimagev)137 int dimagev_send_data(dimagev_t *dimagev) {
138 	dimagev_packet *p;
139 	unsigned char *export_data, char_buffer;
140 
141 
142 	if ( dimagev == NULL ) {
143 		GP_DEBUG( "dimagev_send_data::unable to use NULL dimagev_t");
144 		return GP_ERROR_BAD_PARAMETERS;
145 	}
146 
147 	if ( ( export_data = dimagev_export_camera_data(dimagev->data) ) == NULL ) {
148 		GP_DEBUG( "dimagev_send_data::unable to export camera data");
149 		return GP_ERROR;
150 	}
151 
152 	dimagev_dump_camera_data(dimagev->data);
153 
154 	if ( ( p = dimagev_make_packet(DIMAGEV_SET_DATA, 1, 0) ) == NULL ) {
155 		GP_DEBUG( "dimagev_send_data::unable to create set_data packet");
156 		free(export_data);
157 		return GP_ERROR_NO_MEMORY;
158 	}
159 
160 	if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
161 		GP_DEBUG( "dimagev_send_data::unable to send set_data packet");
162 		free(p);
163 		free(export_data);
164 		return GP_ERROR_IO;
165 	} else if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
166 		GP_DEBUG( "dimagev_send_data::no response from camera - trying to send NAK");
167 		free(p);
168 		free(export_data);
169 		return GP_ERROR_IO;
170 	}
171 
172 	free(p);
173 
174 	switch ( char_buffer ) {
175 		case DIMAGEV_ACK:
176 			break;
177 		case DIMAGEV_NAK:
178 			GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
179 			free(export_data);
180 			return GP_ERROR_IO;
181 		case DIMAGEV_CAN:
182 			GP_DEBUG( "dimagev_send_data::camera cancels transmission");
183 			free(export_data);
184 			return GP_ERROR_IO;
185 		default:
186 			GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
187 			free(export_data);
188 			return GP_ERROR_IO;
189 	}
190 
191 	if ( ( p = dimagev_make_packet(export_data, 9, 1) ) == NULL ) {
192 		GP_DEBUG( "dimagev_send_data::unable to create set_data packet");
193 		free(export_data);
194 		return GP_ERROR_NO_MEMORY;
195 	}
196 
197 	free(export_data);
198 
199 	if ( gp_port_write(dimagev->dev, (char*)p->buffer, p->length) < GP_OK ) {
200 		GP_DEBUG( "dimagev_send_data::unable to send data packet");
201 		free(p);
202 		return GP_ERROR_IO;
203 	}
204 
205 	free(p);
206 
207 	if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
208 		GP_DEBUG( "dimagev_send_data::no response from camera");
209 		return GP_ERROR_IO;
210 	}
211 
212 	switch ( char_buffer ) {
213 		case DIMAGEV_ACK:
214 			break;
215 		case DIMAGEV_NAK:
216 			GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
217 			return GP_ERROR_IO;
218 		case DIMAGEV_CAN:
219 			GP_DEBUG( "dimagev_send_data::camera cancels transmission");
220 			return GP_ERROR_IO;
221 		default:
222 			GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
223 			return GP_ERROR_IO;
224 	}
225 
226 
227 	char_buffer = DIMAGEV_EOT;
228 	if ( gp_port_write(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
229 		GP_DEBUG( "dimagev_send_data::unable to send EOT");
230 		return GP_ERROR_IO;
231 	}
232 
233 	if ( gp_port_read(dimagev->dev, (char*)&char_buffer, 1) < GP_OK ) {
234 		GP_DEBUG( "dimagev_send_data::no response from camera");
235 		return GP_ERROR_IO;
236 	}
237 
238 	switch ( char_buffer ) {
239 		case DIMAGEV_ACK:
240 			break;
241 		case DIMAGEV_NAK:
242 			GP_DEBUG( "dimagev_send_data::camera did not acknowledge transmission");
243 			return GP_ERROR_IO;
244 		case DIMAGEV_CAN:
245 			GP_DEBUG( "dimagev_send_data::camera cancels transmission");
246 			return GP_ERROR_IO;
247 		default:
248 			GP_DEBUG( "dimagev_send_data::camera responded with unknown value %x", char_buffer);
249 			return GP_ERROR_IO;
250 	}
251 
252 	if ( sleep(3) != 0 ) {
253 		GP_DEBUG( "dimagev_send_data::sleep() returned non-zero value");
254 	}
255 
256 	return GP_OK;
257 }
258 
259 /* This function populates and retuens a dimagev_data_t with the values
260    contained inside an array of bytes, as returned by the Dimage V. See
261    the description of these fields in the appropriate header file for
262    more information on the bit-packing done here.
263 */
dimagev_import_camera_data(unsigned char * raw_data)264 dimagev_data_t *dimagev_import_camera_data(unsigned char *raw_data) {
265 	dimagev_data_t *processed_data;
266 
267 	if ( raw_data == NULL ) {
268 		return NULL;
269 	}
270 
271 	if ( ( processed_data = malloc(sizeof(dimagev_data_t)) ) == NULL ) {
272 		return NULL;
273 	}
274 
275 	/* They really pack those bit fields. */
276 	processed_data->host_mode = ( raw_data[0] & 0x80) >> 7;
277 	processed_data->exposure_valid = (raw_data[0] & 0x40 ) >> 6;
278 	processed_data->date_valid = (raw_data[0] & 0x20 ) >> 5;
279 	processed_data->self_timer_mode = (raw_data[0] & 0x10 ) >> 4;
280 	processed_data->flash_mode = ( raw_data[0] & 0x0C ) >> 2;
281 	processed_data->quality_setting = ( raw_data[0] & 0x02 ) >> 1;
282 	processed_data->play_rec_mode = (raw_data[0] & 0x01 );
283 	processed_data->year = dimagev_bcd_to_decimal(raw_data[1]);
284 	processed_data->month = dimagev_bcd_to_decimal(raw_data[2]);
285 	processed_data->day = dimagev_bcd_to_decimal(raw_data[3]);
286 	processed_data->hour = dimagev_bcd_to_decimal(raw_data[4]);
287 	processed_data->minute = dimagev_bcd_to_decimal(raw_data[5]);
288 	processed_data->second = dimagev_bcd_to_decimal(raw_data[6]);
289 	processed_data->exposure_correction = raw_data[7];
290 	processed_data->valid = ( raw_data[8] & 0x80) >> 7;
291 	processed_data->id_number = ( raw_data[8] & 0x7F);
292 
293 	return processed_data;
294 }
295 
dimagev_export_camera_data(dimagev_data_t * good_data)296 unsigned char *dimagev_export_camera_data(dimagev_data_t *good_data) {
297 	unsigned char *export_data;
298 
299 	if ( ( export_data = malloc(9) ) == NULL ) {
300 		perror("dimagev_export_camera_data::unable to allocate buffer");
301 		return NULL;
302 	}
303 
304 	export_data[0] = (unsigned char) 0;
305 	export_data[0] = export_data[0] | ( ( ( good_data->host_mode ) << 7 ) & 0x80 );
306 	export_data[0] = export_data[0] | ( ( ( good_data->exposure_valid ) << 6 ) & 0x40 );
307 	export_data[0] = export_data[0] | ( ( ( good_data->date_valid ) << 5 ) & 0x20 );
308 	export_data[0] = export_data[0] | ( ( ( good_data->self_timer_mode ) << 4 ) & 0x10 );
309 	export_data[0] = export_data[0] | ( ( ( good_data->flash_mode ) << 2 ) & 0x0C );
310 	export_data[0] = export_data[0] | ( ( ( good_data->quality_setting ) << 1 ) & 0x02 );
311 	export_data[0] = export_data[0] | ( ( ( good_data->play_rec_mode )) & 0x01 );
312 	export_data[1] = (unsigned char) 0;
313 	export_data[1] = dimagev_decimal_to_bcd(good_data->year);
314 	export_data[2] = (unsigned char) 0;
315 	export_data[2] = dimagev_decimal_to_bcd(good_data->month);
316 	export_data[3] = (unsigned char) 0;
317 	export_data[3] = dimagev_decimal_to_bcd(good_data->day);
318 	export_data[4] = (unsigned char) 0;
319 	export_data[4] = dimagev_decimal_to_bcd(good_data->hour);
320 	export_data[5] = (unsigned char) 0;
321 	export_data[5] = dimagev_decimal_to_bcd(good_data->minute);
322 	export_data[6] = (unsigned char) 0;
323 	export_data[6] = dimagev_decimal_to_bcd(good_data->second);
324 	export_data[7] = (unsigned char) 0;
325 	export_data[7] = good_data->exposure_correction;
326 	export_data[8] = (unsigned char) 0;
327 	export_data[8] = export_data[8] & ( ( ( good_data->valid ) << 7 ) & 0x80 );
328 	export_data[8] = export_data[8] & ( ( ( good_data->id_number ) ) & 0x7F );
329 
330 	return export_data;
331 }
332 
dimagev_dump_camera_data(dimagev_data_t * data)333 void dimagev_dump_camera_data(dimagev_data_t *data) {
334 	GP_DEBUG( "========= Begin Camera Data =========");
335 	GP_DEBUG( "Host mode: %s ( %d )", data->host_mode != (unsigned char) 0 ? "Host mode" : "Camera mode", data->host_mode);
336 	GP_DEBUG( "Exposure valid: %s ( %d )", data->exposure_valid != (unsigned char) 0 ? "Valid" : "Not Valid", data->exposure_valid);
337 	GP_DEBUG( "Exposure correction: %d", (signed char)data->exposure_correction);
338 	GP_DEBUG( "Date valid: %s ( %d )", data->date_valid != (unsigned char) 0 ? "Valid" : "Not Valid", data->exposure_valid);
339 	GP_DEBUG( "Self timer mode: %s ( %d )", data->self_timer_mode != (unsigned char) 0 ? "Yes" : "No", data->self_timer_mode);
340 	GP_DEBUG( "Flash mode: ");
341 
342 	switch ( data->flash_mode ) {
343 		case 0:
344 			GP_DEBUG( "\tAuto ( 0 )");
345 			break;
346 		case 1:
347 			GP_DEBUG( "\tForce Flash ( 1 )");
348 			break;
349 		case 2:
350 			GP_DEBUG( "\tProhibit Flash ( 2 )");
351 			break;
352 		default:
353 			GP_DEBUG( "\tInvalid mode for flash ( %d )", data->flash_mode);
354 			break;
355 	}
356 
357 	GP_DEBUG( "Quality mode: %s ( %d )", data->quality_setting ? "High" : "Low", data->quality_setting);
358 	GP_DEBUG( "Play or Record mode: %s ( %d )", data->play_rec_mode != (unsigned char) 0 ? "Record" : "Play", data->play_rec_mode);
359 	GP_DEBUG( "Date: %02d/%02d/%02d %02d:%02d:%02d", data->year, data->month, data->day, data->hour, data->minute, data->second);
360 	GP_DEBUG( "Card ID Valid: %s ( %d )", data->valid != (unsigned char) 0 ? "Valid" : "Invalid", data->valid);
361 	GP_DEBUG( "Card ID Data: %02x", data->id_number);
362 	GP_DEBUG( "========== End Camera Data ==========");
363 
364 	return;
365 }
366 
367 /* This function gets the current system time, sets the contents of the current
368    dimagev->data struct appropriately, and then sends the data.
369 */
dimagev_set_date(dimagev_t * dimagev)370 int dimagev_set_date(dimagev_t *dimagev) {
371 	struct tm *this_time;
372 	time_t now;
373 
374 	if ( dimagev == NULL ) {
375 		return GP_ERROR_BAD_PARAMETERS;
376 	}
377 
378 	if ( ( now = time(NULL) ) < 0 ) {
379 		GP_DEBUG( "dimagev_set_date::unable to get system time");
380 		return GP_ERROR;
381 	}
382 
383 	if ( ( this_time = localtime(&now) ) == NULL ) {
384 		GP_DEBUG( "dimagev_set_date::unable to convert system time to local time");
385 		return GP_ERROR;
386 	}
387 
388 	GP_DEBUG( "Setting clock to %02d/%02d/%02d %02d:%02d:%02d", this_time->tm_year % 100, ( this_time->tm_mon + 1 ), this_time->tm_mday, this_time->tm_hour, this_time->tm_min, this_time->tm_sec);
389 
390 	dimagev->data->date_valid = (unsigned char) 1;
391 	dimagev->data->year = (unsigned char) ( this_time->tm_year % 100 );
392 	dimagev->data->month = (unsigned char) ( this_time->tm_mon + 1 );
393 	dimagev->data->day = (unsigned char) this_time->tm_mday;
394 	dimagev->data->hour = (unsigned char) this_time->tm_hour;
395 	dimagev->data->minute = (unsigned char) this_time->tm_min;
396 	dimagev->data->second = (unsigned char) this_time->tm_sec;
397 
398 	if ( dimagev_send_data(dimagev) < GP_OK ) {
399 		GP_DEBUG( "dimagev_set_date::unable to set time");
400 		return GP_ERROR_IO;
401 	}
402 
403 	/* So we don't set this date again later by mistake. */
404 	dimagev->data->date_valid = (unsigned char) 0;
405 
406 	if ( dimagev_send_data(dimagev) < GP_OK ) {
407 		GP_DEBUG( "dimagev_set_date::unable to set time");
408 		return GP_ERROR_IO;
409 	}
410 
411 	return GP_OK;
412 }
413