1
2 #include <QApplication>
3 #include <QDesktopWidget>
4 #include <QFile>
5 #include <QProcess>
6 #include "qtbt.h"
7 #include <unistd.h>
8 #include <sys/prctl.h>
9
10 qtBT* qtBT::_instance = nullptr;
state_cb(RK_BT_STATE state)11 void qtBT::state_cb(RK_BT_STATE state)
12 {
13 switch(state) {
14 case RK_BT_STATE_TURNING_ON:
15 qDebug() << "RK_BT_STATE_TURNING_ON";
16 break;
17 case RK_BT_STATE_ON:
18 qDebug() << "RK_BT_STATE_ON";
19 qDebug() << "RK_START_SCAN 10s";
20 #ifdef RKWIFIBTAPP
21 rk_bt_start_discovery(10000, SCAN_TYPE_BREDR);
22 rk_bt_source_open();
23 #endif
24 break;
25 case RK_BT_STATE_TURNING_OFF:
26 qDebug() << "RK_BT_STATE_TURNING_OFF";
27 break;
28 case RK_BT_STATE_OFF:
29 qDebug() << "RK_BT_STATE_OFF";
30 break;
31 }
32 }
33
bond_cb(const char * bd_addr,const char * name,RK_BT_BOND_STATE state)34 void qtBT::bond_cb(const char *bd_addr, const char *name, RK_BT_BOND_STATE state)
35 {
36 switch(state) {
37 case RK_BT_BOND_STATE_NONE:
38 case RK_BT_BOND_STATE_BONDING:
39 break;
40 case RK_BT_BOND_STATE_BONDED:
41 break;
42 }
43 }
44
scan_status_cb(RK_BT_DISCOVERY_STATE status)45 void qtBT::scan_status_cb(RK_BT_DISCOVERY_STATE status)
46 {
47 switch(status) {
48 case RK_BT_DISC_STARTED:
49 case RK_BT_DISC_START_FAILED:
50 case RK_BT_DISC_STOPPED_BY_USER:
51 break;
52 case RK_BT_DISC_STOPPED_AUTO:
53 #ifdef RKWIFIBTAPP
54 rk_bt_start_discovery(10000, SCAN_TYPE_BREDR);
55 #endif
56 break;
57 }
58 }
59
source_connect_cb(void * userdata,const char * bd_addr,const char * name,const RK_BT_SOURCE_EVENT enEvent)60 void qtBT::source_connect_cb(void *userdata, const char *bd_addr, const char *name, const RK_BT_SOURCE_EVENT enEvent)
61 {
62 qtBT *btlist = getInstance();
63 switch(enEvent)
64 {
65 case BT_SOURCE_EVENT_CONNECT_FAILED:
66 qDebug() << "BT_SOURCE_EVENT_CONNECT_FAILED" << name << bd_addr;
67 break;
68 case BT_SOURCE_EVENT_CONNECTED:
69 qDebug() << "BT_SOURCE_EVENT_CONNECTED" << name << bd_addr;
70 for(int i=0; i<btlist->count(); i++){
71 QListWidgetItem *ii = btlist->item(i);
72 QString str = ii->text();
73 QStringList sl = str.split(" ");
74 QString addr = sl.at(1);
75 QString name = sl.at(2);
76 if(!addr.isEmpty() && !addr.compare(QString(bd_addr))){
77 QString str = "Connected " + QString(bd_addr) + " " + QString(name);
78 QListWidgetItem *iitem = btlist->takeItem(i);
79 iitem->setText(str);
80 btlist->insertItem(0, iitem);
81 return;
82 }
83 }
84 break;
85 case BT_SOURCE_EVENT_DISCONNECTED:
86 qDebug() << "BT_SOURCE_EVENT_DISCONNECTED" << name << bd_addr;
87 for(int i=0; i<btlist->count(); i++){
88 QListWidgetItem *ii = btlist->item(i);
89 QString str = ii->text();
90 QStringList sl = str.split(" ");
91 QString addr = sl.at(1);
92 QString name = sl.at(2);
93 if(!addr.isEmpty() && !addr.compare(QString(bd_addr))){
94 QString str = "Paired " + QString(bd_addr) + " " + QString(name);
95 QListWidgetItem *iitem = btlist->takeItem(i);
96 iitem->setText(str);
97 btlist->insertItem(0, iitem);
98 return;
99 }
100 }
101 break;
102 case BT_SOURCE_EVENT_RC_PLAY:
103 case BT_SOURCE_EVENT_RC_STOP:
104 case BT_SOURCE_EVENT_RC_PAUSE:
105 case BT_SOURCE_EVENT_RC_FORWARD:
106 case BT_SOURCE_EVENT_RC_BACKWARD:
107 case BT_SOURCE_EVENT_RC_VOL_UP:
108 case BT_SOURCE_EVENT_RC_VOL_DOWN:
109 qDebug() << "BT_SOURCE_EVENT_RC: " << BT_SOURCE_EVENT_RC_VOL_DOWN << name << bd_addr;
110 break;
111 }
112 }
113
114
scan_cb(const char * address,const char * name,unsigned int bt_class,int rssi,int change)115 void qtBT::scan_cb(const char *address,const char *name, unsigned int bt_class, int rssi, int change)
116 {
117 struct bt_dev_info *dev = new bt_dev_info;
118 qtBT *btlist = getInstance();
119 dev->address = address;
120 dev->name = name;
121 dev->bt_class = bt_class;
122 dev->rssi = rssi;
123 btlist->dev_list.append(dev);
124
125 // qDebug() << "address: " << address << "name: " << name << "get name: " << dev->name;
126
127 for(int i=0; i<btlist->count(); i++){
128 QListWidgetItem *ii = btlist->item(i);
129 QString str = ii->text();
130 QStringList sl = str.split(" ");
131 QString addr = sl.at(1);
132 QString name = sl.at(2);
133 if(!addr.isEmpty() && !addr.compare(QString(dev->address))){
134 return;
135 }
136 }
137
138 if(dev->address){
139 QString str = "Unpaired " + QString(dev->address) + " " + QString(dev->name);
140 btlist->addItem(new QListWidgetItem(str, btlist));
141 }
142 }
143
open()144 void qtBT::open()
145 {
146 qDebug() << "bt open";
147
148 #ifdef RKWIFIBTAPP
149 int count;
150 RkBtScanedDevice *dev = NULL;
151 static RkBtScanedDevice *g_dev_list_test;
152
153 memset(&bt_content, 0, sizeof(RkBtContent));
154 bt_content.bt_name = "Rockchip Linux BT";
155 bt_content.bt_addr = "11:22:33:44:55:66";
156 rk_bt_register_state_callback(qtBT::state_cb);
157 rk_bt_register_bond_callback(qtBT::bond_cb);
158 rk_bt_register_discovery_callback(qtBT::scan_status_cb);
159 rk_bt_register_dev_found_callback(qtBT::scan_cb);
160 rk_bt_source_register_status_cb(NULL, source_connect_cb);
161
162 if (rk_bt_init(&bt_content) < 0) {
163 qDebug() << "rk_bt_init error";
164 return;
165 }
166
167 rk_bt_set_device_name("Rockchip Linux BT");
168 rk_bt_enable_reconnect(0);
169 //rk_bt_source_open();
170 rk_bt_get_paired_devices(&g_dev_list_test, &count);
171
172 qDebug() << "current paired devices count: " << count;
173 dev = g_dev_list_test;
174 for(int i = 0; i < count; i++) {
175 qDebug() << i << ": " << dev->remote_address << " " << dev->remote_name << " is_connected: " << dev->is_connected;
176 QString str;
177 if(dev->is_connected)
178 str += "Connected ";
179 else
180 str += "Paired ";
181 str += QString(dev->remote_address) + " " + QString(dev->remote_name);
182 addItem(new QListWidgetItem(str, this));
183 dev = dev->next;
184 }
185 rk_bt_free_paired_devices(g_dev_list_test);
186 g_dev_list_test = NULL;
187 rk_bt_start_discovery(10000, SCAN_TYPE_BREDR);
188 #endif
189 }
190
close()191 void qtBT::close()
192 {
193 qDebug() << "bt close";
194 #ifdef RKWIFIBTAPP
195 //rk_bt_cancel_discovery();
196 rk_bt_deinit();
197 #endif
198 }
199
qtBT(QWidget * parent,QLabel * label,QPushButton * btn,bool on)200 qtBT::qtBT(QWidget *parent, QLabel *label, QPushButton *btn, bool on)
201 {
202 const QRect availableGeometry = QApplication::desktop()->availableGeometry(parent);
203 resize(availableGeometry.width(), availableGeometry.height());
204 QFont font;
205 font.setPixelSize(availableGeometry.height()/40);
206 if(btn){
207 switchBtn = btn;
208 switchBtn->setCheckable(true);
209 switchBtn->setVisible(true);
210 switchBtn->setStyleSheet("QPushButton{background-color:green;}");
211 switchBtn->setStyleSheet("QPushButton:checked{background-color:red;}");
212 if (on){
213 switchBtn->setChecked(true);
214 switchBtn->setText("on");
215 } else {
216 switchBtn->setChecked(false);
217 switchBtn->setText("off");
218 }
219 connect(switchBtn, SIGNAL(clicked(bool)), this, SLOT(on_btnClicked()));
220 }
221
222 setObjectName("BT");
223 setFont(font);
224 connect(this, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(on_itemClicked(QListWidgetItem *)));
225 show();
226 qDebug() << "bt init: " << on;
227 if(on)
228 turnOn();
229 }
230
~qtBT()231 qtBT::~qtBT()
232 {
233 #ifdef RKWIFIBTAPP
234 rk_bt_cancel_discovery();
235 #endif
236 if(switchBtn){
237 switchBtn->setVisible(false);
238 }
239 _instance = nullptr;
240 }
241
isOn()242 bool qtBT::isOn()
243 {
244 if(switchBtn){
245 if (! switchBtn->text().compare("on")){
246 return true;
247 } else {
248 return false;
249 }
250 }
251 return false;
252 }
253
turnOn()254 void qtBT::turnOn()
255 {
256 if(QFile::exists("/userdata")){
257 open();
258 } else {
259 QStringList list;
260 list << "bt1" << "bt2" << "bt3" << "bt4" << "bt5" << "bt6" << "bt7";
261 addItems(list);
262 }
263 }
264
turnOff()265 void qtBT::turnOff()
266 {
267 if(QFile::exists("/userdata")){
268 close();
269 }
270 clear();
271 }
272
on_btnClicked()273 void qtBT::on_btnClicked()
274 {
275 if(switchBtn){
276 if (! switchBtn->text().compare("on")){
277 qDebug() << "on_btnClicked turnOff";
278 switchBtn->setText("off");
279 turnOff();
280 } else if (! switchBtn->text().compare("off")){
281 qDebug() << "on_btnClicked turnOn";
282 switchBtn->setText("on");
283 turnOn();
284 }
285 }
286 }
287
on_itemClicked(QListWidgetItem * item)288 void qtBT::on_itemClicked(QListWidgetItem *item)
289 {
290 QString str = item->text();
291 QStringList sl = str.split(" ");
292 QString pair = sl.at(0);
293 QString addr = sl.at(1);
294 QString name = sl.at(2);
295
296 if(!addr.isEmpty()){
297 if(!pair.compare("Paired")){
298 qDebug() << "connecting to " << addr.toLatin1().data();
299 #ifdef RKWIFIBTAPP
300 rk_bt_source_connect_by_addr(addr.toLatin1().data());
301 #endif
302 }else if(!pair.compare("Connected")){
303 qDebug() << "disconnecting " << addr << name;
304 #ifdef RKWIFIBTAPP
305 rk_bt_source_disconnect_by_addr(addr.toLatin1().data());
306 #endif
307 takeItem(row(item));
308 }else{
309 qDebug() << "connecting to " << addr.toLatin1().data();
310 #ifdef RKWIFIBTAPP
311 rk_bt_source_connect_by_addr(addr.toLatin1().data());
312 #endif
313 }
314 }
315 }
316
317