unparsed response handling; async for most calls
This commit is contained in:
+10
-3
@@ -22,6 +22,7 @@ use Menking\Meshcore\Model\MessageResponse;
|
|||||||
use Menking\Meshcore\Model\MessagesWaitingResponse;
|
use Menking\Meshcore\Model\MessagesWaitingResponse;
|
||||||
use Menking\Meshcore\Model\NoMoreMessagesResponse;
|
use Menking\Meshcore\Model\NoMoreMessagesResponse;
|
||||||
use Menking\Meshcore\Model\OkResponse;
|
use Menking\Meshcore\Model\OkResponse;
|
||||||
|
use Menking\Meshcore\Model\UnparsedResponse;
|
||||||
|
|
||||||
class CoreParser {
|
class CoreParser {
|
||||||
/**
|
/**
|
||||||
@@ -34,7 +35,6 @@ class CoreParser {
|
|||||||
case CoreProtocol::RESP_CODE_OK:
|
case CoreProtocol::RESP_CODE_OK:
|
||||||
return self::parseOk($payload);
|
return self::parseOk($payload);
|
||||||
case CoreProtocol::RESP_CODE_ERR:
|
case CoreProtocol::RESP_CODE_ERR:
|
||||||
//throw new \Exception("Protocol error: " . CoreProtocol::getErrorText(ord($payload[1])));
|
|
||||||
return self::parseError($payload);
|
return self::parseError($payload);
|
||||||
case CoreProtocol::RESP_CODE_CONTACT:
|
case CoreProtocol::RESP_CODE_CONTACT:
|
||||||
return self::getContact($payload);
|
return self::getContact($payload);
|
||||||
@@ -76,11 +76,18 @@ class CoreParser {
|
|||||||
case CoreProtocol::PUSH_CODE_CONTACTS_FULL:
|
case CoreProtocol::PUSH_CODE_CONTACTS_FULL:
|
||||||
return new ContactsFullResponse();
|
return new ContactsFullResponse();
|
||||||
default:
|
default:
|
||||||
echo "Unparsed response: " . \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n";
|
return self::unparsed($payload);
|
||||||
return $payload;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function unparsed(string $payload): UnparsedResponse {
|
||||||
|
$m = new UnparsedResponse();
|
||||||
|
$m->code = ord($payload[0]);
|
||||||
|
$m->payload = $payload;
|
||||||
|
|
||||||
|
return $m;
|
||||||
|
}
|
||||||
|
|
||||||
protected static function parseOk(string $payload): OkResponse {
|
protected static function parseOk(string $payload): OkResponse {
|
||||||
$m = new OkResponse();
|
$m = new OkResponse();
|
||||||
$m->code = ord($payload[0]);
|
$m->code = ord($payload[0]);
|
||||||
|
|||||||
+67
-44
@@ -40,22 +40,24 @@ class Meshcore {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $app_name
|
* @param string $app_name
|
||||||
|
* @param bool $async
|
||||||
* @return null|AppStartResponse
|
* @return null|AppStartResponse
|
||||||
*/
|
*/
|
||||||
public function appStart(string $app_name): ?AppStartResponse {
|
public function appStart(string $app_name, bool $async = false): ?AppStartResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_APP_START) . chr(0x00) . " " . $app_name);
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_APP_START) . chr(0x00) . " " . $app_name);
|
||||||
|
|
||||||
return $this->waitForResponse([AppStartResponse::class]);
|
return $this->waitForResponse([AppStartResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param bool $async
|
||||||
* @return null|BatteryStorageResponse
|
* @return null|BatteryStorageResponse
|
||||||
*/
|
*/
|
||||||
public function getBatteryAndStorage(): ?BatteryStorageResponse {
|
public function getBatteryAndStorage(bool $async = false): ?BatteryStorageResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_BATT_AND_STORAGE));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_BATT_AND_STORAGE));
|
||||||
|
|
||||||
return $this->waitForResponse([BatteryStorageResponse::class]);
|
return $this->waitForResponse([BatteryStorageResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,23 +70,25 @@ class Meshcore {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param bool $async
|
||||||
* @return null|DeviceInfoResponse
|
* @return null|DeviceInfoResponse
|
||||||
*/
|
*/
|
||||||
public function getDeviceInfo(): ?DeviceInfoResponse {
|
public function getDeviceInfo(bool $async = false): ?DeviceInfoResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_DEVICE_QUERY) . 0x03);
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_DEVICE_QUERY) . 0x03);
|
||||||
|
|
||||||
return $this->waitForResponse([DeviceInfoResponse::class]);
|
return $this->waitForResponse([DeviceInfoResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param int $channel_idx
|
* @param int $channel_idx
|
||||||
|
* @param bool $async
|
||||||
* @return null|ChannelResponse
|
* @return null|ChannelResponse
|
||||||
*/
|
*/
|
||||||
public function getChannel(int $channel_idx): ?ChannelResponse {
|
public function getChannel(int $channel_idx, bool $async = false): ?ChannelResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_CHANNEL) . chr($channel_idx));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_CHANNEL) . chr($channel_idx));
|
||||||
|
|
||||||
return $this->waitForResponse([ChannelResponse::class]);
|
return $this->waitForResponse([ChannelResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,9 +97,10 @@ class Meshcore {
|
|||||||
* @param float $bw
|
* @param float $bw
|
||||||
* @param int $sf
|
* @param int $sf
|
||||||
* @param int $cr
|
* @param int $cr
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function setRadioParams(float $freq, float $bw, int $sf, int $cr): ?OkResponse {
|
public function setRadioParams(float $freq, float $bw, int $sf, int $cr, bool $async = false): ?OkResponse {
|
||||||
$payload = chr(CoreProtocol::CMD_SET_RADIO_PARAMS)
|
$payload = chr(CoreProtocol::CMD_SET_RADIO_PARAMS)
|
||||||
. pack('V', $freq * 1000)
|
. pack('V', $freq * 1000)
|
||||||
. pack('V', $bw * 1000)
|
. pack('V', $bw * 1000)
|
||||||
@@ -105,7 +110,7 @@ class Meshcore {
|
|||||||
|
|
||||||
CoreProtocol::writeFrame($this->serial, $payload);
|
CoreProtocol::writeFrame($this->serial, $payload);
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,164 +137,182 @@ class Meshcore {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param bool $async
|
||||||
* @return null|MessageResponse
|
* @return null|MessageResponse
|
||||||
*/
|
*/
|
||||||
public function getNextMessage(): ?MessageResponse {
|
public function getNextMessage(bool $async = false): ?MessageResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SYNC_NEXT_MESSAGE));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SYNC_NEXT_MESSAGE));
|
||||||
|
|
||||||
return $this->waitForResponse([MessageResponse::class, NoMoreMessagesResponse::class]);
|
return $this->waitForResponse([MessageResponse::class, NoMoreMessagesResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @param int $channel_idx
|
* @param int $channel_idx
|
||||||
|
* @param bool $async
|
||||||
* @return null|CodeSentResponse
|
* @return null|CodeSentResponse
|
||||||
*/
|
*/
|
||||||
public function sendChannelTxtMessage(string $message, int $channel_idx): ?CodeSentResponse {
|
public function sendChannelTxtMessage(string $message, int $channel_idx, bool $async = false): ?CodeSentResponse {
|
||||||
$payload = chr(CoreProtocol::CMD_SEND_CHANNEL_TXT_MSG) . chr(0x00) . chr($channel_idx) . pack('V', time()) . "$message\0";
|
$payload = chr(CoreProtocol::CMD_SEND_CHANNEL_TXT_MSG) . chr(0x00) . chr($channel_idx) . pack('V', time()) . "$message\0";
|
||||||
CoreProtocol::writeFrame($this->serial, $payload);
|
CoreProtocol::writeFrame($this->serial, $payload);
|
||||||
|
|
||||||
return $this->waitForResponse([CodeSentResponse::class]);
|
return $this->waitForResponse([CodeSentResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @param bool $async
|
||||||
* @return null|CurrentTimeResponse
|
* @return null|CurrentTimeResponse
|
||||||
*/
|
*/
|
||||||
public function getDeviceTime(): ?CurrentTimeResponse {
|
public function getDeviceTime(bool $async = false): ?CurrentTimeResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_DEVICE_TIME));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_DEVICE_TIME));
|
||||||
|
|
||||||
return $this->waitForResponse([CurrentTimeResponse::class]);
|
return $this->waitForResponse([CurrentTimeResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets the time on the device to the current system time.
|
||||||
*
|
*
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function setDeviceTime(): ?OkResponse {
|
public function setDeviceTime(bool $async = false): ?OkResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SET_DEVICE_TIME) . pack('V', time()));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SET_DEVICE_TIME) . pack('V', time()));
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param bool $async
|
||||||
* @return null|CodeSentResponse
|
* @return null|CodeSentResponse
|
||||||
*/
|
*/
|
||||||
public function login(string $contact_pk, string $password): ?CodeSentResponse {
|
public function login(string $contact_pk, string $password, bool $async = false): ?CodeSentResponse {
|
||||||
$payload = chr(CoreProtocol::CMD_SEND_LOGIN) . str_pad(base64_decode($contact_pk), CoreProtocol::PUB_KEY_SIZE, "\0") . $password . chr(0x00);
|
$payload = chr(CoreProtocol::CMD_SEND_LOGIN) . str_pad(base64_decode($contact_pk), CoreProtocol::PUB_KEY_SIZE, "\0") . $password . chr(0x00);
|
||||||
|
|
||||||
CoreProtocol::writeFrame($this->serial, $payload);
|
CoreProtocol::writeFrame($this->serial, $payload);
|
||||||
|
|
||||||
return $this->waitForResponse([CodeSentResponse::class]);
|
return $this->waitForResponse([CodeSentResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function disconnect(string $contact_pk): ?OkResponse {
|
public function disconnect(string $contact_pk, bool $async = false): ?OkResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_LOGOUT) . base64_decode($contact_pk) . "\0");
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_LOGOUT) . base64_decode($contact_pk) . "\0");
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|CodeSentResponse
|
* @return null|CodeSentResponse
|
||||||
*/
|
*/
|
||||||
public function statusRequest(string $contact_pk ): ?CodeSentResponse {
|
public function statusRequest(string $contact_pk, bool $async = false): ?CodeSentResponse {
|
||||||
$payload = chr(CoreProtocol::CMD_SEND_STATUS_REQ) . base64_decode($contact_pk);
|
$payload = chr(CoreProtocol::CMD_SEND_STATUS_REQ) . base64_decode($contact_pk);
|
||||||
|
|
||||||
CoreProtocol::writeFrame($this->serial, $payload);
|
CoreProtocol::writeFrame($this->serial, $payload);
|
||||||
|
|
||||||
return $this->waitForResponse([CodeSentResponse::class]);
|
return $this->waitForResponse([CodeSentResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function connected(string $contact_pk): ?OkResponse {
|
public function connected(string $contact_pk, bool $async = false): ?OkResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_HAS_CONNECTION) . base64_decode($contact_pk) . "\0");
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_HAS_CONNECTION) . base64_decode($contact_pk) . "\0");
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function getTelemetryRequest(string $contact_pk): ?OkResponse {
|
public function getTelemetryRequest(string $contact_pk, bool $async = false): ?OkResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_TELEMETRY_REQ) . base64_decode($contact_pk));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_TELEMETRY_REQ) . base64_decode($contact_pk));
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|OkResponse
|
* @return null|OkResponse
|
||||||
*/
|
*/
|
||||||
public function sendAnonRequest(string $contact_pk): ?OkResponse {
|
public function sendAnonRequest(string $contact_pk, bool $async = false): ?OkResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_ANON_REQ) . base64_decode($contact_pk) . "\0");
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_ANON_REQ) . base64_decode($contact_pk) . "\0");
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $request
|
* @param string $request
|
||||||
|
* @param bool $async
|
||||||
* @return null|CodeSentResponse
|
* @return null|CodeSentResponse
|
||||||
*/
|
*/
|
||||||
public function sendBinaryRequest(string $request): ?CodeSentResponse {
|
public function sendBinaryRequest(string $request, bool $async = false): ?CodeSentResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_BINARY_REQ) . $request);
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SEND_BINARY_REQ) . $request);
|
||||||
|
|
||||||
return $this->waitForResponse([CodeSentResponse::class]);
|
return $this->waitForResponse([CodeSentResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $contact_pk
|
* @param string $contact_pk
|
||||||
|
* @param bool $async
|
||||||
* @return null|AdvertPathResponse
|
* @return null|AdvertPathResponse
|
||||||
*/
|
*/
|
||||||
public function getAdvertPath(string $contact_pk): ?AdvertPathResponse {
|
public function getAdvertPath(string $contact_pk, bool $async = false): ?AdvertPathResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_ADVERT_PATH) . chr(0x00) . base64_decode($contact_pk));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_ADVERT_PATH) . chr(0x00) . base64_decode($contact_pk));
|
||||||
|
|
||||||
return $this->waitForResponse([AdvertPathResponse::class]);
|
return $this->waitForResponse([AdvertPathResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param int $type
|
* @param int $type
|
||||||
|
* @param bool $async
|
||||||
* @return null|CodeStatusResponse
|
* @return null|CodeStatusResponse
|
||||||
*/
|
*/
|
||||||
public function getStats(int $type): ?CodeStatusResponse {
|
public function getStats(int $type, bool $async = false): ?CodeStatusResponse {
|
||||||
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_STATS) . chr($type));
|
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_GET_STATS) . chr($type));
|
||||||
|
|
||||||
return $this->waitForResponse([CodeStatusResponse::class]);
|
return $this->waitForResponse([CodeStatusResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setChannel(int $idx, string $name, string $secret): ?OkResponse {
|
/**
|
||||||
echo "secret length: " . strlen($secret) . "\n";
|
*
|
||||||
|
* @param int $idx
|
||||||
|
* @param string $name
|
||||||
|
* @param string $secret
|
||||||
|
* @param bool $async
|
||||||
|
* @return null|OkResponse
|
||||||
|
*/
|
||||||
|
public function setChannel(int $idx, string $name, string $secret, bool $async = false): ?OkResponse {
|
||||||
$payload = chr(CoreProtocol::CMD_SET_CHANNEL)
|
$payload = chr(CoreProtocol::CMD_SET_CHANNEL)
|
||||||
. chr($idx)
|
. chr($idx)
|
||||||
. str_pad($name, 32, "\0")
|
. str_pad($name, 32, "\0")
|
||||||
. $secret;
|
. $secret;
|
||||||
|
|
||||||
echo "payload length: " . strlen($payload) . "\n";
|
|
||||||
echo \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n";
|
|
||||||
|
|
||||||
CoreProtocol::writeFrame($this->serial, $payload);
|
CoreProtocol::writeFrame($this->serial, $payload);
|
||||||
|
|
||||||
return $this->waitForResponse([OkResponse::class]);
|
return $this->waitForResponse([OkResponse::class], $async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -337,7 +360,7 @@ class Meshcore {
|
|||||||
* @return mixed
|
* @return mixed
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
private function waitForResponse(array $classes_expected): mixed {
|
private function waitForResponse(array $classes_expected, bool $async = false): mixed {
|
||||||
foreach($classes_expected as $class) {
|
foreach($classes_expected as $class) {
|
||||||
if( !class_exists($class) ) {
|
if( !class_exists($class) ) {
|
||||||
throw new \InvalidArgumentException("Class $class does not exist");
|
throw new \InvalidArgumentException("Class $class does not exist");
|
||||||
@@ -354,7 +377,7 @@ class Meshcore {
|
|||||||
array_push($this->msg_queue, $obj);
|
array_push($this->msg_queue, $obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while((time() - $mark) < 5 && !in_array(get_class($obj), $classes_expected));
|
while(!$async && (time() - $mark) < 5 && !in_array(get_class($obj), $classes_expected));
|
||||||
|
|
||||||
return in_array(get_class($obj), $classes_expected)?$obj:null;
|
return in_array(get_class($obj), $classes_expected)?$obj:null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Menking\Meshcore\Model;
|
||||||
|
|
||||||
|
class UnparsedResponse extends Response {
|
||||||
|
public int $code;
|
||||||
|
public string $payload;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user