Browse Source

Import upstream version 1.1.0

Paulo Gouveia 5 years ago
commit
4f02f4a2dc

+ 10 - 0
.gitignore

@@ -0,0 +1,10 @@
+hidapi/
+Release/
+Debug/
+release/
+debug/
+*.swp
+*.bak
+*.o
+.directory
+bin/ykushcmd

+ 21 - 0
LICENSE.md

@@ -0,0 +1,21 @@
+ Copyright (c) 2016 Yepkit Lda
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+

+ 23 - 0
Makefile

@@ -0,0 +1,23 @@
+CUR_PATH = $(shell echo $(PWD))
+OBJS = $(addprefix ykushcmd/objs/,ykushcmd.o commandParser.o usbcom.o)
+LIBS = -lhidapi-libusb -lusb-1.0 -ludev
+LOADPATHS = -L$(CUR_PATH)/ykushcmd/linux
+PREPROCESSOR_DEFS = -DLINUX
+CPP = g++
+
+ykushcmd : $(OBJS)
+	$(CPP) $(LOADPATHS) -o bin/ykushcmd $(OBJS) $(LIBS)
+
+
+ykushcmd/objs/ykushcmd.o : ykushcmd/ykushcmd.cpp ykushcmd/commandParser.h
+	$(CPP) $(PREPROCESSOR_DEFS) -c ykushcmd/ykushcmd.cpp -o ykushcmd/objs/ykushcmd.o
+
+ykushcmd/objs/commandParser.o : ykushcmd/commandParser.cpp ykushcmd/commandParser.h ykushcmd/usbcom.h 
+	$(CPP) $(PREPROCESSOR_DEFS) -c ykushcmd/commandParser.cpp -o ykushcmd/objs/commandParser.o
+
+ykushcmd/objs/usbcom.o : ykushcmd/usbcom.cpp ykushcmd/linux/hidapi.h ykushcmd/usbcom.h
+	$(CPP) $(PREPROCESSOR_DEFS) -c ykushcmd/usbcom.cpp -o ykushcmd/objs/usbcom.o
+
+clean :
+	rm -f bin/ykushcmd $(OBJS)
+

+ 157 - 0
README.md

