Skip to content

Commit f1ec54b

Browse files
committedJan 23, 2011
Add lsusb_gtk and serial_reader, update README.
1 parent 476f1fd commit f1ec54b

File tree

6 files changed

+539
-0
lines changed

6 files changed

+539
-0
lines changed
 

‎README

+5
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
This repository contains some random tools.
22
Here is a quick summary of the tools:
3+
o lsusb_tgk/
4+
A simple GTK wrapper around lsusb, used to display a nice structure
5+
o serial_reader/
6+
A simple tool to read/write from/to a usb serial device.
7+
Useful for use with rockbox usbser driver

‎lsusb_gtk/Makefile

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CC=gcc
2+
CXX=g++
3+
CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g
4+
CXXFLAGS=-W -Wall -O2 `pkg-config --cflags gtkmm-2.4` -g
5+
LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs gtkmm-2.4`
6+
SRC=$(wildcard *.c)
7+
SRCXX=$(wildcard *.cpp)
8+
OBJ=$(SRC:.c=) $(SRCXX:.cpp=)
9+
10+
all: $(OBJ)
11+
12+
%: %.c
13+
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
14+
15+
%: %.cpp
16+
$(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
17+
18+
clean:
19+
rm -rf $(OBJ)
20+
21+

‎lsusb_gtk/lsusb_gtk.cpp

+261
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#include <gtkmm/main.h>
2+
#include "lsusb_gtk.hpp"
3+
#include <cstdio>
4+
#include <cstdlib>
5+
#include <fstream>
6+
#include <string>
7+
#include <vector>
8+
#include <cctype>
9+
#include <cassert>
10+
11+
ListUsb::ListUsb()
12+
{
13+
set_title("lsusb");
14+
maximize();
15+
16+
add(m_box);
17+
m_scrolled_window.add(m_tree_view);
18+
m_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
19+
20+
m_refActionGroup=Gtk::ActionGroup::create();
21+
m_refActionGroup->add(Gtk::Action::create("Quit", Gtk::Stock::QUIT),
22+
sigc::mem_fun(*this, &ListUsb::on_quit));
23+
m_refActionGroup->add(Gtk::Action::create("Refresh", Gtk::Stock::REFRESH),
24+
sigc::mem_fun(*this, &ListUsb::on_refresh));
25+
26+
m_refUIManager=Gtk::UIManager::create();
27+
m_refUIManager->insert_action_group(m_refActionGroup);
28+
29+
add_accel_group(m_refUIManager->get_accel_group());
30+
31+
Glib::ustring ui_info =
32+
"<ui>"
33+
" <toolbar name='ToolBar'>"
34+
" <toolitem action='Refresh'/>"
35+
" <toolitem action='Quit'/>"
36+
" </toolbar>"
37+
"</ui>";
38+
39+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
40+
try
41+
{
42+
m_refUIManager->add_ui_from_string(ui_info);
43+
}
44+
catch(const Glib::Error& ex)
45+
{
46+
fprintf(stderr,"building menus failed: %s",ex.what().c_str());
47+
}
48+
#else
49+
std::auto_ptr<Glib::Error> ex;
50+
m_refUIManager->add_ui_from_string(ui_info,ex);
51+
if(ex.get())
52+
{
53+
fprintf(stderr,"building menus failed: %s",ex->what());
54+
}
55+
#endif //GLIBMM_EXCEPTIONS_ENABLED
56+
57+
Gtk::Widget* pToolbar = m_refUIManager->get_widget("/ToolBar") ;
58+
if(pToolbar)
59+
m_box.pack_start(*pToolbar,Gtk::PACK_SHRINK);
60+
m_box.pack_start(m_scrolled_window);
61+
62+
m_ref_tree_model=Gtk::TreeStore::create(m_columns);
63+
m_tree_view.set_model(m_ref_tree_model);
64+
65+
//Add the TreeView's view columns:
66+
Gtk::TreeViewColumn col_name("Name",m_columns.m_col_name);
67+
Gtk::TreeViewColumn col_value("Value",m_columns.m_col_value);
68+
Gtk::TreeViewColumn col_comment("Comment",m_columns.m_col_comment);
69+
70+
col_name.set_resizable();
71+
col_value.set_resizable();
72+
col_comment.set_resizable();
73+
74+
m_tree_view.append_column(col_name);
75+
m_tree_view.append_column(col_value);
76+
m_tree_view.append_column(col_comment);
77+
78+
show_all_children();
79+
80+
on_refresh();
81+
}
82+
83+
ListUsb::~ListUsb()
84+
{
85+
}
86+
87+
void ListUsb::on_quit()
88+
{
89+
hide();
90+
}
91+
92+
void ListUsb::on_refresh()
93+
{
94+
const char *filename="temp.txt";
95+
const char *command="lsusb -v > temp.txt";
96+
97+
m_ref_tree_model->clear();
98+
99+
int ret=system(command);
100+
101+
if(ret==0)
102+
parse(filename);
103+
104+
::remove(filename);
105+
}
106+
107+
size_t get_left_padding(const std::string& str)
108+
{
109+
size_t i=0;
110+
while(i<str.size() && str[i]==' ')
111+
i++;
112+
return i;
113+
}
114+
115+
std::string trim(const std::string& str)
116+
{
117+
size_t left=0;
118+
while(left<str.size() && str[left]==' ')
119+
left++;
120+
if(left==str.size())
121+
return std::string();
122+
// we can safely assume that str.size()>0
123+
size_t right=str.size()-1;
124+
// we can safely assume that right>0 at any time
125+
while(str[right]==' ')
126+
right--;
127+
128+
assert(left<str.size() && right<str.size() && left<=right);
129+
return str.substr(left,right-left+1);
130+
}
131+
132+
void ListUsb::parse(const char *filename)
133+
{
134+
std::ifstream f(filename);
135+
std::string str;
136+
std::vector<Gtk::TreeStore::iterator> stack;
137+
138+
const size_t indent_step=2;
139+
std::vector<size_t> possible_value_last_pos;
140+
141+
// order is important !
142+
possible_value_last_pos.push_back(22);// for hubs
143+
possible_value_last_pos.push_back(24);// usual value
144+
145+
while(getline(f,str))
146+
{
147+
// ignore empty line
148+
if(str.size()==0)
149+
continue;
150+
// get padding
151+
size_t indent=get_left_padding(str);
152+
// trim left
153+
str.erase(0,indent);
154+
155+
// ignore ill-formed lined
156+
if(indent%indent_step!=0)
157+
continue;
158+
indent/=indent_step;
159+
160+
std::string name;
161+
std::string value;
162+
std::string comment;
163+
bool ok_value=false;
164+
165+
// default behaviour
166+
name=str;
167+
// special cases for descriptive lines
168+
// and also for device announcement lines
169+
if(str[str.size()-1]==':' || str.substr(0,3)=="Bus")
170+
goto Ladd;
171+
172+
for(size_t pvlp=0;pvlp<possible_value_last_pos.size();pvlp++)
173+
{
174+
size_t value_last_pos=possible_value_last_pos[pvlp];
175+
size_t value_first_pos=possible_value_last_pos[pvlp];
176+
// try to see if there is a value
177+
if(str.size()<=value_last_pos || !isxdigit(str[value_last_pos]))
178+
continue;
179+
180+
// it's possible so read back the value: accept hex digits, 'x' and '.'
181+
bool ok=true;
182+
183+
while(value_first_pos>0)
184+
{
185+
char c=str[value_first_pos];
186+
if(c==' ')
187+
break;
188+
else if(isxdigit(c) || c=='.' || c=='x')
189+
value_first_pos--;
190+
else
191+
{
192+
ok=false;
193+
break;
194+
}
195+
}
196+
197+
if(!ok)
198+
continue;
199+
200+
// we've got a value, try to read forward to pick a value unit (e.g mA)
201+
while(value_last_pos<str.size() && str[value_last_pos]!=' ')
202+
value_last_pos++;
203+
204+
name=trim(str.substr(0,value_first_pos));
205+
value=str.substr(value_first_pos,value_last_pos+1-value_first_pos);
206+
207+
if((value_last_pos+1)<str.size())
208+
comment=trim(str.substr(value_last_pos+1));
209+
210+
ok_value=true;
211+
break;
212+
}
213+
214+
if(!ok_value)
215+
goto Ladd;
216+
217+
Ladd:
218+
// try to find a parent
219+
// special case for device line
220+
if(indent!=0 || str.substr(0,3)!="Bus")
221+
indent++;
222+
223+
Gtk::TreeStore::iterator it;
224+
225+
if(indent==0)
226+
{
227+
it=m_ref_tree_model->append();
228+
}
229+
else
230+
{
231+
size_t par_level=indent-1;
232+
if(par_level>=stack.size())
233+
continue;// ignore line
234+
it=m_ref_tree_model->append(stack[par_level]->children());
235+
}
236+
237+
// add to stack
238+
if(indent==stack.size())
239+
stack.push_back(it);
240+
else
241+
stack[indent]=it;
242+
243+
Gtk::TreeModel::Row row=*it;
244+
row[m_columns.m_col_name]=name;
245+
row[m_columns.m_col_value]=value;
246+
row[m_columns.m_col_comment]=comment;
247+
}
248+
249+
f.close();
250+
}
251+
252+
int main(int argc,char **argv)
253+
{
254+
Gtk::Main kit(argc,argv);
255+
256+
ListUsb lsusb;
257+
Gtk::Main::run(lsusb);
258+
259+
return 0;
260+
}
261+

‎lsusb_gtk/lsusb_gtk.hpp

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef __lsusb_gtk__
2+
#define __lsusb_gtk__
3+
4+
#include <gtkmm/window.h>
5+
#include <gtkmm/window.h>
6+
#include <gtkmm/stock.h>
7+
#include <gtkmm/uimanager.h>
8+
#include <gtkmm/box.h>
9+
#include <gtkmm/treestore.h>
10+
#include <gtkmm/treeview.h>
11+
#include <gtkmm/scrolledwindow.h>
12+
13+
class ListUsb : public Gtk::Window
14+
{
15+
public:
16+
ListUsb();
17+
virtual ~ListUsb();
18+
19+
protected:
20+
class ModelColumns : public Gtk::TreeModelColumnRecord
21+
{
22+
public:
23+
ModelColumns()
24+
{
25+
add(m_col_name);
26+
add(m_col_value);
27+
add(m_col_comment);
28+
}
29+
30+
Gtk::TreeModelColumn<Glib::ustring> m_col_name;
31+
Gtk::TreeModelColumn<Glib::ustring> m_col_value;
32+
Gtk::TreeModelColumn<Glib::ustring> m_col_comment;
33+
};
34+
35+
virtual void on_quit();
36+
virtual void on_refresh();
37+
38+
void parse(const char *filename);
39+
40+
Glib::RefPtr<Gtk::UIManager> m_refUIManager;
41+
Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
42+
Gtk::VBox m_box;
43+
ModelColumns m_columns;
44+
Gtk::ScrolledWindow m_scrolled_window;
45+
Gtk::TreeView m_tree_view;
46+
Glib::RefPtr<Gtk::TreeStore> m_ref_tree_model;
47+
};
48+
49+
#endif // __lsusb_gtk__

‎serial_reader/Makefile

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
CC=gcc
2+
CXX=g++
3+
CFLAGS=-W -Wall -O2 `pkg-config --cflags libusb-1.0` -std=c99 -g
4+
CXXFLAGS=-W -Wall -O2 `pkg-config --cflags gtkmm-2.4` -g
5+
LDFLAGS=`pkg-config --libs libusb-1.0` `pkg-config --libs gtkmm-2.4`
6+
SRC=$(wildcard *.c)
7+
SRCXX=$(wildcard *.cpp)
8+
OBJ=$(SRC:.c=) $(SRCXX:.cpp=)
9+
10+
all: $(OBJ)
11+
12+
%: %.c
13+
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
14+
15+
%: %.cpp
16+
$(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
17+
18+
clean:
19+
rm -rf $(OBJ)
20+
21+

‎serial_reader/serial_reader.c

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <libusb.h>
4+
#include <assert.h>
5+
#include <stdbool.h>
6+
#include <string.h>
7+
8+
struct command_block_wrapper
9+
{
10+
unsigned int signature;
11+
unsigned int tag;
12+
unsigned int data_transfer_length;
13+
unsigned char flags;
14+
unsigned char lun;
15+
unsigned char command_length;
16+
unsigned char command_block[16];
17+
} __attribute__ ((packed));
18+
19+
#define CBW_SIGNATURE 0x43425355
20+
#define SCSI_READ_10 0x28
21+
22+
void main_loop(libusb_device_handle *handle)
23+
{
24+
libusb_device *device=libusb_get_device(handle);
25+
printf("device found at %d:%d\n",
26+
libusb_get_bus_number(device),
27+
libusb_get_device_address(device));
28+
29+
struct libusb_device_descriptor dev_desc;
30+
int res=libusb_get_device_descriptor(device,&dev_desc);
31+
assert(res==0);
32+
33+
const int STRING_SIZE=64;
34+
unsigned char string[STRING_SIZE];
35+
36+
/*
37+
res=libusb_get_string_descriptor_ascii(handle,dev_desc.iProduct,string,STRING_SIZE);
38+
assert(res>=0);
39+
printf("device: %s\n",string);
40+
*/
41+
42+
int config_id;
43+
res=libusb_get_configuration(handle,&config_id);
44+
assert(res==0);
45+
struct libusb_config_descriptor *config;
46+
res=libusb_get_active_config_descriptor(device,&config);
47+
assert(res==0);
48+
49+
printf("configuration: %d\n",config_id);
50+
printf("interfaces: %d\n",config->bNumInterfaces);
51+
52+
int serial_interface=-1;
53+
54+
for(int i=0;i<config->bNumInterfaces;i++)
55+
{
56+
printf("interface %d: alternative settings: %d\n",i,config->interface[i].num_altsetting);
57+
for(int j=0;j<config->interface[i].num_altsetting;j++)
58+
{
59+
/*
60+
res=libusb_get_string_descriptor_ascii(handle,config->interface[i].altsetting[j].iInterface,string,STRING_SIZE);
61+
assert(res>=0);
62+
*/
63+
64+
printf("interface %d,%d: class=%#x\n",i,j,config->interface[i].altsetting[j].bInterfaceClass);
65+
printf("interface %d,%d: subclass=%#x\n",i,j,config->interface[i].altsetting[j].bInterfaceSubClass);
66+
67+
if(config->interface[i].altsetting[j].bInterfaceClass==LIBUSB_CLASS_DATA)
68+
serial_interface=i;
69+
}
70+
}
71+
72+
printf("serial interface: %d\n",serial_interface);
73+
struct libusb_interface_descriptor *interface=&config->interface[serial_interface].altsetting[0];
74+
75+
res=libusb_claim_interface(handle,serial_interface);
76+
if(res!=0)
77+
{
78+
printf("claim error: %d\n",res);
79+
assert(false);
80+
}
81+
82+
printf("endpoints: %d\n",interface->bNumEndpoints);
83+
84+
int read_endpoint=-1;
85+
int write_endpoint=-1;
86+
87+
for(int i=0;i<interface->bNumEndpoints;i++)
88+
{
89+
printf("endpoint %d: addr=%d dir=%d type=%d\n",i,
90+
interface->endpoint[i].bEndpointAddress&0x7,interface->endpoint[i].bEndpointAddress>>7,
91+
interface->endpoint[i].bmAttributes&0x3);
92+
93+
if(interface->endpoint[i].bEndpointAddress&LIBUSB_ENDPOINT_IN)
94+
read_endpoint=interface->endpoint[i].bEndpointAddress;
95+
else
96+
write_endpoint=interface->endpoint[i].bEndpointAddress;
97+
}
98+
99+
const int READ_BUF_SIZE=512;
100+
char buffer[READ_BUF_SIZE];
101+
int xfered;
102+
103+
printf("read endpoint: %#x\n",read_endpoint);
104+
printf("write endpoint: %#x\n",write_endpoint);
105+
106+
sprintf(buffer,"HELLO FROM SERIAL_READER\n");
107+
108+
109+
res=libusb_bulk_transfer(handle,write_endpoint,buffer,strlen(buffer),&xfered,0);
110+
if(res<0)
111+
printf("write xfer error: %d\n",res);
112+
else
113+
printf("write xfer success\n");
114+
115+
while(1)
116+
{
117+
res=libusb_bulk_transfer(handle,read_endpoint,buffer,/*READ_BUF_SIZE*/32,&xfered,0);
118+
if(res<0)
119+
{
120+
printf("xfer error: %d\n",res);
121+
//assert(false);
122+
break;
123+
}
124+
/*
125+
else
126+
printf("xfered: %d\n",xfered);
127+
*/
128+
buffer[xfered]=0;
129+
printf("%s",buffer);
130+
fflush(stdout);
131+
}
132+
133+
libusb_release_interface(handle,serial_interface);
134+
}
135+
136+
bool is_sansa(libusb_device *dev)
137+
{
138+
struct libusb_device_descriptor dev_desc;
139+
int res=libusb_get_device_descriptor(dev,&dev_desc);
140+
assert(res==0);
141+
142+
return dev_desc.idVendor==0x0781 && (dev_desc.idProduct==0x7421 || dev_desc.idProduct==0x74d1);
143+
}
144+
145+
int main(int argc,char **argv)
146+
{
147+
(void)argc;
148+
(void)argv;
149+
150+
assert(libusb_init(NULL)==0);
151+
152+
libusb_set_debug(NULL,3);
153+
154+
libusb_device **device_list;
155+
ssize_t list_size=libusb_get_device_list(NULL,&device_list);
156+
157+
assert(list_size>=0);
158+
159+
libusb_device *found = NULL;
160+
for(ssize_t i=0;i<list_size;i++)
161+
{
162+
if(is_sansa(device_list[i]))
163+
found=device_list[i];
164+
}
165+
166+
if(found)
167+
{
168+
libusb_device_handle *handle;
169+
int err=libusb_open(found,&handle);
170+
assert(err==0);
171+
172+
main_loop(handle);
173+
174+
libusb_close(handle);
175+
}
176+
177+
libusb_free_device_list(device_list,1);
178+
179+
libusb_exit(NULL);
180+
181+
return 0;
182+
}

0 commit comments

Comments
 (0)
Please sign in to comment.