2007/07/26
[barry.git] / tools / bcharge.cc
blob8ccb72e107ea5717f016e484aa695d6d9be0910c
1 ///
2 /// \file bcharge.cc
3 /// Talk to the Blackberry just enough to change the Max Power
4 /// to 500mA. Cycles through all devices attached to USB,
5 /// attempting to set all matching Blackberry devices to charge.
6 ///
7 /// This file is part of the Barry project:
8 ///
9 /// http://www.netdirect.ca/software/packages/barry/index.php
10 /// http://sourceforge.net/projects/barry
11 ///
12 /// Compile with the following command (needs libusb):
13 ///
14 /// g++ -o bcharge bcharge.cc -lusb
15 ///
18 Copyright (C) 2006-2007, Net Direct Inc. (http://www.netdirect.ca/)
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
25 This program is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
29 See the GNU General Public License in the COPYING file at the
30 root directory of this project for more details.
33 #include <usb.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
38 #define VENDOR_RIM 0x0fca
39 #define PRODUCT_RIM_BLACKBERRY 0x0001
40 #define PRODUCT_RIM_PEARL_DUAL 0x0004
41 #define PRODUCT_RIM_PEARL 0x0006
43 #define IPRODUCT_RIM_HANDHELD 2
44 #define IPRODUCT_RIM_MASS_STORAGE 4
45 #define IPRODUCT_RIM_COMPOSITE 5
47 #define BLACKBERRY_INTERFACE 0
48 #define BLACKBERRY_CONFIGURATION 1
50 bool old_style_pearl = false;
51 bool force_dual = false;
53 void charge(struct usb_dev_handle *handle)
55 // the special sauce... these steps seem to do the trick
56 // for the 7750 series... needs testing on others
57 char buffer[2];
58 usb_control_msg(handle, 0xc0, 0xa5, 0, 1, buffer, 2, 100);
59 usb_control_msg(handle, 0x40, 0xa2, 0, 1, buffer, 0, 100);
62 void pearl_mode(struct usb_dev_handle *handle)
64 char buffer[2];
65 if( old_style_pearl ) {
66 // use this for "old style" interface: product ID 0001
67 usb_control_msg(handle, 0xc0, 0xa9, 0, 1, buffer, 2, 100);
69 else {
70 // Product ID 0004
71 usb_control_msg(handle, 0xc0, 0xa9, 1, 1, buffer, 2, 100);
75 void process(struct usb_device *dev, bool is_pearl)
77 bool apply = false;
78 printf("Found device #%s...", dev->filename);
80 // open
81 usb_dev_handle *handle = usb_open(dev);
82 if( !handle ) {
83 printf("unable to open device\n");
84 return;
87 // adjust power
88 if( dev->config &&
89 dev->descriptor.bNumConfigurations >= 1 &&
90 dev->config[0].MaxPower < 250 ) {
91 printf("adjusting charge setting");
92 charge(handle);
93 apply = true;
95 else {
96 printf("already at 500mA");
99 // adjust Pearl mode
100 if( is_pearl || force_dual ) {
101 int desired_mode = old_style_pearl
102 ? PRODUCT_RIM_BLACKBERRY : PRODUCT_RIM_PEARL_DUAL;
104 if( desired_mode != dev->descriptor.idProduct ) {
105 printf("...adjusting Pearl mode to %s",
106 old_style_pearl ? "single" : "dual");
107 pearl_mode(handle);
108 apply = true;
110 else {
111 printf("...already in desired Pearl mode");
114 else {
115 printf("...no Pearl adjustment");
118 // apply changes
119 if( apply ) {
120 usb_set_configuration(handle, BLACKBERRY_CONFIGURATION);
122 // the Blackberry Pearl doesn't reset itself after the above,
123 // so do it ourselves
124 if( is_pearl || force_dual ) {
125 usb_reset(handle);
128 printf("...done\n");
130 else {
131 printf("...no change\n");
134 // cleanup
135 usb_close(handle);
138 int main(int argc, char *argv[])
140 struct usb_bus *busses;
143 // allow -o command line switch to choose which mode to use for
144 // Blackberry Pearls:
145 // Dual(default): 0004 -d
146 // With switch: 0001 -o
148 old_style_pearl = (argc > 1 && strcmp(argv[1], "-o") == 0);
149 force_dual = (argc > 1 && strcmp(argv[1], "-d") == 0);
151 usb_init();
152 usb_find_busses();
153 usb_find_devices();
154 busses = usb_get_busses();
156 printf("Scanning for Blackberry devices...\n");
158 struct usb_bus *bus;
159 for( bus = busses; bus; bus = bus->next ) {
160 struct usb_device *dev;
162 for (dev = bus->devices; dev; dev = dev->next) {
163 // Is this a blackberry?
164 if( dev->descriptor.idVendor == VENDOR_RIM ) {
165 switch(dev->descriptor.idProduct)
167 case PRODUCT_RIM_BLACKBERRY:
168 process(dev, false);
169 break;
171 case PRODUCT_RIM_PEARL_DUAL:
172 case PRODUCT_RIM_PEARL:
173 process(dev, true);
174 break;