@@ -0,0 +1,157 @@
+# YKUSH Command Application
+
+
+Control application for Yepkit YKUSH Switchable USB Hub board.
+
+
+Description
+===========
+
+Console application developed to illustrate the programmatic control of YKUSH capabilities.
+It executes one command per run, being appropriate to be executed as a console command.
+But it can be easily adapted to execute a work-flow with multiple commands and we encourage you to alter it to best fit your needs.
+
+The core of the application is consolidated in two source code files, the *commandParser.cpp* and the *usbcom.cpp*.
+The first contains the work-flow control and the second the communication functions.
+
+The implementation makes use of hidapi open-source library which is portable across several operating systems.
+We include a Visual Studio solution file for building on Windows. For Linux we include a build and installation script, `build.sh` and `install.sh` respectively, for building and installing the application. 
+
+Note that hidapi is not included in the source code package and has to be obtained beforehand. For Linux, if the
+`build.sh` script is used, to build the application, it will take care of downloading and building the hidapi library for you. In Windows this step has to
+be manually performed by the user.
+
+
+Licensing
+=========
+
+The source code is licensed under MIT license. 
+Refer to [LICENSE](LICENSE.md) file.
+
+
+Building
+========
+
+The steps for building on Windows and Linux are detailed bellow.
+
+Windows
+-------
+
+Before building the application from source on Windows you need to get the [hidapi library](http://www.signal11.us/oss/hidapi/) and build it.
+Follow the instructions in the hidapi documentation for building the library in the several systems. 
+
+After building the hidapi library you need to include the relevant hidapi files to *ykushcmd* project. 
+
+Copy to `ykush\ykushcmd\windows\` the following hidapi library files:
+- hidapi.dll
+- hidapi.exp
+- hidapi.lib
+
+
+Open the `ykush\ykush.sln` with Microsoft Visual Studio and build the solution.
+After a successful build process the executable file will be created in the`ykush\bin\` folder.
+
+The next step is to make the dynamically linked library accessible to executable.
+We can install the `hidapi.dll` in the system or ensure that a copy of the file is in the same folder than the `ykush.exe`.
+
+
+Linux
+-----
+
+The easiest way to build the application on Linux is to use the `build.sh` script which is in the `ykush/` folder.
+Nonetheless the application can be built running make and using the provided Makefile directly, but it will require
+some prior manual configuration detailed ahead. 
+
+To build the application using the scripts run the following inside the `ykush/` folder.
+```
+./build.sh
+```
+Note that the script requires Internet connectivity to fetch the latest version of hidapi library.
+
+Some dependencies may not have been satisfied and some additional systems components and utilities may be required.
+If that was the case please install them and re-run the script. 
+
+After a successful build process you can install the ykush command in the system. To do so, in `ykush/` folder run:
+```
+sudo ./install.sh
+```
+
+After install, the `ykush` command is ready for use.
+
+
+On the other hand, if you want to build running make directly with the provided Makefile do the following.
+
+First get the [hidapi library](http://www.signal11.us/oss/hidapi/) and build it.
+Please follow the instructions in the hidapi documentation for building the library in the several systems. 
+
+After building the hidapi library include the relevant hidapi files to *ykushcmd* project. 
+
+Copy to `ykush/ykushcmd/linux/` the `libhidapi-hidraw.so` and the `libhidapi-libusb.so` files from hidapi library you
+just built.
+
+Now add the following lines to the `platformdefs.h` file which is in the `ykush/ykushcmd/` folder.
+```
+#ifndef PLATFORMDEFS_H
+#define PLATFORMDEFS_H
+#define LINUX
+#endif
+```
+
+
+Next, in the `ykush/` folder run `make` to build the application.
+If the build process is successful the ykush executable will be created in the `ykush/bin/` folder.
+
+The next step is to make the shared library accessible to the executable.
+Do this by installing the *libhidapi-hidraw.so* or the *libhidapi-libusb.so*, depending if the hidraw or the libusb back-end is to be used (in doubt install both), in a system folder (e.g., /usr/lib/) or set the environment variable *LD_LIBRARY_PATH* with the path to the library files. 
+Alternatively you can run the script `install.sh` which is located in the `ykush/` folder.
+
+
+Using it
+========
+
+Windows
+-------
+Navigate to the `ykush\bin\` folder and run `ykush.exe -h` to print all the available command options a syntax.
+
+Let's look at some command examples.
+
+Assuming that just one YKUSH board is connected to our host, if we wanted to turn **OFF** the downstream port 1 we would issue the following command.
+```
+ykushcmd.exe -d 1
+```
+
+Similarly, if we wanted to turn the downstream 1 back **ON** we would issue the following command.
+```
+ykushcmd.exe -u 1
+```
+
+Assuming that two YKUSH boards are connected to our host and we wanted to turn **OFF** the downstream port 1 of one specific board. 
+To accomplish this we need to address the command by the YKUSH board **serial number**. 
+To find out the boards serial number we can issue the following command.
+```
+ykushcmd.exe -l
+```
+This will print the serial number of all YKUSH boards attached to the host.
+Assuming the our board had the serial number YK1234567, we would issue the following command.
+```
+ykushcmd.exe -s YK1234567 -d 1
+```
+This would turn **OFF** the downstream port 1 of the board with the serial number YK12345.
+
+
+Linux
+-----
+For Linux the command options and syntax are the same with the slight difference that the executable file does not have the `.exe` extension.
+Also depending of your user permissions you may need to precede the command with the *sudo* directive (e.g, `sudo ykushcmd -d 1`).
+
+
+For more information and resources for the YKUSH board please visit the [yepkit website ykush page](https://www.yepkit.com/products/ykush).
+
+
+
+
+
+
+
+
+

+ 0 - 0
bin/placeholder


+ 29 - 0
build.sh

@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# YKUSH command application build script
+
+rm -rf hidapi
+
+echo "Checking for git..."
+command -v git >/dev/null 2>&1 || { echo >&2 "Git is required and is not installed. Aborting."; exit 1; }
+
+echo "Fetching latest version of hidapi..."
+git clone git://github.com/signal11/hidapi.git
+
+echo "Building hidapi..."
+make --directory=hidapi/linux -f Makefile-manual
+cp -fv hidapi/linux/libhidapi-hidraw.so ykushcmd/linux/
+
+make --directory=hidapi/libusb -f Makefile-manual
+cp -fv hidapi/libusb/libhidapi-libusb.so ykushcmd/linux/
+
+echo "Configuring ykush app files..."
+
+echo "#ifndef PLATFORMDEFS_H" > ykushcmd/platformdefs.h
+echo "#define PLATFORMDEFS_H" >> ykushcmd/platformdefs.h
+echo "#define LINUX" >> ykushcmd/platformdefs.h
+echo "#endif" >> ykushcmd/platformdefs.h
+
+echo "Building ykush command..."
+make
+

+ 12 - 0
install.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+
+echo installing ykush command...
+sudo cp -f bin/ykushcmd /usr/bin
+
+echo installing shared libraries...
+sudo cp -f ykushcmd/linux/libhidapi-hidraw.so /usr/lib/libhidapi-hidraw.so
+sudo cp -f ykushcmd/linux/libhidapi-hidraw.so /usr/lib/libhidapi-hidraw.so.0
+
+sudo cp -f ykushcmd/linux/libhidapi-libusb.so /usr/lib/libhidapi-libusb.so
+sudo cp -f ykushcmd/linux/libhidapi-libusb.so /usr/lib/libhidapi-libusb.so.0
+

+ 28 - 0
ykush.sln

@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.23107.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ykushcmd", "ykushcmd\ykushcmd.vcxproj", "{C8815452-C975-41CE-8E08-E12E7E488901}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Debug|x64.ActiveCfg = Debug|x64
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Debug|x64.Build.0 = Debug|x64
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Debug|x86.ActiveCfg = Debug|Win32
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Debug|x86.Build.0 = Debug|Win32
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Release|x64.ActiveCfg = Release|x64
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Release|x64.Build.0 = Release|x64
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Release|x86.ActiveCfg = Release|Win32
+		{C8815452-C975-41CE-8E08-E12E7E488901}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 268 - 0
ykushcmd/commandParser.cpp

@@ -0,0 +1,268 @@
+/****************************************************************************
+ FileName:      commandParser.cpp
+ Dependencies:  See INCLUDES section
+ Compiler:      Visual Studio Community 2015
+ Company:       Yepkit, Lda.
+
+ Software License Agreement:
+
+ Copyright (c) 2015 Yepkit Lda
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*****************************************************************************
+ File Description:
+
+    Change History:
+        Rev     Date            Description
+        ----    -----------     -----------------------------------------
+        1.0     2015-09-11      First Release
+
+
+ ****************************************************************************
+ *  Summary:
+ *      Main program function
+ *
+ *
+ *
+*****************************************************************************/
+
+
+// INCLUDES ---------------------------------------------------------------
+
+#include <cstdlib>
+#include <iostream>
+#include <stdio.h>
+
+#include "stdafx.h"
+#include "commandParser.h"
+#include "usbcom.h"
+
+using namespace std;
+
+
+
+enum cmdAction {
+    PORT_UP,
+    PORT_DOWN,
+    LIST_DEVICES,
+    DISPLAY_SERIAL_NUMBER,
+    GET_PORT_STATUS,
+    PRINT_HELP,
+};
+
+bool bySerial = false;
+
+
+
+int commandParser(int argc, char** argv) {
+
+  	char choice;
+  	char cmd = 0x00;
+	enum cmdAction action = PRINT_HELP;
+	char *iSerial=NULL;
+    char response;
+    char port = 0;
+
+  	if ( argc <= 1){
+		printUsage(argv[0]);
+		return 0;
+    	}
+
+	
+  	//Parse input options and define action
+	switch (argc) {
+		case 2:
+			if ((argv[1][0]=='-') && (argv[1][1]=='l')) {
+				action = LIST_DEVICES;
+			} else {
+				action = PRINT_HELP;
+			}
+			break;
+		case 3:
+			// Single Option
+			if ((argv[1][0] == '-') && (argv[1][1]=='d')) {
+				action = PORT_DOWN;
+				port = argv[2][0];
+			} else if ((argv[1][0] == '-') && (argv[1][1]=='u')) {
+				action = PORT_UP;
+				port = argv[2][0];
+			} else if ((argv[1][0] == '-') && (argv[1][1]=='g')) {
+				action = GET_PORT_STATUS;
+				port = argv[2][0];
+			} else {
+				action = PRINT_HELP;
+			} 	
+			break;
+
+		case 5:
+			// Two Options
+			if ((argv[1][0] == '-') && (argv[1][1]=='s')) {
+				bySerial = true;
+				iSerial = argv[2];	
+			}
+			if ((argv[3][0] == '-') && (argv[3][1]=='d')) {
+				action = PORT_DOWN;
+				port = argv[4][0];
+			} else if ((argv[3][0] == '-') && (argv[3][1]=='u')) {
+				action = PORT_UP;
+				port = argv[4][0];
+			} else if ((argv[3][0] == '-') && (argv[3][1]=='g')) {
+				action = GET_PORT_STATUS;
+				port = argv[4][0];
+			} else {
+				action = PRINT_HELP;
+			}
+			break;
+
+		default:
+			printUsage(argv[0]);
+			break;
+	}
+
+
+
+	//Get options values and execute action
+	
+	if ( action == PORT_DOWN || action == PORT_UP ) {
+		switch(port) {
+			case '1':
+				// Downstream 1 down
+				cmd = 0x01;
+				break;
+
+			case '2':
+				// Downstream 2 down
+				cmd = 0x02;
+				break;
+
+			case '3':
+				// Downstream 3 down
+				cmd = 0x03;
+				break;
+
+			case 'a':
+				// All downstreams down
+				cmd = 0x0a;
+				break;
+
+			default:
+				printUsage(argv[0]);
+				return -1;
+				break;
+		}
+
+		// PORT_UP has 0x11 - 0x1a, while PORT_DOWN has 0x01 - 0x0a
+		if ( action == PORT_UP )
+			cmd += 0x10;
+
+		if (bySerial)
+			commandBySerial(iSerial, cmd);
+		else
+			command(cmd);
+	}
+
+	if (action == GET_PORT_STATUS && port == 'a') {
+		char cmds[3] = { 0x21, 0x22, 0x23 };
+		char resps[3];
+		int i;
+
+		if (bySerial)
+			commandsBySerial(iSerial, cmds, resps, 3);
+		else
+			commands(cmds, resps, 3);
+
+		for (i = 0; i < 3; i++) {
+			response = resps[i] + 0x20 - cmds[i];
+			if (response == 0x10 + cmd) {
+				printf("Downstream port %d is: UP\n", i+1);
+			} else if (response == cmd) {
+				printf("Downstream port %d is: DOWN\n", i+1);
+			} else {
+				printf("Downstream port %d is: UNKNOWN\n", i+1);
+			}
+		}
+	} else if (action == GET_PORT_STATUS) {
+		switch (port) {
+			case '1':
+				//downstream 1 status
+				cmd = 0x1;
+				break;
+			case '2':
+				//downstream 2 status
+				cmd = 0x2;
+				break;
+			case '3':
+				//downstream 3 status
+				cmd = 0x3;
+				break;
+			default:
+				printUsage(argv[0]);
+				return -1;
+				break;
+		}
+
+		if (bySerial) //target board specified by serial number
+			response = commandBySerial(iSerial,cmd + 0x20);
+		else
+			response = command(cmd + 0x20);
+
+		if (response == 0x10 + cmd) {
+			printf("\nDownstream port %c is: UP\n", port);
+		} else if (response == cmd) {
+			printf("\nDownstream port %c is: DOWN\n", port);
+		} else {
+			printf("\nUnable to get port status for port %c\n", port);
+		}
+	}
+
+
+	
+	if ( action == LIST_DEVICES ) {
+		printf("\nAttached YKUSH Boards\n");
+        	printf("\n---------------------\n");
+        	listDevices();
+	}
+
+
+	if ( action == PRINT_HELP ) {
+		printUsage(argv[0]);
+	}
+
+
+    return 0;
+}
+
+
+
+int printUsage(char* execName){
+
+    printf("\n-------------------");
+    printf("\n\tUsage:\n");
+    printf("-------------------\n");
+    printf("\n%s -d downstream_number \t\tTurns DOWN the downstream port with the number downstream_number\n", execName);
+    printf("\n%s -u downstream_number \t\tTurns UP the downstream port with the number downstream_number\n", execName);
+    printf("\n%s -g downstream_number \t\tObtains the switching status of port with the number downstream_number\n", execName);
+    printf("\n%s -l \t\t\t\tLists all currently attached YKUSH boards\n", execName);
+    printf("\n%s -s serial_number -d downstream_number \tTurns DOWN the downstream port with the number downstream_number for the board with the specified serial number\n", execName);
+    printf("\n%s -s serial_number -u downstream_number \tTurns UP the downstream port with the number downstream_number for the board with the specified serial number\n\n\n", execName);
+    printf("\n%s -s serial_number -g downstream_number \tObtains the switching status of port with the number downstream_number for the board with the specified serial number\n\n\n", execName);
+
+    return 0;
+}

+ 8 - 0
ykushcmd/commandParser.h

@@ -0,0 +1,8 @@
+#ifndef COMMANDPARSER_H
+#define COMMANDPARSER_H
+
+int commandParser(int argc, char** argv);
+
+int printUsage(char*);
+
+#endif // COMMANDPARSER_H

+ 0 - 0
ykushcmd/objs/placeholder


+ 4 - 0
ykushcmd/platformdefs.h

@@ -0,0 +1,4 @@
+#ifndef PLATFORMDEFS_H
+#define PLATFORMDEFS_H
+#define LINUX
+#endif

+ 8 - 0
ykushcmd/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// ykushcmd.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file

+ 17 - 0
ykushcmd/stdafx.h

@@ -0,0 +1,17 @@
+
+#include "platformdefs.h"
+
+#ifndef LINUX
+#pragma once
+
+#include "targetver.h"
+#include <tchar.h>
+
+#endif
+
+#include <stdlib.h>
+#include <string>
+#include <stdio.h>
+
+
+

+ 8 - 0
ykushcmd/targetver.h

@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>

+ 338 - 0
ykushcmd/usbcom.cpp

@@ -0,0 +1,338 @@
+/****************************************************************************
+ FileName:      usbcom.cpp
+ Dependencies:  See INCLUDES section
+ Compiler:      Visual Studio Community 2015
+ Company:       Yepkit, Lda.
+
+ Software License Agreement:
+
+ Copyright (c) 2015 Yepkit Lda
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*****************************************************************************
+ File Description:
+
+    Change History:
+        Rev     Date            Description
+        ----    -----------     -----------------------------------------
+        1.0     2015-09-11      First Release
+
+
+ ****************************************************************************
+ *  Summary:
+ *
+ *  Functions that communicate with the YKUSH board and/or provide
+ *  status information.
+ *
+*****************************************************************************/
+
+
+
+//-------------------------------------------------------------------------
+// INCLUDES
+//-------------------------------------------------------------------------
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include "stdafx.h"
+
+#ifndef LINUX
+	#include "windows\hidapi.h"
+#else
+	#include "linux/hidapi.h"
+#endif
+
+#include "usbcom.h"
+
+
+using namespace std;
+
+
+//-------------------------------------------------------------------------
+// DEFINES
+//-------------------------------------------------------------------------
+#define VERSION "0.1.0"
+#define VENDOR_ID 0x04D8
+#define PRODUCT_ID 0xF2F7
+#define OLD_PRODUCT_ID 0x0042
+
+
+
+
+/**************************************************************************
+ * listDevices() - List YKUSH Devices Serial Number
+ *-------------------------------------------------------------------------
+ *
+ * This function prints the iSerial of the
+ * attached YKUSH devices.
+ *
+ **************************************************************************/
+int listDevices() {
+
+    	// Enumerate and print the YKUSH devices on the system
+        
+        hid_device *handle;
+    	struct hid_device_info *devs, *cur_dev;
+
+    	devs = hid_enumerate(0x0, 0x0);
+    	if (devs == NULL) {
+            //APAGAR
+            // Limited Legaccy firmware support (does not work in all systems)
+            //handle = hid_open(VENDOR_ID, OLD_PRODUCT_ID, NULL);
+            //FIM APAGAR
+            if (handle == NULL){
+                // No HID devices found
+                printf("\nNo HID USB devices connected to this Host\n");
+            }
+
+    	}
+
+    	cur_dev = devs;
+    	while (cur_dev) {
+        	if ((cur_dev->vendor_id == VENDOR_ID) && (cur_dev->product_id == PRODUCT_ID)) {
+            		printf("YKUSH device found with Serial Number: %ls", cur_dev->serial_number);
+            		printf("\n");
+            		printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
+            		printf("  Product:      %ls\n", cur_dev->product_string);
+            		printf("\n");
+        	} else if ((cur_dev->vendor_id == VENDOR_ID) && (cur_dev->product_id == OLD_PRODUCT_ID)) {
+                    printf("YKUSH device found with Serial Number: %ls", cur_dev->serial_number);
+            		printf("\n");
+            		printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
+            		printf("  Product:      %ls\n", cur_dev->product_string);
+                    printf("  NOTE: This is an old version of the firmware. If you have access to a PIC programmer contact Yepkit to get the latest version of the firmware.");
+            		printf("\n");
+            }
+
+        	cur_dev = cur_dev->next;
+    	}
+    	hid_free_enumeration(devs);
+    
+	return 0;
+}
+
+
+
+/*******************************************************************************
+ * commandsBySerial(char* iSerial, char *cmd, char* resp, int num) - Sends commands to YKUSH board
+ * -----------------------------------------------------------------------------
+ *
+ * Description:
+ *
+ * 	All commands in the cmd array are send to the YKUSH board and the
+ * 	response bytes are stored in the matching resp entry. If more than
+ * 	one YKUSH board is connected to the host it will send the command
+ * 	just to the first one that appears in the enumerated list.
+ *
+ * 	If there are more than one YKUSH board connected to the same host
+ * 	the commandBySerial function should be used instead.
+ *
+ * Inputs:
+ *
+ *	iSerial	-	Serial number of the YKUSH board to issue the command.
+ *	cmds	-	Command bytes to be sent to YKUSH.
+ *	resp	-	Array for storing response bytes
+ *	num	-	Number of entries in cmds and resp
+ *
+ * Outputs:
+ *
+ * 	The function will return the response byte or zero.
+ *
+ ********************************************************************************/
+char commandsBySerial(char *iSerial, char *cmd, char *resp, int num)
+{
+
+	int res;
+    unsigned char buf[65];
+    unsigned char buf6[6];
+    bool isLegacy = false;
+    #define MAX_STR 255
+    wchar_t wstr[MAX_STR];
+    hid_device *handle;
+    int i;
+	const size_t newsize = 100;
+	wchar_t serial[newsize];
+	
+     
+	if (iSerial) {
+		// Convert to a wchar_t*
+		size_t origsize = strlen(iSerial) + 1;
+		size_t convertedChars = 0;
+
+#ifndef LINUX
+		mbstowcs_s(&convertedChars, serial, origsize, iSerial, _TRUNCATE);
+#else
+		mbstowcs(serial, iSerial, newsize);
+#endif
+	}
+
+     	// Open the YKUSH device 
+        handle = hid_open(VENDOR_ID, PRODUCT_ID, iSerial ? serial : NULL);
+
+    
+        if (handle == NULL) {
+
+            // Limited Legaccy firmware support (does not work in all systems)
+            handle = hid_open(VENDOR_ID, OLD_PRODUCT_ID, NULL);
+
+            if (handle == NULL){
+                return 0;
+            }
+
+            isLegacy = true;
+
+        }
+
+     	// Set the hid_read() function to be blocking (wait for response from YKUSH).
+    	hid_set_nonblocking(handle, 0);
+
+	for (i = 0; i < num; i++) {
+		// Send an Output report with the desired command
+		if (isLegacy) {
+			buf6[0] = 0; 	// First byte is report number
+			buf6[1] = cmd[i];	// Command byte
+			buf6[2] = cmd[i];	// Command confirm byte
+			res = hid_write(handle, buf6, 6);
+		} else {
+			buf[0] = 0; 	// First byte is report number
+			buf[1] = cmd[i];	// Command byte
+			buf[2] = cmd[i];	// Command confirm byte
+			res = hid_write(handle, buf, 65);
+		}
+
+		// Read response
+		if (isLegacy) {
+			res = hid_read(handle, buf, 6);
+		} else {
+			res = hid_read(handle, buf, 65);
+		}
+
+		if (res < 0) {
+			printf("Unable to read YKUSH command response\n");
+		}
+
+		if (res >= 1) {
+			resp[i] = buf[1];
+		}
+	}
+
+    	return 0;
+ }
+
+/*******************************************************************************
+ * commands(char *cmd, char* resp, int num) - Sends commands to YKUSH board
+ * -----------------------------------------------------------------------------
+ *
+ * Description:
+ *
+ * 	All commands in the cmd array are send to the YKUSH board and the
+ * 	response bytes are stored in the matching resp entry. If more than
+ * 	one YKUSH board is connected to the host it will send the command
+ * 	just to the first one that appears in the enumerated list.
+ *
+ * 	If there are more than one YKUSH board connected to the same host
+ * 	the commandBySerial function should be used instead.
+ *
+ * Inputs:
+ *
+ *	cmds	-	Command bytes to be sent to YKUSH.
+ *	resp	-	Array for storing response bytes
+ *	num	-	Number of entries in cmds and resp
+ *
+ * Outputs:
+ *
+ * 	The function will return the response byte or zero.
+ *
+ ********************************************************************************/
+char commands(char *cmd, char *resp, int num)
+{
+	return commandsBySerial(NULL, cmd, resp, num);
+}
+
+/*******************************************************************************
+ * commandBySerial(char *iSerial, char cmd) - Sends the command to YKUSH board
+ * -----------------------------------------------------------------------------
+ *
+ * Description:
+ *
+ * 	The command in the variable cmd is sent to YKUSH board. If more than
+ * 	one YKUSH board is connected to the host it will send the command
+ * 	just to the first one that appears in the enumerated list.
+ *
+ * 	If there are more than one YKUSH board connected to the same host
+ * 	the commandBySerial function should be used instead.
+ *
+ * Inputs:
+ *
+ *	iSerial	-	Serial number of the YKUSH board to issue the command.
+ *	cmd	-	Command byte to be sent to YKUSH.
+ *
+ * Outputs:
+ *
+ * 	The function will return the response byte or zero.
+ *
+ ********************************************************************************/
+char commandBySerial(char *iSerial, char cmd)
+{
+	char resp;
+
+	commandsBySerial(iSerial, &cmd, &resp, 1);
+
+	return resp;
+}
+
+/*******************************************************************************
+ * command(char cmd) - Sends the command to YKUSH board
+ * -----------------------------------------------------------------------------
+ *
+ * Description:
+ *
+ * 	The command in the variable cmd is sent to YKUSH board. If more than
+ * 	one YKUSH board is connected to the host it will send the command
+ * 	just to the first one that appears in the enumerated list.
+ *
+ * 	If there are more than one YKUSH board connected to the same host
+ * 	the commandBySerial function should be used instead.
+ *
+ * Inputs:
+ *
+ * 	cmd	-	Command byte to be sent to YKUSH.
+ *
+ * Outputs:
+ *
+ * 	The function will return the response byte.
+ *
+ ********************************************************************************/
+char command(char cmd)
+{
+	return commandBySerial(NULL, cmd);
+}
+
+
+
+
+
+
+
+
+

+ 15 - 0
ykushcmd/usbcom.h

@@ -0,0 +1,15 @@
+#ifndef USBCOM_H
+#define USBCOM_H
+
+static int sendCommand(unsigned char *toSendBuffer, unsigned char *receivedBuffer);
+
+char commands(char *cmd, char *resp, int num);
+char command(char cmd);
+
+char commandsBySerial(char *iSerial, char *cmd, char *resp, int num);
+char commandBySerial(char *iSerial, char cmd);
+
+int listDevices();
+
+
+#endif // USBCOM_H

+ 12 - 0
ykushcmd/ykushcmd.cpp

@@ -0,0 +1,12 @@
+// Program entry point
+
+#include "stdafx.h"
+#include "commandParser.h"
+
+
+int main(int argc, char* argv[])
+{
+    	commandParser(argc, argv);
+    	return 0;
+}
+

+ 171 - 0
ykushcmd/ykushcmd.vcxproj

@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C8815452-C975-41CE-8E08-E12E7E488901}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>ykushcmd</RootNamespace>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <AdditionalIncludeDirectories>C:\yk\ykush\ykushcmd\windows;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>C:\yk\ykush\ykushcmd\windows;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>hidapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="commandParser.h" />
+    <ClInclude Include="platformdefs.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+    <ClInclude Include="usbcom.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="commandParser.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+    <ClCompile Include="usbcom.cpp" />
+    <ClCompile Include="ykushcmd.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 51 - 0
ykushcmd/ykushcmd.vcxproj.filters

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <Text Include="ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="platformdefs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="commandParser.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="usbcom.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ykushcmd.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="commandParser.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="usbcom.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>