mirror of
https://github.com/HandsomeMod/gc.git
synced 2026-04-09 23:00:02 +02:00
initial commit
This commit is contained in:
37
CMakeLists.txt
Normal file
37
CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (C) 2021 HandsomeMod Project
|
||||
#
|
||||
# GC (Gadget Controller) is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(GC C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)#C11
|
||||
set(CMAKE_CXX_STANDARD 17)#C17
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_INSTALL_PREFIX /usr)
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
|
||||
#file(GLOB_RECURSE INCLUDES "gc_*.h")
|
||||
file(GLOB_RECURSE SOURCES "main.c" "gc_*.c")
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
||||
|
||||
|
||||
# Core Dependency
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(LIBUSBGX REQUIRED libusbgx)
|
||||
list(APPEND EXTRA_LIBS ${LIBUSBGX_LIBRARIES})
|
||||
list(APPEND EXTRA_INCLUDES ${LIBUSBGX_INCLUDE_DIRS})
|
||||
|
||||
# generated headers
|
||||
configure_file (
|
||||
"gc_config.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/gc_config.h"
|
||||
)
|
||||
|
||||
include_directories(${EXTRA_INCLUDES} ${INCLUDES})
|
||||
add_executable(gc ${SOURCES})
|
||||
target_link_libraries(gc PRIVATE ${EXTRA_LIBS})
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/bin/gc DESTINATION bin)
|
||||
57
gc_acm.c
Normal file
57
gc_acm.c
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_acm.h"
|
||||
|
||||
int gc_acm_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_acm;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_ACM);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_ACM,id,NULL,&f_acm);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create acm function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_acm);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind ecm config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
21
gc_acm.h
Normal file
21
gc_acm.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_ACM_H
|
||||
#define GC_ACM_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_acm_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_ACM_H
|
||||
43
gc_config.h
Normal file
43
gc_config.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_CONFIG_H
|
||||
#define GC_CONFIG_H
|
||||
|
||||
/* #undef SERIAL_NUMBER */
|
||||
/* #undef MANUFACTURER */
|
||||
/* #undef PRODUCT */
|
||||
/* #undef ID_VENDOR */
|
||||
/* #undef ID_PRODUCT */
|
||||
|
||||
#ifndef SERIAL_NUMBER
|
||||
#define SERIAL_NUMBER "0123456789"
|
||||
#endif
|
||||
|
||||
#ifndef MANUFACTURER
|
||||
#define MANUFACTURER "HandsomeTech"
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
#define PRODUCT "HandsomeMod Device"
|
||||
#endif
|
||||
|
||||
#ifndef ID_VENDOR
|
||||
#define ID_VENDOR "0x18d1"
|
||||
#endif
|
||||
|
||||
#ifndef ID_PRODUCT
|
||||
#define ID_PRODUCT "0xd001"
|
||||
#endif
|
||||
|
||||
#endif //GC_CONFIG_H
|
||||
43
gc_config.h.in
Normal file
43
gc_config.h.in
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_CONFIG_H
|
||||
#define GC_CONFIG_H
|
||||
|
||||
#cmakedefine SERIAL_NUMBER @SERIAL_NUMBER@
|
||||
#cmakedefine MANUFACTURER @MANUFACTURER@
|
||||
#cmakedefine PRODUCT @PRODUCT@
|
||||
#cmakedefine ID_VENDOR @ID_VENDOR@
|
||||
#cmakedefine ID_PRODUCT @ID_PRODUCT@
|
||||
|
||||
#ifndef SERIAL_NUMBER
|
||||
#define SERIAL_NUMBER "0123456789"
|
||||
#endif
|
||||
|
||||
#ifndef MANUFACTURER
|
||||
#define MANUFACTURER "HandsomeTech"
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
#define PRODUCT "HandsomeMod Device"
|
||||
#endif
|
||||
|
||||
#ifndef ID_VENDOR
|
||||
#define ID_VENDOR "0x18d1"
|
||||
#endif
|
||||
|
||||
#ifndef ID_PRODUCT
|
||||
#define ID_PRODUCT "0xd001"
|
||||
#endif
|
||||
|
||||
#endif //GC_CONFIG_H
|
||||
57
gc_ecm.c
Normal file
57
gc_ecm.c
Normal file
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_ecm.h"
|
||||
|
||||
int gc_ecm_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_ecm;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_ECM);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_ECM,id,NULL,&f_ecm);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create ecm function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_ecm);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind ecm config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
21
gc_ecm.h
Normal file
21
gc_ecm.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_ECM_H
|
||||
#define GC_ECM_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_ecm_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_ECM_H
|
||||
59
gc_ffs.c
Normal file
59
gc_ffs.c
Normal file
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_ffs.h"
|
||||
|
||||
int gc_ffs_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_ffs;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_FFS);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_FFS,id,NULL,&f_ffs);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create ffs function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_ffs);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind ffs config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
23
gc_ffs.h
Normal file
23
gc_ffs.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_FFS_H
|
||||
#define GC_FFS_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_ffs_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_FFS_H
|
||||
251
gc_generic.c
Normal file
251
gc_generic.c
Normal file
@@ -0,0 +1,251 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_generic.h"
|
||||
static usbg_state *state = NULL;
|
||||
|
||||
#define LUGX_CALL(c) \
|
||||
{ \
|
||||
int usbg_ret; \
|
||||
usbg_ret = c; \
|
||||
if (usbg_ret != USBG_SUCCESS) { \
|
||||
fprintf(stderr, "In: %s (Function: %s)\n", #c, __func__); \
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), \
|
||||
usbg_strerror(usbg_ret)); \
|
||||
return GC_FAILED; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
usbg_gadget * gc_init(gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *g;
|
||||
int usbg_ret;
|
||||
|
||||
struct usbg_gadget_attrs g_attrs = {
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
|
||||
.idVendor = info.id_vendor,
|
||||
.idProduct = info.id_product,
|
||||
.bcdDevice = 0x0001, /* Verson of device */
|
||||
};
|
||||
|
||||
struct usbg_gadget_strs g_strs = {
|
||||
.serial = info.serial_number, /* Serial number */
|
||||
.manufacturer = info.manufacturer, /* Manufacturer */
|
||||
.product = info.product /* Product string */
|
||||
};
|
||||
|
||||
usbg_ret = usbg_init(GC_CONFIG_PATH, &state);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to init gadget. \n");
|
||||
state = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now we just support one otg controller */
|
||||
/* if one gadget been created just use it */
|
||||
g = usbg_get_first_gadget(state);
|
||||
if(g == NULL){
|
||||
usbg_ret = usbg_create_gadget(state, "g1", &g_attrs, &g_strs, &g);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr,"failed to create gadget. \n");
|
||||
state = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* disable gadget for now to apply new config */
|
||||
usbg_disable_gadget(g);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
int gc_delete_function(gc_generic_info info,char *target)
|
||||
{
|
||||
usbg_gadget *g;
|
||||
gc_init(info);
|
||||
g = usbg_get_first_gadget(state);
|
||||
if(g == NULL || target == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f = usbg_get_first_function(g);
|
||||
while (f != NULL) {
|
||||
usbg_function *next = usbg_get_next_function(f);
|
||||
if(strcmp(usbg_get_function_instance(f),target) == 0){
|
||||
usbg_rm_function(f,USBG_RM_RECURSE);
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
f = next;
|
||||
}
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
static int remove_gadget(usbg_gadget *g)
|
||||
{
|
||||
usbg_udc *u;
|
||||
|
||||
u = usbg_get_gadget_udc(g);
|
||||
if (u)
|
||||
LUGX_CALL(usbg_disable_gadget(g));
|
||||
|
||||
LUGX_CALL(usbg_rm_gadget(g, USBG_RM_RECURSE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gc_remove_all_gadgets(gc_generic_info info)
|
||||
{
|
||||
if(gc_init(info) == NULL)
|
||||
return GC_FAILED;
|
||||
usbg_gadget *g;
|
||||
g = usbg_get_first_gadget(state);
|
||||
while (g != NULL) {
|
||||
usbg_gadget *next = usbg_get_next_gadget(g);
|
||||
LUGX_CALL(remove_gadget(g));
|
||||
g = next;
|
||||
}
|
||||
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
|
||||
/* id generate helper */
|
||||
static int gc_get_functions()
|
||||
{
|
||||
if(state == NULL)
|
||||
return -1;
|
||||
|
||||
usbg_gadget *gadget = usbg_get_first_gadget(state);
|
||||
|
||||
if(gadget == NULL)
|
||||
return -1;
|
||||
|
||||
usbg_function *last_function = usbg_get_first_function(gadget);
|
||||
int ci = 0;
|
||||
if(last_function == NULL){
|
||||
return 0;
|
||||
}else{
|
||||
while(last_function != NULL){
|
||||
if(usbg_get_next_function(last_function) == NULL)
|
||||
break;
|
||||
last_function = usbg_get_next_function(last_function);
|
||||
ci++;
|
||||
}
|
||||
}
|
||||
|
||||
return ci;
|
||||
|
||||
}
|
||||
|
||||
/* get first config from gadget */
|
||||
/* if not find create a new one */
|
||||
usbg_config *gc_get_config(usbg_gadget *gadget)
|
||||
{
|
||||
if(gadget == NULL)
|
||||
return NULL;
|
||||
|
||||
/* default config */
|
||||
struct usbg_config_strs config_strs = {
|
||||
.configuration = "c1"
|
||||
};
|
||||
|
||||
usbg_config *result = usbg_get_first_config(gadget);
|
||||
|
||||
if(result == NULL){
|
||||
int usbg_ret = usbg_create_config(gadget,1,"c1",NULL,&config_strs,&result);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to get config! \n");
|
||||
gc_clean();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *gc_generate_id(usbg_function_type type)
|
||||
{
|
||||
/*
|
||||
* FORMAT : {function}.{number}
|
||||
* the number not order by the number of same function
|
||||
* by number of all exist usb gadgets function.
|
||||
* if gc -l result like this.
|
||||
* ffs.1
|
||||
* ffs.2
|
||||
* mass.4
|
||||
*
|
||||
* And you add a new ffs function you will get this.
|
||||
* ffs.4
|
||||
* if some gadget function had been deleted. id will be the number of functions +1.
|
||||
*/
|
||||
|
||||
char *result = malloc(sizeof(char) * 20);
|
||||
int id = gc_get_functions() + 1;
|
||||
|
||||
if(id < 1){
|
||||
fprintf(stderr,"failed to get gadgets. \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(type == USBG_F_HID){
|
||||
sprintf(result,"hid.%d",id);
|
||||
}else if(type == USBG_F_ACM){
|
||||
sprintf(result,"acm.%d",id);
|
||||
}else if(type == USBG_F_ECM){
|
||||
sprintf(result,"ecm.%d",id);
|
||||
}else if(type == USBG_F_EEM){
|
||||
sprintf(result,"eem.%d",id);
|
||||
}else if(type == USBG_F_FFS){
|
||||
sprintf(result,"ffs.%d",id);
|
||||
}else if(type == USBG_F_LOOPBACK){
|
||||
sprintf(result,"loopback.%d",id);
|
||||
}else if(type == USBG_F_MASS_STORAGE){
|
||||
sprintf(result,"mass.%d",id);
|
||||
}else if(type == USBG_F_MIDI){
|
||||
sprintf(result,"midi.%d",id);
|
||||
}else if(type == USBG_F_NCM){
|
||||
sprintf(result,"ncm.%d",id);
|
||||
}else if(type == USBG_F_OBEX){
|
||||
sprintf(result,"obex.%d",id);
|
||||
}else if(type == USBG_F_PHONET){
|
||||
sprintf(result,"hid.%d",id);
|
||||
}else if(type == USBG_F_PRINTER){
|
||||
sprintf(result,"printer.%d",id);
|
||||
}else if(type == USBG_F_RNDIS){
|
||||
sprintf(result,"rndis.%d",id);
|
||||
}else if(type == USBG_F_SERIAL){
|
||||
sprintf(result,"serial.%d",id);
|
||||
}else if(type == USBG_F_SUBSET){
|
||||
sprintf(result,"subset.%d",id);
|
||||
}else if(type == USBG_F_UAC2){
|
||||
sprintf(result,"uac.%d",id);
|
||||
}else if(type == USBG_F_UVC){
|
||||
sprintf(result,"uvc.%d",id);
|
||||
}else{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void gc_clean()
|
||||
{
|
||||
usbg_cleanup(state);
|
||||
}
|
||||
|
||||
62
gc_generic.h
Normal file
62
gc_generic.h
Normal file
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_GENERIC_H
|
||||
#define GC_GENERIC_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <usbg/usbg.h>
|
||||
|
||||
#define GC_SUCCESS 0
|
||||
#define GC_FAILED -1
|
||||
#define GC_CONFIG_PATH "/sys/kernel/config"
|
||||
|
||||
typedef enum {
|
||||
USB_HOST,
|
||||
USB_GADGET
|
||||
}gc_usb_mode;
|
||||
|
||||
// generic info passed by cmake
|
||||
typedef struct {
|
||||
char *serial_number;
|
||||
char *manufacturer;
|
||||
char *product;
|
||||
unsigned int id_vendor;
|
||||
unsigned int id_product;
|
||||
}gc_generic_info;
|
||||
|
||||
|
||||
usbg_gadget * gc_init(gc_generic_info info);
|
||||
|
||||
/* 获取usb模式 */
|
||||
gc_usb_mode gc_get_mode();
|
||||
|
||||
/* 生成id */
|
||||
char *gc_generate_id(usbg_function_type type);
|
||||
|
||||
/* 删除特定的function */
|
||||
int gc_delete_function(gc_generic_info info,char *target);
|
||||
|
||||
/* 清除所有的gadget */
|
||||
int gc_remove_all_gadgets(gc_generic_info info);
|
||||
|
||||
/* 销毁usb gadget */
|
||||
void gc_clean();
|
||||
|
||||
/* 得到config */
|
||||
usbg_config *gc_get_config(usbg_gadget *gadget);
|
||||
|
||||
#endif //GC_GENERIC_H
|
||||
103
gc_hid.c
Normal file
103
gc_hid.c
Normal file
@@ -0,0 +1,103 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_hid.h"
|
||||
|
||||
static char report_desc[] = {
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
|
||||
0x09, 0x06, /* USAGE (Keyboard) */
|
||||
0xa1, 0x01, /* COLLECTION (Application) */
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
|
||||
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
|
||||
0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x95, 0x08, /* REPORT_COUNT (8) */
|
||||
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
|
||||
0x95, 0x05, /* REPORT_COUNT (5) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x05, 0x08, /* USAGE_PAGE (LEDs) */
|
||||
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
|
||||
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
|
||||
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x03, /* REPORT_SIZE (3) */
|
||||
0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
|
||||
0x95, 0x06, /* REPORT_COUNT (6) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x65, /* LOGICAL_MAXIMUM (101) */
|
||||
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
|
||||
0x19, 0x00, /* USAGE_MINIMUM (Reserved) */
|
||||
0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */
|
||||
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
|
||||
0xc0 /* END_COLLECTION */
|
||||
};
|
||||
|
||||
int gc_hid_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_hid;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_HID);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
struct usbg_f_hid_attrs f_attrs = {
|
||||
.protocol = 1,
|
||||
.report_desc = {
|
||||
.desc = report_desc,
|
||||
.len = sizeof(report_desc),
|
||||
},
|
||||
.report_length = 8,
|
||||
.subclass = 0,
|
||||
};
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_HID,id,&f_attrs,&f_hid);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create hid function! (maybe kernel module not loaded?)\n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file in */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_hid);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind hid config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
23
gc_hid.h
Normal file
23
gc_hid.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_HID_H
|
||||
#define GC_HID_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
#include <usbg/function/hid.h>
|
||||
|
||||
int gc_hid_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_GC_HID_H
|
||||
324
gc_list.c
Normal file
324
gc_list.c
Normal file
@@ -0,0 +1,324 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_list.h"
|
||||
|
||||
static void show_gadget_strs(usbg_gadget *g, int lang)
|
||||
{
|
||||
int usbg_ret;
|
||||
struct usbg_gadget_strs g_strs;
|
||||
|
||||
usbg_ret = usbg_get_gadget_strs(g, lang, &g_strs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
fprintf(stdout, " Language: \t0x%x\n", lang);
|
||||
fprintf(stdout, " Manufacturer\t%s\n", g_strs.manufacturer);
|
||||
fprintf(stdout, " Product\t\t%s\n", g_strs.product);
|
||||
fprintf(stdout, " Serial Number\t%s\n", g_strs.serial);
|
||||
|
||||
usbg_free_gadget_strs(&g_strs);
|
||||
}
|
||||
|
||||
static void show_gadget(usbg_gadget *g)
|
||||
{
|
||||
const char *name, *udc;
|
||||
usbg_udc *u;
|
||||
int usbg_ret;
|
||||
struct usbg_gadget_attrs g_attrs;
|
||||
int *langs;
|
||||
int i;
|
||||
|
||||
name = usbg_get_gadget_name(g);
|
||||
if (!name) {
|
||||
fprintf(stderr, "Unable to get gadget name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_get_gadget_attrs(g, &g_attrs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, "ID %04x:%04x '%s'\n",
|
||||
g_attrs.idVendor, g_attrs.idProduct, name);
|
||||
|
||||
u = usbg_get_gadget_udc(g);
|
||||
if (u)
|
||||
/* gadget is enabled */
|
||||
udc = usbg_get_udc_name(u);
|
||||
else
|
||||
/* gadget is disabled */
|
||||
udc = "\0";
|
||||
|
||||
fprintf(stdout, " UDC\t\t\t%s\n", udc);
|
||||
|
||||
fprintf(stdout, " bcdUSB\t\t%x.%02x\n",
|
||||
g_attrs.bcdUSB >> 8,
|
||||
g_attrs.bcdUSB & 0x00ff);
|
||||
|
||||
fprintf(stdout, " bDeviceClass\t\t0x%02x\n", g_attrs.bDeviceClass);
|
||||
fprintf(stdout, " bDeviceSubClass\t0x%02x\n", g_attrs.bDeviceSubClass);
|
||||
fprintf(stdout, " bDeviceProtocol\t0x%02x\n", g_attrs.bDeviceProtocol);
|
||||
fprintf(stdout, " bMaxPacketSize0\t%d\n", g_attrs.bMaxPacketSize0);
|
||||
fprintf(stdout, " idVendor\t\t0x%04x\n", g_attrs.idVendor);
|
||||
fprintf(stdout, " idProduct\t\t0x%04x\n", g_attrs.idProduct);
|
||||
fprintf(stdout, " bcdDevice\t\t%x.%02x\n",
|
||||
g_attrs.bcdDevice >> 8,
|
||||
g_attrs.bcdDevice & 0x00ff);
|
||||
|
||||
usbg_ret = usbg_get_gadget_strs_langs(g, &langs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; langs[i]; ++i)
|
||||
show_gadget_strs(g, langs[i]);
|
||||
}
|
||||
|
||||
static void show_function(usbg_function *f)
|
||||
{
|
||||
const char *instance;
|
||||
usbg_function_type type;
|
||||
int usbg_ret;
|
||||
union {
|
||||
struct usbg_f_net_attrs net;
|
||||
char *ffs_dev_name;
|
||||
struct usbg_f_ms_attrs ms;
|
||||
struct usbg_f_midi_attrs midi;
|
||||
int serial_port_num;
|
||||
char *phonet_ifname;
|
||||
struct usbg_f_hid_attrs hid;
|
||||
struct usbg_f_uac2_attrs uac2;
|
||||
} f_attrs;
|
||||
|
||||
instance = usbg_get_function_instance(f);
|
||||
if (!instance) {
|
||||
fprintf(stderr, "Unable to get function instance name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
type = usbg_get_function_type(f);
|
||||
usbg_ret = usbg_get_function_attrs(f, &f_attrs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, " Function, type: %s instance: %s\n",
|
||||
usbg_get_function_type_str(type), instance);
|
||||
|
||||
switch (type) {
|
||||
case USBG_F_ACM:
|
||||
case USBG_F_OBEX:
|
||||
case USBG_F_SERIAL:
|
||||
fprintf(stdout, " port_num\t\t%d\n",
|
||||
f_attrs.serial_port_num);
|
||||
break;
|
||||
|
||||
case USBG_F_ECM:
|
||||
case USBG_F_SUBSET:
|
||||
case USBG_F_NCM:
|
||||
case USBG_F_EEM:
|
||||
case USBG_F_RNDIS:
|
||||
{
|
||||
struct usbg_f_net_attrs *f_net_attrs = &f_attrs.net;
|
||||
|
||||
fprintf(stdout, " dev_addr\t\t%s\n",
|
||||
ether_ntoa(&f_net_attrs->dev_addr));
|
||||
fprintf(stdout, " host_addr\t\t%s\n",
|
||||
ether_ntoa(&f_net_attrs->host_addr));
|
||||
fprintf(stdout, " ifname\t\t%s\n", f_net_attrs->ifname);
|
||||
fprintf(stdout, " qmult\t\t%d\n", f_net_attrs->qmult);
|
||||
break;
|
||||
}
|
||||
|
||||
case USBG_F_PHONET:
|
||||
fprintf(stdout, " ifname\t\t%s\n", f_attrs.phonet_ifname);
|
||||
break;
|
||||
|
||||
case USBG_F_FFS:
|
||||
fprintf(stdout, " dev_name\t\t%s\n", f_attrs.ffs_dev_name);
|
||||
break;
|
||||
|
||||
case USBG_F_MASS_STORAGE:
|
||||
{
|
||||
struct usbg_f_ms_attrs *attrs = &f_attrs.ms;
|
||||
int i;
|
||||
|
||||
fprintf(stdout, " stall\t\t%d\n", attrs->stall);
|
||||
fprintf(stdout, " nluns\t\t%d\n", attrs->nluns);
|
||||
for (i = 0; i < attrs->nluns; ++i) {
|
||||
fprintf(stdout, " lun %d:\n", attrs->luns[i]->id);
|
||||
fprintf(stdout, " cdrom\t\t%d\n", attrs->luns[i]->cdrom);
|
||||
fprintf(stdout, " ro\t\t%d\n", attrs->luns[i]->ro);
|
||||
fprintf(stdout, " nofua\t\t%d\n", attrs->luns[i]->nofua);
|
||||
fprintf(stdout, " removable\t\t%d\n", attrs->luns[i]->removable);
|
||||
fprintf(stdout, " file\t\t%s\n", attrs->luns[i]->file);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case USBG_F_MIDI:
|
||||
{
|
||||
struct usbg_f_midi_attrs *attrs = &f_attrs.midi;
|
||||
|
||||
fprintf(stdout, " index\t\t%d\n", attrs->index);
|
||||
fprintf(stdout, " id\t\t\t%s\n", attrs->id);
|
||||
fprintf(stdout, " in_ports\t\t%d\n", attrs->in_ports);
|
||||
fprintf(stdout, " out_ports\t\t%d\n", attrs->out_ports);
|
||||
fprintf(stdout, " buflen\t\t%d\n", attrs->buflen);
|
||||
fprintf(stdout, " qlen\t\t%d\n", attrs->qlen);
|
||||
break;
|
||||
}
|
||||
case USBG_F_HID:
|
||||
{
|
||||
struct usbg_f_hid_attrs *attrs = &f_attrs.hid;
|
||||
int i;
|
||||
|
||||
fprintf(stdout, " dev\t\t\t%d:%d\n",
|
||||
major(attrs->dev), minor(attrs->dev));
|
||||
fprintf(stdout, " protocol\t\t%d\n", attrs->protocol);
|
||||
fprintf(stdout, " report_desc\t");
|
||||
for (i = 0; i < attrs->report_desc.len; ++i)
|
||||
fprintf(stdout, "%x", attrs->report_desc.desc[i]);
|
||||
fprintf(stdout, "\n");
|
||||
fprintf(stdout, " report_length\t%d\n",
|
||||
attrs->report_length);
|
||||
fprintf(stdout, " subclass\t\t%d\n", attrs->subclass);
|
||||
break;
|
||||
}
|
||||
|
||||
case USBG_F_UAC2:
|
||||
{
|
||||
struct usbg_f_uac2_attrs *attrs = &f_attrs.uac2;
|
||||
|
||||
fprintf(stdout, " c_chmask\t\t%d\n", attrs->c_chmask);
|
||||
fprintf(stdout, " c_srate\t\t%d\n", attrs->c_srate);
|
||||
fprintf(stdout, " c_ssize\t\t%d\n", attrs->c_ssize);
|
||||
fprintf(stdout, " p_chmask\t\t%d\n", attrs->p_chmask);
|
||||
fprintf(stdout, " p_srate\t\t%d\n", attrs->p_srate);
|
||||
fprintf(stdout, " p_ssize\t\t%d\n", attrs->p_ssize);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf(stdout, " UNKNOWN\n");
|
||||
}
|
||||
|
||||
usbg_cleanup_function_attrs(f, &f_attrs);
|
||||
}
|
||||
|
||||
static void show_config_strs(usbg_config *c, int lang)
|
||||
{
|
||||
struct usbg_config_strs c_strs;
|
||||
int usbg_ret;
|
||||
|
||||
usbg_ret = usbg_get_config_strs(c, lang, &c_strs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, " Language: \t0x%x\n", lang);
|
||||
fprintf(stdout, " configuration\t%s\n", c_strs.configuration);
|
||||
|
||||
usbg_free_config_strs(&c_strs);
|
||||
}
|
||||
|
||||
static void show_config(usbg_config *c)
|
||||
{
|
||||
usbg_binding *b;
|
||||
usbg_function *f;
|
||||
const char *label, *instance, *bname;
|
||||
usbg_function_type type;
|
||||
struct usbg_config_attrs c_attrs;
|
||||
int *langs;
|
||||
int usbg_ret, id, i;
|
||||
|
||||
label = usbg_get_config_label(c);
|
||||
if (!label) {
|
||||
fprintf(stderr, "Unable to get config label\n");
|
||||
return;
|
||||
}
|
||||
|
||||
id = usbg_get_config_id(c);
|
||||
fprintf(stdout, " Configuration: '%s' ID: %d\n", label, id);
|
||||
|
||||
usbg_ret = usbg_get_config_attrs(c, &c_attrs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, " MaxPower\t\t%d\n", c_attrs.bMaxPower);
|
||||
fprintf(stdout, " bmAttributes\t0x%02x\n", c_attrs.bmAttributes);
|
||||
|
||||
usbg_ret = usbg_get_config_strs_langs(c, &langs);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; langs[i]; ++i)
|
||||
show_config_strs(c, langs[i]);
|
||||
|
||||
usbg_for_each_binding(b, c) {
|
||||
bname = usbg_get_binding_name(b);
|
||||
f = usbg_get_binding_target(b);
|
||||
instance = usbg_get_function_instance(f);
|
||||
type = usbg_get_function_type(f);
|
||||
if (!bname || !instance) {
|
||||
fprintf(stderr, "Unable to get binding details\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stdout, " %s -> %s %s\n", bname,
|
||||
usbg_get_function_type_str(type), instance);
|
||||
}
|
||||
}
|
||||
|
||||
void gc_show_list()
|
||||
{
|
||||
usbg_state *s;
|
||||
usbg_gadget *g;
|
||||
usbg_function *f;
|
||||
usbg_config *c;
|
||||
int usbg_ret;
|
||||
usbg_ret = usbg_init(GC_CONFIG_PATH, &s);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error on USB gadget init\n");
|
||||
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
|
||||
usbg_strerror(usbg_ret));
|
||||
return;
|
||||
}
|
||||
|
||||
usbg_for_each_gadget(g, s) {
|
||||
show_gadget(g);
|
||||
usbg_for_each_function(f, g)
|
||||
show_function(f);
|
||||
usbg_for_each_config(c, g)
|
||||
show_config(c);
|
||||
}
|
||||
|
||||
usbg_cleanup(s);
|
||||
};
|
||||
35
gc_list.h
Normal file
35
gc_list.h
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_LIST_H
|
||||
#define GC_LIST_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <usbg/usbg.h>
|
||||
#include <usbg/function/ms.h>
|
||||
#include <usbg/function/net.h>
|
||||
#include <usbg/function/ffs.h>
|
||||
#include <usbg/function/phonet.h>
|
||||
#include <usbg/function/midi.h>
|
||||
#include <usbg/function/hid.h>
|
||||
#include <usbg/function/uac2.h>
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
void gc_show_list();
|
||||
|
||||
#endif //GC_LIST_H
|
||||
68
gc_midi.c
Normal file
68
gc_midi.c
Normal file
@@ -0,0 +1,68 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_midi.h"
|
||||
|
||||
int gc_midi_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_midi;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_MIDI);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
struct usbg_f_midi_attrs f_attrs = {
|
||||
.index = 0,
|
||||
.id = id,
|
||||
.buflen = 128,
|
||||
.qlen = 16,
|
||||
.in_ports = 2,
|
||||
.out_ports = 3,
|
||||
};
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_MIDI,id,&f_attrs,&f_midi);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create midi function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_midi);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind midi config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
21
gc_midi.h
Normal file
21
gc_midi.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_MIDI_H
|
||||
#define GC_MIDI_H
|
||||
#include "gc_generic.h"
|
||||
#include <usbg/function/midi.h>
|
||||
|
||||
int gc_midi_create(int argc,char *argv[],gc_generic_info info);
|
||||
#endif //GC_MIDI_H
|
||||
58
gc_printer.c
Normal file
58
gc_printer.c
Normal file
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_printer.h"
|
||||
|
||||
int gc_printer_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_printer;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_PRINTER);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_PRINTER,id,NULL,&f_printer);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create printer function! (maybe kernel module not loaded?)\n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_printer);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind printer config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
22
gc_printer.h
Normal file
22
gc_printer.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_PRINTER_H
|
||||
#define GC_PRINTER_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_printer_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_GC_PRINTER_H
|
||||
82
gc_rndis.c
Normal file
82
gc_rndis.c
Normal file
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_rndis.h"
|
||||
int gc_rndis_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_rndis;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_RNDIS);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
struct usbg_gadget_os_descs g_os_desc = {
|
||||
.use = true,
|
||||
.b_vendor_code = 0xBC,
|
||||
.qw_sign = "MSFT100",
|
||||
};
|
||||
|
||||
struct usbg_function_os_desc f_os_desc = {
|
||||
.compatible_id = "RNDIS",
|
||||
.sub_compatible_id = "5162001",
|
||||
};
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_RNDIS,id,NULL,&f_rndis);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create rndis function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_rndis);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind rndis config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_set_gadget_os_descs(gadget, &g_os_desc);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error setting gadget OS desc\n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_set_os_desc_config(gadget, config);
|
||||
if (usbg_ret != USBG_SUCCESS) {
|
||||
fprintf(stderr, "Error setting gadget OS desc config\n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
|
||||
21
gc_rndis.h
Normal file
21
gc_rndis.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_RNDIS_H
|
||||
#define GC_RNDIS_H
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_rndis_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_GC_RNDIS_H
|
||||
58
gc_serial.c
Normal file
58
gc_serial.c
Normal file
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_serial.h"
|
||||
|
||||
int gc_serial_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_serial;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_SERIAL);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_SERIAL,id,NULL,&f_serial);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create serial function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_serial);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind serial config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
|
||||
21
gc_serial.h
Normal file
21
gc_serial.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GC_SERIAL_H
|
||||
#define GC_SERIAL_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
|
||||
int gc_serial_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_SERIAL_H
|
||||
88
gc_storage.c
Normal file
88
gc_storage.c
Normal file
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc_storage.h"
|
||||
|
||||
int gc_storage_create(int argc,char *argv[],gc_generic_info info){
|
||||
if(argc < 4){
|
||||
fprintf(stderr,"chose a directory to mount! \n");
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_mass;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_MASS_STORAGE);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
struct usbg_f_ms_lun_attrs f_ms_luns_array[] = {
|
||||
{
|
||||
.id = -1, /* allows to place in any position */
|
||||
.cdrom = 0,
|
||||
.ro = 0,
|
||||
.nofua = 0,
|
||||
.removable = 1,
|
||||
.file = argv[3],
|
||||
}
|
||||
};
|
||||
|
||||
struct usbg_f_ms_lun_attrs *f_ms_luns[] = {
|
||||
/*
|
||||
* When id in lun structure is below 0 we can place it in any
|
||||
* arbitrary position
|
||||
*/
|
||||
&f_ms_luns_array[0],
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct usbg_f_ms_attrs f_attrs = {
|
||||
.stall = 0,
|
||||
.nluns = 1,
|
||||
.luns = f_ms_luns,
|
||||
};
|
||||
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_MASS_STORAGE,id,&f_attrs,&f_mass);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create mass storage function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_mass);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind mass storage config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
23
gc_storage.h
Normal file
23
gc_storage.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_STORAGE_H
|
||||
#define GC_STORAGE_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
#include <usbg/function/ms.h>
|
||||
|
||||
int gc_storage_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_GC_STORAGE_H
|
||||
125
gc_uvc.c
Normal file
125
gc_uvc.c
Normal file
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "gc_uvc.h"
|
||||
|
||||
int gc_uvc_create(int argc,char *argv[],gc_generic_info info)
|
||||
{
|
||||
usbg_gadget *gadget = gc_init(info);
|
||||
|
||||
if(gadget == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
usbg_function *f_uvc;
|
||||
int usbg_ret;
|
||||
|
||||
char *id = gc_generate_id(USBG_F_UVC);
|
||||
|
||||
if(id == NULL)
|
||||
return GC_FAILED;
|
||||
|
||||
struct usbg_f_uvc_frame_attrs uvc_frame_attrs_array[] = {
|
||||
{
|
||||
.bFrameIndex = 1,
|
||||
.dwFrameInterval = 2000000,
|
||||
.wHeight = 480,
|
||||
.wWidth = 640,
|
||||
}, {
|
||||
.bFrameIndex = 2,
|
||||
.dwFrameInterval = 2000000,
|
||||
.wHeight = 1080,
|
||||
.wWidth = 1920,
|
||||
}, {
|
||||
.bFrameIndex = 3,
|
||||
.dwFrameInterval = 333333,
|
||||
.wHeight = 1080,
|
||||
.wWidth = 1920,
|
||||
}, {
|
||||
.bFrameIndex = 4,
|
||||
.dwFrameInterval = 333333,
|
||||
.wHeight = 2160,
|
||||
.wWidth = 3840,
|
||||
}
|
||||
};
|
||||
|
||||
struct usbg_f_uvc_frame_attrs *uvc_frame_mjpeg_attrs[] = {
|
||||
&uvc_frame_attrs_array[0],
|
||||
&uvc_frame_attrs_array[1],
|
||||
&uvc_frame_attrs_array[2],
|
||||
&uvc_frame_attrs_array[3],
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct usbg_f_uvc_frame_attrs *uvc_frame_uncompressed_attrs[] = {
|
||||
&uvc_frame_attrs_array[0],
|
||||
&uvc_frame_attrs_array[1],
|
||||
&uvc_frame_attrs_array[2],
|
||||
&uvc_frame_attrs_array[3],
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct usbg_f_uvc_format_attrs uvc_format_attrs_array[] = {
|
||||
{
|
||||
.frames = uvc_frame_mjpeg_attrs,
|
||||
.format = "mjpeg/m",
|
||||
.bDefaultFrameIndex = 3,
|
||||
}, {
|
||||
.frames = uvc_frame_uncompressed_attrs,
|
||||
.format = "uncompressed/u",
|
||||
.bDefaultFrameIndex = 2,
|
||||
}
|
||||
};
|
||||
|
||||
struct usbg_f_uvc_format_attrs *uvc_format_attrs[] = {
|
||||
&uvc_format_attrs_array[0],
|
||||
&uvc_format_attrs_array[1],
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct usbg_f_uvc_attrs uvc_attrs = {
|
||||
.formats = uvc_format_attrs,
|
||||
};
|
||||
|
||||
struct usbg_config_strs config_strs = {
|
||||
.configuration = id
|
||||
};
|
||||
|
||||
usbg_ret = usbg_create_function(gadget,USBG_F_UVC,id,&uvc_attrs,&f_uvc);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to create uvc function! (maybe kernel module not loaded?) \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
/* for now we only create one config file */
|
||||
usbg_config *config = gc_get_config(gadget);
|
||||
|
||||
usbg_ret = usbg_add_config_function(config,id,f_uvc);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to bind uvc config to function! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
usbg_ret = usbg_enable_gadget(gadget, DEFAULT_UDC);
|
||||
if(usbg_ret != USBG_SUCCESS){
|
||||
fprintf(stderr,"failed to enable gadget! \n");
|
||||
gc_clean();
|
||||
return GC_FAILED;
|
||||
}
|
||||
|
||||
gc_clean();
|
||||
return GC_SUCCESS;
|
||||
}
|
||||
|
||||
24
gc_uvc.h
Normal file
24
gc_uvc.h
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021-2022 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GC_UVC_H
|
||||
#define GC_UVC_H
|
||||
|
||||
#include "gc_generic.h"
|
||||
#include <usbg/function/uvc.h>
|
||||
|
||||
int gc_uvc_create(int argc,char *argv[],gc_generic_info info);
|
||||
|
||||
#endif //GC_UVC_H
|
||||
153
main.c
Normal file
153
main.c
Normal file
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 HandsomeMod Project
|
||||
*
|
||||
* Handsomeyingyan <handsomeyingyan@gmail.com>
|
||||
*
|
||||
* GC(Gadget Controller) is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gc_config.h"
|
||||
#include "gc_generic.h"
|
||||
#include "gc_ffs.h"
|
||||
#include "gc_hid.h"
|
||||
#include "gc_midi.h"
|
||||
#include "gc_printer.h"
|
||||
#include "gc_serial.h"
|
||||
#include "gc_uvc.h"
|
||||
#include "gc_storage.h"
|
||||
#include "gc_rndis.h"
|
||||
#include "gc_list.h"
|
||||
#include "gc_ecm.h"
|
||||
#include "gc_acm.h"
|
||||
|
||||
static int is_root(){
|
||||
if(getuid() == 0){
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static void print_help()
|
||||
{
|
||||
printf("Usage : gc [options....] \n");
|
||||
printf("-h Show this help. \n");
|
||||
printf("-l Show active gadget functions. \n");
|
||||
printf("-c Clean all active gadget. \n");
|
||||
printf("-a <function> [configs ...] Add a gadget function. \n");
|
||||
printf("-d <name> Delete a gadget function by name in list (-l). \n");
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
|
||||
if(argc < 2) {
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* generate vendor info */
|
||||
gc_generic_info info;
|
||||
info.id_product = strtoul(ID_PRODUCT,0,16);
|
||||
info.id_vendor = strtoul(ID_VENDOR,0,16);
|
||||
info.manufacturer = MANUFACTURER;
|
||||
info.product = PRODUCT;
|
||||
info.serial_number = SERIAL_NUMBER;
|
||||
|
||||
/* deal with args */
|
||||
if(strcmp(argv[1],"-h") == 0) {
|
||||
/* help */
|
||||
print_help();
|
||||
} else if(strcmp(argv[1],"-l") == 0) {
|
||||
/* list gadget functions */
|
||||
gc_show_list();
|
||||
} else if(strcmp(argv[1],"-a") == 0) {
|
||||
/* add a gadget function */
|
||||
if(!is_root()){
|
||||
printf("you need root to set usb gadget!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(argc < 3) {
|
||||
printf("You need a function to add ! \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[2],"ffs") == 0){
|
||||
if(gc_ffs_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"hid") == 0){
|
||||
if(gc_hid_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"midi") == 0){
|
||||
if(gc_midi_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"printer") == 0){
|
||||
if(gc_printer_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"serial") == 0){
|
||||
if(gc_serial_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"uvc") == 0){
|
||||
if(gc_uvc_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"mass") == 0){
|
||||
if(gc_storage_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"rndis") == 0){
|
||||
if(gc_rndis_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"ecm") == 0){
|
||||
if(gc_ecm_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}else if(strcmp(argv[2],"acm") == 0){
|
||||
if(gc_acm_create(argc,argv,info) == GC_FAILED)
|
||||
return -1;
|
||||
}
|
||||
} else if(strcmp(argv[1],"-d") == 0) {
|
||||
/* delete a gadget function */
|
||||
if(argc < 3) {
|
||||
printf("You need a gadget to remove ! \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(gc_delete_function(info,argv[2]) == GC_FAILED){
|
||||
fprintf(stderr,"failed to remove gadget function!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!is_root()){
|
||||
printf("you need root to delete usb gadget!\n");
|
||||
return -1;
|
||||
}
|
||||
} else if(strcmp(argv[1],"-c") == 0){
|
||||
if(!is_root()){
|
||||
printf("you need root to clear usb gadget!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(gc_remove_all_gadgets(info) != GC_SUCCESS) {
|
||||
fprintf(stderr,"failed to remove all gadgets. \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if(strcmp(argv[1],"playing") == 0 ){
|
||||
/* eastern egg :p */
|
||||
/* 'gc playing' is a command in bhuman simrobot */
|
||||
printf("Hi ! I'm XBMUAttila1. \n");
|
||||
} else{
|
||||
fprintf(stderr,"Invalid Argument!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
45
readme.md
Normal file
45
readme.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Gadget Controller
|
||||
|
||||
### A Simple Tool To Control Usb Gadget
|
||||
|
||||
## Dependency
|
||||
|
||||
* Cmake
|
||||
* libusbgx
|
||||
|
||||
## Compile
|
||||
|
||||
``` shell
|
||||
git clone https://github.com/HandsomeMod/gc.git
|
||||
cd gc
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
``` shell
|
||||
Usage : gc [options....]
|
||||
-h Show this help.
|
||||
-l Show active gadget functions.
|
||||
-c Clean all active gadget.
|
||||
-a <function> [configs ...] Add a gadget function.
|
||||
-d <name> Delete a gadget function by name in list (-l).
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
``` shell
|
||||
# Add a rndis function to gadget
|
||||
gc -a rndis
|
||||
# Show Gadget Status
|
||||
gc -l
|
||||
# Add a mass storage function to gadget
|
||||
gc -a mass /home/user
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Gadget Controller is licensed under GPL-2.0.
|
||||
Reference in New Issue
Block a user