1#include <stdio.h>
2#include "FinePix.h"
3
4/* Describes the hardware. */
5struct camera_hw {
6	unsigned long /*__u16*/ vendor;
7	unsigned long /*__u16*/ product;
8	/* Offical name of the camera. */
9	char name[32];
10};
11
12static struct camera_hw cam_supp[23] = {
13	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_4800_PID, "Fujifilm FinePix 4800"},
14	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A202_PID, "Fujifilm FinePix A202"},
15	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A203_PID, "Fujifilm FinePix A203"},
16	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A204_PID, "Fujifilm FinePix A204"},
17	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A205_PID, "Fujifilm FinePix A205"},
18	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A210_PID, "Fujifilm FinePix A210"},
19	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A303_PID, "Fujifilm FinePix A303"},
20	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_A310_PID, "Fujifilm FinePix A310"},
21	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_F401_PID, "Fujifilm FinePix F401"},
22	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_F402_PID, "Fujifilm FinePix F402"},
23	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_F410_PID, "Fujifilm FinePix F410"},
24	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_F601_PID, "Fujifilm FinePix F601"},
25	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_F700_PID, "Fujifilm FinePix F700"},
26	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_M603_PID, "Fujifilm FinePix M603"},
27	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_S3000_PID,
28	 "Fujifilm FinePix S3000"},
29	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_S304_PID, "Fujifilm FinePix S304"},
30	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_S5000_PID,
31	 "Fujifilm FinePix S5000"},
32	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_S602_PID, "Fujifilm FinePix S602"},
33	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_S7000_PID,
34	 "Fujifilm FinePix S7000"},
35
36	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_X1_PID,
37	 "Fujifilm FinePix unknown model"},
38	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_X2_PID,
39	 "Fujifilm FinePix unknown model"},
40	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_X3_PID,
41	 "Fujifilm FinePix unknown model"},
42	{USB_FUJIFILM_VENDOR_ID, USB_FINEPIX_X4_PID,
43	 "Fujifilm FinePix unknown model"},
44};
45
46FinePix::FinePix()
47{
48	fprintf(stderr, "FinePix::FinePix()\n");
49
50	// Initially we don't have a camera device opened.
51	camera = NULL;
52
53	// Start the roster that will wait for FinePix USB devices.
54	BUSBRoster::Start();
55}
56
57FinePix::~FinePix()
58{
59	fprintf(stderr, "FinePix: ~FinePix()\n");
60
61	BUSBRoster::Stop();
62}
63
64status_t FinePix::InitCheck()
65{
66	fprintf(stderr, "FinePix: InitCheck()\n");
67
68	if (camera != NULL)
69		return B_NO_ERROR;
70	else
71		return B_ERROR;
72}
73
74int FinePix::SetupCam()
75{
76	int ret; // Return value
77
78	fprintf(stderr, "FinePix: SetupCam()\n");
79
80	/* Reset bulk in endpoint */
81	camera->ControlTransfer (USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN,
82						 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, 0, NULL);
83
84	/* Reset the camera *//* Init the device */
85
86		unsigned char data[] = { 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 };
87
88		ret = camera->ControlTransfer(USB_REQTYPE_INTERFACE_OUT |USB_REQTYPE_CLASS ,
89										 USB_REQUEST_GET_STATUS, 0x00, 0x00, 12, data);
90
91		fprintf(stderr,"data: %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n",
92					data[0], data[1],data[2], data[3],data[4], data[5],
93					data[6], data[7],data[8], data[9],data[10], data[11]);
94
95		if (ret != 12) {
96			fprintf(stderr,"usb_control_msg failed (%d)\n", ret);
97			return 1;
98		}
99
100		unsigned char data3[MAX_BUFFER_SIZE];
101		ret = bulk_in->BulkTransfer(data3, MAX_BUFFER_SIZE);
102			fprintf(stderr,"BulkIn: %x, %x, %x, %x, %x, %x\n",
103					data3[0],data3[1],data3[2],data3[3],data3[4],data3[5]);
104
105		if (ret < 0) {
106			fprintf(stderr,"failed to read the result (%d)\n", ret);
107			//return 1;
108		}
109
110	/* Again, reset bulk in endpoints */
111	camera->ControlTransfer (USB_REQTYPE_STANDARD | USB_REQTYPE_ENDPOINT_IN,
112						 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, 0, 0, NULL);
113
114	return 0;
115}
116
117int FinePix::GetPic(uint8 *frame, int &total_size)
118{
119	fprintf(stderr, "FinePix: GetPic()\n");
120	int ret; // Return value
121
122	/* Request a frame */
123	fprintf(stderr,"request a frame\n");
124
125	unsigned char data2[] = { 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 };
126
127	ret = camera->ControlTransfer(USB_REQTYPE_INTERFACE_OUT |USB_REQTYPE_CLASS ,
128									 USB_REQUEST_GET_STATUS, 0x00, 0x00, 12, data2);
129
130	fprintf(stderr,"data: %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n",
131				data2[0], data2[1],data2[2], data2[3],data2[4], data2[5],
132				data2[6], data2[7],data2[8], data2[9],data2[10], data2[11]);
133
134	if (ret != 12)
135	{
136		fprintf(stderr,"usb_control_msg failed (%d)\n", ret);
137		return 1;
138	}
139
140	/* Read the frame */
141	int offset = 0;
142	total_size = 0;
143
144	do
145	{
146		fprintf(stderr,"reading part of the frame\n");
147
148		ret = bulk_in->BulkTransfer(&frame[offset], MAX_BUFFER_SIZE);
149
150		fprintf(stderr,"frame: %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x\n",
151			frame[offset+0], frame[offset+1],frame[offset+2], frame[offset+3],
152			frame[offset+4], frame[offset+5],frame[offset+6], frame[offset+7],
153			frame[offset+8], frame[offset+9],frame[offset+10], frame[offset+11]);
154
155		if (ret < 0) { //this doesn't help, if we have an error we hang at the transfer
156			fprintf(stderr,"failed to read (%d)\n", ret);
157
158			return 1;
159		}
160
161		offset += ret;
162		total_size += ret;
163
164		if (ret != MAX_BUFFER_SIZE) // not a full buffer, must be end of frame
165			break;
166	} while(1);
167
168	fprintf(stderr,"this frame was %d bytes\n", total_size);
169
170	return 0;
171}
172
173status_t FinePix::DeviceAdded(BUSBDevice *dev)
174{
175	fprintf(stderr, "FinePix: DeviceAdded()\n");
176
177	// Waits for FinePix devices.  When one is attached, configure it,
178	// so that we are ready to use it.
179
180	if (camera != NULL)
181		return B_ERROR;
182
183	int myCam = -1;
184	// Find the device in our hardware list
185	if (dev->VendorID() == USB_FUJIFILM_VENDOR_ID)
186	{
187		for (int j = 0; j < 23; j++) //TODO use a cleaner way to check j < cam_supp.count
188		{
189			if (cam_supp[j].product == dev->ProductID())
190			{
191				myCam = j;
192				break;
193			}
194		}
195	}
196
197	if (myCam >= 0)
198	{
199		fprintf(stderr, "Found cam: ");
200		fprintf(stderr, cam_supp[myCam].name);
201		fprintf(stderr, "\n");
202
203		if (dev->SetConfiguration(dev->ConfigurationAt(0)) == 0)
204		{
205			camera = dev;
206
207			//set endpoint
208			bulk_in = 0;
209
210			int num_epoints = camera->ActiveConfiguration()->InterfaceAt(0)->CountEndpoints();
211
212			fprintf(stderr, "CountEndpoints: %d\n", num_epoints);
213
214			for (int i = 0; i < num_epoints; i++)
215			{
216				if (camera->ActiveConfiguration()->InterfaceAt(0)->EndpointAt(i)->IsBulk())
217					if (camera->ActiveConfiguration()->InterfaceAt(0)->EndpointAt(i)->IsInput())
218						bulk_in = camera->ActiveConfiguration()->InterfaceAt(0)->EndpointAt(i);
219			}
220
221			if (bulk_in == 0)
222			{
223				fprintf(stderr, "bad endpoint");
224				return B_ERROR;
225			}
226
227			fprintf(stderr, "Successfully set configuration!\n");
228
229			return B_OK;
230		}
231		else
232			return B_ERROR;
233	}
234	else
235		return B_ERROR;
236}
237
238void FinePix::DeviceRemoved(BUSBDevice *dev)
239{
240	fprintf(stderr, "FinePix: DeviceRemoved()\n");
241
242	// If they remove our device, then we can't use it anymore.
243	if (dev == camera)
244		camera = NULL;
245}
246