summaryrefslogtreecommitdiff
path: root/utils/hwstub/tools
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-02-07 21:42:15 +0000
committerAmaury Pouly <amaury.pouly@gmail.com>2016-04-08 19:37:30 +0200
commit3d8a08ca25c3041ac677335e51341d966a9b370b (patch)
tree1bf06dea354e3ae95c1ec91b6ee259d0ac21659c /utils/hwstub/tools
parent56dc54d38ac6c1d47ea6dbae88b1e5f7fee9f3ec (diff)
downloadrockbox-3d8a08ca25c3041ac677335e51341d966a9b370b.tar.gz
rockbox-3d8a08ca25c3041ac677335e51341d966a9b370b.zip
hwstub: rewrite and expand library
Rewrite the hwstub library in C++, with a clean and modular design. The library was designed from the ground up to be aware of multithreading issues and to handle memory allocation nicely with shared pointers. Compared to the original library, it brings the following major features: - support for JZ boot devices, it is very easy to add support for others - support for network transparent operations (through sockets): both tcp and unix domains are support Change-Id: I75899cb9c7aa938c17ede2bb3f468e7a55d625b4
Diffstat (limited to 'utils/hwstub/tools')
-rw-r--r--utils/hwstub/tools/Makefile16
-rw-r--r--utils/hwstub/tools/hwstub_server.cpp127
-rw-r--r--utils/hwstub/tools/hwstub_test.cpp219
3 files changed, 358 insertions, 4 deletions
diff --git a/utils/hwstub/tools/Makefile b/utils/hwstub/tools/Makefile
index 868ddcca79..079933ad25 100644
--- a/utils/hwstub/tools/Makefile
+++ b/utils/hwstub/tools/Makefile
@@ -1,13 +1,15 @@
1CC=gcc 1CC=gcc
2CXX=g++ 2CXX=g++
3LD=g++ 3LD=g++
4HWSTUB_INCLUDE_DIR=../include
4HWSTUB_LIB_DIR=../lib 5HWSTUB_LIB_DIR=../lib
5REGTOOLS_INCLUDE_DIR=../../regtools/include 6REGTOOLS_INCLUDE_DIR=../../regtools/include
6REGTOOLS_LIB_DIR=../../regtools/lib 7REGTOOLS_LIB_DIR=../../regtools/lib
7CFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_INCLUDE_DIR) `pkg-config --cflags lua5.2` 8INCLUDES=-I$(HWSTUB_INCLUDE_DIR) -I$(REGTOOLS_INCLUDE_DIR) `pkg-config --cflags lua5.2` `pkg-config --cflags libusb-1.0`
8CXXFLAGS=-Wall -O2 `pkg-config --cflags libusb-1.0` -g -I$(HWSTUB_LIB_DIR) -I$(REGTOOLS_INCLUDE_DIR) `pkg-config --cflags lua5.2` 9CFLAGS=-Wall -O2 -std=c99 -g $(INCLUDES) -D_XOPEN_SOURCE=600
9LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs lua5.2` -lreadline -L$(HWSTUB_LIB_DIR) -L$(REGTOOLS_LIB_DIR) -lsocdesc -lhwstub `xml2-config --libs` 10CXXFLAGS=-Wall -O2 -std=c++11 -g $(INCLUDES)
10EXEC=hwstub_shell hwstub_load 11LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs lua5.2` -lreadline -L$(HWSTUB_LIB_DIR) -L$(REGTOOLS_LIB_DIR) -lsocdesc -lhwstub `xml2-config --libs` -pthread
12EXEC=hwstub_shell hwstub_load hwstub_server hwstub_test
11SRC=$(wildcard *.c) 13SRC=$(wildcard *.c)
12SRCXX=$(wildcard *.cpp) 14SRCXX=$(wildcard *.cpp)
13OBJ=$(SRC:.c=.o) $(SRCXX:.cpp=.o) 15OBJ=$(SRC:.c=.o) $(SRCXX:.cpp=.o)
@@ -33,6 +35,12 @@ hwstub_shell: hwstub_shell.o prompt.o $(LIBS)
33hwstub_load: hwstub_load.o $(LIBS) 35hwstub_load: hwstub_load.o $(LIBS)
34 $(LD) -o $@ $^ $(LDFLAGS) 36 $(LD) -o $@ $^ $(LDFLAGS)
35 37
38hwstub_server: hwstub_server.o $(LIBS)
39 $(LD) -o $@ $^ $(LDFLAGS)
40
41hwstub_test: hwstub_test.o $(LIBS)
42 $(LD) -o $@ $^ $(LDFLAGS)
43
36clean: 44clean:
37 rm -rf $(OBJ) $(LIB) $(EXEC) 45 rm -rf $(OBJ) $(LIB) $(EXEC)
38 46
diff --git a/utils/hwstub/tools/hwstub_server.cpp b/utils/hwstub/tools/hwstub_server.cpp
new file mode 100644
index 0000000000..6cb8010897
--- /dev/null
+++ b/utils/hwstub/tools/hwstub_server.cpp
@@ -0,0 +1,127 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <cstdio>
22#include <thread>
23#include <chrono>
24#include <cstring>
25#include <iostream>
26#include "hwstub.hpp"
27#include "hwstub_usb.hpp"
28#include "hwstub_uri.hpp"
29#include "hwstub_net.hpp"
30#include <signal.h>
31#include <getopt.h>
32
33/* capture CTRL+C */
34volatile sig_atomic_t g_exit_loop = 0;
35
36void do_signal(int sig)
37{
38 g_exit_loop = 1;
39}
40
41std::shared_ptr<hwstub::context> g_ctx;
42std::shared_ptr<hwstub::net::server> g_srv;
43
44int usage()
45{
46 printf("usage: hwstub_server [options]\n");
47 printf(" --help/-h Display this help\n");
48 printf(" --verbose/-v Verbose output\n");
49 printf(" --context/-c <uri> Context URI (see below)\n");
50 printf(" --server/-s <uri> Server URI (see below)\n");
51 printf("\n");
52 hwstub::uri::print_usage(stdout, true, true);
53 return 1;
54}
55
56int main(int argc, char **argv)
57{
58 hwstub::uri::uri ctx_uri = hwstub::uri::default_uri();
59 hwstub::uri::uri srv_uri = hwstub::uri::default_server_uri();
60 bool verbose = false;
61
62 while(1)
63 {
64 static struct option long_options[] =
65 {
66 {"help", no_argument, 0, 'h'},
67 {"verbose", no_argument, 0, 'v'},
68 {"context", required_argument, 0, 'c'},
69 {"server", required_argument, 0, 's'},
70 {0, 0, 0, 0}
71 };
72
73 int c = getopt_long(argc, argv, "hvc:s:", long_options, NULL);
74 if(c == -1)
75 break;
76 switch(c)
77 {
78 case -1:
79 break;
80 case 'v':
81 verbose = true;
82 break;
83 case 'h':
84 return usage();
85 case 'c':
86 ctx_uri = hwstub::uri::uri(optarg);
87 break;
88 case 's':
89 srv_uri = hwstub::uri::uri(optarg);
90 break;
91 default:
92 abort();
93 }
94 }
95
96 if(optind != argc)
97 return usage();
98
99 /* intercept CTRL+C */
100 signal(SIGINT, do_signal);
101
102 std::string error;
103 g_ctx = hwstub::uri::create_context(ctx_uri, &error);
104 if(!g_ctx)
105 {
106 printf("Cannot create context: %s\n", error.c_str());
107 return 1;
108 }
109 g_ctx->start_polling();
110
111 g_srv = hwstub::uri::create_server(g_ctx, srv_uri, &error);
112 if(!g_srv)
113 {
114 printf("Cannot create server: %s\n", error.c_str());
115 return 1;
116 }
117 if(verbose)
118 g_srv->set_debug(std::cout);
119
120 while(!g_exit_loop)
121 std::this_thread::sleep_for(std::chrono::seconds(1));
122 printf("Shutting down...\n");
123 g_srv.reset(); /* will cleanup */
124 g_ctx.reset(); /* will cleanup */
125
126 return 0;
127}
diff --git a/utils/hwstub/tools/hwstub_test.cpp b/utils/hwstub/tools/hwstub_test.cpp
new file mode 100644
index 0000000000..c93e601c36
--- /dev/null
+++ b/utils/hwstub/tools/hwstub_test.cpp
@@ -0,0 +1,219 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <cstdio>
22#include <thread>
23#include <chrono>
24#include <cstring>
25#include <iostream>
26#include "hwstub.hpp"
27#include "hwstub_usb.hpp"
28#include "hwstub_uri.hpp"
29#include <signal.h>
30#include <getopt.h>
31
32/* capture CTRL+C */
33volatile sig_atomic_t g_exit_loop = 0;
34
35void do_signal(int sig)
36{
37 g_exit_loop = 1;
38}
39
40std::shared_ptr<hwstub::context> g_ctx;
41
42void print_error(hwstub::error err, bool nl = true)
43{
44 switch(err)
45 {
46 case hwstub::error::SUCCESS: printf("success"); break;
47 case hwstub::error::ERROR: printf("error"); break;
48 default: printf("unknown(%d)", (int)err); break;
49 }
50 if(nl)
51 printf("\n");
52}
53
54const char *target_string(uint32_t id)
55{
56 switch(id)
57 {
58 case HWSTUB_TARGET_UNK: return "unknown";
59 case HWSTUB_TARGET_STMP: return "stmp";
60 case HWSTUB_TARGET_RK27: return "rk27";
61 case HWSTUB_TARGET_PP: return "pp";
62 case HWSTUB_TARGET_ATJ: return "atj";
63 case HWSTUB_TARGET_JZ: return "jz";
64 default: return "unknown";
65 }
66}
67
68void print_dev_details(std::shared_ptr<hwstub::device> dev)
69{
70 std::shared_ptr<hwstub::handle> h;
71 hwstub::error err = dev->open(h);
72 if(err != hwstub::error::SUCCESS)
73 {
74 printf(" [cannot open dev: %s]\n", error_string(err).c_str());
75 return;
76 }
77 /* version */
78 struct hwstub_version_desc_t ver_desc;
79 err = h->get_version_desc(ver_desc);
80 if(err != hwstub::error::SUCCESS)
81 {
82 printf(" [cannot get version descriptor: %s]\n", error_string(err).c_str());
83 return;
84 }
85 printf(" [version %d.%d.%d]\n", ver_desc.bMajor, ver_desc.bMinor, ver_desc.bRevision);
86 /* target */
87 struct hwstub_target_desc_t target_desc;
88 err = h->get_target_desc(target_desc);
89 if(err != hwstub::error::SUCCESS)
90 {
91 printf(" [cannot get target descriptor: %s]\n", error_string(err).c_str());
92 return;
93 }
94 std::string name(target_desc.bName, sizeof(target_desc.bName));
95 printf(" [target %s: %s]\n", target_string(target_desc.dID), name.c_str());
96 /* layout */
97 struct hwstub_layout_desc_t layout_desc;
98 err = h->get_layout_desc(layout_desc);
99 if(err != hwstub::error::SUCCESS)
100 {
101 printf(" [cannot get layout descriptor: %s]\n", error_string(err).c_str());
102 return;
103 }
104 printf(" [code layout %#x bytes @ %#x]\n", layout_desc.dCodeSize, layout_desc.dCodeStart);
105 printf(" [stack layout %#x bytes @ %#x]\n", layout_desc.dStackSize, layout_desc.dStackStart);
106 printf(" [buffer layout %#x bytes @ %#x]\n", layout_desc.dBufferSize, layout_desc.dBufferStart);
107}
108
109void print_device(std::shared_ptr<hwstub::device> dev, bool arrived = true)
110{
111 hwstub::usb::device *udev = dynamic_cast< hwstub::usb::device* >(dev.get());
112 if(arrived)
113 printf("--> ");
114 else
115 printf("<-- ");
116 if(udev)
117 {
118 libusb_device *uudev = udev->native_device();
119 struct libusb_device_descriptor dev_desc;
120 libusb_get_device_descriptor(uudev, &dev_desc);
121 printf("USB device @ %d.%u: ID %04x:%04x\n", udev->get_bus_number(),
122 udev->get_address(), dev_desc.idVendor, dev_desc.idProduct);
123 }
124 else
125 printf("Unknown device\n");
126 if(arrived)
127 print_dev_details(dev);
128}
129
130void dev_changed(std::shared_ptr<hwstub::context> ctx, bool arrived, std::shared_ptr<hwstub::device> dev)
131{
132 print_device(dev, arrived);
133}
134
135void print_list()
136{
137 std::vector<std::shared_ptr<hwstub::device>> list;
138 hwstub::error ret = g_ctx->get_device_list(list);
139 if(ret != hwstub::error::SUCCESS)
140 {
141 printf("Cannot get device list: %s\n", error_string(ret).c_str());
142 return;
143 }
144 for(auto d : list)
145 print_device(d);
146}
147
148int usage()
149{
150 printf("usage: hwstub_test [options]\n");
151 printf(" --help/-h Display this help\n");
152 printf(" --verbose/-v Verbose output\n");
153 printf(" --context/-c <uri> Context URI (see below)\n");
154 printf("\n");
155 hwstub::uri::print_usage(stdout, true, false);
156 return 1;
157}
158
159int main(int argc, char **argv)
160{
161 hwstub::uri::uri uri = hwstub::uri::default_uri();
162 bool verbose = false;
163
164 while(1)
165 {
166 static struct option long_options[] =
167 {
168 {"help", no_argument, 0, 'h'},
169 {"verbose", no_argument, 0, 'v'},
170 {"context", required_argument, 0, 'c'},
171 {0, 0, 0, 0}
172 };
173
174 int c = getopt_long(argc, argv, "hvc:", long_options, NULL);
175 if(c == -1)
176 break;
177 switch(c)
178 {
179 case -1:
180 break;
181 case 'v':
182 verbose = true;
183 break;
184 case 'h':
185 return usage();
186 case 'c':
187 uri = hwstub::uri::uri(optarg);
188 break;
189 default:
190 abort();
191 }
192 }
193
194 if(optind != argc)
195 return usage();
196
197 /* intercept CTRL+C */
198 signal(SIGINT, do_signal);
199
200 std::string error;
201 g_ctx = hwstub::uri::create_context(uri, &error);
202 if(!g_ctx)
203 {
204 printf("Cannot create context: %s\n", error.c_str());
205 return 1;
206 }
207 if(verbose)
208 g_ctx->set_debug(std::cout);
209 print_list();
210 g_ctx->register_callback(dev_changed);
211 g_ctx->start_polling();
212 while(!g_exit_loop)
213 std::this_thread::sleep_for(std::chrono::seconds(1));
214 printf("Shutting down...\n");
215 g_ctx.reset(); /* will cleanup */
216
217 return 0;
218}
219