void show_gadget(usbg_gadget *g) { const char *name, *udc; usbg_udc *u; int usbg_ret; usbg_gadget_attrs g_attrs; usbg_gadget_strs g_strs; 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(g, LANG_US_ENG, &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, " Manufacturer\t\t%s\n", g_strs.str_mnf); fprintf(stdout, " Product\t\t%s\n", g_strs.str_prd); fprintf(stdout, " Serial Number\t\t%s\n", g_strs.str_ser); }
void show_config(usbg_config *c) { usbg_binding *b; usbg_function *f; const char *label, *instance, *bname; usbg_function_type type; usbg_config_attrs c_attrs; usbg_config_strs c_strs; int usbg_ret, id; 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(c, LANG_US_ENG, &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, " configuration\t%s\n", c_strs.configuration); 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 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; } 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 F_ACM: case F_OBEX: case F_SERIAL: fprintf(stdout, " port_num\t\t%d\n", f_attrs.serial_port_num); break; case F_ECM: case F_SUBSET: case F_NCM: case F_EEM: case 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 F_PHONET: fprintf(stdout, " ifname\t\t%s\n", f_attrs.phonet_ifname); break; case F_FFS: fprintf(stdout, " dev_name\t\t%s\n", f_attrs.ffs_dev_name); break; case 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 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; } default: fprintf(stdout, " UNKNOWN\n"); } usbg_cleanup_function_attrs(f, &f_attrs); }
int main(void) { usbg_state *s; usbg_gadget *g; usbg_config *c; usbg_function *f_ffs1, *f_ffs2; int ret = -EINVAL; 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 = VENDOR, .idProduct = PRODUCT, .bcdDevice = 0x0001, /* Verson of device */ }; struct usbg_gadget_strs g_strs = { .serial = "0123456789", /* Serial number */ .manufacturer = "Foo Inc.", /* Manufacturer */ .product = "Bar Gadget" /* Product string */ }; struct usbg_config_strs c_strs = { .configuration = "2xFFS" }; usbg_ret = usbg_init("/sys/kernel/config", &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)); goto out1; } usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error on create gadget\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, USBG_F_FFS, "my_dev_name", NULL, &f_ffs1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating ffs1 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, USBG_F_FFS, "my_other_dev_name", NULL, &f_ffs2); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating ffs2 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } /* NULL can be passed to use kernel defaults */ usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating config\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "some_name_here", f_ffs1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding ffs1\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "some_name_here_too", f_ffs2); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding ffs2\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } fprintf(stdout, "2xFFS gadget has been created.\n" "Enable it after preparing your functions.\n"); /* * Here we end up with two created ffs instances but they are not * fully operational. Now we have to do step by step: * 1) Mount both instances: * $ mount my_dev_name -t functionfs /path/to/mount/dir1 * $ mount my_awesome_dev_name -t functionfs /path/to/mount/dir2 * * 2) Run ffs daemons for both instances: * $ my-ffs-daemon /path/to/mount/dir1 * $ my-ffs-daemon /path/to/mount/dir2 * * 3) Enable your gadget: * $ echo "my_udc_name" > /sys/kernel/config/usb_gadget/g1/UDC */ ret = 0; out2: usbg_cleanup(s); out1: return ret; }
int main(void) { usbg_state *s; usbg_gadget *g; usbg_config *c; usbg_function *f_acm0, *f_acm1, *f_ecm; int ret = -EINVAL; int usbg_ret; usbg_gadget_attrs g_attrs = { .bcdUSB = 0x0200, .bDeviceClass = USB_CLASS_PER_INTERFACE, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, .bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */ .idVendor = VENDOR, .idProduct = PRODUCT, .bcdDevice = 0x0001, /* Verson of device */ }; usbg_gadget_strs g_strs = { .str_ser = "0123456789", /* Serial number */ .str_mnf = "Foo Inc.", /* Manufacturer */ .str_prd = "Bar Gadget" /* Product string */ }; usbg_config_strs c_strs = { .configuration = "CDC 2xACM+ECM" }; usbg_ret = usbg_init("/sys/kernel/config", &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)); goto out1; } usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error on create gadget\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ACM, "usb0", NULL, &f_acm0); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm0 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ACM, "usb1", NULL, &f_acm1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm1 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ECM, "usb0", NULL, &f_ecm); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating ecm function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } /* NULL can be passed to use kernel defaults */ usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating config\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "acm.GS0", f_acm0); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding acm.GS0\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "acm.GS1", f_acm1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding acm.GS1\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "ecm.usb0", f_ecm); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding ecm.usb0\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_enable_gadget(g, DEFAULT_UDC); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error enabling gadget\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } ret = 0; out2: usbg_cleanup(s); out1: return ret; }
int gt_backend_init(const char *program_name, enum gt_option_flags flags) { enum gt_backend_type backend_type; GError *err = NULL; if (strcmp(program_name, "gt") == 0) backend_type = GT_BACKEND_LIBUSBG; else if (strcmp(program_name, "gadgetctl") == 0) backend_type = GT_BACKEND_GADGETD; else if (strcmp(program_name, "gt-parse-test") == 0) backend_type = GT_BACKEND_NOT_IMPLEMENTED; else backend_type = GT_BACKEND_AUTO; if (backend_type == GT_BACKEND_NOT_IMPLEMENTED) { backend_ctx.backend = >_backend_not_implemented; return 0; } if (backend_type == GT_BACKEND_GADGETD || backend_type == GT_BACKEND_AUTO) { GDBusConnection *conn; backend_ctx.backend = >_backend_gadgetd; #if ! GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); #endif conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); if (err) { fprintf(stderr, "Unable to connect to d-bus: %s\n", err->message); goto out_gadgetd; } g_dbus_connection_call_sync(conn, "org.usb.gadgetd", "/", "org.freedesktop.DBus.Peer", "Ping", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); if (err) { /* We omit showing glib-provided error message here * as it's not really that useful for end-users. * * This message could be probably shown in verbose * mode (which we don't have yet). */ fprintf(stderr, "Unable to initialize gadgetd backend_type\n"); goto out_gadgetd; } backend_ctx.backend_type = GT_BACKEND_GADGETD; backend_ctx.gadgetd_conn = conn; return 0; } out_gadgetd: if (err && backend_type == GT_BACKEND_GADGETD) return -1; if (backend_type == GT_BACKEND_LIBUSBG || backend_type == GT_BACKEND_AUTO) { usbg_state *s = NULL; int r; backend_ctx.backend = >_backend_libusbg; r = usbg_init("/sys/kernel/config", &s); if (r != USBG_SUCCESS) { fprintf(stderr, "Unable to initialize libusbg backend_type: %s\n", usbg_strerror(r)); goto out_libusbg; } backend_ctx.backend_type = GT_BACKEND_LIBUSBG; backend_ctx.libusbg_state = s; return 0; } out_libusbg: return -1; }
int main(void) { usbg_state *s; usbg_gadget *g; usbg_config *c; usbg_function *f_acm0, *f_acm1, *f_ecm; int ret = -EINVAL; int usbg_ret; usbg_gadget_attrs g_attrs = { 0x0200, /* bcdUSB */ 0x00, /* Defined at interface level */ 0x00, /* subclass */ 0x00, /* device protocol */ 0x0040, /* Max allowed packet size */ VENDOR, PRODUCT, 0x0001, /* Verson of device */ }; usbg_gadget_strs g_strs = { "0123456789", /* Serial number */ "Foo Inc.", /* Manufacturer */ "Bar Gadget" /* Product string */ }; usbg_config_strs c_strs = { "CDC 2xACM+ECM" }; usbg_ret = usbg_init("/sys/kernel/config", &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)); goto out1; } usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error on create gadget\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ACM, "usb0", NULL, &f_acm0); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm0 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ACM, "usb1", NULL, &f_acm1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating acm1 function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_create_function(g, F_ECM, "usb0", NULL, &f_ecm); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating ecm function\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } /* NULL can be passed to use kernel defaults */ usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating config\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "acm.GS0", f_acm0); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding acm.GS0\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "acm.GS1", f_acm1); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding acm.GS1\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_add_config_function(c, "ecm.usb0", f_ecm); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error adding ecm.usb0\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } usbg_ret = usbg_enable_gadget(g, DEFAULT_UDC); if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error enabling gadget\n"); fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret), usbg_strerror(usbg_ret)); goto out2; } ret = 0; out2: usbg_cleanup(s); out1: return ret; }