Permalink
Browse files

Scan when adding a new device. Small fixes.

  • Loading branch information...
thesoultaker48 committed Sep 14, 2018
1 parent 6483db0 commit a74e34ce2909ef7517452a9d261f73cc6ebba5e8
Showing with 157 additions and 60 deletions.
  1. +97 −52 modules/bluetoothdevices/bluetoothdevices.class.php
  2. +60 −8 templates/bluetoothdevices/bluetoothdevices.html
@@ -26,10 +26,8 @@ function bluetoothdevices() {
if(IsWindowsOS()) { if(IsWindowsOS()) {
// Windows // Windows
$this->scanMethod = 'discovery'; $this->scanMethod = 'discovery';
if($bluetoothview_version = $this->get_product_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe')) { if($this->check_programs_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe', '1.41')) {
if(!$this->compare_programs_versions($bluetoothview_version, '1.41')) { $this->scanMethod = 'connect';
$this->scanMethod = 'connect';
}
} }
} else { } else {
// Linux // Linux
@@ -108,16 +106,27 @@ private function compare_programs_versions($first, $second) {
return FALSE; return FALSE;
} }
// Check programs version
private function check_programs_version($exe, $version) {
$results = FALSE;
if($product_version = $this->get_product_version($exe)) {
if(!$this->compare_programs_versions($product_version, $version)) {
$results = TRUE;
}
}
return $results;
}
// Bluetooth: reset // Bluetooth: reset
private function bluetooth_reset(&$messages=array()) { private function bluetooth_reset(&$messages=array()) {
$results = FALSE; $results = FALSE;
if(IsWindowsOS()) { if(IsWindowsOS()) {
// Windows // Windows
$messages[] = date('[d/m/Y H:i:s]:').' Reset bluetooth is not supported for Windows OS!'; $messages[] = array('time' => time(), 'text' => 'Reset bluetooth is not supported for Windows OS!');
} else { } else {
// Linux // Linux
$this->get_config(); $this->get_config();
$messages[] = date('[d/m/Y H:i:s]:').' Reset bluetooth...'; $messages[] = array('time' => time(), 'text' => 'Reset bluetooth...');
exec(($this->sudo?'sudo ':'').'hciconfig hci0 down; sudo hciconfig hci0 up'); exec(($this->sudo?'sudo ':'').'hciconfig hci0 down; sudo hciconfig hci0 up');
setGlobal('bluetoothdevices_resetTime', time()); setGlobal('bluetoothdevices_resetTime', time());
$results = TRUE; $results = TRUE;
@@ -132,9 +141,8 @@ private function bluetooth_scan(&$messages=array()) {
// Windows // Windows
// FIXME: does not find BLE devices // FIXME: does not find BLE devices
// FIXME: finds an offline device if it is paired // FIXME: finds an offline device if it is paired
$devices_file = SERVER_ROOT.'/apps/bluetoothview/devices.txt'; $devices_file = SERVER_ROOT.'/apps/bluetoothview/devices_'.uniqid().'.txt';
@unlink($devices_file); exec(SERVER_ROOT.'/apps/bluetoothview/bluetoothview.exe /stab "'.$devices_file.'"');
exec(SERVER_ROOT.'/apps/bluetoothview/bluetoothview.exe /stab '.$devices_file);
if(file_exists($devices_file)) { if(file_exists($devices_file)) {
if($data = LoadFile($devices_file)) { if($data = LoadFile($devices_file)) {
$data = str_replace(chr(0), '', $data); $data = str_replace(chr(0), '', $data);
@@ -143,17 +151,22 @@ private function bluetooth_scan(&$messages=array()) {
$total = count($lines); $total = count($lines);
for($i=0; $i<$total; $i++) { for($i=0; $i<$total; $i++) {
$fields = explode("\t", $lines[$i]); $fields = explode("\t", $lines[$i]);
$results[] = array( $address = trim(strtolower($fields[2]));
'address' => strtolower($fields[2]), $name = trim($fields[1]);
'name' => trim($fields[1]), if(!empty($address)) {
); $results[] = array(
'address' => $address,
'name' => $name,
);
}
} }
} else { } else {
$messages[] = date('[d/m/Y H:i:s]:').' Error opening file "'.$devices_file.'"!'; $messages[] = array('time' => time(), 'text' => 'Error opening file "'.$devices_file.'"!');
$results = FALSE; $results = FALSE;
} }
@unlink($devices_file);
} else { } else {
$messages[] = date('[d/m/Y H:i:s]:').' Missing file "'.$devices_file.'"!'; $messages[] = array('time' => time(), 'text' => 'Missing file "'.$devices_file.'"!');
$results = FALSE; $results = FALSE;
} }
} else { } else {
@@ -165,13 +178,14 @@ private function bluetooth_scan(&$messages=array()) {
$total = count($data); $total = count($data);
for($i=0; $i<$total; $i++) { for($i=0; $i<$total; $i++) {
$data[$i] = trim($data[$i]); $data[$i] = trim($data[$i]);
if(!$data[$i]) { $address = trim(strtolower(substr($data[$i], 0, 17)));
continue; $name = trim(substr($data[$i], 17));
if(!empty($address)) {
$results[] = array(
'address' => $address,
'name' => $name,
);
} }
$results[] = array(
'address' => strtolower(substr($data[$i], 0, 17)),
'name' => trim(substr($data[$i], 17)),
);
} }
} }
return $results; return $results;
@@ -200,7 +214,7 @@ private function bluetooth_ping($address, &$messages=array()) {
$results = FALSE; $results = FALSE;
if(IsWindowsOS()) { if(IsWindowsOS()) {
// Windows // Windows
$messages[] = date('[d/m/Y H:i:s]:').' Method "ping" is not supported for Windows OS!'; $messages[] = array('time' => time(), 'text' => 'Method "ping" is not supported for Windows OS!');
} else { } else {
// Linux // Linux
$this->get_config(); $this->get_config();
@@ -214,7 +228,7 @@ private function bluetooth_ping($address, &$messages=array()) {
// Bluetooth: discovery // Bluetooth: discovery
private function bluetooth_discovery($address, &$messages=array()) { private function bluetooth_discovery($address, &$messages=array()) {
$devices = bluetooth_scan($messages); $devices = $this->bluetooth_scan($messages);
if(is_array($devices)) { if(is_array($devices)) {
foreach($devices as $device) { foreach($devices as $device) {
if($device['address'] == $address) { if($device['address'] == $address) {
@@ -230,18 +244,14 @@ private function bluetooth_connect($address, &$messages=array()) {
$results = FALSE; $results = FALSE;
if(IsWindowsOS()) { if(IsWindowsOS()) {
// Windows // Windows
if($bluetoothview_version = $this->get_product_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe')) { if($this->check_programs_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe', '1.41')) {
if(!$this->compare_programs_versions($bluetoothview_version, '1.41')) { // BluetoothView version >= 1.41
// BluetoothView version >= 1.41 exec(SERVER_ROOT.'/apps/bluetoothview/bluetoothview.exe /try_to_connect '.$address, $data, $code);
exec(SERVER_ROOT.'/apps/bluetoothview/bluetoothview.exe /try_to_connect '.$address, $data, $code); if($code == 0) {
if($code == 0) { $results = TRUE;
$results = TRUE;
}
} else {
$messages[] = date('[d/m/Y H:i:s]:').' The current version of BluetoothView is lower than required (1.41)!';
} }
} else { } else {
$messages[] = date('[d/m/Y H:i:s]:').' it is impossible to determine the version of BluetoothView!'; $messages[] = array('time' => time(), 'text' => 'The current version of BluetoothView is lower than required (1.41)!');
} }
} else { } else {
// Linux // Linux
@@ -327,6 +337,11 @@ function admin(&$out) {
} }
// OS type // OS type
$out['IS_WINDOWS_OS'] = (int)IsWindowsOS(); $out['IS_WINDOWS_OS'] = (int)IsWindowsOS();
// Features
$out['IS_HYBRID_AVAILABLE'] = (int)!IsWindowsOS();
$out['IS_PING_AVAILABLE'] = (int)!IsWindowsOS();
$out['IS_SCAN_AVAILABLE'] = (int)TRUE;
$out['IS_CONNECT_AVAILABLE'] = (int)TRUE;
// Views // Views
if($this->data_source == 'bluetoothdevices' || $this->data_source == '') { if($this->data_source == 'bluetoothdevices' || $this->data_source == '') {
switch($this->view_mode) { switch($this->view_mode) {
@@ -350,10 +365,8 @@ function admin(&$out) {
$out['BV_UNSUPPORTED_VERSION'] = (int)FALSE; $out['BV_UNSUPPORTED_VERSION'] = (int)FALSE;
if(IsWindowsOS()) { if(IsWindowsOS()) {
$out['BV_UNSUPPORTED_VERSION'] = (int)TRUE; $out['BV_UNSUPPORTED_VERSION'] = (int)TRUE;
if($bluetoothview_version = $this->get_product_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe')) { if($this->check_programs_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe', '1.41')) {
if(!$this->compare_programs_versions($bluetoothview_version, '1.41')) { $out['BV_UNSUPPORTED_VERSION'] = (int)FALSE;
$out['BV_UNSUPPORTED_VERSION'] = (int)FALSE;
}
} }
} }
} }
@@ -379,18 +392,11 @@ function settings_bluetoothdevices(&$out) {
$out['SCAN_INTERVAL'] = $this->scanInterval; $out['SCAN_INTERVAL'] = $this->scanInterval;
$out['SCAN_TIMEOUT'] = $this->scanTimeout; $out['SCAN_TIMEOUT'] = $this->scanTimeout;
$out['RESET_INTERVAL'] = $this->resetInterval; $out['RESET_INTERVAL'] = $this->resetInterval;
// Features
$out['IS_HYBRID_AVAILABLE'] = (int)!IsWindowsOS();
$out['IS_PING_AVAILABLE'] = (int)!IsWindowsOS();
$out['IS_SCAN_AVAILABLE'] = (int)TRUE;
$out['IS_CONNECT_AVAILABLE'] = (int)TRUE;
// BluetoothView // BluetoothView
if(IsWindowsOS()) { if(IsWindowsOS()) {
$out['IS_CONNECT_AVAILABLE'] = (int)FALSE; $out['IS_CONNECT_AVAILABLE'] = (int)FALSE;
if($bluetoothview_version = $this->get_product_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe')) { if($this->check_programs_version(SERVER_ROOT.'/apps/bluetoothview/BluetoothView.exe', '1.41')) {
if(!$this->compare_programs_versions($bluetoothview_version, '1.41')) { $out['IS_CONNECT_AVAILABLE'] = (int)TRUE;
$out['IS_CONNECT_AVAILABLE'] = (int)TRUE;
}
} }
} }
} }
@@ -512,7 +518,46 @@ function list_bluetoothdevices(&$out) {
// FrontEnd // FrontEnd
function usual(&$out) { function usual(&$out) {
global $session; global $session, $ajax, $command;
if(isset($ajax)) {
// JSON default
$json = array(
'command' => $command,
'success' => FALSE,
'message' => NULL,
'data' => NULL,
);
// Command
switch($command) {
case 'scan':
$messages = array();
$data = $this->bluetooth_scan($messages);
if(is_array($data)) {
$json['success'] = TRUE;
$json['message'] = 'OK';
$json['data'] = $data;
} else {
$json['success'] = FALSE;
if(count($messages) > 0) {
foreach($messages as $message) {
$json['message'] .= $message['text'].' ';
}
$json['message'] = trim($json['message']);
} else {
$json['message'] = 'bluetooth_scan() error!';
}
}
break;
default:
$json['success'] = FALSE;
$json['message'] = 'Unknown command!';
}
// Return json
if(!$this->intCall) {
$session->save();
die(json_encode($json));
}
}
} }
// Cycle // Cycle
@@ -536,20 +581,20 @@ function processCycle() {
$is_found = $this->bluetooth_hybrid($address, $messages); $is_found = $this->bluetooth_hybrid($address, $messages);
break; break;
case 'ping': // Ping case 'ping': // Ping
$is_found = $this->bluetooth_hybrid($address, $messages); $is_found = $this->bluetooth_ping($address, $messages);
break; break;
case 'discovery': // Discovery case 'discovery': // Discovery
$is_found = $this->bluetooth_hybrid($address, $messages); $is_found = $this->bluetooth_discovery($address, $messages);
break; break;
case 'connect': // Connect case 'connect': // Connect
$is_found = $this->bluetooth_hybrid($address, $messages); $is_found = $this->bluetooth_connect($address, $messages);
break; break;
default: default:
$messages[] = date('[d/m/Y H:i:s]:').' Unknown method "'.$this->scanMethod.'"!'; $messages[] = array('time' => time(), 'text' => 'Unknown method "'.$this->scanMethod.'"!');
} }
// Print messages // Print messages
foreach($messages as $message) { foreach($messages as $message) {
echo $message.PHP_EOL; echo date('[d/m/Y H:i:s]:', $message['time']).' '.$message['text'].PHP_EOL;
} }
// Update object // Update object
if($is_found) { if($is_found) {
@@ -20,14 +20,14 @@
[#endif#] [#endif#]
[#if DEVICES#] [#if DEVICES#]
<table align="center" class="table table-striped"> <table align="center" class="table table-striped">
<tr> <tr class="table_header">
<td><b>Объект</b></td> <th>Объект</th>
<td>&nbsp;</td> <th>&nbsp;</th>
<td><b>Описание</b></td> <th>Описание</th>
<td><b>Адрес устройства</b></td> <th>Адрес устройства</th>
<td><b>Последняя активность</b></td> <th>Последняя активность</th>
<td><b>Пользователь</b></td> <th>Пользователь</th>
<td>&nbsp;</td> <th>&nbsp;</th>
</tr> </tr>
[#begin DEVICES#] [#begin DEVICES#]
<tr> <tr>
@@ -57,6 +57,58 @@
[#if VIEW_MODE="add_bluetoothdevices"#] [#if VIEW_MODE="add_bluetoothdevices"#]
[#if ERROR_TEXT#]<div class="alert alert-error">[#ERROR_TEXT#]</div>[#endif#] [#if ERROR_TEXT#]<div class="alert alert-error">[#ERROR_TEXT#]</div>[#endif#]
[#if IS_SCAN_AVAILABLE==1#]
<script type="text/javascript">
// Scan bluetooth devices
function bluetooth_rescan() {
if($('#bluetooth_searching').is(':hidden')) {
$('.bt_scan_btn').css('color', '#ccc');
$('table.devices_list').find('tr').not('.table_header').remove();
$('#bluetooth_searching').show();
$.ajax({
url: '/apps/bluetoothdevices.html?ajax=1&command=scan',
dataType: 'json'
}).done(function(json) {
if(json.success) {
json.data.forEach(function(item) {
$('table.devices_list tr:last').after('<tr><td class="bt_address" style="vertical-align: middle; padding-left: 15px;">'+item.address+'</td><td class="bt_name" style="vertical-align: middle;">'+item.name+'</td><td style="vertical-align: middle; padding-right: 15px; text-align: right;"><a href="#" class="btn btn-default btn-sm" title="Выбрать устройство" onclick="return bluetooth_select(this);"><i class="glyphicon glyphicon-ok"></i></a></td></tr>');
});
} else {
console.warn(json.message);
}
}).fail(function(jqXHR) {
console.error('Error '+jqXHR.status+': '+jqXHR.statusText);
}).always(function() {
$('#bluetooth_searching').hide();
$('.bt_scan_btn').css('color', '');
});
}
}
// Select bluetooth device
function bluetooth_select(obj) {
var tr = $(obj).closest('tr');
var address = $(tr).find('td.bt_address').text();
var name = $(tr).find('td.bt_name').text();
$('input[name=address]').val(address);
$('input[name=description]').val(name);
}
// Page has fully loaded
$(document).ready(function() {
bluetooth_rescan();
});
</script>
<table align="center" class="table table-striped devices_list">
<tr class="table_header">
<th style="vertical-align: middle; padding-left: 15px;">Адрес устройства</th>
<th style="vertical-align: middle;">Имя устройства</th>
<th style="vertical-align: middle; padding-right: 15px; text-align: right;"><a href="#" class="btn btn-default btn-sm bt_scan_btn" title="Обновить список" onclick="return bluetooth_rescan();"><i class="glyphicon glyphicon-refresh"></i></a></th>
</tr>
</table>
<div id="bluetooth_searching" style="text-align: center; display: none;">Поиск Bluetooth устройств...</div>
<hr>
[#endif#]
<form action="?" method="post" class="form-horizontal"> <form action="?" method="post" class="form-horizontal">
<fieldset> <fieldset>
<div class="form-group"> <div class="form-group">

0 comments on commit a74e34c

Please sign in to comment.