diff --git a/src/CoreParser.php b/src/CoreParser.php index 1ef67d7..d1f428f 100644 --- a/src/CoreParser.php +++ b/src/CoreParser.php @@ -52,6 +52,14 @@ class CoreParser { return self::parseCodeStatusResponse($payload); case CoreProtocol::RESP_CODE_DEVICE_INFO: return self::parseDeviceInfoResponse($payload); + case CoreProtocol::RESP_CODE_CHANNEL_INFO: + return self::parseChannelInfoResponse($payload); + case CoreProtocol::PUSH_CODE_MSG_WAITING: + return ['code'=>CoreProtocol::PUSH_CODE_MSG_WAITING]; + case CoreProtocol::RESP_CODE_CONTACT_MSG_RECV_V3: + case CoreProtocol::RESP_CODE_CHANNEL_MSG_RECV_V3: + case CoreProtocol::RESP_CODE_CHANNEL_MSG_RECV: + return $payload; default: echo "Unparsed response: " . \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n"; return $payload; @@ -353,6 +361,17 @@ class CoreParser { return $info; } + public static function parseChannelInfoResponse(string $payload) { + $info = [ + 'code'=>ord($payload[0]), + 'channel_idx'=>ord($payload[1]), + 'channel_name'=>self::readCstring(substr($payload, 2, 32)), + 'channel_secret'=>substr($payload, 34, 16) + ]; + + return $info; + } + public static function parseMessage(string $payload) { $data = [ 'code'=>ord($payload[0]), @@ -365,4 +384,15 @@ class CoreParser { return $data; } + + public static function readCstring($str) { + $x = strpos($str, "\0"); + + if( $x === false ) { + return null; + } + else { + return trim(substr($str, 0, $x)); + } + } } \ No newline at end of file diff --git a/src/Meshcore.php b/src/Meshcore.php index 401ea17..89b093c 100644 --- a/src/Meshcore.php +++ b/src/Meshcore.php @@ -8,6 +8,7 @@ use Menking\Meshcore\Model\BinaryResponse; class Meshcore { private $serial; static private ?Meshcore $instance = null; + private $msg_queue = []; private function __construct() { CoreProtocol::configureTty(Environment::getDevice()); @@ -135,24 +136,13 @@ class Meshcore { /** * - * @param null|string $tag * @return mixed */ - public function getNextMessage(?string $tag = null): mixed { + public function getNextMessage(): mixed { CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SYNC_NEXT_MESSAGE)); $response = CoreProtocol::readFrame($this->serial); - $data = CoreParser::parseResponse($response); - - if( $data->code == 10 ) { // RESP_CODE_NO_MORE_MESSAGES - return null; - } - - if( !is_null($tag) && $data->tag != $tag ) { - return null; - } - - return $data; + return CoreParser::parseResponse($response); } /** @@ -199,7 +189,7 @@ class Meshcore { * @return mixed */ public function login(string $contact_pk, string $password): mixed { - $payload = chr(CoreProtocol::CMD_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); $response = CoreProtocol::readFrame($this->serial); @@ -320,6 +310,22 @@ class Meshcore { return CoreParser::parseResponse($response); } + public function setChannel(int $idx, string $name, string $secret): mixed { + echo "secret length: " . strlen($secret) . "\n"; + $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); + $response = CoreProtocol::readFrame($this->serial); + + return CoreParser::parseResponse($response); + } + public function readFrame(): mixed { return CoreProtocol::readFrame($this->serial); } @@ -339,15 +345,21 @@ class Meshcore { do { $msg = self::getNextMessage(); - if( $msg instanceof BinaryResponse ) { + if( $msg->code != 10) { $messages[] = $msg; + + if( $msg instanceof BinaryResponse && $msg->tag == $tag ) { + return $messages; + } } - if( $msg instanceof BinaryResponse && $msg->tag == $tag ) { - return $messages; - } + usleep(250000); - usleep(500000); + $response = $this->readFrame(); + + echo "readFrame: " . \Menking\Meshcore\Util\Debug::hexDump($response) . "\n"; + + usleep(250000); } while( ((time() - $mark) * 1000) < $timeout_ms ); diff --git a/tests/getMessages.php b/tests/getMessages.php index aa32b51..a1b67de 100644 --- a/tests/getMessages.php +++ b/tests/getMessages.php @@ -14,7 +14,8 @@ $mc = Meshcore::getInstance(); $mc->appStart("get_messages"); -$resp = $mc->getNextMessage(); +while(true) { + $msgs = $mc->pollForMessage(''); -print_r($resp); -exit; + if( !empty($msgs) ) print_r($msgs); +} \ No newline at end of file diff --git a/tests/sendMessage.php b/tests/sendMessage.php index 745d8c6..0da08cf 100644 --- a/tests/sendMessage.php +++ b/tests/sendMessage.php @@ -13,11 +13,31 @@ Environment::configure($argv[1]); $mc = Meshcore::getInstance(); $mc->appStart("send message"); -$resp = $mc->sendChannelTxtMessage("Ping", 0); // default channel Public on 0 -echo "Send Channel Txt Message result: " . print_r($resp, true) . "\n"; +$channels = []; -$msgs = $mc->pollForMessage(''); +for( $i = 0; $i < 40; $i++ ) { + $chan = $mc->getChannel($i); + + if( !empty($chan['channel_name']) ) { + $channels[] = $chan; + } +} + +$idx = 0; +foreach($channels as $channel) { + echo "({$channel['channel_idx']}) {$channel['channel_name']}\n"; + echo "\t{$channel['channel_secret']}\n"; +} + +$chan_id = readline("Which channel to send message? "); + +$message = readline("Message? "); + +if( $mc->sendChannelTxtMessage($message, $chan_id) ) { + echo "Message sent\n"; +} + +$msgs = $mc->pollForMessage('', 7000); print_r($msgs); - diff --git a/tests/setChannel.php b/tests/setChannel.php new file mode 100644 index 0000000..0b52a3c --- /dev/null +++ b/tests/setChannel.php @@ -0,0 +1,40 @@ +\n"); + +Environment::configure($argv[1]); + +$channel = [ + 'name'=>'LocalTestSville', + 'secret'=>base64_encode(hex2bin('4a1de86aa067e36b6ae99bd4930210df')), +]; + +$mc = Meshcore::getInstance(); + +$mc->appStart("set channel"); + +$channels = []; + +for( $i = 0; $i < 40; $i++ ) { + $chan = $mc->getChannel($i); + + if( !empty($chan['channel_name']) ) { + $channels[] = $chan; + } +} + +foreach($channels as $channel) { + echo "{$channel['channel_idx']}\t\t{$channel['channel_name']}\t\t" . bin2hex($channel['channel_secret']) . "\n"; +} +echo "\n"; + +readline("Enter to continue"); + +$resp = $mc->setChannel(1, $channel['name'], base64_decode($channel['secret'])); + +print_r($resp);