Daten für Client Socket in "Form bringen"

Hallo Leute,

ich stehe ein bisschen auf dem Schlauch. Die Datendie über den IPS-Client Server gesendet werden müssen, müssen abstrakt diese Form haben:

typedef struct
 {
    uint32_t cmd;
    uint32_t p1;
    uint32_t p2;
    union
    {
       uint32_t p3;
       uint32_t ext_len;
       uint32_t res;
    };
 } cmdCmd_t;

Wie muss dieses korrekt erstellt werden, wenn z.B.
cmd = 5
p1 = 23
p2 = 255
ist?

Joachim

Schau mal hier: PHP: pack - Manual

Du hast insgesamt 4x32Bit (=4x4 Byte). Diese kannst du über pack und dem Typ L einfach bauen und dann versenden.

paresy

Hallo Paresy,

vielen Dank für Deine Antwort.

Müsste das dann in der gestellten Aufgabe etwa so sein:

$binaerdaten = pack("LLL", 5, 23, 255, 0);

?

Joachim

Es müsste eher vier mal L sein oder L*

Und die Länge die rauskommt (strlen) soll 16 sein.

paresy

Okay, dann werde ich das mal so probieren:

$binaerdaten = pack("LLLL", 5, 23, 255, 0); 
CSCK_SendText(12345, $binaerdaten ); 

Die Länge müsste sich doch dann „automatisch“ ergeben oder sollte man das noch mal explizit prüfen?

Joachim

Die sollte automatisch korrekt sein. Müsstest du aber auch im Client Socket Debug überprüfen können.

paresy

Hallo Paresy,

gestern hatte ich leider nur ein paar Minuten Zeit, das Ergebnis ist aber mehr als beeindruckend!
Statt bisher >2 Sek bis der Befehl ausgeführt wurde bin ich nun <0,2 Sek!

Was ich auf die Schnelle nicht verifizieren konnte, ist ob die Rückmeldungen - die irgendwie über p3 kommen sollen - auch registriert werden…

Joachim

Hallo Paresy,

vielleicht magst Du mir noch mal auf die Spünge helfen…

Im Debug-Fenster des Client Socket sehe ich die Antwort.
Beispiel: Abfrage der Hardwareversion:
11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Antwort:
11 00 00 00 00 00 00 00 00 00 00 00 0D 00 00 00
Das dritte Parameter soll die Antwort enthalten (hier:0D 00 00 00).
Ich habe nun folgendes versucht:

$result = CSCK_SendText(44669 /*[GPIO]*/, pack("LLLL", 17, 0, 0, 0));
$resultarray = unpack("LLLL", $result);

Bekomme aber die Fehlermeldung das es nicht genug Zeichen für „L“ sind. Frage ich

Echo $result;

bekomme ich auch nur eine „1“ angezeigt…

Wo liegt der Fehler? Wie komme ich an das, was auch im Debug-Fenster angezeigt wird?

Joachim

Result enthält true wenn der Befehl ausgeführt wurde.
Nicht die Antwort der Gegenseite.
Dafür braucht es die RegisterVariable oder ein Modul mit ReceiveData Methode.
Das war dass was ich mit ‚senden und empfangen in unterschiedlichen PHP-Threads‘ meinte.
Da du ja vermutlich die Daten immer anfordern musst und nicht periodisch bekommst, verzichtet auf den ClientSocket und sende es direkt per PHP.
http://php.net/manual/de/function.socket-create.php
Michael

Okay, Denkfehler…:smiley:

In meinem Modul habe ich das bereits. Aber wie heißt das Datenfeld dazu?

IPS_LogMessage("ReceiveData", utf8_decode($data->Buffer));

Was muss für die Information als Benennung eingesetzt werden? Die Daten kommen vom Client Socket, nicht von meinem selbst definiertem Modul…:confused:

Joachim

Vielleicht wäre es gut wenn du mal zeigst was du hast :slight_smile:
Buffer enthält doch die Daten…
Michael

…im Splitter habe ich diese Funktion eingebaut:

  	  public function ReceiveData($JSONString) 
  	  {
 		// Empfangene Daten vom I/O
		$data = json_decode($JSONString);
		IPS_LogMessage("ReceiveData", utf8_decode($data->Buffer));
		 
		// Hier werden die Daten verarbeitet
		 
		// Weiterleitung zu allen Gerät-/Device-Instanzen
		//$this->SendDataToChildren(json_encode(Array("DataID" => "{66164EB8-3439-4599-B937-A365D7A68567}", "Buffer" => $data->Buffer)));
	 }

das übergeordnete Modul ist der Client Socket.
Wenn ich die Abfrage sende, antwortet der Server wie erwartet. Nun muss ich diesen jedoch weiterverarbeiten.
Zunächst sollte er dann wohl mit

unpack

bearbeitet werden. Jedoch sehe ich - zumindest im Log nur ein leerer Feld (vielleicht liegt es ja auch nur daran, das IPS im Log diese Bitfolge nicht darstellen kann?).

Joachim

Korrekt daran wird es liegen :slight_smile:
Aber nimm anstatt LogMessage doch SendDebug.
Dann landen deine Daten im Debug Fenster deines Splitters. Und der kann auch Rohdaten darstellen.
Michael

Michael gab mir den Tipp, nicht den IPS-Client-Server zu nutzen, sondern bei dem was ich vor habe selbst einen zu erstellen. Das hat mich überzeugt, weil es mir m.E. einige Dinge erleichtert - wenn man denn einmal soweit ist!:smiley:

Hier mein Skript:

if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Couldn't create socket: [$errorcode] $errormsg 
");
}

echo "Socket created";

if(!socket_connect($sock , '192.168.178.53' , 8888))
{
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not connect: [$errorcode] $errormsg 
");
}

echo "Connection established 
";

$message = pack("LLLL", 17, 0, 0, 0);

//Send the message to the server
if( ! socket_send ( $sock , $message , strlen($message) , 0))
{
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not send data: [$errorcode] $errormsg 
");
}

echo "Message send successfully 
";

//Now receive reply from server
if(socket_recv ( $sock , $buf , 16, MSG_WAITALL ) === FALSE)
{
	$errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not receive data: [$errorcode] $errormsg 
");
}

//print the received message
//echo $buf;
print_r (unpack("LLLL", $buf));

Das Ergebnis überrascht mich aber etwas:

Array
(
    [LLL] => 17
)

Erwartet hätte ich die vier Werte (wie ich sie auch im Debug des IPS-Client sehe 11 00 00 00 00 00 00 00 00 00 00 00 0D 00 00 00).

Wo liegt der Fehler?

Joachim

Bei Unpack steht:

The unpacked data is stored in an associative array. To accomplish this you have to name the different format codes and separate them by a slash /. If a repeater argument is present, then each of the array keys will have a sequence number behind the given name.

Das hier:

print_r(unpack("L4ulong", $buf));

Ergibt dann:

Array
(
    [ulong1] => 17
    [ulong2] => 0
    [ulong3] => 0
    [ulong4] => 13
)

Michael

…Eingebung:

print_r (unpack("L*", $buf));

Funktioniert!!:smiley:

Oder so :smiley:

Das hier geht auch :wink:

print_r(unpack("La/Lb/Lc/Ld", $buf));

Michael