diff --git a/src/CoreParser.php b/src/CoreParser.php index bcab6cc..c0f6fd3 100644 --- a/src/CoreParser.php +++ b/src/CoreParser.php @@ -22,6 +22,7 @@ use Menking\Meshcore\Model\MessageResponse; use Menking\Meshcore\Model\MessagesWaitingResponse; use Menking\Meshcore\Model\NoMoreMessagesResponse; use Menking\Meshcore\Model\OkResponse; +use Menking\Meshcore\Model\UnparsedResponse; class CoreParser { /** @@ -34,7 +35,6 @@ class CoreParser { case CoreProtocol::RESP_CODE_OK: return self::parseOk($payload); case CoreProtocol::RESP_CODE_ERR: - //throw new \Exception("Protocol error: " . CoreProtocol::getErrorText(ord($payload[1]))); return self::parseError($payload); case CoreProtocol::RESP_CODE_CONTACT: return self::getContact($payload); @@ -76,11 +76,18 @@ class CoreParser { case CoreProtocol::PUSH_CODE_CONTACTS_FULL: return new ContactsFullResponse(); default: - echo "Unparsed response: " . \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n"; - return $payload; + return self::unparsed($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 { $m = new OkResponse(); $m->code = ord($payload[0]); diff --git a/src/Meshcore.php b/src/Meshcore.php index 4cd782d..d722d2f 100644 --- a/src/Meshcore.php +++ b/src/Meshcore.php @@ -40,22 +40,24 @@ class Meshcore { /** * * @param string $app_name + * @param bool $async * @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); - return $this->waitForResponse([AppStartResponse::class]); + return $this->waitForResponse([AppStartResponse::class], $async); } /** * + * @param bool $async * @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)); - return $this->waitForResponse([BatteryStorageResponse::class]); + return $this->waitForResponse([BatteryStorageResponse::class], $async); } /** @@ -68,23 +70,25 @@ class Meshcore { /** * + * @param bool $async * @return null|DeviceInfoResponse */ - public function getDeviceInfo(): ?DeviceInfoResponse { + public function getDeviceInfo(bool $async = false): ?DeviceInfoResponse { 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 bool $async * @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)); - return $this->waitForResponse([ChannelResponse::class]); + return $this->waitForResponse([ChannelResponse::class], $async); } /** @@ -93,9 +97,10 @@ class Meshcore { * @param float $bw * @param int $sf * @param int $cr + * @param bool $async * @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) . pack('V', $freq * 1000) . pack('V', $bw * 1000) @@ -105,7 +110,7 @@ class Meshcore { 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 */ - public function getNextMessage(): ?MessageResponse { + public function getNextMessage(bool $async = false): ?MessageResponse { 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 int $channel_idx + * @param bool $async * @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"; CoreProtocol::writeFrame($this->serial, $payload); - return $this->waitForResponse([CodeSentResponse::class]); + return $this->waitForResponse([CodeSentResponse::class], $async); } /** * + * @param bool $async * @return null|CurrentTimeResponse */ - public function getDeviceTime(): ?CurrentTimeResponse { + public function getDeviceTime(bool $async = false): ?CurrentTimeResponse { 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 */ - public function setDeviceTime(): ?OkResponse { + public function setDeviceTime(bool $async = false): ?OkResponse { 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 $password + * @param bool $async * @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); CoreProtocol::writeFrame($this->serial, $payload); - return $this->waitForResponse([CodeSentResponse::class]); + return $this->waitForResponse([CodeSentResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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"); - return $this->waitForResponse([OkResponse::class]); + return $this->waitForResponse([OkResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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); CoreProtocol::writeFrame($this->serial, $payload); - return $this->waitForResponse([CodeSentResponse::class]); + return $this->waitForResponse([CodeSentResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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"); - return $this->waitForResponse([OkResponse::class]); + return $this->waitForResponse([OkResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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)); - return $this->waitForResponse([OkResponse::class]); + return $this->waitForResponse([OkResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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"); - return $this->waitForResponse([OkResponse::class]); + return $this->waitForResponse([OkResponse::class], $async); } /** * * @param string $request + * @param bool $async * @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); - return $this->waitForResponse([CodeSentResponse::class]); + return $this->waitForResponse([CodeSentResponse::class], $async); } /** * * @param string $contact_pk + * @param bool $async * @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)); - return $this->waitForResponse([AdvertPathResponse::class]); + return $this->waitForResponse([AdvertPathResponse::class], $async); } /** * * @param int $type + * @param bool $async * @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)); - 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) . chr($idx) . str_pad($name, 32, "\0") . $secret; - echo "payload length: " . strlen($payload) . "\n"; - echo \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n"; - CoreProtocol::writeFrame($this->serial, $payload); - return $this->waitForResponse([OkResponse::class]); + return $this->waitForResponse([OkResponse::class], $async); } /** @@ -337,7 +360,7 @@ class Meshcore { * @return mixed * @throws InvalidArgumentException */ - private function waitForResponse(array $classes_expected): mixed { + private function waitForResponse(array $classes_expected, bool $async = false): mixed { foreach($classes_expected as $class) { if( !class_exists($class) ) { throw new \InvalidArgumentException("Class $class does not exist"); @@ -354,7 +377,7 @@ class Meshcore { 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; } diff --git a/src/Model/UnparsedResponse.php b/src/Model/UnparsedResponse.php new file mode 100644 index 0000000..f15a699 --- /dev/null +++ b/src/Model/UnparsedResponse.php @@ -0,0 +1,9 @@ +