This source file includes following definitions.
- init_chdk_ptp
- init_chdk_ptp_task
- recv_ptp_data_init
- recv_ptp_data_chunk
- recv_ptp_data_finish
- recv_ptp_data
- flush_recv_ptp_data
- send_ptp_data_buf_init
- send_ptp_data_buf_free
- send_ptp_data
- send_ptp_data_buffered
- script_msg_q_next
- script_msg_q_full
- script_msg_q_empty
- enqueue_script_msg
- dequeue_script_msg
- empty_script_msg_q
- ptp_script_create_msg
- ptp_script_write_msg
- ptp_script_read_msg
- ptp_script_write_error_msg
- start_ptp_script
- script_start_ptp
- handle_ptp
1 #include "platform.h"
2 #include "camera_info.h"
3 #include "color.h"
4 #include "keyboard.h"
5 #include "ptp_chdk.h"
6 #include "core.h"
7 #include "task.h"
8 #include "script.h"
9 #include "action_stack.h"
10 #include "live_view.h"
11 #include "meminfo.h"
12 #include "modules.h"
13 #include "callfunc.h"
14 #include "stdio.h"
15
16 #include "remotecap_core.h"
17
18 int get_ptp_file_buf_size(void);
19 char *get_ptp_file_buf(void);
20
21
22
23 static unsigned script_run_id;
24
25 static int handle_ptp(
26 int h, ptp_data *data, int opcode, int sess_id, int trans_id,
27 int param1, int param2, int param3, int param4, int param5);
28
29 static void init_chdk_ptp()
30 {
31 int r;
32
33
34 r = 0x17;
35 while ( r==0x17 )
36 {
37 r = add_ptp_handler(PTP_OC_CHDK,handle_ptp,0);
38 msleep(250);
39 }
40
41 ExitTask();
42 }
43
44 void init_chdk_ptp_task()
45 {
46 CreateTask("InitCHDKPTP", 0x19, 0x200, init_chdk_ptp);
47 }
48
49 typedef struct {
50 char *buf;
51 char *dst_buf;
52 int buf_size;
53 int total_size;
54 int total_read;
55 int last_read;
56 } recv_ptp_data_state_t;
57
58
59
60
61
62
63
64
65
66 static int recv_ptp_data_init(recv_ptp_data_state_t *rs, int total_size, char *dst_buf)
67 {
68 memset(rs,0,sizeof(recv_ptp_data_state_t));
69 #ifdef CAM_PTP_USE_NATIVE_BUFFER
70 rs->buf_size = (get_ptp_file_buf_size() >> 1);
71 rs->buf = get_ptp_file_buf();
72 #else
73
74 rs->buf_size = (core_get_free_memory() >> 1);
75 #endif
76
77 #ifdef PTP_RECV_BUF_MAX_SIZE
78 if(rs->buf_size > PTP_RECV_BUF_MAX_SIZE) {
79 rs->buf_size = PTP_RECV_BUF_MAX_SIZE;
80 }
81 #endif
82
83
84
85
86 rs->buf_size &= 0xFFFFFE00;
87
88 if(rs->buf_size < 2048) {
89 return 0;
90 }
91
92 if(rs->buf_size > total_size) {
93 rs->buf_size = total_size;
94 }
95 rs->total_size = total_size;
96 rs->total_read = 0;
97 rs->last_read = 0;
98 rs->dst_buf = dst_buf;
99
100 #ifndef CAM_PTP_USE_NATIVE_BUFFER
101 if(!dst_buf) {
102 rs->buf = malloc(rs->buf_size);
103 if(!rs->buf) {
104 return 0;
105 }
106 } else {
107 rs->buf = NULL;
108 }
109 #endif
110 return 1;
111 }
112
113
114
115
116
117 static int recv_ptp_data_chunk(recv_ptp_data_state_t *rs,ptp_data *data)
118 {
119 int size_left = rs->total_size - rs->total_read;
120 if(size_left <= 0) {
121 return 0;
122 }
123 #ifndef CAM_PTP_USE_NATIVE_BUFFER
124
125 if(!rs->buf) {
126
127 rs->total_read = rs->last_read = rs->total_size;
128 if(data->recv_data(data->handle,rs->dst_buf,rs->total_size,0,0) != 0) {
129 return 0;
130 }
131 return 1;
132 }
133 #endif
134
135 int rsize;
136
137 if(size_left <= rs->buf_size) {
138 rsize = size_left;
139 } else {
140 rsize = rs->buf_size;
141
142
143 if(size_left <= rs->buf_size * 2) {
144
145 int rest = size_left % rs->buf_size;
146
147
148 if(rs->buf_size >= 0x800 && rest > 0x1f4 && rest < 0x3f4) {
149 rsize -= 0x400;
150 }
151 }
152 }
153 rs->last_read = rsize;
154 if(data->recv_data(data->handle,rs->buf,rsize,0,0) != 0) {
155 return 0;
156 }
157 if(rs->dst_buf) {
158 memcpy(rs->dst_buf + rs->total_read,rs->buf,rsize);
159 }
160 rs->total_read += rsize;
161 return 1;
162 }
163
164
165
166
167 static void recv_ptp_data_finish(recv_ptp_data_state_t *rs)
168 {
169 #ifndef CAM_PTP_USE_NATIVE_BUFFER
170 free(rs->buf);
171 #endif
172 memset(rs,0,sizeof(recv_ptp_data_state_t));
173 }
174
175
176
177
178
179
180 static int recv_ptp_data(ptp_data *data, char *buf, int size)
181 {
182 recv_ptp_data_state_t rs;
183 if(!recv_ptp_data_init(&rs,size,buf)) {
184 return 0;
185 }
186 int status=1;
187 while(rs.total_read < size && status) {
188 status = recv_ptp_data_chunk(&rs,data);
189 }
190 recv_ptp_data_finish(&rs);
191 return status;
192 }
193 static void flush_recv_ptp_data(ptp_data *data,int size) {
194 recv_ptp_data(data,NULL,size);
195 }
196
197 typedef struct {
198 char *buf;
199 int size;
200 } send_ptp_data_buf_t;
201
202
203
204
205
206
207
208 static int send_ptp_data_buf_init(send_ptp_data_buf_t *sb,int total_size)
209 {
210 int buf_size=(core_get_free_memory()>>1);
211
212 buf_size &= 0xFFFFFFFC;
213 if(buf_size > total_size) {
214 buf_size = total_size;
215 }
216 sb->buf=malloc(buf_size);
217 if(!sb->buf) {
218 sb->size=0;
219 return 0;
220 }
221 sb->size=buf_size;
222 return 1;
223 }
224
225
226
227
228 static void send_ptp_data_buf_free(send_ptp_data_buf_t *sb)
229 {
230 free(sb->buf);
231 sb->buf=NULL;
232 sb->size=0;
233 }
234
235
236
237
238
239 static int send_ptp_data(ptp_data *data, const char *src, int size)
240 {
241 if ( data->send_data(data->handle,src,size,size,0,0,0) )
242 {
243 return 0;
244 }
245 return 1;
246 }
247
248
249
250
251
252
253 static int send_ptp_data_buffered(ptp_data *data, void * (*copy_fn)(void *d, const void *s, long sz), const char *src, int size)
254 {
255 send_ptp_data_buf_t sb;
256 if(!send_ptp_data_buf_init(&sb,size)) {
257 return 0;
258 }
259
260 int tmpsize = size;
261 int send_size;
262 while ( size > 0 )
263 {
264 if(size > sb.size) {
265 send_size = sb.size;
266 } else {
267 send_size = size;
268 }
269
270 if(src >= sb.buf && src < sb.buf + send_size) {
271
272 if(src + size < sb.buf + sb.size) {
273
274 send_size = size;
275 } else {
276
277 send_size = sb.size - (src - sb.buf);
278 }
279 } else {
280
281 if(src < sb.buf && src + send_size > sb.buf) {
282
283 send_size = sb.buf - src;
284 }
285 copy_fn(sb.buf,src,send_size);
286 }
287 if ( data->send_data(data->handle,sb.buf,send_size,tmpsize,0,0,0) )
288 {
289 return 0;
290 }
291 tmpsize = 0;
292 size -= send_size;
293 src += send_size;
294 }
295 send_ptp_data_buf_free(&sb);
296 return 1;
297 }
298
299
300 #define PTP_SCRIPT_MSG_Q_LEN 16
301 typedef struct {
302 unsigned r;
303 unsigned w;
304 ptp_script_msg *q[PTP_SCRIPT_MSG_Q_LEN];
305 } ptp_script_msg_q;
306
307
308 ptp_script_msg_q msg_q_in;
309 ptp_script_msg_q msg_q_out;
310
311 unsigned script_msg_q_next(unsigned i) {
312 if(i == PTP_SCRIPT_MSG_Q_LEN - 1) {
313 return 0;
314 }
315 return i+1;
316 }
317
318 unsigned script_msg_q_full(ptp_script_msg_q *q) {
319 return (script_msg_q_next(q->w) == q->r);
320 }
321
322 unsigned script_msg_q_empty(ptp_script_msg_q *q) {
323 return (q->w == q->r);
324 }
325
326 int enqueue_script_msg(ptp_script_msg_q *q,ptp_script_msg *msg) {
327 unsigned w = script_msg_q_next(q->w);
328 if(w == q->r) {
329 return 0;
330 }
331 if(msg == NULL) {
332 return 0;
333 }
334 q->q[q->w] = msg;
335 q->w = w;
336 return 1;
337 }
338
339 ptp_script_msg* dequeue_script_msg(ptp_script_msg_q *q) {
340 ptp_script_msg *msg;
341 if(script_msg_q_empty(q)) {
342 return NULL;
343 }
344 msg = q->q[q->r];
345 q->r = script_msg_q_next(q->r);
346 return msg;
347 }
348
349
350 void empty_script_msg_q(ptp_script_msg_q *q) {
351 ptp_script_msg *msg;
352 while((msg = dequeue_script_msg(q))) {
353 free(msg);
354 }
355 }
356
357
358
359 ptp_script_msg* ptp_script_create_msg(unsigned type, unsigned subtype, unsigned datasize, const void *data) {
360 ptp_script_msg *msg;
361 msg = malloc(sizeof(ptp_script_msg) + datasize);
362 msg->size = datasize;
363 msg->type = type;
364 msg->subtype = subtype;
365
366
367 if(data && datasize) {
368 memcpy(msg->data,data,msg->size);
369 }
370 return msg;
371 }
372
373
374 int ptp_script_write_msg(ptp_script_msg *msg) {
375 msg->script_id = script_run_id;
376 return enqueue_script_msg(&msg_q_out,msg);
377 }
378
379
380 ptp_script_msg* ptp_script_read_msg(void) {
381 ptp_script_msg *msg;
382 while(1) {
383 msg = dequeue_script_msg(&msg_q_in);
384
385 if(!msg) {
386 return NULL;
387 }
388
389 if(!msg->script_id || msg->script_id == script_run_id) {
390 return msg;
391 } else {
392
393 free(msg);
394 }
395 }
396 }
397
398
399 int ptp_script_write_error_msg(unsigned errtype, const char *err) {
400 if(script_msg_q_full(&msg_q_out)) {
401 return 0;
402 }
403 ptp_script_msg *msg = ptp_script_create_msg(PTP_CHDK_S_MSGTYPE_ERR,errtype,strlen(err),err);
404 if(!msg) {
405 return 0;
406 }
407 return ptp_script_write_msg(msg);
408 }
409
410 static char* ptp_script = 0;
411 static int ptp_script_state = 0;
412
413
414
415 void start_ptp_script()
416 {
417 if (ptp_script)
418 {
419 module_set_script_lang(0);
420 if (libscriptapi->script_start(ptp_script,1))
421 {
422 camera_info.state.auto_started = 0;
423 ptp_script_state = script_stack_start();
424 }
425 else
426 ptp_script_state = -1;
427 ptp_script = 0;
428 }
429 }
430
431
432 static long script_start_ptp( char *script )
433 {
434 ptp_script = script;
435 while (ptp_script) msleep(10);
436 return ptp_script_state;
437 }
438
439 static int handle_ptp(
440 __attribute__ ((unused))int h, ptp_data *data, __attribute__ ((unused))int opcode, int sess_id, int trans_id,
441 int param1, int param2, int param3, int param4, __attribute__ ((unused))int param5)
442 {
443 static union {
444 char *str;
445 } temp_data;
446 static int temp_data_kind = 0;
447 static int temp_data_extra;
448 PTPContainer ptp;
449
450
451 memset(&ptp,0,sizeof(PTPContainer));
452 ptp.code = PTP_RC_OK;
453 ptp.sess_id = sess_id;
454 ptp.trans_id = trans_id;
455 ptp.num_param = 0;
456
457
458 switch ( param1 )
459 {
460
461 case PTP_CHDK_Version:
462 ptp.num_param = 2;
463 ptp.param1 = PTP_CHDK_VERSION_MAJOR;
464 ptp.param2 = PTP_CHDK_VERSION_MINOR;
465 break;
466 case PTP_CHDK_ScriptSupport:
467 ptp.num_param = 1;
468 ptp.param1 = 0;
469 ptp.param1 |= PTP_CHDK_SCRIPT_SUPPORT_LUA;
470 break;
471 case PTP_CHDK_ScriptStatus:
472 ptp.num_param = 1;
473 ptp.param1 = 0;
474 ptp.param1 |= script_is_running()?PTP_CHDK_SCRIPT_STATUS_RUN:0;
475 ptp.param1 |= (!script_msg_q_empty(&msg_q_out))?PTP_CHDK_SCRIPT_STATUS_MSG:0;
476 break;
477 case PTP_CHDK_GetMemory:
478 {
479 char *src=(char *)param2;
480 int size=param3;
481 int result=0;
482 if ( size < 1 )
483 {
484 ptp.code = PTP_RC_GeneralError;
485 break;
486 }
487
488 if (param4 == PTP_CHDK_GETMEM_MODE_DIRECT) {
489 int total_size = size;
490
491
492
493 if((unsigned)param2 < 4 ) {
494 char x[4];
495 int send_size = 4 - param2;
496 if(send_size > size) {
497 send_size = size;
498 }
499 memcpy(x,src,send_size);
500
501
502 if(data->send_data(data->handle,x,send_size,total_size,0,0,0) != 0) {
503 ptp.code = PTP_RC_GeneralError;
504 break;
505 }
506
507 if(size == send_size) {
508 break;
509 }
510 size -= send_size;
511
512 total_size = 0;
513 src+=send_size;
514 }
515
516 if(data->send_data(data->handle,src,size,total_size,0,0,0) == 0) {
517 result = 1;
518 }
519 } else if(param4 == PTP_CHDK_GETMEM_MODE_BUFFER) {
520 result = send_ptp_data_buffered(data,memcpy,src,size);
521 }
522 if(!result)
523 {
524 ptp.code = PTP_RC_GeneralError;
525 }
526 break;
527 }
528 case PTP_CHDK_SetMemory:
529 if ( param2 == 0 || param3 < 1 )
530 {
531 ptp.code = PTP_RC_GeneralError;
532 break;
533 }
534
535 data->get_data_size(data->handle);
536 if ( !recv_ptp_data(data,(char *) param2,param3) )
537 {
538 ptp.code = PTP_RC_GeneralError;
539 }
540 break;
541
542 case PTP_CHDK_CallFunction:
543 {
544 int s = data->get_data_size(data->handle);
545 if (s <= 0 || (s&3))
546 {
547 ptp.code = PTP_RC_GeneralError;
548 break;
549 }
550 unsigned *buf = malloc(s);
551
552 if ( buf == NULL )
553 {
554 ptp.code = PTP_RC_GeneralError;
555 break;
556 }
557
558 if ( recv_ptp_data(data,(char *) buf,s) )
559 {
560 ptp.num_param = 1;
561 ptp.param1 = call_func_ptr((void *)buf[0],(unsigned *)buf+1,(s-4)/4);
562 } else {
563 ptp.code = PTP_RC_GeneralError;
564 }
565
566 free(buf);
567 break;
568 }
569
570 case PTP_CHDK_TempData:
571 if ( param2 & PTP_CHDK_TD_DOWNLOAD )
572 {
573 const char *s = NULL;
574 size_t l = 0;
575
576 if ( temp_data_kind == 0 )
577 {
578 ptp.code = PTP_RC_GeneralError;
579 break;
580 }
581
582 if ( temp_data_kind == 1 )
583 {
584 s = temp_data.str;
585 l = temp_data_extra;
586 }
587
588 if ( !send_ptp_data(data,s,l) )
589 {
590 ptp.code = PTP_RC_GeneralError;
591 break;
592 }
593
594 } else if ( ! (param2 & PTP_CHDK_TD_CLEAR) ) {
595 if ( temp_data_kind == 1 )
596 {
597 free(temp_data.str);
598 }
599 temp_data_kind = 0;
600
601 temp_data_extra = data->get_data_size(data->handle);
602
603 temp_data.str = (char *) malloc(temp_data_extra);
604 if ( temp_data.str == NULL )
605 {
606 ptp.code = PTP_RC_GeneralError;
607 break;
608 }
609
610 if ( !recv_ptp_data(data,temp_data.str,temp_data_extra) )
611 {
612 ptp.code = PTP_RC_GeneralError;
613 break;
614 }
615 temp_data_kind = 1;
616 }
617 if ( param2 & PTP_CHDK_TD_CLEAR )
618 {
619 if ( temp_data_kind == 1 )
620 {
621 free(temp_data.str);
622 }
623 temp_data_kind = 0;
624 }
625 break;
626
627 case PTP_CHDK_UploadFile:
628 {
629 FILE *f=NULL;
630 char *fn=NULL;
631 unsigned data_size,fn_len;
632 recv_ptp_data_state_t rs;
633 data_size = data->get_data_size(data->handle);
634
635 if(!recv_ptp_data_init(&rs,data_size,NULL)) {
636 ptp.code = PTP_RC_GeneralError;
637 break;
638 }
639 int recv_err = 0;
640 while ( data_size > 0 ) {
641 if(!recv_ptp_data_chunk(&rs,data)) {
642 ptp.code = PTP_RC_GeneralError;
643 recv_err = 1;
644 break;
645 }
646
647 if(!f) {
648 fn_len = *(unsigned *)rs.buf;
649 fn = malloc(fn_len+1);
650 if(!fn) {
651 ptp.code = PTP_RC_GeneralError;
652 break;
653 }
654 memcpy(fn,rs.buf+4,fn_len);
655 fn[fn_len] = 0;
656 f = fopen(fn,"wb");
657 free(fn);
658 if(!f) {
659 ptp.code = PTP_RC_GeneralError;
660 break;
661 }
662 fwrite(rs.buf+4+fn_len,1,rs.last_read - 4 - fn_len,f);
663 } else {
664 fwrite(rs.buf,1,rs.last_read,f);
665 }
666 data_size -= rs.last_read;
667 }
668
669 if(f) {
670 fclose(f);
671 }
672 recv_ptp_data_finish(&rs);
673 if(data_size > 0 && ptp.code != PTP_RC_OK && !recv_err) {
674 flush_recv_ptp_data(data,data_size);
675 }
676 break;
677 }
678
679 case PTP_CHDK_DownloadFile:
680 {
681 FILE *f;
682 int tmp,t,total_size,r;
683 char *fn;
684
685 if ( temp_data_kind != 1 )
686 {
687
688 send_ptp_data(data,"\0",1);
689 ptp.code = PTP_RC_GeneralError;
690 break;
691 }
692
693 fn = (char *) malloc(temp_data_extra+1);
694 if ( fn == NULL )
695 {
696
697 send_ptp_data(data,"\0",1);
698 free(temp_data.str);
699 temp_data_kind = 0;
700 ptp.code = PTP_RC_GeneralError;
701 break;
702 }
703 memcpy(fn,temp_data.str,temp_data_extra);
704 fn[temp_data_extra] = '\0';
705
706 free(temp_data.str);
707 temp_data_kind = 0;
708
709 f = fopen(fn,"rb");
710 if ( f == NULL )
711 {
712
713 send_ptp_data(data,"\0",1);
714 ptp.code = PTP_RC_GeneralError;
715 free(fn);
716 break;
717 }
718 free(fn);
719
720 fseek(f,0,SEEK_END);
721 total_size = ftell(f);
722 fseek(f,0,SEEK_SET);
723
724 send_ptp_data_buf_t sb;
725 if(!send_ptp_data_buf_init(&sb,total_size))
726 {
727
728 send_ptp_data(data,"\0",1);
729 ptp.code = PTP_RC_GeneralError;
730 fclose(f);
731 break;
732 }
733
734 tmp = total_size;
735 t = total_size;
736 while ( (r = fread(sb.buf,1,(t<sb.size)?t:sb.size,f)) > 0 )
737 {
738 t -= r;
739 data->send_data(data->handle,sb.buf,r,tmp,0,0,0);
740 tmp = 0;
741 }
742 fclose(f);
743
744
745 ptp.num_param = 1;
746 ptp.param1 = total_size;
747
748 send_ptp_data_buf_free(&sb);
749
750 break;
751 }
752 break;
753
754 case PTP_CHDK_ExecuteScript:
755 {
756 int s;
757 char *buf;
758
759 ptp.num_param = 2;
760 ptp.param1 = script_run_id;
761
762 s = data->get_data_size(data->handle);
763
764 if ( (param2&PTP_CHDK_SL_MASK) != PTP_CHDK_SL_LUA )
765 {
766 flush_recv_ptp_data(data,s);
767 ptp.code = PTP_RC_ParameterNotSupported;
768 break;
769 }
770
771 buf = (char *) malloc(s);
772 if ( buf == NULL )
773 {
774 ptp.code = PTP_RC_GeneralError;
775 break;
776 }
777
778 recv_ptp_data(data,buf,s);
779
780
781 if (camera_info.state.state_kbd_script_run) {
782
783 if (param2 & PTP_CHDK_SCRIPT_FL_NOKILL) {
784
785
786 ptp.param2 = PTP_CHDK_S_ERR_SCRIPTRUNNING;
787 free(buf);
788 break;
789 }
790
791 script_wait_terminate();
792 }
793
794 if(param2 & PTP_CHDK_SCRIPT_FL_FLUSH_CAM_MSGS) {
795 empty_script_msg_q(&msg_q_out);
796 }
797
798 if(param2 & PTP_CHDK_SCRIPT_FL_FLUSH_HOST_MSGS) {
799 empty_script_msg_q(&msg_q_in);
800 }
801
802
803 script_run_id++;
804 ptp.param1 = script_run_id;
805
806
807 if (script_start_ptp(buf) < 0) {
808 ptp.param2 = PTP_CHDK_S_ERRTYPE_COMPILE;
809 } else {
810 ptp.param2 = PTP_CHDK_S_ERRTYPE_NONE;
811 }
812
813 free(buf);
814
815 break;
816 }
817 case PTP_CHDK_ReadScriptMsg:
818 {
819 char *pdata="";
820 unsigned datasize=1;
821
822 ptp_script_msg *msg = dequeue_script_msg(&msg_q_out);
823 ptp.num_param = 4;
824 if(msg) {
825 ptp.param1 = msg->type;
826 ptp.param2 = msg->subtype;
827 ptp.param3 = msg->script_id;
828 ptp.param4 = msg->size;
829
830 if(msg->size) {
831 datasize = msg->size;
832 pdata = msg->data;
833 }
834 } else {
835
836 ptp.param1 = PTP_CHDK_S_MSGTYPE_NONE;
837 ptp.param2 = 0;
838 ptp.param3 = 0;
839 ptp.param4 = 0;
840 }
841
842
843 if ( !send_ptp_data(data,pdata,datasize) )
844 {
845 ptp.code = PTP_RC_GeneralError;
846 }
847 free(msg);
848 break;
849 }
850 case PTP_CHDK_WriteScriptMsg:
851 {
852 int msg_size;
853 ptp_script_msg *msg;
854 ptp.num_param = 1;
855 ptp.param1 = PTP_CHDK_S_MSGSTATUS_OK;
856 if (!script_is_running()) {
857 ptp.param1 = PTP_CHDK_S_MSGSTATUS_NOTRUN;
858 } else if(param2 && (unsigned)param2 != script_run_id) {
859 ptp.param1 = PTP_CHDK_S_MSGSTATUS_BADID;
860 } else if(script_msg_q_full(&msg_q_in)) {
861 ptp.param1 = PTP_CHDK_S_MSGSTATUS_QFULL;
862 }
863
864 msg_size = data->get_data_size(data->handle);
865
866
867 if(ptp.param1 != PTP_CHDK_S_MSGSTATUS_OK) {
868 flush_recv_ptp_data(data,msg_size);
869 break;
870 }
871 msg = ptp_script_create_msg(PTP_CHDK_S_MSGTYPE_USER,PTP_CHDK_TYPE_STRING,msg_size,NULL);
872 if ( !msg )
873 {
874
875 flush_recv_ptp_data(data,msg_size);
876 ptp.code = PTP_RC_GeneralError;
877 break;
878 }
879 msg->script_id = param2;
880 if ( !recv_ptp_data(data,msg->data,msg->size) )
881 {
882 ptp.code = PTP_RC_GeneralError;
883 free(msg);
884 break;
885 }
886 if( !enqueue_script_msg(&msg_q_in,msg) ) {
887 ptp.code = PTP_RC_GeneralError;
888 free(msg);
889 }
890 break;
891 }
892
893 case PTP_CHDK_GetDisplayData:
894 {
895 extern int live_view_get_data(ptp_data *data, int flags);
896
897 ptp.num_param = 1;
898 ptp.param1 = live_view_get_data(data,param2);
899 if(!ptp.param1)
900 {
901 ptp.code = PTP_RC_GeneralError;
902
903 send_ptp_data(data,"\0",1);
904 }
905 }
906 break;
907 case PTP_CHDK_RemoteCaptureIsReady:
908 ptp.num_param = 2;
909 remotecap_is_ready(&ptp.param1,&ptp.param2);
910 break;
911 case PTP_CHDK_RemoteCaptureGetData:
912 {
913 unsigned int rcgd_size;
914 int rcgd_status;
915 char *rcgd_addr;
916 int rcgd_pos;
917
918 rcgd_status = remotecap_get_data_chunk(param2, &rcgd_addr, &rcgd_size, &rcgd_pos);
919 ptp.num_param = 3;
920 ptp.param3 = rcgd_pos;
921 if ( (rcgd_addr==0) || (rcgd_size==0) ) {
922
923 send_ptp_data(data,"\0",1);
924 ptp.param1 = 0;
925 ptp.param2 = 0;
926 } else {
927
928 data->send_data(data->handle,rcgd_addr,rcgd_size,rcgd_size,0,0,0);
929
930 ptp.param1 = rcgd_size;
931 if(rcgd_status == REMOTECAP_CHUNK_STATUS_MORE) {
932 ptp.param2 = 1;
933 } else {
934 ptp.param2 = 0;
935 }
936 }
937
938 if(!remotecap_send_complete(rcgd_status,param2)) {
939 ptp.code = PTP_RC_GeneralError;
940 }
941 }
942 break;
943 default:
944 ptp.code = PTP_RC_ParameterNotSupported;
945 break;
946 }
947
948
949 data->send_resp( data->handle, &ptp, 0 );
950
951 return 1;
952 }