Blame view

tests/ReceiveAndSendData/PC.c 5.9 KB
0d065eeb   root   Suite
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  #include <libusb-1.0/libusb.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <signal.h>
  #include <unistd.h>
  
  // arduino ID vendor and product
  #define ID_VENDOR 0x2341
  #define ID_PRODUCT 0x01
  #define ENDPOINTS_NUMBER 4
  #define TIMEOUT 50
  #define MAX_DATA 50
  
  void init(libusb_context **context, libusb_device ***devices, ssize_t *devices_count){
  	int status = libusb_init(context);
  	if(status != 0){perror("libusb_init"); exit(-1);}
  
  	*devices_count = libusb_get_device_list(*context, devices);
  	if(*devices_count < 0){perror("libusb_get_device_list"); exit(-1);}
  }
  
  libusb_device* searchArduino(libusb_device **devices, ssize_t devices_count){
  	for(int i=0; i<devices_count; i++){
  		libusb_device *device = devices[i];
  
  		// device description
  		struct libusb_device_descriptor desc;
  		int status = libusb_get_device_descriptor(device, &desc);
  		if(status != 0) continue;
  		
  		// search for device
  		if(desc.idVendor == ID_VENDOR
  				&& desc.idProduct == ID_PRODUCT)
  			return device;
  	}
  	return NULL;
  }
  
  void openConnection(libusb_device *arduino, libusb_device_handle **handle, struct libusb_config_descriptor **config_desc){
  	// open connection
  	int status = libusb_open(arduino, handle);
  	if(status != 0){ perror("libusb_open"); exit(-1); }
  	
  	// prepare config
  	status = libusb_get_config_descriptor(arduino, 0, config_desc);
  	if(status != 0){ perror("libusb_get_config_descriptor"); exit(-1); }
  	int configuration = (*config_desc)->bConfigurationValue;
  
  	// detach kernel
  	for(int j=0; j<(*config_desc)->bNumInterfaces; j++){
  		int interface = (*config_desc)->interface[j].altsetting[0].bInterfaceNumber;
  		if(libusb_kernel_driver_active(*handle, interface)){
  			status = libusb_detach_kernel_driver(*handle, interface);
  			if(status != 0){ perror("libusb_detach_kernel_driver"); exit(-1); }
  		}
  	}
  	
  	// use config
  	status = libusb_set_configuration(*handle, configuration);
  	if(status != 0){ perror("libusb_set_configuration"); exit(-1); }
  	
  	// claim interfaces
  	for(int j=0; j<(*config_desc)->bNumInterfaces; j++){
  		struct libusb_interface_descriptor interface_desc = (*config_desc)->interface[j].altsetting[0];
  		int interface = interface_desc.bInterfaceNumber;
  
  		status = libusb_claim_interface(*handle, interface);
  		if(status != 0){ perror("libusb_claim_interface"); exit(-1); }
  	}
  }
  
  void getEndpoints(struct libusb_config_descriptor *config_desc, struct libusb_endpoint_descriptor *endpoint_desc_list){
  	int count = 0;
  	// in interfaces
  	for(int j=0; j<config_desc->bNumInterfaces; j++){
  		// find endpoints
  		for(int k=0; k<config_desc->interface[j].altsetting[0].bNumEndpoints; k++){
  			if(count > ENDPOINTS_NUMBER){ printf("getEndpoints: Array out of bound :%d:", count); exit(-1); }
  			*(endpoint_desc_list + count) = config_desc->interface[j].altsetting[0].endpoint[k];
  			count++;
  		}
  	}
  	//if(count != ENDPOINTS_NUMBER){ printf("Wrong number of endpoints.\nIs this the good device ?\n"); exit(-1); }
  }
  
  void start(libusb_context **context, libusb_device ***devices, libusb_device_handle **handle, struct libusb_config_descriptor **config_desc, struct libusb_endpoint_descriptor *endpoint_desc_list){
  	// init
  	ssize_t devices_count;
  	init(context, devices, &devices_count);
  
  	// get arduino device
  	libusb_device *arduino = searchArduino(*devices, devices_count);
  	if(arduino == NULL){ printf("Arduino device not found\n"); exit(-1); }
  
  	// open connection, use config, detach kernel and claim interfaces
  	openConnection(arduino, handle, config_desc);
  
  	// get enpoints
  	getEndpoints(*config_desc, endpoint_desc_list);
  }
  
  void stop(struct libusb_config_descriptor *config_desc, libusb_device_handle *handle, libusb_device **devices, libusb_context *context){
  	// release interfaces
  	for(int j=0; j<config_desc->bNumInterfaces; j++){
  		struct libusb_interface_descriptor interface_desc = config_desc->interface[j].altsetting[0];
  		int interface = interface_desc.bInterfaceNumber;
  
  		int status = libusb_release_interface(handle, interface);
  		if(status != 0){ perror("libusb_release_interface"); exit(-1); }
  	}
  	
  	// free config
  	libusb_free_config_descriptor(config_desc);
  
  	// close connection
  	libusb_close(handle);
  
  	// free device list
  	libusb_free_device_list(devices, 1);
  
  	// libusb exit
  	libusb_exit(context);
  }
  
  void sendData(int endpoint_id, uint8_t data, libusb_device_handle *handle, struct libusb_endpoint_descriptor *endpoint_desc_list){
  	if(endpoint_id < 0 || endpoint_id > 1){ printf("(sendData) Wrong endpoint !\nMust be 0 or 1\n"); return; }
  	int status = libusb_interrupt_transfer(handle, endpoint_desc_list[endpoint_id].bEndpointAddress, (unsigned char *) &data, 1, NULL, TIMEOUT);
  	if(status!=0 && status!=LIBUSB_ERROR_TIMEOUT){ perror("libusb_interrupt_transfer"); exit(-1); }
  }
  
  int receiveData(int endpoint_id, uint8_t *data, libusb_device_handle *handle, struct libusb_endpoint_descriptor *endpoint_desc_list){
  	if(endpoint_id < 2 || endpoint_id > 3){ printf("(sendData) Wrong endpoint !\nMust be 2 or 3\n"); return -1; }
  	int status = libusb_interrupt_transfer(handle, endpoint_desc_list[endpoint_id].bEndpointAddress, (unsigned char *) data, 1, NULL, TIMEOUT);
  	if(status!=0 && status!=LIBUSB_ERROR_TIMEOUT){ perror("libusb_interrupt_transfer"); exit(-1); }
  	return status;
  }
  
  int go = 1;
  void signalINT(int sig){
  	if(sig == SIGINT){
  		go = 0;
  	}
  }
  int main(){
  	libusb_context *context;
  	libusb_device **devices;
  	libusb_device_handle *handle;
  	struct libusb_config_descriptor *config_desc;
  	struct libusb_endpoint_descriptor endpoint_desc_list[ENDPOINTS_NUMBER];
  
  	// start
  	printf("Starting...\n");
  	start(&context, &devices, &handle, &config_desc, endpoint_desc_list);
  	printf("Start complete\n");
  
  	// singals
  	struct sigaction action;
  	action.sa_handler = signalINT;
  	sigaction(SIGINT, &action, NULL);
  
  	uint8_t data;
  	while(go){
  		int status = receiveData(2, &data, handle, endpoint_desc_list);
  		if(status == 0)
  			sendData(0, data, handle, endpoint_desc_list);
  	}
  
  	// stop
  	printf("\nStopping...\n");
  	stop(config_desc, handle, devices, context);
  	printf("Stop complete...\n");
  }