Commit d029a016a5d77c731fce8d811d476617b80ddf35

Authored by achemin1
2 parents 8b438d9c 16cfb9bf

Merge branch 'configuration' into arduino

README.md
... ... @@ -10,8 +10,12 @@ Dossier src/ contenant les sources
10 10 Il faut installer les dépendances : libusb avec `apt-get install libusb-1.0`
11 11 Pour compiler il faut lancer la commande `make`
12 12  
  13 +Pour avoir un niveau haut de verbosité, on peut lancer la commande `make DEBUG=1`
  14 +
13 15  
14 16 ## Utiliser
15 17  
16   -Pour lancer les programmes ...
  18 +Pour lancer le programme principale, il faut exécuter bin/main.exe
  19 +
  20 +Les demo des questions se lancent avec `make demostep` (pour l'instant)
17 21  
... ...
.gitignore renamed to Software/.gitignore
Software/Makefile 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +BIN = bin
  2 +OBJ = obj
  3 +SRC = src
  4 +INCLUDE = include
  5 +CFLAGS =
  6 +CLIBS = -lusb-1.0 -I"C:\Program Files\zLib\libusb-1.0.23\include"
  7 +#sur le Windows d'Axel :
  8 +CLIBS := ${CLIBS} -B"C:\Program Files\zLib\libusb-1.0.23\MinGW32\static"
  9 +GNUMAKEFLAGS = --no-print-directory
  10 +
  11 +gcc = gcc
  12 +#sur le Windows d'Axel :
  13 +gcc := "/mnt/c/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/gcc.exe"
  14 +
  15 +
  16 +DEBUG?=0
  17 +ifeq ($(DEBUG), 0)
  18 + CFLAGS = -W -Wall
  19 +else
  20 + CFLAGS = -W -Wall -g -O0 -DDEBUG
  21 +endif
  22 +
  23 +
  24 +
  25 +all : main
  26 +
  27 +
  28 +version :
  29 + ${gcc} -v
  30 +
  31 +main : bin libusb_wrapper ${SRC}/main.c
  32 + ${gcc} -o ${OBJ}/$@.o -c ${SRC}/$@.c -I ${INCLUDE} ${CLIBS} ${CFLAGS}
  33 + ${gcc} -o ${BIN}/$@.exe ${OBJ}/main.o ${OBJ}/libusb_wrapper.o ${CFLAGS} ${CLIBS}
  34 +
  35 +demostep : main
  36 + ${BIN}/main.exe demo4.1
  37 +
  38 +libs: libusb_wrapper
  39 +
  40 +libusb_wrapper: obj ${SRC}/libusb_wrapper.c ${INCLUDE}/libusb_wrapper.h
  41 + ${gcc} -o ${OBJ}/$@.o -c ${SRC}/$@.c -I ${INCLUDE} ${CLIBS} ${CFLAGS}
  42 +
  43 +
  44 +
  45 +obj :
  46 + @-mkdir ${OBJ}
  47 +
  48 +bin :
  49 + @-mkdir ${BIN}
  50 +
  51 +clean :
  52 + rm -rf obj/*.o
  53 +
  54 +mrproper: clean
  55 + rm -rf bin
  56 + rm -rf obj
... ...
Software/hexToDec.sh 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +#!/bin/bash
  2 +
  3 +if [ $# -eq 1 ]; then
  4 + echo "obase=10; ibase=16; $1" | bc
  5 +else
  6 + echo "Type a hex number"
  7 + read hexNum
  8 + echo -n "The decimal value of $hexNum="
  9 + echo "obase=10; ibase=16; $hexNum" | bc
  10 +fi
... ...
Software/include/libusb_wrapper.h 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +#ifndef LIBUSB_WRAPPER_H_
  2 +#define LIBUSB_WRAPPER_H_
  3 +
  4 +#include <libusb-1.0/libusb.h>
  5 +#include <stdbool.h>
  6 +#include <stdio.h>
  7 +#include <stdlib.h>
  8 +
  9 +void usbinit(libusb_context **context_ptr);
  10 +void usbclose(libusb_context *context);
  11 +
  12 +void interfaceclaim(libusb_device_handle *handle,
  13 + struct libusb_interface *interface);
  14 +void interfaceclose(libusb_device_handle *handle,
  15 + struct libusb_interface *interface);
  16 +
  17 +ssize_t getListDevices(libusb_context *context, libusb_device ***list_ptr);
  18 +void getFromKernel(libusb_device_handle *handle, int interface);
  19 +
  20 +void displayDevices(libusb_context *context);
  21 +void displayDevicesMore(libusb_context *context);
  22 +
  23 +void getFirstDeviceFromID(libusb_context *context, int vid, int pid,
  24 + libusb_device **device);
  25 +
  26 +void getOurInterfaces(libusb_device *device,
  27 + struct libusb_interface **int_hidjoy,
  28 + struct libusb_interface **int_leds,
  29 + struct libusb_interface **int_vibrators);
  30 +
  31 +void displayDeviceEndpoints();
  32 +
  33 +char getOnlyEndpoint(struct libusb_interface *interface);
  34 +
  35 +#endif
... ...
Software/src/libusb_wrapper.c 0 → 100644
... ... @@ -0,0 +1,307 @@
  1 +#include "libusb_wrapper.h"
  2 +
  3 +void usbinit(libusb_context **context_ptr) {
  4 + // libusb_context *context;
  5 + int statusInit = libusb_init(context_ptr);
  6 + if (statusInit != LIBUSB_SUCCESS) {
  7 + perror("libusb_init");
  8 + exit(-1);
  9 + }
  10 +}
  11 +
  12 +void usbclose(libusb_context *context) { libusb_exit(context); }
  13 +
  14 +void interfaceclaim(libusb_device_handle *handle,
  15 + struct libusb_interface *interface) {
  16 + const struct libusb_interface_descriptor *interface_desc =
  17 + &interface->altsetting[0]; // TODO enlever cette ligne, refactor
  18 +
  19 + if (interface_desc->bInterfaceClass ==
  20 + LIBUSB_CLASS_VENDOR_SPEC) { // ON PEUT VERIFIER LA CLASS
  21 + printf("> vendor specific class\n");
  22 +
  23 + int status =
  24 + libusb_claim_interface(handle, interface_desc->bInterfaceNumber);
  25 + if (status != 0) {
  26 + perror("libusb_claim_interface");
  27 + exit(-1);
  28 + }
  29 + }
  30 +}
  31 +
  32 +void interfaceclose(libusb_device_handle *handle,
  33 + struct libusb_interface *interface) {
  34 + const struct libusb_interface_descriptor *interface_desc =
  35 + &interface->altsetting[0];
  36 + int status =
  37 + libusb_release_interface(handle, interface_desc->bInterfaceNumber);
  38 + if (status != 0) {
  39 + perror("libusb_release_interface");
  40 + exit(-1);
  41 + }
  42 +}
  43 +
  44 +// Si le méchant noyau est passé avant vous :
  45 +void getFromKernel(libusb_device_handle *handle,
  46 + int interface) { // private method for now
  47 + if (libusb_kernel_driver_active(handle, interface)) {
  48 + int statusKDriver = libusb_detach_kernel_driver(handle, interface);
  49 + if (statusKDriver != LIBUSB_SUCCESS) {
  50 + perror("libusb_detach_kernel_driver");
  51 + exit(-1);
  52 + }
  53 + }
  54 +}
  55 +
  56 +ssize_t getListDevices(libusb_context *context, libusb_device ***list_ptr) {
  57 + ssize_t count = libusb_get_device_list(context, list_ptr);
  58 + if (count < 0) {
  59 + perror("libusb_get_device_list");
  60 + exit(-1);
  61 + }
  62 + return count;
  63 +}
  64 +
  65 +void *_enumerateDevices(libusb_context *context,
  66 + void (*func)(libusb_device *device)) {
  67 + libusb_device **list;
  68 + ssize_t count = getListDevices(context, &list);
  69 +
  70 + ssize_t i = 0;
  71 + for (i = 0; i < count; i++) {
  72 + libusb_device *device = list[i];
  73 +
  74 + func(device);
  75 + }
  76 +
  77 + libusb_free_device_list(list, 1);
  78 +
  79 + return NULL; // DBGONLY TEMP
  80 +}
  81 +
  82 +// print readable string, not asked for tutoring
  83 +void _printConfig(libusb_device *device) { // private method
  84 + // Ouverture du périphérique
  85 + libusb_device_handle *handle;
  86 + int statusDevice = libusb_open(device, &handle);
  87 + if (statusDevice != LIBUSB_SUCCESS) {
  88 + perror("libusb_open");
  89 + // return; //exit(-1);
  90 + }
  91 +
  92 + int MAXLEN_DESCRIPTOR_STRING = 200;
  93 + uint8_t desc_idx = 2;
  94 + // uint16_t langid = 16;
  95 + unsigned char data[200];
  96 +
  97 + // TEST 16
  98 + for (desc_idx = 0; desc_idx < 16; desc_idx++) {
  99 + int statusAscii = libusb_get_string_descriptor_ascii(
  100 + handle, desc_idx, data, MAXLEN_DESCRIPTOR_STRING);
  101 + if (statusAscii == -9) // TEST seems to be LIBUSB_ERROR
  102 + break;
  103 + printf(" - Descriptor string : %s ; %i\n", data, statusAscii);
  104 + }
  105 +
  106 + libusb_close(handle);
  107 +}
  108 +
  109 +void _displayOneDevice(libusb_device *device) {
  110 + struct libusb_device_descriptor desc;
  111 +
  112 + int status = libusb_get_device_descriptor(device, &desc);
  113 + if (status != LIBUSB_SUCCESS) {
  114 + printf("Cannot get device desc : %s\n",
  115 + libusb_error_name(status)); // DBGONLY
  116 + perror("libusb_open");
  117 + return;
  118 + }
  119 +
  120 + uint8_t bus = libusb_get_bus_number(device);
  121 + uint8_t address = libusb_get_device_address(device);
  122 +
  123 + printf("Device Found @ (Bus:Address) %d:%d\n", bus, address);
  124 + printf("Vendor ID 0x0%x\n", desc.idVendor);
  125 + printf("Product ID 0x0%x\n", desc.idProduct);
  126 +
  127 + // displayDeviceEndpoints(device); //Not really work on Axel@Alptop
  128 +}
  129 +
  130 +void displayDevices(libusb_context *context) {
  131 + _enumerateDevices(context, _displayOneDevice);
  132 +}
  133 +
  134 +void _displayOneDeviceMore(libusb_device *device) {
  135 + _displayOneDevice(device);
  136 + _printConfig(device);
  137 +}
  138 +
  139 +void displayDevicesMore(libusb_context *context) {
  140 + _enumerateDevices(context, _displayOneDeviceMore);
  141 +}
  142 +
  143 +// get device from iteration (and not from not recommanded function :
  144 +// ugly using global vars ?? Cannot communicate between getFirstDeviceFromID and
  145 +// _getFirstDeviceFromID
  146 +int g_vid;
  147 +int g_pid;
  148 +libusb_device *g_device = NULL;
  149 +void _getFirstDeviceFromID(libusb_device *device) {
  150 + struct libusb_device_descriptor desc;
  151 +
  152 + int status = libusb_get_device_descriptor(device, &desc);
  153 + if (status != LIBUSB_SUCCESS) {
  154 + printf("Cannot get device desc : %s\n",
  155 + libusb_error_name(status)); // DBGONLY
  156 + perror("libusb_open");
  157 + return;
  158 + }
  159 +
  160 + if (desc.idVendor == g_vid && desc.idProduct == g_pid) {
  161 + g_device = device;
  162 + }
  163 +}
  164 +
  165 +void getFirstDeviceFromID(libusb_context *context, int vid, int pid,
  166 + libusb_device **device) {
  167 + g_vid = vid; // pass parameters for enumeration
  168 + g_pid = pid; // idem
  169 + _enumerateDevices(context, _getFirstDeviceFromID);
  170 + *device = g_device; // get return from enumeration
  171 +}
  172 +
  173 +// void getDevicesFromID(vid, pid) //return array
  174 +
  175 +void displayDeviceEndpoints(libusb_device_handle *handle) {
  176 + // recover pointer from handle
  177 + libusb_device *device;
  178 + device = libusb_get_device(handle);
  179 +
  180 + // lectures des configs => on prend la première configuration pour l'instant
  181 + /*int configuration = 0; // valueof("bConfigurationValue");
  182 + int statusConfig = libusb_set_configuration(handle, configuration);
  183 + if (statusConfig != LIBUSB_SUCCESS) {
  184 + perror("libusb_set_configuration");
  185 + return;
  186 + }*/
  187 +
  188 + // 4.2 configuration du périph usb
  189 + struct libusb_config_descriptor *config;
  190 + int statusFetchConfig = libusb_get_active_config_descriptor(device, &config);
  191 + if (statusFetchConfig != LIBUSB_SUCCESS) {
  192 + perror("libusb_get_active_config_descriptor");
  193 + return;
  194 + }
  195 +
  196 + // caractéristiques globales
  197 + printf("Config.bConfigurationValue : %d\n", config->bConfigurationValue);
  198 + printf("Config/ bLength:%d\nbDescriptorType:%d\nbNumInterfaces:%d\n",
  199 + config->bLength, config->bDescriptorType, config->bNumInterfaces);
  200 +
  201 + // itération des interfaces
  202 + printf("Itération de l'interface\n");
  203 + for (int indexInterface = 0; indexInterface < config->bNumInterfaces;
  204 + indexInterface++) {
  205 + printf("-indexInterface=%d\n", indexInterface);
  206 + printf("-Altsetting=%d\n",
  207 + config->interface[indexInterface].num_altsetting);
  208 +
  209 + const struct libusb_interface *interface =
  210 + &config->interface[indexInterface];
  211 +
  212 + // if 1 setting (or more)
  213 + if (interface->num_altsetting != 0) {
  214 + const struct libusb_interface_descriptor *interface_desc =
  215 + &interface->altsetting[0];
  216 +
  217 + printf("--bNumEndpoints=%d\n", interface_desc->bNumEndpoints);
  218 + printf("--bDescriptorType=%d\n", interface_desc->bDescriptorType);
  219 +
  220 + for (int indexEndpoints = 0;
  221 + indexEndpoints < interface_desc->bNumEndpoints; indexEndpoints++) {
  222 + const struct libusb_endpoint_descriptor *endpoint_desc =
  223 + &interface_desc->endpoint[indexEndpoints];
  224 + printf("---bDescriptorType=%d\n", endpoint_desc->bDescriptorType);
  225 + printf("---bEndpointAddress=%d\n", endpoint_desc->bEndpointAddress);
  226 +
  227 + if (endpoint_desc->extra != NULL)
  228 + printf("---extra: %s\n", endpoint_desc->extra);
  229 + if (endpoint_desc->bmAttributes ==
  230 + LIBUSB_TRANSFER_TYPE_INTERRUPT) // TODO AJOUT MASQUE ? (voir doc)
  231 + printf("---is of type INTERRUPT\n");
  232 + }
  233 + }
  234 +
  235 + // Affichez l’indice et le numéro de chaque interface détectée et réclamée.
  236 + // Affichez aussi les points d’accès trouvés en précisant ceux sauvés.
  237 +
  238 + /*
  239 + //int interface=valueof("bInterfaceNumber");
  240 + int
  241 + status=libusb_claim_interface(handle,interface->bInterfaceNumber);
  242 + if(status!=0){ perror("libusb_claim_interface"); exit(-1); }
  243 +
  244 + status=libusb_release_interface(handle,interface->bInterfaceNumber);
  245 + if(status!=0){ perror("libusb_release_interface"); exit(-1); }
  246 +
  247 + //claim_interface(.., config interface altsetting bInterfaceNumber
  248 + //config interface altsetting endpoint bmAttributes ==
  249 + LIBUSB_TRANSFER_TYPE_INTERRUPT
  250 + //add des enpoint unint8_t*/
  251 +
  252 + // DESCRIPTOR.C /.H :décommenter
  253 +
  254 + // IL FAUT RELEASE UNIQUEMENT LES INTERFACES QUI NE SONT PAS DES HID
  255 + }
  256 +
  257 + printf("\n");
  258 +
  259 + libusb_close(handle);
  260 +}
  261 +
  262 +void getOurInterfaces(libusb_device *device,
  263 + struct libusb_interface **int_hidjoy,
  264 + struct libusb_interface **int_leds,
  265 + struct libusb_interface **int_vibrators) {
  266 + struct libusb_config_descriptor *config;
  267 + int statusFetchConfig = libusb_get_active_config_descriptor(device, &config);
  268 + if (statusFetchConfig != LIBUSB_SUCCESS) {
  269 + perror("libusb_get_active_config_descriptor");
  270 + return;
  271 + }
  272 +
  273 + // itération des interfaces
  274 + for (int indexInterface = 0; indexInterface < config->bNumInterfaces;
  275 + indexInterface++) {
  276 +
  277 + const struct libusb_interface *interface =
  278 + &config->interface[indexInterface];
  279 +
  280 + // todo use le descriptor pour avoir bInterfaceNumber?
  281 + if (indexInterface == 0) {
  282 + *int_hidjoy = (struct libusb_interface *)interface;
  283 + } else if (indexInterface == 1) {
  284 + *int_leds = (struct libusb_interface *)interface;
  285 + } else if (indexInterface == 2) {
  286 + *int_vibrators = (struct libusb_interface *)interface;
  287 + }
  288 +
  289 + //#define pour les indices correspondants aux interfaces
  290 + // variables globales
  291 + }
  292 +}
  293 +
  294 +char getOnlyEndpoint(struct libusb_interface *interface) {
  295 +
  296 + const struct libusb_interface_descriptor *interface_desc =
  297 + &interface->altsetting[0];
  298 +
  299 + const struct libusb_endpoint_descriptor *endpoint_desc =
  300 + &interface_desc->endpoint[0];
  301 +
  302 + if (endpoint_desc->bmAttributes !=
  303 + LIBUSB_TRANSFER_TYPE_INTERRUPT) // ON PEUT VERIFIER LE TRANSFER TYPE
  304 + printf("> is NOT of type INTERRUPT\n");
  305 +
  306 + return (char)endpoint_desc->bEndpointAddress;
  307 +}
