|
1 | 1 | (******************************************************************************)
|
2 | 2 | (* uMQTTbroker.pas 13.10.2023 *)
|
3 | 3 | (* *)
|
4 |
| -(* Version : 0.01 *) |
| 4 | +(* Version : 0.02 *) |
5 | 5 | (* *)
|
6 | 6 | (* Author : Uwe Schächterle (Corpsman) *)
|
7 | 7 | (* *)
|
|
42 | 42 | (* Known Issues: it seems that the socket is not freeed correctly *)
|
43 | 43 | (* *)
|
44 | 44 | (* History : 0.01 - Initial version *)
|
| 45 | +(* 0.02 - Support for Unsubsciption *) |
45 | 46 | (* *)
|
46 | 47 | (******************************************************************************)
|
47 | 48 |
|
|
102 | 103 | TReturn = (rQoS0, rQoS1, rQoS2, rFailure);
|
103 | 104 |
|
104 | 105 | TOnLog = Procedure(Sender: TObject; ClientID: integer; LogText: String) Of Object; // 0 = from Broker
|
105 |
| - TOnSubscribeRequest = Function(Sender: TObject; ClientID: integer; Subscription: String): TReturn Of Object; |
| 106 | + TOnSubscribeRequest = Function(Sender: TObject; ClientID: integer; PackageIdentifier: uint16; Subscription: String): TReturn Of Object; |
| 107 | + TOnUnSubscribeRequest = Procedure(Sender: TObject; ClientID: integer; PackageIdentifier: uint16; Subscription: String) Of Object; |
106 | 108 | TOnPublishRequest = Procedure(Sender: TObject; ClientID: integer; aName, aPayload: String; DUP, Retain: Boolean) Of Object;
|
107 | 109 | TOnClientEvent = Procedure(Sender: TObject; ClientID: integer) Of Object;
|
108 | 110 |
|
|
137 | 139 | *)
|
138 | 140 | Procedure HandleConnectPacket(Clientindex: Integer; Const aPacket: TMQTTPacket);
|
139 | 141 | Procedure HandleSubscribePacket(Clientindex: Integer; Const aPacket: TMQTTPacket);
|
| 142 | + Procedure HandleUnSubscribePacket(Clientindex: Integer; Const aPacket: TMQTTPacket); |
140 | 143 | Procedure HandlePublishPacket(Clientindex: Integer; Const aPacket: TMQTTPacket);
|
141 | 144 | Procedure HandlePingPacket(Clientindex: Integer; Const aPacket: TMQTTPacket);
|
142 | 145 |
|
|
148 | 151 |
|
149 | 152 | OnAcceptMQTTClient: TOnClientEvent;
|
150 | 153 | OnSubscribeRequest: TOnSubscribeRequest;
|
| 154 | + OnUnSubscribeRequest: TOnUnSubscribeRequest; |
151 | 155 | OnPublishRequest: TOnPublishRequest;
|
152 | 156 | OnPingEvent: TOnClientEvent;
|
153 | 157 |
|
|
186 | 190 |
|
187 | 191 | OnAcceptMQTTClient := Nil;
|
188 | 192 | OnSubscribeRequest := Nil;
|
| 193 | + OnUnSubscribeRequest := Nil; |
189 | 194 | OnPublishRequest := Nil;
|
190 | 195 | OnPingEvent := Nil;
|
191 | 196 |
|
|
446 | 451 | Procedure TMQTTBroker.HandleSubscribePacket(Clientindex: Integer;
|
447 | 452 | Const aPacket: TMQTTPacket);
|
448 | 453 | Var
|
449 |
| - IdentifierLen, PackageIdentifier: uint16; |
| 454 | + SubscriptionLen, PackageIdentifier: uint16; |
450 | 455 |
|
451 |
| - Identifier: String; |
| 456 | + Subscribtion: String; |
452 | 457 | i: Integer;
|
453 | 458 | a: Array Of Byte;
|
454 | 459 | q: TReturn;
|
455 | 460 | Begin
|
456 |
| - // +++++= Package Identifier |
| 461 | + // +++++= Package Subscribtion |
457 | 462 | // Unknown package: 8 2 [31]: 00 0A 00 1A 77 61 74 65 72 6D 65 74 65 72 2F 63 74 72 6C 2F 66 6C 6F 77 5F 73 74 61 72 74 00
|
458 | 463 | // Unknown package: 8 2 [33]: 00 0B 00 1C 77 61 74 65 72 6D 65 74 65 72 2F 63 74 72 6C 2F 73 65 74 5F 70 72 65 76 61 6C 75 65 00
|
459 | 464 | PackageIdentifier := aPacket.Payload[0] Shl 8 Or aPacket.Payload[1];
|
460 |
| - IdentifierLen := aPacket.Payload[2] Shl 8 Or aPacket.Payload[3]; |
461 |
| - Identifier := ''; |
462 |
| - For i := 0 To IdentifierLen - 1 Do Begin |
463 |
| - Identifier := Identifier + chr(aPacket.Payload[4 + i]); |
| 465 | + SubscriptionLen := aPacket.Payload[2] Shl 8 Or aPacket.Payload[3]; |
| 466 | + Subscribtion := ''; |
| 467 | + For i := 0 To SubscriptionLen - 1 Do Begin |
| 468 | + Subscribtion := Subscribtion + chr(aPacket.Payload[4 + i]); |
464 | 469 | End;
|
465 |
| - // log(format('Subsribe: %0.4X : %s', [PackageIdentifier, Identifier])); |
| 470 | + // log(format('Subsribe: %0.4X : %s', [PackageIdentifier, Subscribtion])); |
466 | 471 | // Subsribe: 0011 : watermeter/ctrl/flow_start
|
467 | 472 | // Subsribe: 0012 : watermeter/ctrl/set_prevalue
|
468 | 473 |
|
|
475 | 480 | If Not assigned(OnSubscribeRequest) Then Begin
|
476 | 481 | Raise exception.create('Error, a client want to subsribe, but no callback is defined.');
|
477 | 482 | End;
|
478 |
| - q := OnSubscribeRequest(self, fClients[Clientindex].ID, Identifier); |
| 483 | + q := OnSubscribeRequest(self, fClients[Clientindex].ID, PackageIdentifier, Subscribtion); |
479 | 484 |
|
480 | 485 | // --> Verlangte Antwort SUBACK
|
481 | 486 | a := Nil;
|
482 | 487 | setlength(a, 5);
|
483 | 488 | a[0] := CPT_SUBACK Shl 4;
|
484 | 489 | a[1] := 3; // Länge der Payload
|
485 |
| - a[2] := (PackageIdentifier Shr 8) And $FF; // Repeat Package identifier |
486 |
| - a[3] := PackageIdentifier And $FF; // Repeat Package identifier |
| 490 | + a[2] := (PackageIdentifier Shr 8) And $FF; // Repeat Package Subscribtion |
| 491 | + a[3] := PackageIdentifier And $FF; // Repeat Package Subscribtion |
487 | 492 | // Add Result from Application
|
488 | 493 | Case q Of
|
489 | 494 | rQoS0: a[4] := 0;
|
|
494 | 499 | fClients[Clientindex].Socket.Send(a[0], length(a));
|
495 | 500 | End;
|
496 | 501 |
|
| 502 | +Procedure TMQTTBroker.HandleUnSubscribePacket(Clientindex: Integer; |
| 503 | + Const aPacket: TMQTTPacket); |
| 504 | +Var |
| 505 | + SubscriptionLen, PacketIdentifier: uint16; |
| 506 | + Subscribtion: String; |
| 507 | + a: Array Of Byte; |
| 508 | + i: Integer; |
| 509 | +Begin |
| 510 | + // TODO: This is untested Code ! |
| 511 | + PacketIdentifier := aPacket.Payload[0] Shl 8 Or aPacket.Payload[1]; |
| 512 | + SubscriptionLen := aPacket.Payload[2] Shl 8 Or aPacket.Payload[3]; |
| 513 | + Subscribtion := ''; |
| 514 | + For i := 0 To SubscriptionLen - 1 Do Begin |
| 515 | + Subscribtion := Subscribtion + chr(aPacket.Payload[4 + i]); |
| 516 | + End; |
| 517 | + // TODO: The Filter is missing here, that follows the subscrition |
| 518 | + |
| 519 | + If Not assigned(OnUnSubscribeRequest) Then Begin |
| 520 | + Raise exception.create('Error, a client want to unsubsribe, but no callback is defined.'); |
| 521 | + End; |
| 522 | + OnUnSubscribeRequest(self, fClients[Clientindex].ID, PacketIdentifier, Subscribtion); |
| 523 | + a := Nil; |
| 524 | + setlength(a, 4); |
| 525 | + a[0] := CPT_UNSUBACK Shl 4; |
| 526 | + a[1] := 2; |
| 527 | + a[2] := (PacketIdentifier Shr 8) And $FF; //Packet Identifier MSB |
| 528 | + a[3] := (PacketIdentifier) And $FF; //Packet Identifier LSB |
| 529 | + fClients[Clientindex].Socket.Send(a[0], length(a)); |
| 530 | +End; |
| 531 | + |
497 | 532 | Procedure TMQTTBroker.HandlePublishPacket(Clientindex: Integer;
|
498 | 533 | Const aPacket: TMQTTPacket);
|
499 | 534 | Var
|
|
589 | 624 | // CPT_PUBCOMP:
|
590 | 625 | CPT_SUBSCRIBE: HandleSubscribePacket(Clientindex, aPacket);
|
591 | 626 | // CPT_SUBACK: -- Das Gibts auf dem Server gar nicht ist ja eine Antwort
|
592 |
| - // CPT_UNSUBSCRIBE: |
| 627 | + CPT_UNSUBSCRIBE: HandleUnSubscribePacket(Clientindex, aPacket); |
593 | 628 | // CPT_UNSUBACK: -- Das Gibts auf dem Server gar nicht ist ja eine Antwort
|
594 | 629 | CPT_PINGREQ: HandlePingPacket(Clientindex, aPacket);
|
595 | 630 | // CPT_PINGRESP: -- Das Gibts auf dem Server gar nicht ist ja eine Antwort
|
|
0 commit comments