├── LICENSE ├── Makefile ├── README ├── TODO ├── alphamote ├── alphamote.c ├── alphamote.h ├── aperture_dec.c ├── aperture_inc.c ├── contrib └── tethered.sh ├── doc ├── usb_reverse_engineering_cda.odp └── usb_reverse_engineering_cda.pdf ├── download.c ├── info.c ├── init.c └── shutter.c /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2009 Alexander Klink 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | OBJS = alphamote.o 3 | LDFLAGS = -lusb 4 | 5 | default: init aperture_dec aperture_inc info shutter download 6 | 7 | init: $(OBJS) 8 | $(CC) -o alphamote-init init.c $(OBJS) $(LDFLAGS) 9 | 10 | info: $(OBJS) 11 | $(CC) -o alphamote-info info.c $(OBJS) $(LDFLAGS) 12 | 13 | aperture_inc: $(OBJS) 14 | $(CC) -o alphamote-aperture-inc aperture_inc.c $(OBJS) $(LDFLAGS) 15 | 16 | aperture_dec: $(OBJS) 17 | $(CC) -o alphamote-aperture-dec aperture_dec.c $(OBJS) $(LDFLAGS) 18 | 19 | shutter: $(OBJS) 20 | $(CC) -o alphamote-shutter shutter.c $(OBJS) $(LDFLAGS) 21 | 22 | download: $(OBJS) 23 | $(CC) -o alphamote-download download.c $(OBJS) $(LDFLAGS) 24 | 25 | clean: 26 | rm alphamote-* 27 | rm *.o 28 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | alphamote - Free Sony alpha camera remote tools 2 | =============================================== 3 | 4 | alphamote is a work in progress to build a libusb-based 5 | replacement for Sony's Remote Camera Control software. 6 | 7 | Why? Sony's software does not run on free Unix systems 8 | and can not be scripted ... 9 | 10 | To compile, run make 11 | 12 | ./alphamote-init 13 | ./alphamote-trigger 14 | 15 | should then create a /tmp/foo.jpg file. 16 | 17 | ./alphamote-info will show you the settings and a dump of 18 | the corresponding message block. Play with the camera settings 19 | to figure out which blocks correspond to what ... 20 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODOs: 2 | 3 | - record USB traffic for changing settings other than aperture 4 | - figure out when file from camera is available for download 5 | - figure out how the camera reports if a photo could not be taken 6 | - In trigger.c, read filename from the camera and use it as a default 7 | -------------------------------------------------------------------------------- /alphamote: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | BINARY_PATH=. 3 | ACTION=$1 4 | shift 5 | $BINARY_PATH/alphamote-$ACTION $@ 6 | -------------------------------------------------------------------------------- /alphamote.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct usb_dev_handle *devh; 10 | 11 | void release_usb_device(int dummy) { 12 | int ret; 13 | ret = usb_release_interface(devh, 0); 14 | if (!ret) 15 | printf("failed to release interface: %d\n", ret); 16 | usb_close(devh); 17 | if (!ret) 18 | printf("failed to close interface: %d\n", ret); 19 | exit(1); 20 | } 21 | 22 | struct usb_device *find_device(int vendor, int product) { 23 | struct usb_bus *bus; 24 | 25 | for (bus = usb_get_busses(); bus; bus = bus->next) { 26 | struct usb_device *dev; 27 | 28 | for (dev = bus->devices; dev; dev = dev->next) { 29 | if (dev->descriptor.idVendor == vendor 30 | && dev->descriptor.idProduct == product) 31 | return dev; 32 | } 33 | } 34 | return NULL; 35 | } 36 | 37 | void init_usb() { 38 | int vendor, product, ret; 39 | struct usb_device *dev; 40 | char buf[65535]; 41 | 42 | usb_init(); 43 | usb_find_busses(); 44 | usb_find_devices(); 45 | 46 | // vendor and product code for Sony alpha 700 47 | vendor = 0x054c; 48 | product = 0x02e7; 49 | dev = find_device(vendor, product); 50 | if (! dev) { 51 | fprintf(stderr, "No camera found!\n"); 52 | exit(1); 53 | } 54 | 55 | devh = usb_open(dev); 56 | assert(devh); 57 | 58 | signal(SIGTERM, release_usb_device); 59 | 60 | ret = usb_get_driver_np(devh, 0, buf, sizeof(buf)); 61 | ret = usb_claim_interface(devh, 0); 62 | if (ret != 0) { 63 | printf("claim failed with error %d\n", ret); 64 | exit(1); 65 | } 66 | 67 | ret = usb_set_altinterface(devh, 0); 68 | assert(ret >= 0); 69 | 70 | ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012); 71 | usleep(4*1000); 72 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000009); 73 | usleep(3*1000); 74 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000027); 75 | usleep(4*1000); 76 | ret = usb_release_interface(devh, 0); 77 | if (ret != 0) printf("failed to release interface before set_configuration: %d\n", ret); 78 | ret = usb_set_configuration(devh, 0x0000001); 79 | ret = usb_claim_interface(devh, 0); 80 | if (ret != 0) printf("claim after set_configuration failed with error %d\n", ret); 81 | ret = usb_set_altinterface(devh, 0); 82 | 83 | return; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /alphamote.h: -------------------------------------------------------------------------------- 1 | #ifndef ALPHAMOTE_H 2 | #define ALPHAMOTE_H 3 | // exported variables 4 | extern struct usb_dev_handle *devh; 5 | // exported functions 6 | void release_usb_device(int); 7 | struct usb_device *find_device(int, int); 8 | void init_usb(); 9 | #endif 10 | struct usb_dev_handle *devh; 11 | -------------------------------------------------------------------------------- /aperture_dec.c: -------------------------------------------------------------------------------- 1 | /* This file is generated with usbsnoop2libusb.pl from a usbsnoop log file. */ 2 | /* Latest version of the script should be in http://iki.fi/lindi/usb/usbsnoop2libusb.pl */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "alphamote.h" 11 | 12 | int main(int argc, char **argv) { 13 | int ret; 14 | char buf[65535]; 15 | 16 | init_usb(); 17 | 18 | ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012); 19 | usleep(4*1000); 20 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000009); 21 | usleep(3*1000); 22 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000027); 23 | usleep(4*1000); 24 | ret = usb_release_interface(devh, 0); 25 | if (ret != 0) printf("failed to release interface before set_configuration: %d\n", ret); 26 | ret = usb_set_configuration(devh, 0x0000001); 27 | ret = usb_claim_interface(devh, 0); 28 | if (ret != 0) printf("claim after set_configuration failed with error %d\n", ret); 29 | ret = usb_set_altinterface(devh, 0); 30 | 31 | // 9207: open up aperture 32 | usleep(6*1000); 33 | memcpy(buf, "\x10\x00\x00\x00\x01\x00\x07\x92\x78\x00\x00\x00\x07\x50\x00\x00", 0x0000010); 34 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000010, 1000); 35 | usleep(4*1000); 36 | memcpy(buf, "\x0d\x00\x00\x00\x02\x00\x07\x92\x78\x00\x00\x00\xff", 0x000000d); 37 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000d, 1000); 38 | ret = usb_release_interface(devh, 0); 39 | assert(ret == 0); 40 | ret = usb_close(devh); 41 | assert(ret == 0); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /aperture_inc.c: -------------------------------------------------------------------------------- 1 | /* This file is generated with usbsnoop2libusb.pl from a usbsnoop log file. */ 2 | /* Latest version of the script should be in http://iki.fi/lindi/usb/usbsnoop2libusb.pl */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "alphamote.h" 11 | 12 | int main(int argc, char **argv) { 13 | int ret; 14 | char buf[65535]; 15 | 16 | init_usb(); 17 | 18 | ret = usb_get_descriptor(devh, 0x0000001, 0x0000000, buf, 0x0000012); 19 | usleep(4*1000); 20 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000009); 21 | usleep(3*1000); 22 | ret = usb_get_descriptor(devh, 0x0000002, 0x0000000, buf, 0x0000027); 23 | usleep(4*1000); 24 | ret = usb_release_interface(devh, 0); 25 | if (ret != 0) printf("failed to release interface before set_configuration: %d\n", ret); 26 | ret = usb_set_configuration(devh, 0x0000001); 27 | ret = usb_claim_interface(devh, 0); 28 | if (ret != 0) printf("claim after set_configuration failed with error %d\n", ret); 29 | ret = usb_set_altinterface(devh, 0); 30 | 31 | // 9207: close down aperture 32 | usleep(8*1000); 33 | memcpy(buf, "\x10\x00\x00\x00\x01\x00\x07\x92\x10\x01\x00\x00\x07\x50\x00\x00", 0x0000010); 34 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000010, 1000); 35 | usleep(4*1000); 36 | memcpy(buf, "\x0d\x00\x00\x00\x02\x00\x07\x92\x10\x01\x00\x00\x01", 0x000000d); 37 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000d, 1000); 38 | usleep(3*1000); 39 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 40 | ret = usb_release_interface(devh, 0); 41 | assert(ret == 0); 42 | ret = usb_close(devh); 43 | assert(ret == 0); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /contrib/tethered.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # a quick script to do tethered shooting in (c)RAW + JPG mode: 4 | # download the photo, rename it, show it using qiv, download the ARW file 5 | alphamote download 6 | DATE=`date +%s` 7 | mv /tmp/foo.jpg $DATE.jpg 8 | qiv -f -m $DATE.jpg & 9 | alphamote download 10 | mv /tmp/foo.jpg $DATE.arw 11 | -------------------------------------------------------------------------------- /doc/usb_reverse_engineering_cda.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alech/alphamote/60b2859ec8c65897fa862fcb2d962870c40ce2eb/doc/usb_reverse_engineering_cda.odp -------------------------------------------------------------------------------- /doc/usb_reverse_engineering_cda.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alech/alphamote/60b2859ec8c65897fa862fcb2d962870c40ce2eb/doc/usb_reverse_engineering_cda.pdf -------------------------------------------------------------------------------- /download.c: -------------------------------------------------------------------------------- 1 | /* This file is generated with usbsnoop2libusb.pl from a usbsnoop log file. */ 2 | /* Latest version of the script should be in http://iki.fi/lindi/usb/usbsnoop2libusb.pl */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "alphamote.h" 12 | 13 | void print_bytes(char *bytes, int len) { 14 | int i; 15 | if (len > 0) { 16 | for (i=0; i 0) { 89 | // something to read left 90 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 4932); 91 | // append to file 92 | int i; 93 | for (i = 0; i < ret; i++) { 94 | fputc(buf[i], out); 95 | } 96 | } 97 | fclose(out); 98 | ret = usb_release_interface(devh, 0); 99 | assert(ret == 0); 100 | ret = usb_close(devh); 101 | assert(ret == 0); 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /info.c: -------------------------------------------------------------------------------- 1 | /* This file is generated with usbsnoop2libusb.pl from a usbsnoop log file. */ 2 | /* Latest version of the script should be in http://iki.fi/lindi/usb/usbsnoop2libusb.pl */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "alphamote.h" 11 | 12 | void print_bytes(char *bytes, int len) { 13 | int i; 14 | if (len > 0) { 15 | printf("00: "); 16 | for (i=0; i 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "alphamote.h" 11 | 12 | int main(int argc, char **argv) { 13 | int ret; 14 | char buf[65535]; 15 | 16 | init_usb(); 17 | 18 | memcpy(buf, "\x10\x00\x00\x00\x01\x00\x02\x10\x00\x00\x00\x00\x01\x00\x00\x00", 0x0000010); 19 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000010, 1000); 20 | usleep(4*1000); 21 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 22 | if (buf[6] == 1) { 23 | printf("initializing ...\n"); 24 | } 25 | else { 26 | printf("already initialized, no need to do it again\n"); 27 | exit(0); 28 | } 29 | usleep(5*1000); 30 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x01\x10\x01\x00\x00\x00", 0x000000c); 31 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 32 | usleep(1*1000); 33 | ret = usb_interrupt_read(devh, 0x00000083, buf, 0x0000008, 1000); 34 | usleep(4*1000); 35 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 36 | usleep(3*1000); 37 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 38 | usleep(5*1000); 39 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x04\x10\x02\x00\x00\x00", 0x000000c); 40 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 41 | usleep(4*1000); 42 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 43 | usleep(4*1000); 44 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 45 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x03\x10\x03\x00\x00\x00", 0x000000c); 46 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 47 | usleep(4*1000); 48 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 49 | memcpy(buf, "\x10\x00\x00\x00\x01\x00\x02\x10\x00\x00\x00\x00\x01\x00\x00\x00", 0x0000010); 50 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000010, 1000); 51 | usleep(6*1000); 52 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 53 | usleep(5*1000); 54 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x01\x10\x01\x00\x00\x00", 0x000000c); 55 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 56 | usleep(3*1000); 57 | ret = usb_interrupt_read(devh, 0x00000083, buf, 0x0000008, 1000); 58 | usleep(3*1000); 59 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 60 | usleep(4*1000); 61 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 62 | usleep(4*1000); 63 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x04\x10\x02\x00\x00\x00", 0x000000c); 64 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 65 | usleep(8*1000); 66 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 67 | usleep(4*1000); 68 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 69 | usleep(17*1000); 70 | memcpy(buf, "\x18\x00\x00\x00\x01\x00\x01\x92\x03\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x0000018); 71 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000018, 1000); 72 | usleep(10*1000); 73 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 74 | usleep(9*1000); 75 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 76 | usleep(10*1000); 77 | memcpy(buf, "\x18\x00\x00\x00\x01\x00\x01\x92\x04\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x0000018); 78 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000018, 1000); 79 | usleep(4*1000); 80 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 81 | usleep(4*1000); 82 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 83 | usleep(4*1000); 84 | memcpy(buf, "\x0c\x00\x00\x00\x01\x00\x02\x92\x05\x00\x00\x00", 0x000000c); 85 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x000000c, 1000); 86 | usleep(6*1000); 87 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 88 | usleep(7*1000); 89 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 90 | usleep(6*1000); 91 | memcpy(buf, "\x18\x00\x00\x00\x01\x00\x01\x92\x06\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0x0000018); 92 | ret = usb_bulk_write(devh, 0x00000001, buf, 0x0000018, 1000); 93 | usleep(4*1000); 94 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 95 | ret = usb_bulk_read(devh, 0x00000082, buf, 0x0000200, 1030); 96 | ret = usb_release_interface(devh, 0); 97 | assert(ret == 0); 98 | ret = usb_close(devh); 99 | assert(ret == 0); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /shutter.c: -------------------------------------------------------------------------------- 1 | /* This file is generated with usbsnoop2libusb.pl from a usbsnoop log file. */ 2 | /* Latest version of the script should be in http://iki.fi/lindi/usb/usbsnoop2libusb.pl */ 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "alphamote.h" 12 | 13 | void print_bytes(char *bytes, int len) { 14 | int i; 15 | if (len > 0) { 16 | for (i=0; i