get and send messages impl

This commit is contained in:
Ben Menking
2026-05-10 23:26:00 -04:00
parent 9eeb383ee4
commit 2201890975
5 changed files with 129 additions and 26 deletions
+30
View File
@@ -52,6 +52,14 @@ class CoreParser {
return self::parseCodeStatusResponse($payload); return self::parseCodeStatusResponse($payload);
case CoreProtocol::RESP_CODE_DEVICE_INFO: case CoreProtocol::RESP_CODE_DEVICE_INFO:
return self::parseDeviceInfoResponse($payload); 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: default:
echo "Unparsed response: " . \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n"; echo "Unparsed response: " . \Menking\Meshcore\Util\Debug::hexDump($payload) . "\n";
return $payload; return $payload;
@@ -353,6 +361,17 @@ class CoreParser {
return $info; 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) { public static function parseMessage(string $payload) {
$data = [ $data = [
'code'=>ord($payload[0]), 'code'=>ord($payload[0]),
@@ -365,4 +384,15 @@ class CoreParser {
return $data; return $data;
} }
public static function readCstring($str) {
$x = strpos($str, "\0");
if( $x === false ) {
return null;
}
else {
return trim(substr($str, 0, $x));
}
}
} }
+29 -17
View File
@@ -8,6 +8,7 @@ use Menking\Meshcore\Model\BinaryResponse;
class Meshcore { class Meshcore {
private $serial; private $serial;
static private ?Meshcore $instance = null; static private ?Meshcore $instance = null;
private $msg_queue = [];
private function __construct() { private function __construct() {
CoreProtocol::configureTty(Environment::getDevice()); CoreProtocol::configureTty(Environment::getDevice());
@@ -135,24 +136,13 @@ class Meshcore {
/** /**
* *
* @param null|string $tag
* @return mixed * @return mixed
*/ */
public function getNextMessage(?string $tag = null): mixed { public function getNextMessage(): mixed {
CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SYNC_NEXT_MESSAGE)); CoreProtocol::writeFrame($this->serial, chr(CoreProtocol::CMD_SYNC_NEXT_MESSAGE));
$response = CoreProtocol::readFrame($this->serial); $response = CoreProtocol::readFrame($this->serial);
$data = CoreParser::parseResponse($response); return 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;
} }
/** /**
@@ -199,7 +189,7 @@ class Meshcore {
* @return mixed * @return mixed
*/ */
public function login(string $contact_pk, string $password): 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); CoreProtocol::writeFrame($this->serial, $payload);
$response = CoreProtocol::readFrame($this->serial); $response = CoreProtocol::readFrame($this->serial);
@@ -320,6 +310,22 @@ class Meshcore {
return CoreParser::parseResponse($response); 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 { public function readFrame(): mixed {
return CoreProtocol::readFrame($this->serial); return CoreProtocol::readFrame($this->serial);
} }
@@ -339,15 +345,21 @@ class Meshcore {
do { do {
$msg = self::getNextMessage(); $msg = self::getNextMessage();
if( $msg instanceof BinaryResponse ) { if( $msg->code != 10) {
$messages[] = $msg; $messages[] = $msg;
}
if( $msg instanceof BinaryResponse && $msg->tag == $tag ) { if( $msg instanceof BinaryResponse && $msg->tag == $tag ) {
return $messages; return $messages;
} }
}
usleep(500000); usleep(250000);
$response = $this->readFrame();
echo "readFrame: " . \Menking\Meshcore\Util\Debug::hexDump($response) . "\n";
usleep(250000);
} }
while( ((time() - $mark) * 1000) < $timeout_ms ); while( ((time() - $mark) * 1000) < $timeout_ms );
+4 -3
View File
@@ -14,7 +14,8 @@ $mc = Meshcore::getInstance();
$mc->appStart("get_messages"); $mc->appStart("get_messages");
$resp = $mc->getNextMessage(); while(true) {
$msgs = $mc->pollForMessage('');
print_r($resp); if( !empty($msgs) ) print_r($msgs);
exit; }
+24 -4
View File
@@ -13,11 +13,31 @@ Environment::configure($argv[1]);
$mc = Meshcore::getInstance(); $mc = Meshcore::getInstance();
$mc->appStart("send message"); $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); print_r($msgs);
+40
View File
@@ -0,0 +1,40 @@
<?php
use Menking\Meshcore\Environment;
use Menking\Meshcore\Meshcore;
require(__DIR__ . '/../vendor/autoload.php');
if( !isset($argv[1]) ) die("{$argv[0]} <port>\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);