Bugfixes part 3 #209
@@ -201,7 +201,7 @@ ssize_t PICloudServer::Client::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
if (buff.isEmpty()) {
|
if (buff.isEmpty()) {
|
||||||
sz = 0;
|
sz = 0;
|
||||||
} else {
|
} else {
|
||||||
sz = piMini(max_size, buff.size());
|
sz = piMin<ssize_t>(max_size, buff.size_s());
|
||||||
memcpy(read_to, buff.data(), sz);
|
memcpy(read_to, buff.data(), sz);
|
||||||
buff.remove(0, sz);
|
buff.remove(0, sz);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ PIByteArray piDecompress(const PIByteArray & zba) {
|
|||||||
ba.resize(sz);
|
ba.resize(sz);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
ulong s = sz;
|
ulong s = sz;
|
||||||
ret = uncompress(ba.data(), &s, zba.data(), zba.size());
|
ret = uncompress(ba.data(), &s, zba.data(), zba.size() - sizeof(ullong));
|
||||||
if (ret != Z_OK) {
|
if (ret != Z_OK) {
|
||||||
piCout << "[PICompress]"
|
piCout << "[PICompress]"
|
||||||
<< "Error: invalid input or not enought memory"_tr("PICompress");
|
<< "Error: invalid input or not enought memory"_tr("PICompress");
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "picrypt.h"
|
#include "picrypt.h"
|
||||||
|
|
||||||
#include "pitranslator.h"
|
#include "pitranslator.h"
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ bool PICrypt::setKey(const PIByteArray & _key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PICrypt::setKey(const PIString & secret) {;
|
bool PICrypt::setKey(const PIString & secret) {
|
||||||
key_ = hash(secret);
|
key_ = hash(secret);
|
||||||
return key_.isNotEmpty();
|
return key_.isNotEmpty();
|
||||||
}
|
}
|
||||||
@@ -262,7 +263,6 @@ PIByteArray PICrypt::signMessage(const PIByteArray & data, const PIByteArray & s
|
|||||||
bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key) {
|
bool PICrypt::verifySign(const PIByteArray & data, const PIByteArray & signature, const PIByteArray & public_key) {
|
||||||
if (!init()) return false;
|
if (!init()) return false;
|
||||||
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0);
|
return (crypto_sign_verify_detached(signature.data(), data.data(), data.size(), public_key.data()) == 0);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -317,10 +317,10 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, const PIByteArray &
|
|||||||
return PIByteArray();
|
return PIByteArray();
|
||||||
}
|
}
|
||||||
PIByteArray n;
|
PIByteArray n;
|
||||||
n.resize(crypto_secretbox_NONCEBYTES);
|
n.resize(crypto_box_NONCEBYTES);
|
||||||
const ullong data_size = crypt_data.size() - n.size();
|
const ullong data_size = crypt_data.size() - n.size();
|
||||||
PIByteArray ret;
|
PIByteArray ret;
|
||||||
ret.resize(data_size - crypto_secretbox_MACBYTES);
|
ret.resize(data_size - crypto_box_MACBYTES);
|
||||||
memcpy(n.data(), crypt_data.data(data_size), n.size());
|
memcpy(n.data(), crypt_data.data(data_size), n.size());
|
||||||
if (crypto_box_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), public_key.data(), secret_key.data()) != 0) {
|
if (crypto_box_open_easy(ret.data(), crypt_data.data(), data_size, n.data(), public_key.data(), secret_key.data()) != 0) {
|
||||||
// Bad key
|
// Bad key
|
||||||
|
|||||||
@@ -92,5 +92,10 @@ void CurlThreadPool::destroy() {
|
|||||||
for (auto c: *cr)
|
for (auto c: *cr)
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
auto cr = clients_in_proc.getRef();
|
||||||
|
for (auto c: *cr)
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
// piCout << "~CurlThreadPool ok";
|
// piCout << "~CurlThreadPool ok";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
|||||||
} else
|
} else
|
||||||
hdr << int(cd.size_s());
|
hdr << int(cd.size_s());
|
||||||
cd.insert(0, hdr);
|
cd.insert(0, hdr);
|
||||||
|
if (max_packet_size <= 0) return;
|
||||||
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
||||||
for (int i = 0; i < pcnt; ++i) {
|
for (int i = 0; i < pcnt; ++i) {
|
||||||
if (i == pcnt - 1)
|
if (i == pcnt - 1)
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ PILuaProgram::PILuaProgram() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PILuaProgram::~PILuaProgram() {
|
||||||
|
lua_close(PRIVATE->lua_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PILuaProgram::load(const PIString & script) {
|
bool PILuaProgram::load(const PIString & script) {
|
||||||
int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8());
|
int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8());
|
||||||
if (ret != 0) return false;
|
if (ret != 0) return false;
|
||||||
|
|||||||
@@ -270,8 +270,8 @@ PIInit::~PIInit() {
|
|||||||
mach_port_deallocate(mach_task_self(), __pi_mac_clock);
|
mach_port_deallocate(mach_task_self(), __pi_mac_clock);
|
||||||
# endif
|
# endif
|
||||||
if (PRIVATE->delete_locs) {
|
if (PRIVATE->delete_locs) {
|
||||||
if (__syslocname__) delete __syslocname__;
|
if (__syslocname__) delete[] __syslocname__;
|
||||||
if (__sysoemname__) delete __sysoemname__;
|
if (__sysoemname__) delete[] __sysoemname__;
|
||||||
}
|
}
|
||||||
# ifdef PIP_ICU
|
# ifdef PIP_ICU
|
||||||
u_cleanup();
|
u_cleanup();
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ bool PICAN::openDevice() {
|
|||||||
}
|
}
|
||||||
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
|
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
|
||||||
ifreq ifr;
|
ifreq ifr;
|
||||||
strcpy(ifr.ifr_name, path().dataAscii());
|
piZeroMemory(ifr);
|
||||||
|
strncpy(ifr.ifr_name, path().dataAscii(), sizeof(ifr.ifr_name));
|
||||||
piCout << "PICAN try to get interface index...";
|
piCout << "PICAN try to get interface index...";
|
||||||
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
|
if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
|
||||||
piCoutObj << "Error! while determin the interface ioctl";
|
piCoutObj << "Error! while determin the interface ioctl";
|
||||||
@@ -124,7 +125,7 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
#ifdef PIP_CAN
|
#ifdef PIP_CAN
|
||||||
if (sock == -1) return -1;
|
if (sock == -1) return -1;
|
||||||
// piCout << "PICAN read";
|
// piCout << "PICAN read";
|
||||||
can_frame frame;
|
can_frame frame = {};
|
||||||
ssize_t ret = 0;
|
ssize_t ret = 0;
|
||||||
if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame));
|
if (PRIVATE->event.wait(sock)) ret = ::read(sock, &frame, sizeof(can_frame));
|
||||||
if (ret < 0) { /*piCoutObj << "Error while read CAN frame " << ret;*/
|
if (ret < 0) { /*piCoutObj << "Error while read CAN frame " << ret;*/
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
dirent ** list;
|
dirent ** list = nullptr;
|
||||||
int cnt = scandir(p.data(),
|
int cnt = scandir(p.data(),
|
||||||
&list,
|
&list,
|
||||||
0,
|
0,
|
||||||
@@ -381,6 +381,7 @@ PIVector<PIFile::FileInfo> PIDir::entries(const PIRegularExpression & regexp) {
|
|||||||
# else
|
# else
|
||||||
versionsort);
|
versionsort);
|
||||||
# endif
|
# endif
|
||||||
|
if (cnt < 0) return ret;
|
||||||
for (int i = 0; i < cnt; ++i) {
|
for (int i = 0; i < cnt; ++i) {
|
||||||
ret << PIFile::fileInfo(dp + PIString(list[i]->d_name));
|
ret << PIFile::fileInfo(dp + PIString(list[i]->d_name));
|
||||||
free(list[i]);
|
free(list[i]);
|
||||||
|
|||||||
@@ -1206,8 +1206,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
strcpy(ir.ifr_name, in.dataAscii());
|
strcpy(ir.ifr_name, in.dataAscii());
|
||||||
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0) ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
if (ioctl(s, SIOCGIFHWADDR, &ir) == 0) ci.mac = macFromBytes(PIByteArray(ir.ifr_hwaddr.sa_data, 6));
|
||||||
if (ioctl(s, SIOCGIFADDR, &ir) >= 0) ci.address = getSockAddr(&ir.ifr_addr);
|
if (ioctl(s, SIOCGIFADDR, &ir) >= 0) ci.address = getSockAddr(&ir.ifr_addr);
|
||||||
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_addr);
|
if (ioctl(s, SIOCGIFNETMASK, &ir) >= 0) ci.netmask = getSockAddr(&ir.ifr_netmask);
|
||||||
ioctl(s, SIOCGIFMTU, &ci.mtu);
|
if (ioctl(s, SIOCGIFMTU, &ir) == 0) {
|
||||||
|
ci.mtu = ir.ifr_mtu;
|
||||||
|
}
|
||||||
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
|
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
|
||||||
il << ci;
|
il << ci;
|
||||||
}
|
}
|
||||||
@@ -1301,7 +1303,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
|
|||||||
#else
|
#else
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
piZeroMemory(ifr);
|
piZeroMemory(ifr);
|
||||||
strcpy(ifr.ifr_name, interface_.dataAscii());
|
strncpy(ifr.ifr_name, interface_.dataAscii(), sizeof(ifr.ifr_name));
|
||||||
int s = ::socket(AF_INET, SOCK_DGRAM, 0);
|
int s = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (s != -1) {
|
if (s != -1) {
|
||||||
ioctl(s, SIOCGIFADDR, &ifr);
|
ioctl(s, SIOCGIFADDR, &ifr);
|
||||||
|
|||||||
@@ -1292,6 +1292,11 @@ PIVector<PISerial::DeviceInfo> PISerial::availableDevicesInfo(bool test) {
|
|||||||
if (!rok) {
|
if (!rok) {
|
||||||
ret.remove(i);
|
ret.remove(i);
|
||||||
--i;
|
--i;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
CloseHandle(hComm);
|
||||||
|
#else
|
||||||
|
::close(fd);
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
|
|||||||
@@ -144,6 +144,9 @@ bool PISharedMemory::openDevice() {
|
|||||||
::close(fd);
|
::close(fd);
|
||||||
if (PRIVATE->data == MAP_FAILED) {
|
if (PRIVATE->data == MAP_FAILED) {
|
||||||
piCoutObj << "mmap error," << errorString();
|
piCoutObj << "mmap error," << errorString();
|
||||||
|
if (PRIVATE->owner) shm_unlink((const char *)PRIVATE->name.data());
|
||||||
|
PRIVATE->data = nullptr;
|
||||||
|
PRIVATE->owner = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// piCoutObj << "opened" << PRIVATE->data;
|
// piCoutObj << "opened" << PRIVATE->data;
|
||||||
@@ -251,6 +254,7 @@ int PISharedMemory::read(void * read_to, int max_size) {
|
|||||||
|
|
||||||
|
|
||||||
int PISharedMemory::read(void * read_to, int max_size, int offset) {
|
int PISharedMemory::read(void * read_to, int max_size, int offset) {
|
||||||
|
if (offset < 0 || max_size < 0 || offset > dsize - max_size) return -1;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (!PRIVATE->data) return -1;
|
if (!PRIVATE->data) return -1;
|
||||||
CopyMemory(read_to, &(((char *)(PRIVATE->data))[offset]), max_size);
|
CopyMemory(read_to, &(((char *)(PRIVATE->data))[offset]), max_size);
|
||||||
@@ -271,6 +275,7 @@ int PISharedMemory::write(const void * data, int max_size) {
|
|||||||
|
|
||||||
|
|
||||||
int PISharedMemory::write(const void * data, int max_size, int offset) {
|
int PISharedMemory::write(const void * data, int max_size, int offset) {
|
||||||
|
if (offset < 0 || max_size < 0 || offset > dsize - max_size) return -1;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (!PRIVATE->data) return -1;
|
if (!PRIVATE->data) return -1;
|
||||||
CopyMemory(&(((char *)(PRIVATE->data))[offset]), data, max_size);
|
CopyMemory(&(((char *)(PRIVATE->data))[offset]), data, max_size);
|
||||||
|
|||||||
@@ -106,18 +106,24 @@ bool PISPI::openDevice() {
|
|||||||
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode);
|
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MODE, &spi_mode);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
piCoutObj << "can't set spi write mode";
|
piCoutObj << "can't set spi write mode";
|
||||||
|
::close(PRIVATE->fd);
|
||||||
|
PRIVATE->fd = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// piCoutObj << "set bits" << spi_bits;
|
// piCoutObj << "set bits" << spi_bits;
|
||||||
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
|
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
piCoutObj << "can't set bits per word";
|
piCoutObj << "can't set bits per word";
|
||||||
|
::close(PRIVATE->fd);
|
||||||
|
PRIVATE->fd = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// piCoutObj << "set speed" << spi_speed;
|
// piCoutObj << "set speed" << spi_speed;
|
||||||
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
|
ret = ioctl(PRIVATE->fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
piCoutObj << "can't set max write speed hz";
|
piCoutObj << "can't set max write speed hz";
|
||||||
|
::close(PRIVATE->fd);
|
||||||
|
PRIVATE->fd = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
piCoutObj << "SPI open" << path() << "speed:" << spi_speed / 1000 << "KHz"
|
piCoutObj << "SPI open" << path() << "speed:" << spi_speed / 1000 << "KHz"
|
||||||
|
|||||||
@@ -133,6 +133,67 @@ void PIBaseTransfer::received(PIByteArray data) {
|
|||||||
}
|
}
|
||||||
mutex_header.unlock();
|
mutex_header.unlock();
|
||||||
break;
|
break;
|
||||||
|
case pt_Start:
|
||||||
|
mutex_header.lock();
|
||||||
|
if (is_pause && (is_sending || is_receiving)) {
|
||||||
|
if (header.session_id == h.session_id) {
|
||||||
|
is_pause = false;
|
||||||
|
mutex_header.unlock();
|
||||||
|
resumed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_sending && header.session_id != h.session_id) {
|
||||||
|
sendBreak(h.session_id);
|
||||||
|
mutex_header.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_receiving) {
|
||||||
|
if (header.session_id != h.session_id) {
|
||||||
|
piCoutObj << "restart receive"_tr("PIBaseTransfer");
|
||||||
|
mutex_header.unlock();
|
||||||
|
finish_receive(false, true);
|
||||||
|
} else {
|
||||||
|
header.id = 0;
|
||||||
|
sendReply(pt_ReplySuccess);
|
||||||
|
mutex_header.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_header.unlock();
|
||||||
|
if (data.size() == sizeof(StartRequest)) {
|
||||||
|
StartRequest sr;
|
||||||
|
data >> sr;
|
||||||
|
mutex_header.lock();
|
||||||
|
mutex_session.lock();
|
||||||
|
bytes_cur = 0;
|
||||||
|
state_string = "start request";
|
||||||
|
bytes_all = sr.size;
|
||||||
|
header.session_id = h.session_id;
|
||||||
|
header.id = 0;
|
||||||
|
packets_count = 10;
|
||||||
|
session.clear();
|
||||||
|
replies.clear();
|
||||||
|
session.resize(sr.packets);
|
||||||
|
replies.resize(sr.packets + 1);
|
||||||
|
replies.fill(pt_Unknown);
|
||||||
|
pm_string.resize(replies.size(), '-');
|
||||||
|
diag.reset();
|
||||||
|
is_receiving = true;
|
||||||
|
break_ = false;
|
||||||
|
mutex_send.lock();
|
||||||
|
send_queue = 0;
|
||||||
|
mutex_send.unlock();
|
||||||
|
beginReceive();
|
||||||
|
receiveStarted();
|
||||||
|
state_string = "receiving";
|
||||||
|
replies[0] = pt_ReplySuccess;
|
||||||
|
pm_string[0] = '#';
|
||||||
|
mutex_session.unlock();
|
||||||
|
sendReply(pt_ReplySuccess);
|
||||||
|
mutex_header.unlock();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case pt_ReplySuccess:
|
case pt_ReplySuccess:
|
||||||
case pt_ReplyInvalid:
|
case pt_ReplyInvalid:
|
||||||
mutex_header.lock();
|
mutex_header.lock();
|
||||||
@@ -199,68 +260,6 @@ void PIBaseTransfer::received(PIByteArray data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case pt_Start:
|
|
||||||
mutex_header.lock();
|
|
||||||
if (is_pause && (is_sending || is_receiving)) {
|
|
||||||
if (header.session_id == h.session_id) {
|
|
||||||
is_pause = false;
|
|
||||||
mutex_header.unlock();
|
|
||||||
resumed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_sending && header.session_id != h.session_id) {
|
|
||||||
sendBreak(h.session_id);
|
|
||||||
mutex_header.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (is_receiving) {
|
|
||||||
if (header.session_id != h.session_id) {
|
|
||||||
piCoutObj << "restart receive"_tr("PIBaseTransfer");
|
|
||||||
mutex_header.unlock();
|
|
||||||
finish_receive(false, true);
|
|
||||||
} else {
|
|
||||||
header.id = 0;
|
|
||||||
sendReply(pt_ReplySuccess);
|
|
||||||
mutex_header.unlock();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_header.unlock();
|
|
||||||
if (data.size() == sizeof(StartRequest)) {
|
|
||||||
StartRequest sr;
|
|
||||||
data >> sr;
|
|
||||||
mutex_session.lock();
|
|
||||||
mutex_header.lock();
|
|
||||||
bytes_cur = 0;
|
|
||||||
state_string = "start request";
|
|
||||||
bytes_all = sr.size;
|
|
||||||
header.session_id = h.session_id;
|
|
||||||
header.id = 0;
|
|
||||||
packets_count = 10;
|
|
||||||
session.clear();
|
|
||||||
replies.clear();
|
|
||||||
session.resize(sr.packets);
|
|
||||||
replies.resize(sr.packets + 1);
|
|
||||||
replies.fill(pt_Unknown);
|
|
||||||
pm_string.resize(replies.size(), '-');
|
|
||||||
diag.reset();
|
|
||||||
// piCoutObj << "receiveStarted()";
|
|
||||||
is_receiving = true;
|
|
||||||
break_ = false;
|
|
||||||
mutex_send.lock();
|
|
||||||
send_queue = 0;
|
|
||||||
mutex_send.unlock();
|
|
||||||
beginReceive();
|
|
||||||
receiveStarted();
|
|
||||||
state_string = "receiving";
|
|
||||||
replies[0] = pt_ReplySuccess;
|
|
||||||
pm_string[0] = '#';
|
|
||||||
mutex_session.unlock();
|
|
||||||
sendReply(pt_ReplySuccess);
|
|
||||||
mutex_header.unlock();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case pt_Pause:
|
case pt_Pause:
|
||||||
mutex_header.lock();
|
mutex_header.lock();
|
||||||
if (header.session_id == h.session_id) {
|
if (header.session_id == h.session_id) {
|
||||||
@@ -424,8 +423,8 @@ int PIBaseTransfer::checkSession() {
|
|||||||
|
|
||||||
|
|
||||||
void PIBaseTransfer::buildSession(PIVector<Part> parts) {
|
void PIBaseTransfer::buildSession(PIVector<Part> parts) {
|
||||||
mutex_session.lock();
|
|
||||||
mutex_header.lock();
|
mutex_header.lock();
|
||||||
|
mutex_session.lock();
|
||||||
state_string = "calculating parts ... ";
|
state_string = "calculating parts ... ";
|
||||||
session.clear();
|
session.clear();
|
||||||
header.session_id = randomi();
|
header.session_id = randomi();
|
||||||
@@ -478,8 +477,8 @@ void PIBaseTransfer::buildSession(PIVector<Part> parts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cur_size > min_size) session << lfi;
|
if (cur_size > min_size) session << lfi;
|
||||||
mutex_header.unlock();
|
|
||||||
mutex_session.unlock();
|
mutex_session.unlock();
|
||||||
|
mutex_header.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include "picrc.h"
|
#include "picrc.h"
|
||||||
#include "pidiagnostics.h"
|
#include "pidiagnostics.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
|
||||||
//! \~\ingroup IO-Utils
|
//! \~\ingroup IO-Utils
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
@@ -301,7 +303,7 @@ protected:
|
|||||||
bool send_process();
|
bool send_process();
|
||||||
|
|
||||||
uint packet_header_size, part_header_size;
|
uint packet_header_size, part_header_size;
|
||||||
bool break_, is_sending, is_receiving, is_pause;
|
std::atomic<bool> break_{true}, is_sending{false}, is_receiving{false}, is_pause{false};
|
||||||
PIString state_string;
|
PIString state_string;
|
||||||
llong bytes_all, bytes_cur;
|
llong bytes_all, bytes_cur;
|
||||||
|
|
||||||
|
|||||||
@@ -572,6 +572,8 @@ bool PIConnection::removeFilter(const PIString & name_) {
|
|||||||
|
|
||||||
|
|
||||||
void PIConnection::removeAllFilters() {
|
void PIConnection::removeAllFilters() {
|
||||||
|
PIVector<Extractor *> to_delete;
|
||||||
|
PIVector<PIDiagnostics *> diags_to_delete;
|
||||||
__device_pool__->lock();
|
__device_pool__->lock();
|
||||||
for (auto i = extractors.begin(); i != extractors.end(); i++) {
|
for (auto i = extractors.begin(); i != extractors.end(); i++) {
|
||||||
if (!i.value()) continue;
|
if (!i.value()) continue;
|
||||||
@@ -581,14 +583,18 @@ void PIConnection::removeAllFilters() {
|
|||||||
it.value().removeAll(i.value()->extractor);
|
it.value().removeAll(i.value()->extractor);
|
||||||
}
|
}
|
||||||
if (diags_.value(i.value()->extractor)) {
|
if (diags_.value(i.value()->extractor)) {
|
||||||
delete diags_.value(i.value()->extractor);
|
diags_to_delete << diags_.value(i.value()->extractor);
|
||||||
}
|
|
||||||
diags_.remove(i.value()->extractor);
|
diags_.remove(i.value()->extractor);
|
||||||
delete i.value();
|
}
|
||||||
|
to_delete << i.value();
|
||||||
}
|
}
|
||||||
extractors.clear();
|
extractors.clear();
|
||||||
bounded_extractors.clear();
|
bounded_extractors.clear();
|
||||||
__device_pool__->unlock();
|
__device_pool__->unlock();
|
||||||
|
for (auto e: to_delete)
|
||||||
|
delete e;
|
||||||
|
for (auto d: diags_to_delete)
|
||||||
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -994,6 +1000,7 @@ PIIODevice * PIConnection::DevicePool::addDevice(PIConnection * parent, const PI
|
|||||||
if (pmode == mode || pmode == PIIODevice::ReadWrite) return dd->dev;
|
if (pmode == mode || pmode == PIIODevice::ReadWrite) return dd->dev;
|
||||||
if ((mode & PIIODevice::ReadOnly) > 0) {
|
if ((mode & PIIODevice::ReadOnly) > 0) {
|
||||||
if (dd->rthread) {
|
if (dd->rthread) {
|
||||||
|
dd->rthread->stopAndWait();
|
||||||
delete dd->rthread;
|
delete dd->rthread;
|
||||||
dd->rthread = nullptr;
|
dd->rthread = nullptr;
|
||||||
dd->started = false;
|
dd->started = false;
|
||||||
@@ -1133,10 +1140,13 @@ PIConnection::DevicePool::DeviceData::~DeviceData() {
|
|||||||
void PIConnection::DevicePool::run() {
|
void PIConnection::DevicePool::run() {
|
||||||
PIVector<PIConnection *> conns(PIConnection::allConnections());
|
PIVector<PIConnection *> conns(PIConnection::allConnections());
|
||||||
for (PIConnection * c: conns) {
|
for (PIConnection * c: conns) {
|
||||||
|
if (!c) continue;
|
||||||
|
__device_pool__->lock();
|
||||||
for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) {
|
for (auto d = c->diags_.begin(); d != c->diags_.end(); d++) {
|
||||||
if (!d.value()) continue;
|
if (!d.value()) continue;
|
||||||
d.value()->tick(1);
|
d.value()->tick(1);
|
||||||
}
|
}
|
||||||
|
__device_pool__->unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1228,8 +1238,13 @@ void PIConnection::Sender::tick(int) {
|
|||||||
// piCoutObj << "write"<<data.size()<<"bytes to"<<devices.size()<<"devices";
|
// piCoutObj << "write"<<data.size()<<"bytes to"<<devices.size()<<"devices";
|
||||||
for (PIIODevice * d: devices) {
|
for (PIIODevice * d: devices) {
|
||||||
int ret = d->write(data);
|
int ret = d->write(data);
|
||||||
PIDiagnostics * diag = parent->diags_.value(d, nullptr);
|
if (ret > 0) {
|
||||||
if (diag && ret > 0) diag->sended(ret);
|
PIDiagnostics * diag = nullptr;
|
||||||
|
__device_pool__->lock();
|
||||||
|
diag = parent->diags_.value(d, nullptr);
|
||||||
|
__device_pool__->unlock();
|
||||||
|
if (diag) diag->sended(ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ public:
|
|||||||
//! \~russian Создает объект Lua-программы и открывает стандартные библиотеки Lua.
|
//! \~russian Создает объект Lua-программы и открывает стандартные библиотеки Lua.
|
||||||
PILuaProgram();
|
PILuaProgram();
|
||||||
|
|
||||||
|
//! \~english Closes the Lua state and releases all associated resources.
|
||||||
|
//! \~russian Закрывает Lua state и освобождает все связанные ресурсы.
|
||||||
|
~PILuaProgram();
|
||||||
|
|
||||||
//! \~english Loads and executes Lua source code from \a script.
|
//! \~english Loads and executes Lua source code from \a script.
|
||||||
//! \~russian Загружает и выполняет исходный код Lua из \a script.
|
//! \~russian Загружает и выполняет исходный код Lua из \a script.
|
||||||
bool load(const PIString & script);
|
bool load(const PIString & script);
|
||||||
|
|||||||
@@ -242,7 +242,16 @@ PRIVATE_DEFINITION_START(PIProcess)
|
|||||||
BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL);
|
BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL);
|
||||||
if (!ok) sz = 0;
|
if (!ok) sz = 0;
|
||||||
# else
|
# else
|
||||||
sz = ::write(pipes[StdIn][PipeWrite], data.data(), data.size());
|
size_t offset = 0;
|
||||||
|
while (offset < data.size()) {
|
||||||
|
ssize_t wr = ::write(pipes[StdIn][PipeWrite], data.data() + offset, data.size() - offset);
|
||||||
|
if (wr < 0) {
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
offset += wr;
|
||||||
|
}
|
||||||
|
sz = offset;
|
||||||
# endif
|
# endif
|
||||||
return sz == (SizeType)data.size_s();
|
return sz == (SizeType)data.size_s();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
|
|||||||
l_df.pop_front();
|
l_df.pop_front();
|
||||||
for (const auto & s: l_df) {
|
for (const auto & s: l_df) {
|
||||||
PIStringList ml(s.replacedAll(" ", " ").split(" "));
|
PIStringList ml(s.replacedAll(" ", " ").split(" "));
|
||||||
if (ml.size_s() < 2) continue;
|
if (ml.size_s() < 3) continue;
|
||||||
if (ml.front() == "none") continue;
|
if (ml.front() == "none") continue;
|
||||||
m.space_all = ml[1].toULLong();
|
m.space_all = ml[1].toULLong();
|
||||||
m.space_used = ml[2].toULLong();
|
m.space_used = ml[2].toULLong();
|
||||||
|
|||||||
@@ -135,17 +135,19 @@ bool PIConditionVariable::waitFor(PIMutex & lk, PISystemTime timeout, std::funct
|
|||||||
if (condition()) break;
|
if (condition()) break;
|
||||||
bool isTimeout;
|
bool isTimeout;
|
||||||
#if defined(WINDOWS)
|
#if defined(WINDOWS)
|
||||||
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle,
|
{
|
||||||
(PCRITICAL_SECTION)lk.handle(),
|
int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
|
||||||
timeout.toMilliseconds() - (int)measurer.elapsed_m()) == 0;
|
if (remain <= 0) return false;
|
||||||
|
isTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), remain) == 0;
|
||||||
|
}
|
||||||
#elif defined(FREERTOS)
|
#elif defined(FREERTOS)
|
||||||
|
{
|
||||||
|
int remain = (int)(timeout.toMilliseconds() - (int)measurer.elapsed_m());
|
||||||
|
if (remain <= 0) return false;
|
||||||
EventBits_t uxBits;
|
EventBits_t uxBits;
|
||||||
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle,
|
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, remain / portTICK_PERIOD_MS);
|
||||||
1,
|
|
||||||
pdTRUE,
|
|
||||||
pdTRUE,
|
|
||||||
(timeout.toMilliseconds() - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS);
|
|
||||||
isTimeout = (uxBits & 1) == 0;
|
isTimeout = (uxBits & 1) == 0;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0;
|
isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t *)lk.handle(), &expire_ts) != 0;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1080,7 +1080,6 @@ bool PIThread::_waitForFinish(PISystemTime max_tm) {
|
|||||||
if (!running_) return true;
|
if (!running_) return true;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (!isExists(PRIVATE->thread)) {
|
if (!isExists(PRIVATE->thread)) {
|
||||||
unlock();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -173,7 +173,10 @@ public:
|
|||||||
|
|
||||||
//! \~english Remove one bit from the end of array.
|
//! \~english Remove one bit from the end of array.
|
||||||
//! \~russian Удаляет один бит с конца массива.
|
//! \~russian Удаляет один бит с конца массива.
|
||||||
PIBitArray & pop_back() { return resize(size_ - 1); }
|
PIBitArray & pop_back() {
|
||||||
|
if (size_ == 0) return *this;
|
||||||
|
return resize(size_ - 1);
|
||||||
|
}
|
||||||
|
|
||||||
//! \~english Remove one bit from the beginning of array.
|
//! \~english Remove one bit from the beginning of array.
|
||||||
//! \~russian Удаляет один бит с начала массива.
|
//! \~russian Удаляет один бит с начала массива.
|
||||||
|
|||||||
@@ -198,10 +198,11 @@ PIByteArray PIByteArray::fromBase64(const PIByteArray & base64) {
|
|||||||
base64HelpStruct hs;
|
base64HelpStruct hs;
|
||||||
PIByteArray ret;
|
PIByteArray ret;
|
||||||
const int sz = base64.size_s();
|
const int sz = base64.size_s();
|
||||||
|
if (sz < 4) return PIByteArray();
|
||||||
int ind = -1;
|
int ind = -1;
|
||||||
uchar t[4];
|
uchar t[4];
|
||||||
ret.resize(sz / 4 * 3);
|
ret.resize(sz / 4 * 3);
|
||||||
for (int i = 0; i < sz; i += 4) {
|
for (int i = 0; i < sz / 4 * 4; i += 4) {
|
||||||
hs.setAscii(base64.data(i));
|
hs.setAscii(base64.data(i));
|
||||||
hs.getBytes(t);
|
hs.getBytes(t);
|
||||||
ret[++ind] = (t[0]);
|
ret[++ind] = (t[0]);
|
||||||
|
|||||||
@@ -133,15 +133,15 @@ void PIVariant::setValueFromString(const PIString & v) {
|
|||||||
case PIVariant::pivComplexf: {
|
case PIVariant::pivComplexf: {
|
||||||
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
||||||
setValue(complexf(sl.size() > 0 ? sl[0].toFloat() : 0.f, sl.size() > 1 ? sl[1].toFloat() : 0.f));
|
setValue(complexf(sl.size() > 0 ? sl[0].toFloat() : 0.f, sl.size() > 1 ? sl[1].toFloat() : 0.f));
|
||||||
}
|
} break;
|
||||||
case PIVariant::pivComplexd: {
|
case PIVariant::pivComplexd: {
|
||||||
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
||||||
setValue(complexd(sl.size() > 0 ? sl[0].toDouble() : 0., sl.size() > 1 ? sl[1].toDouble() : 0.));
|
setValue(complexd(sl.size() > 0 ? sl[0].toDouble() : 0., sl.size() > 1 ? sl[1].toDouble() : 0.));
|
||||||
}
|
} break;
|
||||||
case PIVariant::pivComplexld: {
|
case PIVariant::pivComplexld: {
|
||||||
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
PIStringList sl = v.mid(1, v.size_s() - 2).split(';');
|
||||||
setValue(complexld(sl.size() > 0 ? sl[0].toLDouble() : 0.L, sl.size() > 1 ? sl[1].toLDouble() : 0.L));
|
setValue(complexld(sl.size() > 0 ? sl[0].toLDouble() : 0.L, sl.size() > 1 ? sl[1].toLDouble() : 0.L));
|
||||||
}
|
} break;
|
||||||
case PIVariant::pivTime: {
|
case PIVariant::pivTime: {
|
||||||
setValue(PITime::fromString(v));
|
setValue(PITime::fromString(v));
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ PIOpenCL::Context * PIOpenCL::Context::create(const PIOpenCL::DeviceList & dl) {
|
|||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
piCout << "[PIOpenCL::Context]"
|
piCout << "[PIOpenCL::Context]"
|
||||||
<< "clCreateCommandQueue error" << ret;
|
<< "clCreateCommandQueue error" << ret;
|
||||||
|
clReleaseContext(con);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
piCout << "create done for" << dl[0].name;
|
piCout << "create done for" << dl[0].name;
|
||||||
|
|||||||
+5
-4
@@ -239,7 +239,7 @@ bool PIUSB::openDevice() {
|
|||||||
for (int i = 0; i < dc.bNumInterfaces; ++i) {
|
for (int i = 0; i < dc.bNumInterfaces; ++i) {
|
||||||
conf.interfaces << Interface();
|
conf.interfaces << Interface();
|
||||||
Interface & infc(conf.interfaces.back());
|
Interface & infc(conf.interfaces.back());
|
||||||
struct usb_interface_descriptor * di(dc.interface[c].altsetting);
|
struct usb_interface_descriptor * di(dc.interface[i].altsetting);
|
||||||
infc.index = i;
|
infc.index = i;
|
||||||
infc.value_to_select = di->bAlternateSetting;
|
infc.value_to_select = di->bAlternateSetting;
|
||||||
infc.class_code = di->bInterfaceClass;
|
infc.class_code = di->bInterfaceClass;
|
||||||
@@ -320,7 +320,7 @@ bool PIUSB::openDevice() {
|
|||||||
bool PIUSB::closeDevice() {
|
bool PIUSB::closeDevice() {
|
||||||
#ifdef PIP_USB
|
#ifdef PIP_USB
|
||||||
if (hdev == 0) return true;
|
if (hdev == 0) return true;
|
||||||
usb_release_interface(hdev, intefrace_);
|
if (interface_claimed >= 0) usb_release_interface(hdev, interface_claimed);
|
||||||
usb_close(hdev);
|
usb_close(hdev);
|
||||||
hdev = 0;
|
hdev = 0;
|
||||||
interface_claimed = -1;
|
interface_claimed = -1;
|
||||||
@@ -340,6 +340,7 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
case Endpoint::Bulk:
|
case Endpoint::Bulk:
|
||||||
/*piCoutObj << "bulk read" << max_size;*/
|
/*piCoutObj << "bulk read" << max_size;*/
|
||||||
ret = usb_bulk_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
|
ret = usb_bulk_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
|
||||||
|
break;
|
||||||
case Endpoint::Interrupt: ret = usb_interrupt_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
|
case Endpoint::Interrupt: ret = usb_interrupt_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -354,11 +355,11 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
|
|||||||
ssize_t PIUSB::writeDevice(const void * data, ssize_t max_size) {
|
ssize_t PIUSB::writeDevice(const void * data, ssize_t max_size) {
|
||||||
#ifdef PIP_USB
|
#ifdef PIP_USB
|
||||||
if (isClosed() || ep_write.isNull()) return -1;
|
if (isClosed() || ep_write.isNull()) return -1;
|
||||||
switch (ep_read.transfer_type) {
|
switch (ep_write.transfer_type) {
|
||||||
case Endpoint::Bulk:
|
case Endpoint::Bulk:
|
||||||
/*piCoutObj << "bulk write" << max_size;*/
|
/*piCoutObj << "bulk write" << max_size;*/
|
||||||
return usb_bulk_write(hdev, ep_write.address, (char *)const_cast<void *>(data), max_size, timeout_w);
|
return usb_bulk_write(hdev, ep_write.address, (char *)const_cast<void *>(data), max_size, timeout_w);
|
||||||
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_read.address, (char *)data, max_size, timeout_w);
|
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_write.address, (char *)data, max_size, timeout_w);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "pisharedmemory.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
# include <process.h>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST(PISharedMemory_Test, ReadWriteBounds) {
|
||||||
|
PISharedMemory shm("pip_bughunt_shm_bounds_" + PIString::fromNumber(int(getpid())), 64);
|
||||||
|
ASSERT_TRUE(shm.open());
|
||||||
|
|
||||||
|
const char payload[32] = "0123456789abcdef";
|
||||||
|
ASSERT_EQ(32, shm.write(payload, 32));
|
||||||
|
ASSERT_EQ(16, shm.write(payload, 16, 10));
|
||||||
|
|
||||||
|
// Out-of-bounds writes must be rejected, not silently overflow the mapping.
|
||||||
|
EXPECT_EQ(-1, shm.write(payload, 100)); // exceeds size
|
||||||
|
EXPECT_EQ(-1, shm.write(payload, 32, 97)); // offset + size exceeds size
|
||||||
|
EXPECT_EQ(-1, shm.write(payload, 16, -5)); // negative offset
|
||||||
|
|
||||||
|
// Out-of-bounds reads must be rejected.
|
||||||
|
char dst[128];
|
||||||
|
EXPECT_EQ(-1, shm.read(dst, 200)); // exceeds size
|
||||||
|
EXPECT_EQ(-1, shm.read(dst, 32, 97)); // offset + size exceeds size
|
||||||
|
EXPECT_EQ(-1, shm.read(dst, 32, -1));
|
||||||
|
|
||||||
|
// In-bounds reads must still succeed.
|
||||||
|
EXPECT_EQ(16, shm.read(dst, 16, 10));
|
||||||
|
ASSERT_EQ(0, memcmp(dst, "0123456789abcdef", 16));
|
||||||
|
|
||||||
|
ASSERT_TRUE(shm.close());
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user