... ...
Software/src/main.c 0 → 100644
... ... @@ -0,0 +1,132 @@
  1 +#include "libusb_wrapper.h"
  2 +#include <stdio.h>
  3 +#include <string.h>
  4 +
  5 +#define VID 1003
  6 +#define PID 8259
  7 +
  8 +int main(int argc, char *argv[]) {
  9 + printf("Hello World :-|\n");
  10 +
  11 + libusb_context *context;
  12 + usbinit(&context);
  13 +#ifdef DEBUG
  14 + libusb_set_option(context, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
  15 +#endif
  16 +
  17 + if (argc > 1) {
  18 + // command mode
  19 + if (strcmp(argv[1], "demo4.1") == 0) { // if 4.1
  20 + printf("\e[91mDemo 4.1\e[39m\n");
  21 + displayDevices(context);
  22 + } else if (strcmp(argv[1], "demo4.1plus") == 0) { // if 4.1 bonus
  23 + printf("\e[91mDemo 4.1\e[39m\n");
  24 + displayDevicesMore(context);
  25 + } else if (strcmp(argv[1], "demo4.2") == 0) { // if 4.2
  26 + printf("\e[91mDemo 4.2\e[39m\n");
  27 +
  28 + if (argc > 3) {
  29 + uint16_t vendor_id;
  30 + uint16_t product_id;
  31 + sscanf(argv[2], "%hu", &vendor_id);
  32 + sscanf(argv[3], "%hu", &product_id);
  33 +
  34 + libusb_device_handle *handle;
  35 + handle =
  36 + libusb_open_device_with_vid_pid(context, vendor_id, product_id);
  37 + if (handle != NULL) {
  38 + printf("Show endpoints of VID:%hu;PID:%hu\n", vendor_id, product_id);
  39 + displayDeviceEndpoints(handle);
  40 + } else {
  41 + printf("Error while getting handle of VID:%hu;PID:%hu\n", vendor_id,
  42 + product_id);
  43 + }
  44 + } else {
  45 + printf("Error, need VID and PID\n");
  46 + }
  47 + } else {
  48 + printf("Wrong command\n");
  49 + }
  50 +
  51 + } else {
  52 + // interactive mode
  53 + printf("Welcome to interactive mode\n");
  54 + printf("Compiled for VID:PID => %d:%d\n", VID, PID);
  55 +
  56 + // Find the device
  57 + printf("Iterate list of devices, and getting the right one\n");
  58 + libusb_device *device = NULL;
  59 + getFirstDeviceFromID(context, VID, PID, &device);
  60 + // code
  61 + if (device == NULL) {
  62 + printf("Error : cannot find the device !\n");
  63 + return 1;
  64 + }
  65 +
  66 + // take the handle
  67 + libusb_device_handle *device_handle = NULL;
  68 + if (libusb_open(device, &device_handle) != 0) {
  69 + printf("Error : cannot handle the device\n");
  70 + return 1;
  71 + }
  72 +
  73 + // Take the interfaces
  74 + printf("\nSearch for interfaces\n");
  75 + struct libusb_interface *int_hidjoy = NULL;
  76 + struct libusb_interface *int_leds = NULL;
  77 + struct libusb_interface *int_vibrators = NULL;
  78 + getOurInterfaces(device, &int_hidjoy, &int_leds, &int_vibrators);
  79 +
  80 + // Claim interface
  81 + printf("\nClaim interfaces ...\n");
  82 + printf("-Leds\n");
  83 + interfaceclaim(device_handle, int_leds);
  84 + printf("-Vibrators\n");
  85 + interfaceclaim(device_handle, int_vibrators);
  86 +
  87 + // récupération des endpoints
  88 + printf("\nRécupération endpoints\n");
  89 + printf("-Leds");
  90 + int endpoint_leds =
  91 + getOnlyEndpoint(int_leds); /* ID of endpoint (bit 8 is 0) */
  92 + printf(" is %d\n", endpoint_leds);
  93 + printf("-Vibrators");
  94 + int endpoint_vibrators =
  95 + getOnlyEndpoint(int_vibrators); /* ID of endpoint (bit 8 is 0) */
  96 + printf(" is %d\n", endpoint_vibrators);
  97 +
  98 + /*LE CODE UTILE*/
  99 + int i;
  100 + for(i = 0 ; i<5 ; i++) {
  101 + unsigned char data[2] = {0xff, 0xff}; // data to send or to receive
  102 + int size = 2; // size to send or maximum size to receive
  103 + int timeout = 1000; // timeout in ms
  104 +
  105 + // OUT interrupt, from host to device
  106 + int bytes_out;
  107 + printf("%p %02X\n", device_handle, endpoint_leds);
  108 + int status = libusb_interrupt_transfer(device_handle, endpoint_leds, data,
  109 + size, &bytes_out, timeout);
  110 + if (status != 0) {
  111 + perror("libusb_interrupt_transfer");
  112 + exit(-1);
  113 + }
  114 +
  115 + //sleep(1); demande l'ajout de macro pour la portabilité
  116 + }
  117 + /*FIN DU CODE UTILE*/
  118 +
  119 + // Close
  120 + printf("\nUnclaim interfaces ...\n");
  121 + printf("-Leds\n");
  122 + interfaceclose(device_handle, int_leds);
  123 + printf("-Vibrators\n");
  124 + interfaceclose(device_handle, int_vibrators);
  125 +
  126 + printf("Finished\n");
  127 + }
  128 +
  129 + usbclose(context);
  130 +
  131 + return 0;
  132 +}
... ...