├── .abapgit.xml
├── LICENSE
├── README.md
├── abaplint.json
└── src
├── mqtt
├── package.devc.xml
├── packets
│ ├── package.devc.xml
│ ├── zcl_mqtt_packet_connack.clas.abap
│ ├── zcl_mqtt_packet_connack.clas.testclasses.abap
│ ├── zcl_mqtt_packet_connack.clas.xml
│ ├── zcl_mqtt_packet_connect.clas.abap
│ ├── zcl_mqtt_packet_connect.clas.testclasses.abap
│ ├── zcl_mqtt_packet_connect.clas.xml
│ ├── zcl_mqtt_packet_disconnect.clas.abap
│ ├── zcl_mqtt_packet_disconnect.clas.testclasses.abap
│ ├── zcl_mqtt_packet_disconnect.clas.xml
│ ├── zcl_mqtt_packet_pingreq.clas.abap
│ ├── zcl_mqtt_packet_pingreq.clas.testclasses.abap
│ ├── zcl_mqtt_packet_pingreq.clas.xml
│ ├── zcl_mqtt_packet_pingresp.clas.abap
│ ├── zcl_mqtt_packet_pingresp.clas.testclasses.abap
│ ├── zcl_mqtt_packet_pingresp.clas.xml
│ ├── zcl_mqtt_packet_puback.clas.abap
│ ├── zcl_mqtt_packet_puback.clas.testclasses.abap
│ ├── zcl_mqtt_packet_puback.clas.xml
│ ├── zcl_mqtt_packet_pubcomp.clas.abap
│ ├── zcl_mqtt_packet_pubcomp.clas.testclasses.abap
│ ├── zcl_mqtt_packet_pubcomp.clas.xml
│ ├── zcl_mqtt_packet_publish.clas.abap
│ ├── zcl_mqtt_packet_publish.clas.testclasses.abap
│ ├── zcl_mqtt_packet_publish.clas.xml
│ ├── zcl_mqtt_packet_pubrec.clas.abap
│ ├── zcl_mqtt_packet_pubrec.clas.testclasses.abap
│ ├── zcl_mqtt_packet_pubrec.clas.xml
│ ├── zcl_mqtt_packet_pubrel.clas.abap
│ ├── zcl_mqtt_packet_pubrel.clas.testclasses.abap
│ ├── zcl_mqtt_packet_pubrel.clas.xml
│ ├── zcl_mqtt_packet_suback.clas.abap
│ ├── zcl_mqtt_packet_suback.clas.testclasses.abap
│ ├── zcl_mqtt_packet_suback.clas.xml
│ ├── zcl_mqtt_packet_subscribe.clas.abap
│ ├── zcl_mqtt_packet_subscribe.clas.testclasses.abap
│ ├── zcl_mqtt_packet_subscribe.clas.xml
│ ├── zcl_mqtt_packet_unsuback.clas.abap
│ ├── zcl_mqtt_packet_unsuback.clas.testclasses.abap
│ ├── zcl_mqtt_packet_unsuback.clas.xml
│ ├── zcl_mqtt_packet_unsubscribe.clas.abap
│ ├── zcl_mqtt_packet_unsubscribe.clas.testclasses.abap
│ ├── zcl_mqtt_packet_unsubscribe.clas.xml
│ ├── zcl_mqtt_stream.clas.abap
│ ├── zcl_mqtt_stream.clas.testclasses.abap
│ ├── zcl_mqtt_stream.clas.xml
│ ├── zif_mqtt_packet.intf.abap
│ └── zif_mqtt_packet.intf.xml
├── zcl_mqtt_transport_tcp.clas.abap
├── zcl_mqtt_transport_tcp.clas.xml
├── zcl_mqtt_transport_ws.clas.abap
├── zcl_mqtt_transport_ws.clas.xml
├── zcx_mqtt.clas.abap
├── zcx_mqtt.clas.xml
├── zcx_mqtt_timeout.clas.abap
├── zcx_mqtt_timeout.clas.xml
├── zif_mqtt_constants.intf.abap
├── zif_mqtt_constants.intf.xml
├── zif_mqtt_transport.intf.abap
└── zif_mqtt_transport.intf.xml
├── package.devc.xml
└── test
├── package.devc.xml
├── zabapmq_http_client.prog.abap
├── zabapmq_http_client.prog.xml
├── zabapmq_mqtt.prog.abap
├── zabapmq_mqtt.prog.xml
├── zabapmq_performance.prog.abap
└── zabapmq_performance.prog.xml
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | E
6 | /src/
7 | PREFIX
8 |
9 | - /.gitignore
10 | - /LICENSE
11 | - /README.md
12 | - /package.json
13 | - /.travis.yml
14 |
15 |
16 | -
17 | SAP_BASIS
18 | 750
19 | 0001
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 INVIXO Consulting Group A/S
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # abapMQ
2 |
3 | MQTT client implemented in ABAP
4 |
5 | Supports:
6 | * [MQTT, Version 3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html)
7 |
8 | ABAP version 750sp01 required
9 |
10 | Install via [abapGit](http://abapgit.org)
11 |
--------------------------------------------------------------------------------
/abaplint.json:
--------------------------------------------------------------------------------
1 | {
2 | "global": {
3 | "files": "/src/**/*.*",
4 | "skipGeneratedGatewayClasses": true,
5 | "skipGeneratedPersistentClasses": true,
6 | "skipGeneratedFunctionGroups": true,
7 | "applyUnspecifiedRules": false
8 | },
9 | "dependencies": [
10 | {
11 | "url": "https://github.com/abaplint/deps",
12 | "folder": "/deps",
13 | "files": "/src/**/*.*"
14 | }
15 | ],
16 | "syntax": {
17 | "version": "v750",
18 | "errorNamespace": "^(Z|Y)",
19 | "globalConstants": [],
20 | "globalMacros": []
21 | },
22 | "rules": {
23 | "7bit_ascii": {
24 | "enabled": true,
25 | "exclude": [],
26 | "reason": ""
27 | },
28 | "abapdoc": {
29 | "enabled": false,
30 | "exclude": [],
31 | "reason": "",
32 | "checkLocal": false
33 | },
34 | "allowed_object_naming": {
35 | "enabled": true,
36 | "exclude": [],
37 | "reason": ""
38 | },
39 | "allowed_object_types": {
40 | "enabled": true,
41 | "exclude": [],
42 | "reason": "",
43 | "allowed": []
44 | },
45 | "ambiguous_statement": {
46 | "enabled": true,
47 | "exclude": [],
48 | "reason": ""
49 | },
50 | "avoid_use": {
51 | "enabled": true,
52 | "exclude": [],
53 | "reason": "",
54 | "define": true,
55 | "endselect": true,
56 | "execSQL": true,
57 | "kernelCall": true,
58 | "communication": true,
59 | "statics": true,
60 | "systemCall": true
61 | },
62 | "begin_end_names": {
63 | "enabled": true,
64 | "exclude": [],
65 | "reason": ""
66 | },
67 | "breakpoint": {
68 | "enabled": true,
69 | "exclude": [],
70 | "reason": ""
71 | },
72 | "chain_mainly_declarations": {
73 | "enabled": true,
74 | "exclude": [],
75 | "reason": ""
76 | },
77 | "check_abstract": {
78 | "enabled": true,
79 | "exclude": [],
80 | "reason": ""
81 | },
82 | "check_comments": {
83 | "enabled": false,
84 | "exclude": [],
85 | "reason": "",
86 | "allowEndOfLine": false
87 | },
88 | "check_ddic": {
89 | "enabled": true,
90 | "exclude": [],
91 | "reason": ""
92 | },
93 | "check_include": {
94 | "enabled": true,
95 | "exclude": [],
96 | "reason": ""
97 | },
98 | "check_no_handler_pragma": {
99 | "enabled": true,
100 | "exclude": [],
101 | "reason": ""
102 | },
103 | "check_syntax": {
104 | "enabled": true,
105 | "exclude": [],
106 | "reason": ""
107 | },
108 | "check_text_elements": {
109 | "enabled": true,
110 | "exclude": [],
111 | "reason": ""
112 | },
113 | "check_transformation_exists": {
114 | "enabled": true,
115 | "exclude": [],
116 | "reason": ""
117 | },
118 | "class_attribute_names": {
119 | "enabled": false,
120 | "exclude": [],
121 | "reason": "",
122 | "patternKind": "required",
123 | "ignoreNames": [],
124 | "ignorePatterns": [],
125 | "ignoreExceptions": true,
126 | "statics": "^G._.+$",
127 | "instance": "^M._.+$"
128 | },
129 | "cloud_types": {
130 | "enabled": true,
131 | "exclude": [],
132 | "reason": ""
133 | },
134 | "colon_missing_space": {
135 | "enabled": true,
136 | "exclude": [],
137 | "reason": ""
138 | },
139 | "commented_code": {
140 | "enabled": true,
141 | "exclude": [],
142 | "reason": ""
143 | },
144 | "constructor_visibility_public": {
145 | "enabled": true,
146 | "exclude": [],
147 | "reason": ""
148 | },
149 | "contains_tab": {
150 | "enabled": true,
151 | "exclude": [],
152 | "reason": ""
153 | },
154 | "definitions_top": {
155 | "enabled": true,
156 | "exclude": [],
157 | "reason": ""
158 | },
159 | "description_empty": {
160 | "enabled": true,
161 | "exclude": [],
162 | "reason": ""
163 | },
164 | "double_space": {
165 | "enabled": false,
166 | "exclude": [],
167 | "reason": "",
168 | "keywords": true,
169 | "startParen": true,
170 | "endParen": true,
171 | "afterColon": true
172 | },
173 | "empty_line_in_statement": {
174 | "enabled": true,
175 | "exclude": [],
176 | "reason": "",
177 | "allowChained": false
178 | },
179 | "empty_statement": {
180 | "enabled": true,
181 | "exclude": [],
182 | "reason": ""
183 | },
184 | "empty_structure": {
185 | "enabled": true,
186 | "exclude": [],
187 | "reason": "",
188 | "loop": true,
189 | "if": true,
190 | "while": true,
191 | "case": true,
192 | "select": true,
193 | "do": true,
194 | "at": true
195 | },
196 | "exit_or_check": {
197 | "enabled": true,
198 | "exclude": [],
199 | "reason": ""
200 | },
201 | "exporting": {
202 | "enabled": true,
203 | "exclude": [],
204 | "reason": ""
205 | },
206 | "form_no_dash": {
207 | "enabled": true,
208 | "exclude": [],
209 | "reason": ""
210 | },
211 | "form_tables_obsolete": {
212 | "enabled": true,
213 | "exclude": [],
214 | "reason": ""
215 | },
216 | "fully_type_constants": {
217 | "enabled": true,
218 | "exclude": [],
219 | "reason": "",
220 | "checkData": true
221 | },
222 | "functional_writing": {
223 | "enabled": true,
224 | "exclude": [],
225 | "reason": "",
226 | "ignoreExceptions": true
227 | },
228 | "global_class": {
229 | "enabled": true,
230 | "exclude": [],
231 | "reason": ""
232 | },
233 | "identical_form_names": {
234 | "enabled": true,
235 | "exclude": [],
236 | "reason": ""
237 | },
238 | "if_in_if": {
239 | "enabled": true,
240 | "exclude": [],
241 | "reason": ""
242 | },
243 | "implement_methods": {
244 | "enabled": true,
245 | "exclude": [],
246 | "reason": ""
247 | },
248 | "in_statement_indentation": {
249 | "enabled": true,
250 | "exclude": [],
251 | "reason": "",
252 | "ignoreExceptions": true
253 | },
254 | "indentation": {
255 | "enabled": true,
256 | "exclude": [],
257 | "reason": "",
258 | "ignoreExceptions": true,
259 | "alignTryCatch": false,
260 | "globalClassSkipFirst": false,
261 | "ignoreGlobalClassDefinition": false,
262 | "ignoreGlobalInterface": false
263 | },
264 | "inline_data_old_versions": {
265 | "enabled": true,
266 | "exclude": [],
267 | "reason": ""
268 | },
269 | "keyword_case": {
270 | "enabled": true,
271 | "exclude": [],
272 | "reason": "",
273 | "style": "upper",
274 | "ignoreExceptions": true,
275 | "ignoreLowerClassImplmentationStatement": true,
276 | "ignoreGlobalClassDefinition": false,
277 | "ignoreGlobalInterface": false,
278 | "ignoreFunctionModuleName": false
279 | },
280 | "line_length": {
281 | "enabled": true,
282 | "exclude": [],
283 | "reason": "",
284 | "length": 120
285 | },
286 | "line_only_punc": {
287 | "enabled": true,
288 | "exclude": [],
289 | "reason": "",
290 | "ignoreExceptions": true
291 | },
292 | "local_class_naming": {
293 | "enabled": true,
294 | "exclude": [],
295 | "reason": "",
296 | "patternKind": "required",
297 | "ignoreNames": [],
298 | "ignorePatterns": [],
299 | "local": "^LCL_.+$",
300 | "exception": "^LCX_.+$",
301 | "test": "^LTCL_.+$"
302 | },
303 | "local_testclass_location": {
304 | "enabled": true,
305 | "exclude": [],
306 | "reason": ""
307 | },
308 | "local_variable_names": {
309 | "enabled": true,
310 | "exclude": [],
311 | "reason": "",
312 | "patternKind": "required",
313 | "ignoreNames": [],
314 | "ignorePatterns": [],
315 | "expectedData": "^L._.+$",
316 | "expectedConstant": "^LC_.+$",
317 | "expectedFS": "^$"
318 | },
319 | "main_file_contents": {
320 | "enabled": true,
321 | "exclude": [],
322 | "reason": ""
323 | },
324 | "max_one_statement": {
325 | "enabled": true,
326 | "exclude": [],
327 | "reason": ""
328 | },
329 | "message_exists": {
330 | "enabled": true,
331 | "exclude": [],
332 | "reason": ""
333 | },
334 | "method_length": {
335 | "enabled": true,
336 | "exclude": [],
337 | "reason": "",
338 | "statements": 100,
339 | "errorWhenEmpty": true,
340 | "ignoreTestClasses": false
341 | },
342 | "method_parameter_names": {
343 | "enabled": true,
344 | "exclude": [],
345 | "reason": "",
346 | "patternKind": "required",
347 | "ignoreNames": [],
348 | "ignorePatterns": [],
349 | "ignoreExceptions": true,
350 | "importing": "^I._.+$",
351 | "returning": "^R._.+$",
352 | "changing": "^C._.+$",
353 | "exporting": "^E._.+$"
354 | },
355 | "mix_returning": {
356 | "enabled": true,
357 | "exclude": [],
358 | "reason": ""
359 | },
360 | "msag_consistency": {
361 | "enabled": true,
362 | "exclude": [],
363 | "reason": ""
364 | },
365 | "nesting": {
366 | "enabled": true,
367 | "exclude": [],
368 | "reason": "",
369 | "depth": 5
370 | },
371 | "newline_between_methods": {
372 | "enabled": true,
373 | "exclude": [],
374 | "reason": "",
375 | "count": 3,
376 | "logic": "less"
377 | },
378 | "no_public_attributes": {
379 | "enabled": false,
380 | "exclude": [],
381 | "reason": "",
382 | "allowReadOnly": false
383 | },
384 | "object_naming": {
385 | "enabled": true,
386 | "exclude": [],
387 | "reason": "",
388 | "patternKind": "required",
389 | "ignoreNames": [],
390 | "ignorePatterns": [],
391 | "clas": "^ZC(L|X)\\_",
392 | "intf": "^ZIF\\_",
393 | "prog": "^Z",
394 | "fugr": "^Z",
395 | "tabl": "^Z",
396 | "ttyp": "^Z",
397 | "dtel": "^Z",
398 | "doma": "^Z",
399 | "msag": "^Z",
400 | "tran": "^Z",
401 | "enqu": "^EZ",
402 | "auth": "^Z",
403 | "pinf": "^Z",
404 | "idoc": "^Z",
405 | "xslt": "^Z"
406 | },
407 | "obsolete_statement": {
408 | "enabled": true,
409 | "exclude": [],
410 | "reason": "",
411 | "refresh": true,
412 | "compute": true,
413 | "add": true,
414 | "subtract": true,
415 | "multiply": true,
416 | "move": true,
417 | "divide": true,
418 | "requested": true,
419 | "occurs": true
420 | },
421 | "parser_error": {
422 | "enabled": true,
423 | "exclude": [],
424 | "reason": ""
425 | },
426 | "preferred_compare_operator": {
427 | "enabled": true,
428 | "exclude": [],
429 | "reason": "",
430 | "badOperators": [
431 | "EQ",
432 | "><",
433 | "NE",
434 | "GE",
435 | "GT",
436 | "LT",
437 | "LE"
438 | ]
439 | },
440 | "release_idoc": {
441 | "enabled": true,
442 | "exclude": [],
443 | "reason": ""
444 | },
445 | "remove_descriptions": {
446 | "enabled": false,
447 | "exclude": [],
448 | "reason": "",
449 | "ignoreExceptions": false
450 | },
451 | "rfc_error_handling": {
452 | "enabled": true,
453 | "exclude": [],
454 | "reason": ""
455 | },
456 | "selection_screen_naming": {
457 | "enabled": true,
458 | "exclude": [],
459 | "reason": "",
460 | "patternKind": "required",
461 | "ignoreNames": [],
462 | "ignorePatterns": [],
463 | "parameter": "^P_.+$",
464 | "selectOption": "^S_.+$"
465 | },
466 | "sequential_blank": {
467 | "enabled": true,
468 | "exclude": [],
469 | "reason": "",
470 | "lines": 4
471 | },
472 | "short_case": {
473 | "enabled": true,
474 | "exclude": [],
475 | "reason": "",
476 | "length": 1,
477 | "allow": []
478 | },
479 | "sicf_consistency": {
480 | "enabled": true,
481 | "exclude": [],
482 | "reason": ""
483 | },
484 | "space_before_colon": {
485 | "enabled": true,
486 | "exclude": [],
487 | "reason": ""
488 | },
489 | "space_before_dot": {
490 | "enabled": true,
491 | "exclude": [],
492 | "reason": "",
493 | "ignoreGlobalDefinition": true,
494 | "ignoreExceptions": true
495 | },
496 | "start_at_tab": {
497 | "enabled": true,
498 | "exclude": [],
499 | "reason": ""
500 | },
501 | "superclass_final": {
502 | "enabled": true,
503 | "exclude": [],
504 | "reason": ""
505 | },
506 | "tabl_enhancement_category": {
507 | "enabled": true,
508 | "exclude": [],
509 | "reason": ""
510 | },
511 | "type_begin_single_include": {
512 | "enabled": true,
513 | "exclude": [],
514 | "reason": ""
515 | },
516 | "type_form_parameters": {
517 | "enabled": true,
518 | "exclude": [],
519 | "reason": ""
520 | },
521 | "types_naming": {
522 | "enabled": true,
523 | "exclude": [],
524 | "reason": "",
525 | "pattern": "^TY_.+$"
526 | },
527 | "unreachable_code": {
528 | "enabled": true,
529 | "exclude": [],
530 | "reason": ""
531 | },
532 | "use_new": {
533 | "enabled": true,
534 | "exclude": [],
535 | "reason": ""
536 | },
537 | "when_others_last": {
538 | "enabled": true,
539 | "exclude": [],
540 | "reason": ""
541 | },
542 | "whitespace_end": {
543 | "enabled": true,
544 | "exclude": [],
545 | "reason": ""
546 | },
547 | "xml_consistency": {
548 | "enabled": true,
549 | "exclude": [],
550 | "reason": ""
551 | }
552 | }
553 | }
554 |
--------------------------------------------------------------------------------
/src/mqtt/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MQTT Client
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/mqtt/packets/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Packets
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connack.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_connack DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | TYPES:
10 | ty_return_code TYPE x LENGTH 1 .
11 |
12 | CONSTANTS:
13 | BEGIN OF gc_return_code,
14 | accepted TYPE ty_return_code VALUE '00',
15 | unacceptabe_protocol TYPE ty_return_code VALUE '01',
16 | identifer_rejected TYPE ty_return_code VALUE '02',
17 | server_unavailable TYPE ty_return_code VALUE '03',
18 | bad_username_or_password TYPE ty_return_code VALUE '04',
19 | not_authorized TYPE ty_return_code VALUE '05',
20 | END OF gc_return_code .
21 |
22 | METHODS get_session_present
23 | RETURNING
24 | VALUE(rv_session_present) TYPE abap_bool .
25 | METHODS get_return_code
26 | RETURNING
27 | VALUE(rv_return_code) TYPE ty_return_code .
28 | PROTECTED SECTION.
29 |
30 | DATA mv_session_present TYPE abap_bool .
31 | DATA mv_return_code TYPE ty_return_code .
32 | PRIVATE SECTION.
33 | ENDCLASS.
34 |
35 |
36 |
37 | CLASS ZCL_MQTT_PACKET_CONNACK IMPLEMENTATION.
38 |
39 |
40 | METHOD get_return_code.
41 |
42 | rv_return_code = mv_return_code.
43 |
44 | ENDMETHOD.
45 |
46 |
47 | METHOD get_session_present.
48 |
49 | rv_session_present = mv_session_present.
50 |
51 | ENDMETHOD.
52 |
53 |
54 | METHOD zif_mqtt_packet~decode.
55 |
56 | CONSTANTS: lc_header TYPE xstring VALUE '2002'.
57 |
58 | ASSERT io_stream->eat_hex( 2 ) = lc_header.
59 |
60 | CASE io_stream->eat_hex( 1 ).
61 | WHEN '00'.
62 | mv_session_present = abap_false.
63 | WHEN '01'.
64 | mv_session_present = abap_true.
65 | WHEN OTHERS.
66 | ASSERT 0 = 1.
67 | ENDCASE.
68 |
69 | mv_return_code = io_stream->eat_hex( 1 ).
70 |
71 | ASSERT io_stream->get_length( ) = 0.
72 |
73 | ENDMETHOD.
74 |
75 |
76 | METHOD zif_mqtt_packet~encode.
77 |
78 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
79 |
80 | IF mv_session_present = abap_true.
81 | lo_payload->add_hex( '01' ).
82 | ELSE.
83 | lo_payload->add_hex( '00' ).
84 | ENDIF.
85 |
86 | lo_payload->add_hex( mv_return_code ).
87 |
88 | ro_stream = NEW #( ).
89 |
90 | ro_stream->add_packet(
91 | ii_packet = me
92 | io_payload = lo_payload ).
93 |
94 | ENDMETHOD.
95 |
96 |
97 | METHOD zif_mqtt_packet~get_type.
98 |
99 | rv_value = zif_mqtt_constants=>gc_packets-connack.
100 |
101 | ENDMETHOD.
102 | ENDCLASS.
103 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connack.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_connack.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '20020000'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->get_return_code( )
35 | exp = '00' ).
36 |
37 | cl_abap_unit_assert=>assert_equals(
38 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
39 | exp = lc_hex ).
40 |
41 | ENDMETHOD.
42 |
43 | ENDCLASS.
44 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connack.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_CONNACK
7 | E
8 | CONNACK
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connect.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_connect DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constructor
10 | IMPORTING
11 | !iv_clean_session TYPE abap_bool DEFAULT abap_true
12 | !iv_username TYPE string OPTIONAL
13 | !iv_password TYPE string OPTIONAL
14 | !iv_client_id TYPE string OPTIONAL
15 | iv_will_qos TYPE zif_mqtt_packet=>ty_qos OPTIONAL
16 | is_will_message TYPE zif_mqtt_packet=>ty_message OPTIONAL
17 | iv_will_retain TYPE abap_bool OPTIONAL
18 | !iv_keep_alive TYPE i DEFAULT 30 .
19 | PROTECTED SECTION.
20 |
21 | TYPES:
22 | BEGIN OF ty_flags,
23 | username TYPE abap_bool,
24 | password TYPE abap_bool,
25 | will_retain TYPE abap_bool,
26 | will_qos TYPE zif_mqtt_packet=>ty_qos,
27 | will_flag TYPE abap_bool,
28 | clean_session TYPE abap_bool,
29 | END OF ty_flags .
30 |
31 | CONSTANTS lc_protocol_name TYPE string VALUE 'MQTT' ##NO_TEXT.
32 | CONSTANTS lc_protocol_level TYPE xstring VALUE '04' ##NO_TEXT.
33 | DATA mv_username TYPE string .
34 | DATA mv_password TYPE xstring .
35 | DATA mv_client_id TYPE string .
36 | DATA mv_will_qos TYPE zif_mqtt_packet=>ty_qos .
37 | DATA ms_will_message TYPE zif_mqtt_packet=>ty_message .
38 | DATA mv_will_retain TYPE abap_bool .
39 | DATA:
40 | mv_keep_alive TYPE x LENGTH 2 .
41 | DATA mv_clean_session TYPE abap_bool .
42 |
43 | CLASS-METHODS decode_flags
44 | IMPORTING
45 | !iv_hex TYPE xsequence
46 | RETURNING
47 | VALUE(rs_flags) TYPE ty_flags .
48 | CLASS-METHODS encode_flags
49 | IMPORTING
50 | !is_flags TYPE ty_flags
51 | RETURNING
52 | VALUE(rv_hex) TYPE xstring .
53 | PRIVATE SECTION.
54 | ENDCLASS.
55 |
56 |
57 |
58 | CLASS ZCL_MQTT_PACKET_CONNECT IMPLEMENTATION.
59 |
60 |
61 | METHOD constructor.
62 |
63 | mv_clean_session = iv_clean_session.
64 | mv_client_id = iv_client_id.
65 | mv_keep_alive = iv_keep_alive.
66 | mv_password = cl_binary_convert=>string_to_xstring_utf8( CONV #( iv_password ) ).
67 | mv_username = iv_username.
68 | ms_will_message = is_will_message.
69 | mv_will_qos = iv_will_qos.
70 | mv_will_retain = iv_will_retain.
71 |
72 | ENDMETHOD.
73 |
74 |
75 | METHOD decode_flags.
76 |
77 | DATA: lv_int TYPE i.
78 |
79 | lv_int = iv_hex.
80 |
81 | IF lv_int DIV 128 = 1.
82 | rs_flags-username = abap_true.
83 | ENDIF.
84 |
85 | IF lv_int DIV 64 = 1.
86 | rs_flags-password = abap_true.
87 | ENDIF.
88 |
89 | IF lv_int DIV 32 = 1.
90 | rs_flags-will_retain = abap_true.
91 | ENDIF.
92 |
93 | rs_flags-will_qos = ( lv_int DIV 8 ) MOD 4.
94 |
95 | IF lv_int DIV 4 = 1.
96 | rs_flags-will_flag = abap_true.
97 | ENDIF.
98 |
99 | IF lv_int DIV 2 = 1.
100 | rs_flags-clean_session = abap_true.
101 | ENDIF.
102 |
103 | ENDMETHOD.
104 |
105 |
106 | METHOD encode_flags.
107 |
108 | DATA: lv_int TYPE i,
109 | lv_hex TYPE x LENGTH 1.
110 |
111 |
112 | IF is_flags-username = abap_true.
113 | lv_int = lv_int + 128.
114 | ENDIF.
115 |
116 | IF is_flags-password = abap_true.
117 | lv_int = lv_int + 64.
118 | ENDIF.
119 |
120 | IF is_flags-will_retain = abap_true.
121 | lv_int = lv_int + 32.
122 | ENDIF.
123 |
124 | lv_int = lv_int + is_flags-will_qos * 8.
125 |
126 | IF is_flags-will_flag = abap_true.
127 | lv_int = lv_int + 4.
128 | ENDIF.
129 |
130 | IF is_flags-clean_session = abap_true.
131 | lv_int = lv_int + 2.
132 | ENDIF.
133 |
134 | lv_hex = lv_int.
135 | rv_hex = lv_hex.
136 |
137 | ENDMETHOD.
138 |
139 |
140 | METHOD zif_mqtt_packet~decode.
141 |
142 | DATA: lv_length TYPE i.
143 |
144 | ASSERT io_stream->eat_hex( 1 ) = '10'.
145 | io_stream->eat_length( ).
146 | ASSERT io_stream->eat_utf8( ) = lc_protocol_name.
147 | ASSERT io_stream->eat_hex( 1 ) = lc_protocol_level.
148 |
149 | DATA(ls_flags) = decode_flags( io_stream->eat_hex( 1 ) ).
150 | mv_clean_session = ls_flags-clean_session.
151 | mv_will_qos = ls_flags-will_qos.
152 | mv_will_retain = ls_flags-will_retain.
153 |
154 | mv_keep_alive = io_stream->eat_hex( 2 ).
155 |
156 | mv_client_id = io_stream->eat_utf8( ).
157 |
158 | IF ls_flags-will_flag = abap_true.
159 | ms_will_message-topic = io_stream->eat_utf8( ).
160 | lv_length = io_stream->eat_hex( 2 ).
161 | ms_will_message-message = io_stream->eat_hex( lv_length ).
162 | ENDIF.
163 |
164 | IF ls_flags-username = abap_true.
165 | mv_username = io_stream->eat_utf8( ).
166 | ENDIF.
167 |
168 | IF ls_flags-password = abap_true.
169 | lv_length = io_stream->eat_hex( 2 ).
170 | mv_password = io_stream->eat_hex( lv_length ).
171 | ENDIF.
172 |
173 | ASSERT io_stream->get_length( ) = 0.
174 |
175 | ENDMETHOD.
176 |
177 |
178 | METHOD zif_mqtt_packet~encode.
179 |
180 | DATA: lv_length TYPE x LENGTH 2.
181 |
182 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
183 |
184 | lo_payload->add_utf8( lc_protocol_name ).
185 |
186 | lo_payload->add_hex( lc_protocol_level ).
187 |
188 | lo_payload->add_hex( encode_flags( VALUE #(
189 | username = boolc( NOT mv_username IS INITIAL )
190 | password = boolc( NOT mv_password IS INITIAL )
191 | will_retain = mv_will_retain
192 | will_qos = mv_will_qos
193 | will_flag = boolc( NOT ms_will_message IS INITIAL )
194 | clean_session = mv_clean_session ) ) ).
195 |
196 | lo_payload->add_hex( mv_keep_alive ).
197 |
198 | lo_payload->add_utf8( mv_client_id ).
199 |
200 | IF NOT ms_will_message IS INITIAL.
201 | lo_payload->add_utf8( ms_will_message-topic ).
202 | lv_length = xstrlen( ms_will_message-message ).
203 | lo_payload->add_hex( lv_length ).
204 | lo_payload->add_hex( ms_will_message-message ).
205 | ENDIF.
206 |
207 | IF NOT mv_username IS INITIAL.
208 | lo_payload->add_utf8( mv_username ).
209 | ENDIF.
210 |
211 | IF NOT mv_password IS INITIAL.
212 | lv_length = xstrlen( mv_password ). " <-- fix, was xstrlen( ms_will_message-message ).
213 | lo_payload->add_hex( lv_length ).
214 | lo_payload->add_hex( mv_password ).
215 | ENDIF.
216 |
217 | ro_stream = NEW #( ).
218 |
219 | ro_stream->add_packet(
220 | ii_packet = me
221 | io_payload = lo_payload ).
222 |
223 | ENDMETHOD.
224 |
225 |
226 | METHOD zif_mqtt_packet~get_type.
227 |
228 | rv_value = zif_mqtt_constants=>gc_packets-connect.
229 |
230 | ENDMETHOD.
231 | ENDCLASS.
232 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connect.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | METHODS:
8 | test FOR TESTING,
9 | test_new FOR TESTING.
10 |
11 | ENDCLASS.
12 |
13 |
14 | CLASS ltcl_test IMPLEMENTATION.
15 |
16 | METHOD test.
17 |
18 | CONSTANTS: lc_hex TYPE xstring VALUE '100C00044D5154540402001E0000'.
19 |
20 | DATA(lo_encoded) = NEW zcl_mqtt_packet_connect( ).
21 |
22 | DATA(lv_hex) = lo_encoded->zif_mqtt_packet~encode( )->get_hex( ).
23 |
24 | cl_abap_unit_assert=>assert_equals(
25 | act = lv_hex
26 | exp = lc_hex ).
27 |
28 | ENDMETHOD.
29 |
30 | METHOD test_new.
31 |
32 | CONSTANTS: lc_hex TYPE xstring VALUE '100C00044D5154540402001E0000'.
33 |
34 | DATA(lo_connect) = NEW zcl_mqtt_packet_connect( ).
35 | lo_connect->zif_mqtt_packet~decode( NEW zcl_mqtt_stream( lc_hex ) ).
36 |
37 | DATA(lv_hex) = lo_connect->zif_mqtt_packet~encode( )->get_hex( ).
38 |
39 | cl_abap_unit_assert=>assert_equals(
40 | act = lv_hex
41 | exp = lc_hex ).
42 |
43 | ENDMETHOD.
44 |
45 | ENDCLASS.
46 |
47 |
48 | CLASS ltcl_flags DEFINITION DEFERRED.
49 | CLASS zcl_mqtt_packet_connect DEFINITION LOCAL FRIENDS ltcl_flags.
50 |
51 | CLASS ltcl_flags DEFINITION FOR TESTING
52 | DURATION SHORT
53 | RISK LEVEL HARMLESS FINAL.
54 |
55 | PRIVATE SECTION.
56 | DATA: mo_cut TYPE REF TO zcl_mqtt_packet_connect.
57 |
58 | METHODS: setup,
59 | test FOR TESTING.
60 |
61 | ENDCLASS.
62 |
63 |
64 | CLASS ltcl_flags IMPLEMENTATION.
65 |
66 | METHOD setup.
67 | mo_cut = NEW #( ).
68 | ENDMETHOD.
69 |
70 | METHOD test.
71 |
72 | CONSTANTS: lc_hex TYPE x LENGTH 1 VALUE '02'.
73 |
74 | DATA: ls_flags TYPE zcl_mqtt_packet_connect=>ty_flags.
75 |
76 |
77 | ls_flags = mo_cut->decode_flags( lc_hex ).
78 |
79 | DATA(ls_expected) = VALUE zcl_mqtt_packet_connect=>ty_flags(
80 | username = abap_false
81 | password = abap_false
82 | will_retain = abap_false
83 | will_qos = zif_mqtt_packet=>gc_qos-at_most_once
84 | will_flag = abap_false
85 | clean_session = abap_true ).
86 |
87 | cl_abap_unit_assert=>assert_equals(
88 | act = ls_flags
89 | exp = ls_expected ).
90 |
91 | cl_abap_unit_assert=>assert_equals(
92 | act = mo_cut->encode_flags( ls_flags )
93 | exp = CONV xstring( lc_hex ) ).
94 |
95 | ENDMETHOD.
96 |
97 | ENDCLASS.
98 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_connect.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_CONNECT
7 | E
8 | CONNECT
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_disconnect.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_disconnect DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 | PROTECTED SECTION.
9 | PRIVATE SECTION.
10 | ENDCLASS.
11 |
12 |
13 |
14 | CLASS ZCL_MQTT_PACKET_DISCONNECT IMPLEMENTATION.
15 |
16 |
17 | METHOD zif_mqtt_packet~decode.
18 |
19 | ASSERT io_stream->eat_hex( 2 ) = 'E000'.
20 |
21 | ENDMETHOD.
22 |
23 |
24 | METHOD zif_mqtt_packet~encode.
25 |
26 | ro_stream = NEW #( ).
27 |
28 | ro_stream->add_packet( me ).
29 |
30 | ENDMETHOD.
31 |
32 |
33 | METHOD zif_mqtt_packet~get_type.
34 |
35 | rv_value = zif_mqtt_constants=>gc_packets-disconnect.
36 |
37 | ENDMETHOD.
38 | ENDCLASS.
39 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_disconnect.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | METHODS: test FOR TESTING.
8 |
9 | ENDCLASS.
10 |
11 |
12 | CLASS ltcl_test IMPLEMENTATION.
13 |
14 | METHOD test.
15 |
16 | DATA(lo_connect) = NEW zcl_mqtt_packet_disconnect( ).
17 |
18 | DATA(lv_hex) = lo_connect->zif_mqtt_packet~encode( )->get_hex( ).
19 |
20 | cl_abap_unit_assert=>assert_equals(
21 | act = lv_hex
22 | exp = 'E000' ).
23 |
24 | ENDMETHOD.
25 |
26 | ENDCLASS.
27 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_disconnect.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_DISCONNECT
7 | E
8 | DISCONNECT
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingreq.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_pingreq DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | ALIASES decode
10 | FOR zif_mqtt_packet~decode .
11 | ALIASES encode
12 | FOR zif_mqtt_packet~encode .
13 | ALIASES get_type
14 | FOR zif_mqtt_packet~get_type .
15 | PROTECTED SECTION.
16 | PRIVATE SECTION.
17 | ENDCLASS.
18 |
19 |
20 |
21 | CLASS ZCL_MQTT_PACKET_PINGREQ IMPLEMENTATION.
22 |
23 |
24 | METHOD zif_mqtt_packet~decode.
25 |
26 | ASSERT io_stream->eat_hex( 2 ) = 'C000'.
27 |
28 | ENDMETHOD.
29 |
30 |
31 | METHOD zif_mqtt_packet~encode.
32 |
33 | ro_stream = NEW #( ).
34 |
35 | ro_stream->add_packet( me ).
36 |
37 | ENDMETHOD.
38 |
39 |
40 | METHOD zif_mqtt_packet~get_type.
41 |
42 | rv_value = zif_mqtt_constants=>gc_packets-pingreq.
43 |
44 | ENDMETHOD.
45 | ENDCLASS.
46 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingreq.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mi_cut TYPE REF TO zif_mqtt_packet.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 | ENDCLASS.
14 |
15 |
16 | CLASS ltcl_test IMPLEMENTATION.
17 |
18 | METHOD setup.
19 | mi_cut = NEW zcl_mqtt_packet_pingreq( ).
20 | ENDMETHOD.
21 |
22 | METHOD test.
23 |
24 | DATA(lv_hex) = mi_cut->encode( )->get_hex( ).
25 |
26 | cl_abap_unit_assert=>assert_equals(
27 | act = lv_hex
28 | exp = 'C000' ).
29 |
30 | ENDMETHOD.
31 |
32 | ENDCLASS.
33 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingreq.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PINGREQ
7 | E
8 | PINGREQ
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingresp.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_pingresp DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 | PROTECTED SECTION.
9 | PRIVATE SECTION.
10 | ENDCLASS.
11 |
12 |
13 |
14 | CLASS ZCL_MQTT_PACKET_PINGRESP IMPLEMENTATION.
15 |
16 |
17 | METHOD zif_mqtt_packet~decode.
18 |
19 | ASSERT io_stream->eat_hex( 2 ) = 'D000'.
20 |
21 | ENDMETHOD.
22 |
23 |
24 | METHOD zif_mqtt_packet~encode.
25 |
26 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
27 |
28 | ro_stream = NEW #( ).
29 |
30 | ro_stream->add_packet(
31 | ii_packet = me
32 | io_payload = lo_payload ).
33 |
34 | ENDMETHOD.
35 |
36 |
37 | METHOD zif_mqtt_packet~get_type.
38 |
39 | rv_value = zif_mqtt_constants=>gc_packets-pingresp.
40 |
41 | ENDMETHOD.
42 | ENDCLASS.
43 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingresp.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_pingresp.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE 'D000'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pingresp.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PINGRESP
7 | E
8 | PINGRESP
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_puback.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_puback DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constructor
10 | IMPORTING
11 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
12 | METHODS get_packet_identifier
13 | RETURNING
14 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
15 | METHODS set_packet_identifier
16 | IMPORTING
17 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
18 | PROTECTED SECTION.
19 |
20 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
21 | PRIVATE SECTION.
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS ZCL_MQTT_PACKET_PUBACK IMPLEMENTATION.
27 |
28 |
29 | METHOD constructor.
30 |
31 | mv_packet_identifier = iv_packet_identifier.
32 |
33 | ENDMETHOD.
34 |
35 |
36 | METHOD get_packet_identifier.
37 |
38 | rv_packet_identifier = mv_packet_identifier.
39 |
40 | ENDMETHOD.
41 |
42 |
43 | METHOD set_packet_identifier.
44 |
45 | mv_packet_identifier = iv_packet_identifier.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD zif_mqtt_packet~decode.
51 |
52 | ASSERT io_stream->eat_hex( 1 ) = '42'.
53 |
54 | io_stream->eat_length( ).
55 |
56 | mv_packet_identifier = io_stream->eat_hex( 2 ).
57 |
58 | ENDMETHOD.
59 |
60 |
61 | METHOD zif_mqtt_packet~encode.
62 |
63 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
64 |
65 | ASSERT NOT mv_packet_identifier IS INITIAL.
66 | lo_payload->add_hex( mv_packet_identifier ).
67 |
68 | ro_stream = NEW #( ).
69 |
70 | ro_stream->add_packet(
71 | ii_packet = me
72 | iv_flags = 2
73 | io_payload = lo_payload ).
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD zif_mqtt_packet~get_type.
79 |
80 | rv_value = zif_mqtt_constants=>gc_packets-puback.
81 |
82 | ENDMETHOD.
83 | ENDCLASS.
84 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_puback.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_puback.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '42020001'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_puback.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PUBACK
7 | E
8 | PUBACK
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubcomp.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_pubcomp DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constructor
10 | IMPORTING
11 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
12 | METHODS get_packet_identifier
13 | RETURNING
14 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
15 | METHODS set_packet_identifier
16 | IMPORTING
17 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
18 | PROTECTED SECTION.
19 |
20 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
21 | PRIVATE SECTION.
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS ZCL_MQTT_PACKET_PUBCOMP IMPLEMENTATION.
27 |
28 |
29 | METHOD constructor.
30 |
31 | mv_packet_identifier = iv_packet_identifier.
32 |
33 | ENDMETHOD.
34 |
35 |
36 | METHOD get_packet_identifier.
37 |
38 | rv_packet_identifier = mv_packet_identifier.
39 |
40 | ENDMETHOD.
41 |
42 |
43 | METHOD set_packet_identifier.
44 |
45 | mv_packet_identifier = iv_packet_identifier.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD zif_mqtt_packet~decode.
51 |
52 | ASSERT io_stream->eat_hex( 1 ) = '72'.
53 |
54 | io_stream->eat_length( ).
55 |
56 | mv_packet_identifier = io_stream->eat_hex( 2 ).
57 |
58 | ENDMETHOD.
59 |
60 |
61 | METHOD zif_mqtt_packet~encode.
62 |
63 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
64 |
65 | ASSERT NOT mv_packet_identifier IS INITIAL.
66 | lo_payload->add_hex( mv_packet_identifier ).
67 |
68 | ro_stream = NEW #( ).
69 |
70 | ro_stream->add_packet(
71 | ii_packet = me
72 | iv_flags = 2
73 | io_payload = lo_payload ).
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD zif_mqtt_packet~get_type.
79 |
80 | rv_value = zif_mqtt_constants=>gc_packets-pubcomp.
81 |
82 | ENDMETHOD.
83 | ENDCLASS.
84 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubcomp.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_pubcomp.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '72020001'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubcomp.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PUBCOMP
7 | E
8 | PUBCOMP
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_publish.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_publish DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | ALIASES decode
10 | FOR zif_mqtt_packet~decode .
11 | ALIASES encode
12 | FOR zif_mqtt_packet~encode .
13 | ALIASES get_type
14 | FOR zif_mqtt_packet~get_type .
15 |
16 | METHODS get_message
17 | RETURNING
18 | VALUE(rs_message) TYPE zif_mqtt_packet=>ty_message .
19 | METHODS set_message
20 | IMPORTING
21 | !is_message TYPE zif_mqtt_packet=>ty_message .
22 | METHODS constructor
23 | IMPORTING
24 | !is_message TYPE zif_mqtt_packet=>ty_message OPTIONAL
25 | !iv_dup_flag TYPE abap_bool OPTIONAL
26 | !iv_qos_level TYPE zif_mqtt_packet=>ty_qos OPTIONAL
27 | !iv_retain TYPE abap_bool OPTIONAL
28 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
29 | METHODS get_packet_identifier
30 | RETURNING
31 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
32 | METHODS set_packet_identifier
33 | IMPORTING
34 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
35 | PROTECTED SECTION.
36 |
37 | DATA ms_message TYPE zif_mqtt_packet=>ty_message .
38 | DATA mv_dup_flag TYPE abap_bool .
39 | DATA mv_qos_level TYPE zif_mqtt_packet=>ty_qos .
40 | DATA mv_retain TYPE abap_bool .
41 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
42 |
43 | CLASS-METHODS decode_flags
44 | IMPORTING
45 | !iv_flags TYPE i
46 | EXPORTING
47 | !ev_qos_level TYPE zif_mqtt_packet=>ty_qos
48 | !ev_retain TYPE abap_bool
49 | !ev_dup_flag TYPE abap_bool .
50 | CLASS-METHODS encode_flags
51 | IMPORTING
52 | !iv_dup_flag TYPE abap_bool
53 | !iv_qos_level TYPE zif_mqtt_packet=>ty_qos
54 | !iv_retain TYPE abap_bool
55 | RETURNING
56 | VALUE(rv_flags) TYPE i .
57 | PRIVATE SECTION.
58 | ENDCLASS.
59 |
60 |
61 |
62 | CLASS ZCL_MQTT_PACKET_PUBLISH IMPLEMENTATION.
63 |
64 |
65 | METHOD constructor.
66 |
67 | ms_message = is_message.
68 | mv_dup_flag = iv_dup_flag.
69 | mv_qos_level = iv_qos_level.
70 | mv_retain = iv_retain.
71 | mv_packet_identifier = iv_packet_identifier.
72 |
73 | ENDMETHOD.
74 |
75 |
76 | METHOD decode_flags.
77 |
78 | IF iv_flags MOD 2 = 1.
79 | ev_retain = abap_true.
80 | ELSE.
81 | ev_retain = abap_false.
82 | ENDIF.
83 |
84 | ev_qos_level = ( iv_flags DIV 2 ) MOD 4.
85 |
86 | IF iv_flags MOD 8 = 1.
87 | ev_dup_flag = abap_true.
88 | ELSE.
89 | ev_dup_flag = abap_false.
90 | ENDIF.
91 |
92 | ENDMETHOD.
93 |
94 |
95 | METHOD encode_flags.
96 |
97 | IF iv_retain = abap_true.
98 | rv_flags = 1.
99 | ENDIF.
100 |
101 | rv_flags = rv_flags + iv_qos_level * 2.
102 |
103 | IF iv_dup_flag = abap_true.
104 | rv_flags = rv_flags + 8.
105 | ENDIF.
106 |
107 | ENDMETHOD.
108 |
109 |
110 | METHOD get_message.
111 |
112 | rs_message = ms_message.
113 |
114 | ENDMETHOD.
115 |
116 |
117 | METHOD get_packet_identifier.
118 |
119 | rv_packet_identifier = mv_packet_identifier.
120 |
121 | ENDMETHOD.
122 |
123 |
124 | METHOD set_message.
125 |
126 | ms_message = is_message.
127 |
128 | ENDMETHOD.
129 |
130 |
131 | METHOD set_packet_identifier.
132 |
133 | mv_packet_identifier = iv_packet_identifier.
134 |
135 | ENDMETHOD.
136 |
137 |
138 | METHOD zif_mqtt_packet~decode.
139 |
140 | DATA(lv_hex) = io_stream->eat_hex( 1 ).
141 |
142 | zcl_mqtt_packet_publish=>decode_flags(
143 | EXPORTING
144 | iv_flags = CONV #( lv_hex )
145 | IMPORTING
146 | ev_qos_level = mv_qos_level
147 | ev_retain = mv_retain
148 | ev_dup_flag = mv_dup_flag ).
149 |
150 | io_stream->eat_length( ).
151 |
152 | ms_message-topic = io_stream->eat_utf8( ).
153 |
154 | IF mv_qos_level > 0.
155 | mv_packet_identifier = io_stream->eat_hex( 2 ).
156 | ENDIF.
157 |
158 | ms_message-message = io_stream->eat_hex( io_stream->get_length( ) ).
159 |
160 | ASSERT io_stream->get_length( ) = 0.
161 |
162 | ENDMETHOD.
163 |
164 |
165 | METHOD zif_mqtt_packet~encode.
166 |
167 | ASSERT NOT ms_message-topic IS INITIAL.
168 | ASSERT NOT ms_message-message IS INITIAL.
169 |
170 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
171 |
172 | IF mv_qos_level > 0.
173 | ASSERT NOT mv_packet_identifier IS INITIAL.
174 | lo_payload->add_hex( mv_packet_identifier ).
175 | ENDIF.
176 |
177 | lo_payload->add_utf8( ms_message-topic ).
178 | lo_payload->add_hex( ms_message-message ).
179 |
180 | DATA(lv_flags) = encode_flags(
181 | iv_dup_flag = mv_dup_flag
182 | iv_qos_level = mv_qos_level
183 | iv_retain = mv_retain ).
184 |
185 | ro_stream = NEW #( ).
186 |
187 | ro_stream->add_packet(
188 | ii_packet = me
189 | io_payload = lo_payload ).
190 |
191 | ENDMETHOD.
192 |
193 |
194 | METHOD zif_mqtt_packet~get_type.
195 |
196 | rv_value = zif_mqtt_constants=>gc_packets-publish.
197 |
198 | ENDMETHOD.
199 | ENDCLASS.
200 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_publish.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_publish.
9 |
10 | METHODS:
11 | setup,
12 | decode FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD decode.
26 |
27 | CONSTANTS: lc_topic TYPE string VALUE 'topic',
28 | lc_message TYPE xstring VALUE '001122334455'.
29 |
30 |
31 | mo_cut->set_message( VALUE #(
32 | topic = lc_topic
33 | message = lc_message ) ).
34 |
35 | mo_cut->zif_mqtt_packet~decode( mo_cut->zif_mqtt_packet~encode( ) ).
36 |
37 | cl_abap_unit_assert=>assert_equals(
38 | act = mo_cut->get_message( )-topic
39 | exp = lc_topic ).
40 |
41 | cl_abap_unit_assert=>assert_equals(
42 | act = mo_cut->get_message( )-message
43 | exp = lc_message ).
44 |
45 | ENDMETHOD.
46 |
47 | ENDCLASS.
48 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_publish.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PUBLISH
7 | E
8 | PUBLISH
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrec.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_pubrec DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constuctor
10 | IMPORTING
11 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
12 | METHODS get_packet_identifier
13 | RETURNING
14 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
15 | METHODS set_packet_identifier
16 | IMPORTING
17 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
18 | PROTECTED SECTION.
19 |
20 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
21 | PRIVATE SECTION.
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS ZCL_MQTT_PACKET_PUBREC IMPLEMENTATION.
27 |
28 |
29 | METHOD constuctor.
30 |
31 | mv_packet_identifier = iv_packet_identifier.
32 |
33 | ENDMETHOD.
34 |
35 |
36 | METHOD get_packet_identifier.
37 |
38 | rv_packet_identifier = mv_packet_identifier.
39 |
40 | ENDMETHOD.
41 |
42 |
43 | METHOD set_packet_identifier.
44 |
45 | mv_packet_identifier = iv_packet_identifier.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD zif_mqtt_packet~decode.
51 |
52 | ASSERT io_stream->eat_hex( 1 ) = '52'.
53 |
54 | io_stream->eat_length( ).
55 |
56 | mv_packet_identifier = io_stream->eat_hex( 2 ).
57 |
58 | ENDMETHOD.
59 |
60 |
61 | METHOD zif_mqtt_packet~encode.
62 |
63 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
64 |
65 | ASSERT NOT mv_packet_identifier IS INITIAL.
66 | lo_payload->add_hex( mv_packet_identifier ).
67 |
68 | ro_stream = NEW #( ).
69 |
70 | ro_stream->add_packet(
71 | ii_packet = me
72 | iv_flags = 2
73 | io_payload = lo_payload ).
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD zif_mqtt_packet~get_type.
79 |
80 | rv_value = zif_mqtt_constants=>gc_packets-pubrec.
81 |
82 | ENDMETHOD.
83 | ENDCLASS.
84 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrec.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_pubrec.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '52020001'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrec.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PUBREC
7 | E
8 | PUBREC
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrel.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_pubrel DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constructor
10 | IMPORTING
11 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
12 | METHODS get_packet_identifier
13 | RETURNING
14 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
15 | METHODS set_packet_identifier
16 | IMPORTING
17 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
18 | PROTECTED SECTION.
19 |
20 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
21 | PRIVATE SECTION.
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS ZCL_MQTT_PACKET_PUBREL IMPLEMENTATION.
27 |
28 |
29 | METHOD constructor.
30 |
31 | mv_packet_identifier = iv_packet_identifier.
32 |
33 | ENDMETHOD.
34 |
35 |
36 | METHOD get_packet_identifier.
37 |
38 | rv_packet_identifier = mv_packet_identifier.
39 |
40 | ENDMETHOD.
41 |
42 |
43 | METHOD set_packet_identifier.
44 |
45 | mv_packet_identifier = iv_packet_identifier.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD zif_mqtt_packet~decode.
51 |
52 | ASSERT io_stream->eat_hex( 1 ) = '62'.
53 |
54 | io_stream->eat_length( ).
55 |
56 | mv_packet_identifier = io_stream->eat_hex( 2 ).
57 |
58 | ENDMETHOD.
59 |
60 |
61 | METHOD zif_mqtt_packet~encode.
62 |
63 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
64 |
65 | ASSERT NOT mv_packet_identifier IS INITIAL.
66 | lo_payload->add_hex( mv_packet_identifier ).
67 |
68 | ro_stream = NEW #( ).
69 |
70 | ro_stream->add_packet(
71 | ii_packet = me
72 | iv_flags = 2
73 | io_payload = lo_payload ).
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD zif_mqtt_packet~get_type.
79 |
80 | rv_value = zif_mqtt_constants=>gc_packets-pubrel.
81 |
82 | ENDMETHOD.
83 | ENDCLASS.
84 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrel.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_pubrel.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '62020001'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_pubrel.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_PUBREL
7 | E
8 | PUBREL
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_suback.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_suback DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | TYPES:
10 | ty_hex TYPE x LENGTH 1 .
11 | TYPES:
12 | ty_return_codes TYPE STANDARD TABLE OF ty_hex WITH EMPTY KEY .
13 |
14 | METHODS set_return_codes
15 | IMPORTING
16 | !it_return_codes TYPE ty_return_codes .
17 | METHODS get_return_codes
18 | RETURNING
19 | VALUE(rt_return_codes) TYPE ty_return_codes .
20 | METHODS constructor
21 | IMPORTING
22 | !it_return_codes TYPE ty_return_codes OPTIONAL
23 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
24 | METHODS get_packet_identifier
25 | RETURNING
26 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
27 | METHODS set_packet_identifier
28 | IMPORTING
29 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
30 | PROTECTED SECTION.
31 |
32 | DATA mt_return_codes TYPE ty_return_codes .
33 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
34 | PRIVATE SECTION.
35 | ENDCLASS.
36 |
37 |
38 |
39 | CLASS ZCL_MQTT_PACKET_SUBACK IMPLEMENTATION.
40 |
41 |
42 | METHOD constructor.
43 |
44 | mv_packet_identifier = iv_packet_identifier.
45 | mt_return_codes = it_return_codes.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD get_packet_identifier.
51 |
52 | rv_packet_identifier = mv_packet_identifier.
53 |
54 | ENDMETHOD.
55 |
56 |
57 | METHOD get_return_codes.
58 |
59 | rt_return_codes = mt_return_codes.
60 |
61 | ENDMETHOD.
62 |
63 |
64 | METHOD set_packet_identifier.
65 |
66 | mv_packet_identifier = iv_packet_identifier.
67 |
68 | ENDMETHOD.
69 |
70 |
71 | METHOD set_return_codes.
72 |
73 | mt_return_codes = it_return_codes.
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD zif_mqtt_packet~decode.
79 |
80 | ASSERT io_stream->eat_hex( 1 ) = '90'.
81 |
82 | io_stream->eat_length( ).
83 |
84 | mv_packet_identifier = io_stream->eat_hex( 2 ).
85 |
86 | WHILE io_stream->get_length( ) > 0.
87 | APPEND io_stream->eat_hex( 1 ) TO mt_return_codes.
88 | ENDWHILE.
89 |
90 | ENDMETHOD.
91 |
92 |
93 | METHOD zif_mqtt_packet~encode.
94 |
95 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
96 |
97 | ASSERT NOT mv_packet_identifier IS INITIAL.
98 | lo_payload->add_hex( mv_packet_identifier ).
99 |
100 | LOOP AT mt_return_codes INTO DATA(lv_return_code).
101 | lo_payload->add_hex( lv_return_code ).
102 | ENDLOOP.
103 |
104 | ro_stream = NEW #( ).
105 |
106 | ro_stream->add_packet(
107 | ii_packet = me
108 | io_payload = lo_payload ).
109 |
110 | ENDMETHOD.
111 |
112 |
113 | METHOD zif_mqtt_packet~get_type.
114 |
115 | rv_value = zif_mqtt_constants=>gc_packets-suback.
116 |
117 | ENDMETHOD.
118 | ENDCLASS.
119 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_suback.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_suback.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE '9003000100'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_suback.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_SUBACK
7 | E
8 | SUBACK
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_subscribe.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_subscribe DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | TYPES: BEGIN OF ty_topic,
10 | topic TYPE zif_mqtt_packet=>ty_topic,
11 | qos TYPE zif_mqtt_packet=>ty_qos,
12 | END OF ty_topic.
13 |
14 | TYPES:
15 | ty_topics TYPE STANDARD TABLE OF ty_topic WITH EMPTY KEY .
16 |
17 | METHODS get_topics
18 | RETURNING
19 | VALUE(rt_topics) TYPE ty_topics .
20 | METHODS set_topics
21 | IMPORTING
22 | !it_topics TYPE ty_topics
23 | RETURNING
24 | VALUE(ro_subscribe) TYPE REF TO zcl_mqtt_packet_subscribe .
25 | METHODS constructor
26 | IMPORTING
27 | !it_topics TYPE ty_topics OPTIONAL
28 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
29 | METHODS get_packet_identifier
30 | RETURNING
31 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
32 | METHODS set_packet_identifier
33 | IMPORTING
34 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
35 | PROTECTED SECTION.
36 |
37 | DATA mt_topics TYPE ty_topics .
38 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
39 | PRIVATE SECTION.
40 | ENDCLASS.
41 |
42 |
43 |
44 | CLASS ZCL_MQTT_PACKET_SUBSCRIBE IMPLEMENTATION.
45 |
46 |
47 | METHOD constructor.
48 |
49 | mt_topics = it_topics.
50 | mv_packet_identifier = iv_packet_identifier.
51 |
52 | ENDMETHOD.
53 |
54 |
55 | METHOD get_packet_identifier.
56 |
57 | rv_packet_identifier = mv_packet_identifier.
58 |
59 | ENDMETHOD.
60 |
61 |
62 | METHOD get_topics.
63 |
64 | rt_topics = mt_topics.
65 |
66 | ENDMETHOD.
67 |
68 |
69 | METHOD set_packet_identifier.
70 |
71 | mv_packet_identifier = iv_packet_identifier.
72 |
73 | ENDMETHOD.
74 |
75 |
76 | METHOD set_topics.
77 |
78 | mt_topics = it_topics.
79 |
80 | ro_subscribe = me.
81 |
82 | ENDMETHOD.
83 |
84 |
85 | METHOD zif_mqtt_packet~decode.
86 |
87 | DATA: ls_topic LIKE LINE OF mt_topics.
88 |
89 |
90 | ASSERT io_stream->eat_hex( 1 ) = '82'.
91 |
92 | io_stream->eat_length( ).
93 |
94 | mv_packet_identifier = io_stream->eat_hex( 2 ).
95 |
96 | WHILE io_stream->get_length( ) > 0.
97 | ls_topic-topic = io_stream->eat_utf8( ).
98 | ls_topic-qos = io_stream->eat_hex( 1 ).
99 | APPEND ls_topic TO mt_topics.
100 | ENDWHILE.
101 |
102 | ENDMETHOD.
103 |
104 |
105 | METHOD zif_mqtt_packet~encode.
106 |
107 | ASSERT lines( mt_topics ) > 0.
108 |
109 |
110 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
111 |
112 | ASSERT NOT mv_packet_identifier IS INITIAL.
113 | lo_payload->add_hex( mv_packet_identifier ).
114 |
115 | LOOP AT mt_topics INTO DATA(ls_topic).
116 | lo_payload->add_utf8( ls_topic-topic ).
117 | lo_payload->add_hex( CONV xstring( ls_topic-qos ) ).
118 | ENDLOOP.
119 |
120 | ro_stream = NEW #( ).
121 |
122 | ro_stream->add_packet(
123 | ii_packet = me
124 | io_payload = lo_payload
125 | iv_flags = 2 ).
126 |
127 | ENDMETHOD.
128 |
129 |
130 | METHOD zif_mqtt_packet~get_type.
131 |
132 | rv_value = zif_mqtt_constants=>gc_packets-subscribe.
133 |
134 | ENDMETHOD.
135 | ENDCLASS.
136 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_subscribe.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_subscribe.
9 |
10 | METHODS:
11 | setup,
12 | encode FOR TESTING,
13 | test FOR TESTING.
14 |
15 | ENDCLASS.
16 |
17 |
18 | CLASS ltcl_test IMPLEMENTATION.
19 |
20 | METHOD setup.
21 |
22 | mo_cut = NEW #( ).
23 |
24 | ENDMETHOD.
25 |
26 | METHOD encode.
27 |
28 | mo_cut->set_topics( VALUE #( ( topic = |something| ) ) ).
29 | mo_cut->set_packet_identifier( '0001' ).
30 |
31 | DATA(lv_hex) = mo_cut->zif_mqtt_packet~encode( )->get_hex( ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = lv_hex
35 | exp = '820E00010009736F6D657468696E6700' ).
36 |
37 | ENDMETHOD.
38 |
39 | METHOD test.
40 |
41 | CONSTANTS: lc_hex TYPE xstring VALUE '820E00010009736F6D657468696E6700'.
42 |
43 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
44 |
45 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
46 |
47 | cl_abap_unit_assert=>assert_equals(
48 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
49 | exp = lc_hex ).
50 |
51 | ENDMETHOD.
52 |
53 | ENDCLASS.
54 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_subscribe.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_SUBSCRIBE
7 | E
8 | SUBSCRIBE
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsuback.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_unsuback DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS constructor
10 | IMPORTING
11 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
12 | METHODS get_packet_identifier
13 | RETURNING
14 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
15 | METHODS set_packet_identifier
16 | IMPORTING
17 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
18 | PROTECTED SECTION.
19 |
20 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
21 | PRIVATE SECTION.
22 | ENDCLASS.
23 |
24 |
25 |
26 | CLASS ZCL_MQTT_PACKET_UNSUBACK IMPLEMENTATION.
27 |
28 |
29 | METHOD constructor.
30 |
31 | mv_packet_identifier = iv_packet_identifier.
32 |
33 | ENDMETHOD.
34 |
35 |
36 | METHOD get_packet_identifier.
37 |
38 | rv_packet_identifier = mv_packet_identifier.
39 |
40 | ENDMETHOD.
41 |
42 |
43 | METHOD set_packet_identifier.
44 |
45 | mv_packet_identifier = iv_packet_identifier.
46 |
47 | ENDMETHOD.
48 |
49 |
50 | METHOD zif_mqtt_packet~decode.
51 |
52 | CONSTANTS: lc_header TYPE xstring VALUE 'B0'.
53 |
54 | ASSERT io_stream->eat_hex( 1 ) = lc_header.
55 |
56 | io_stream->eat_length( ).
57 |
58 | mv_packet_identifier = io_stream->eat_hex( 2 ).
59 |
60 | ENDMETHOD.
61 |
62 |
63 | METHOD zif_mqtt_packet~encode.
64 |
65 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
66 |
67 | ASSERT NOT mv_packet_identifier IS INITIAL.
68 | lo_payload->add_hex( mv_packet_identifier ).
69 |
70 | ro_stream = NEW #( ).
71 |
72 | ro_stream->add_packet(
73 | ii_packet = me
74 | io_payload = lo_payload ).
75 |
76 | ENDMETHOD.
77 |
78 |
79 | METHOD zif_mqtt_packet~get_type.
80 |
81 | rv_value = zif_mqtt_constants=>gc_packets-unsuback.
82 |
83 | ENDMETHOD.
84 | ENDCLASS.
85 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsuback.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_unsuback.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE 'B0020001'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
35 | exp = lc_hex ).
36 |
37 | ENDMETHOD.
38 |
39 | ENDCLASS.
40 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsuback.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_UNSUBACK
7 | E
8 | UNSUBACK
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsubscribe.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_packet_unsubscribe DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_packet .
8 |
9 | METHODS get_topics
10 | RETURNING
11 | VALUE(rt_topics) TYPE zif_mqtt_packet=>ty_topics_tt .
12 | METHODS set_topics
13 | IMPORTING
14 | !it_topics TYPE zif_mqtt_packet=>ty_topics_tt .
15 | METHODS constructor
16 | IMPORTING
17 | !it_topics TYPE zif_mqtt_packet=>ty_topics_tt OPTIONAL
18 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier OPTIONAL .
19 | METHODS get_packet_identifier
20 | RETURNING
21 | VALUE(rv_packet_identifier) TYPE zif_mqtt_packet=>ty_packet_identifier .
22 | METHODS set_packet_identifier
23 | IMPORTING
24 | !iv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
25 | PROTECTED SECTION.
26 |
27 | DATA mt_topics TYPE zif_mqtt_packet=>ty_topics_tt .
28 | DATA mv_packet_identifier TYPE zif_mqtt_packet=>ty_packet_identifier .
29 | PRIVATE SECTION.
30 | ENDCLASS.
31 |
32 |
33 |
34 | CLASS ZCL_MQTT_PACKET_UNSUBSCRIBE IMPLEMENTATION.
35 |
36 |
37 | METHOD constructor.
38 |
39 | mt_topics = it_topics.
40 | mv_packet_identifier = iv_packet_identifier.
41 |
42 | ENDMETHOD.
43 |
44 |
45 | METHOD get_packet_identifier.
46 |
47 | rv_packet_identifier = mv_packet_identifier.
48 |
49 | ENDMETHOD.
50 |
51 |
52 | METHOD get_topics.
53 |
54 | rt_topics = mt_topics.
55 |
56 | ENDMETHOD.
57 |
58 |
59 | METHOD set_packet_identifier.
60 |
61 | mv_packet_identifier = iv_packet_identifier.
62 |
63 | ENDMETHOD.
64 |
65 |
66 | METHOD set_topics.
67 |
68 | mt_topics = it_topics.
69 |
70 | ENDMETHOD.
71 |
72 |
73 | METHOD zif_mqtt_packet~decode.
74 |
75 | CONSTANTS: lc_header TYPE xstring VALUE 'A2'.
76 |
77 | ASSERT io_stream->eat_hex( 1 ) = lc_header.
78 |
79 | io_stream->eat_length( ).
80 |
81 | mv_packet_identifier = io_stream->eat_hex( 2 ).
82 |
83 | WHILE io_stream->get_length( ) > 0.
84 | APPEND io_stream->eat_utf8( ) TO mt_topics.
85 | ENDWHILE.
86 |
87 | ASSERT lines( mt_topics ) > 0.
88 |
89 | ENDMETHOD.
90 |
91 |
92 | METHOD zif_mqtt_packet~encode.
93 |
94 | DATA(lo_payload) = NEW zcl_mqtt_stream( ).
95 |
96 | ASSERT NOT mv_packet_identifier IS INITIAL.
97 | lo_payload->add_hex( mv_packet_identifier ).
98 |
99 | ASSERT lines( mt_topics ) > 0.
100 | LOOP AT mt_topics INTO DATA(lv_topic).
101 | lo_payload->add_utf8( lv_topic ).
102 | ENDLOOP.
103 |
104 | ro_stream = NEW #( ).
105 |
106 | ro_stream->add_packet(
107 | ii_packet = me
108 | iv_flags = 2
109 | io_payload = lo_payload ).
110 |
111 | ENDMETHOD.
112 |
113 |
114 | METHOD zif_mqtt_packet~get_type.
115 |
116 | rv_value = zif_mqtt_constants=>gc_packets-unsubscribe.
117 |
118 | ENDMETHOD.
119 | ENDCLASS.
120 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsubscribe.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_test DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_packet_unsubscribe.
9 |
10 | METHODS:
11 | setup,
12 | test FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 |
17 | CLASS ltcl_test IMPLEMENTATION.
18 |
19 | METHOD setup.
20 |
21 | mo_cut = NEW #( ).
22 |
23 | ENDMETHOD.
24 |
25 | METHOD test.
26 |
27 | CONSTANTS: lc_hex TYPE xstring VALUE 'A20A00010006666F6F626172'.
28 |
29 | DATA(lo_stream) = NEW zcl_mqtt_stream( lc_hex ).
30 |
31 | mo_cut->zif_mqtt_packet~decode( lo_stream ).
32 |
33 | cl_abap_unit_assert=>assert_equals(
34 | act = mo_cut->get_topics( )
35 | exp = VALUE zif_mqtt_packet=>ty_topics_tt( ( |foobar| ) ) ).
36 |
37 | cl_abap_unit_assert=>assert_equals(
38 | act = mo_cut->zif_mqtt_packet~encode( )->get_hex( )
39 | exp = lc_hex ).
40 |
41 | ENDMETHOD.
42 |
43 | ENDCLASS.
44 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_packet_unsubscribe.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_PACKET_UNSUBSCRIBE
7 | E
8 | UNSUBSCRIBE
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_stream.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_stream DEFINITION
2 | PUBLIC
3 | CREATE PUBLIC .
4 |
5 | PUBLIC SECTION.
6 |
7 | METHODS add_hex
8 | IMPORTING
9 | !iv_hex TYPE xsequence
10 | RETURNING
11 | VALUE(ro_stream) TYPE REF TO zcl_mqtt_stream .
12 | METHODS add_length
13 | IMPORTING
14 | !iv_length TYPE i .
15 | METHODS add_packet
16 | IMPORTING
17 | !ii_packet TYPE REF TO zif_mqtt_packet
18 | !io_payload TYPE REF TO zcl_mqtt_stream OPTIONAL
19 | !iv_flags TYPE i DEFAULT 0
20 | RETURNING
21 | VALUE(ro_stream) TYPE REF TO zcl_mqtt_stream .
22 | METHODS add_stream
23 | IMPORTING
24 | !io_stream TYPE REF TO zcl_mqtt_stream .
25 | METHODS add_utf8
26 | IMPORTING
27 | !iv_string TYPE csequence
28 | RETURNING
29 | VALUE(ro_stream) TYPE REF TO zcl_mqtt_stream .
30 | METHODS constructor
31 | IMPORTING
32 | !iv_hex TYPE xsequence OPTIONAL .
33 | METHODS eat_hex
34 | IMPORTING
35 | !iv_length TYPE i
36 | RETURNING
37 | VALUE(rv_hex) TYPE xstring .
38 | METHODS eat_length
39 | RETURNING
40 | VALUE(rv_length) TYPE i .
41 | METHODS eat_packet
42 | RETURNING
43 | VALUE(ri_packet) TYPE REF TO zif_mqtt_packet .
44 | METHODS eat_utf8
45 | RETURNING
46 | VALUE(rv_string) TYPE string .
47 | METHODS get_hex
48 | RETURNING
49 | VALUE(rv_hex) TYPE xstring .
50 | METHODS get_length
51 | RETURNING
52 | VALUE(rv_length) TYPE i .
53 | METHODS peek_hex
54 | IMPORTING
55 | !iv_length TYPE i
56 | RETURNING
57 | VALUE(rv_hex) TYPE xstring .
58 | PROTECTED SECTION.
59 |
60 | DATA mv_hex TYPE xstring .
61 | PRIVATE SECTION.
62 | ENDCLASS.
63 |
64 |
65 |
66 | CLASS ZCL_MQTT_STREAM IMPLEMENTATION.
67 |
68 |
69 | METHOD add_hex.
70 |
71 | CONCATENATE mv_hex iv_hex INTO mv_hex IN BYTE MODE.
72 |
73 | ro_stream = me.
74 |
75 | ENDMETHOD.
76 |
77 |
78 | METHOD add_length.
79 |
80 | DATA: lv_length LIKE iv_length,
81 | lv_byte TYPE x.
82 |
83 |
84 | ASSERT iv_length >= 0.
85 |
86 | lv_length = iv_length.
87 | WHILE lv_length > 0.
88 | lv_byte = lv_length MOD 128.
89 |
90 | lv_length = lv_length DIV 128.
91 | IF lv_length > 0.
92 | lv_byte = lv_byte + 128.
93 | ENDIF.
94 |
95 | add_hex( lv_byte ).
96 | ENDWHILE.
97 |
98 | IF iv_length = 0.
99 | add_hex( '00' ).
100 | ENDIF.
101 |
102 | ENDMETHOD.
103 |
104 |
105 | METHOD add_packet.
106 |
107 | DATA: lv_byte TYPE x,
108 | lv_length TYPE i.
109 |
110 | lv_byte = ii_packet->get_type( ) * 16 + iv_flags.
111 |
112 | add_hex( lv_byte ).
113 |
114 | IF io_payload IS SUPPLIED.
115 | lv_length = io_payload->get_length( ).
116 | ENDIF.
117 | add_length( lv_length ).
118 |
119 | IF io_payload IS SUPPLIED.
120 | add_stream( io_payload ).
121 | ENDIF.
122 |
123 | ro_stream = me.
124 |
125 | ENDMETHOD.
126 |
127 |
128 | METHOD add_stream.
129 |
130 | DATA: lv_hex TYPE xstring.
131 |
132 |
133 | lv_hex = io_stream->get_hex( ).
134 |
135 | CONCATENATE mv_hex lv_hex INTO mv_hex IN BYTE MODE.
136 |
137 | ENDMETHOD.
138 |
139 |
140 | METHOD add_utf8.
141 |
142 | DATA: lv_len TYPE x LENGTH 2.
143 |
144 |
145 | DATA(lv_hex) = cl_binary_convert=>string_to_xstring_utf8( iv_string ).
146 |
147 | lv_len = xstrlen( lv_hex ).
148 |
149 | CONCATENATE mv_hex lv_len lv_hex INTO mv_hex IN BYTE MODE.
150 |
151 | ro_stream = me.
152 |
153 | ENDMETHOD.
154 |
155 |
156 | METHOD constructor.
157 |
158 | IF iv_hex IS SUPPLIED.
159 | mv_hex = iv_hex.
160 | ENDIF.
161 |
162 | ENDMETHOD.
163 |
164 |
165 | METHOD eat_hex.
166 |
167 | rv_hex = mv_hex(iv_length).
168 |
169 | mv_hex = mv_hex+iv_length.
170 |
171 | ENDMETHOD.
172 |
173 |
174 | METHOD eat_length.
175 |
176 | DATA: lv_byte TYPE x LENGTH 1,
177 | lv_multiplier TYPE i VALUE 1.
178 |
179 |
180 | DO.
181 | ASSERT sy-index <= 4.
182 |
183 | lv_byte = eat_hex( 1 ).
184 |
185 | rv_length = rv_length + ( lv_byte MOD 128 ) * lv_multiplier.
186 | lv_multiplier = lv_multiplier * 128.
187 |
188 | IF lv_byte < 128.
189 | EXIT.
190 | ENDIF.
191 | ENDDO.
192 |
193 | ENDMETHOD.
194 |
195 |
196 | METHOD eat_packet.
197 |
198 | DATA: lv_int TYPE i.
199 |
200 |
201 | lv_int = peek_hex( 1 ) / 16.
202 |
203 | CASE lv_int.
204 | WHEN zif_mqtt_constants=>gc_packets-connect.
205 | ri_packet = NEW zcl_mqtt_packet_connect( ).
206 | WHEN zif_mqtt_constants=>gc_packets-connack.
207 | ri_packet = NEW zcl_mqtt_packet_connack( ).
208 | WHEN zif_mqtt_constants=>gc_packets-publish.
209 | ri_packet = NEW zcl_mqtt_packet_publish( ).
210 | WHEN zif_mqtt_constants=>gc_packets-puback.
211 | ri_packet = NEW zcl_mqtt_packet_puback( ).
212 | WHEN zif_mqtt_constants=>gc_packets-pubrec.
213 | ri_packet = NEW zcl_mqtt_packet_pubrec( ).
214 | WHEN zif_mqtt_constants=>gc_packets-pubrel.
215 | ri_packet = NEW zcl_mqtt_packet_pubrel( ).
216 | WHEN zif_mqtt_constants=>gc_packets-pubcomp.
217 | ri_packet = NEW zcl_mqtt_packet_pubcomp( ).
218 | WHEN zif_mqtt_constants=>gc_packets-subscribe.
219 | ri_packet = NEW zcl_mqtt_packet_subscribe( ).
220 | WHEN zif_mqtt_constants=>gc_packets-suback.
221 | ri_packet = NEW zcl_mqtt_packet_suback( ).
222 | WHEN zif_mqtt_constants=>gc_packets-unsubscribe.
223 | ri_packet = NEW zcl_mqtt_packet_unsubscribe( ).
224 | WHEN zif_mqtt_constants=>gc_packets-unsuback.
225 | ri_packet = NEW zcl_mqtt_packet_unsuback( ).
226 | WHEN zif_mqtt_constants=>gc_packets-pingreq.
227 | ri_packet = NEW zcl_mqtt_packet_pingreq( ).
228 | WHEN zif_mqtt_constants=>gc_packets-pingresp.
229 | ri_packet = NEW zcl_mqtt_packet_pingresp( ).
230 | WHEN zif_mqtt_constants=>gc_packets-disconnect.
231 | ri_packet = NEW zcl_mqtt_packet_disconnect( ).
232 | WHEN OTHERS.
233 | ASSERT 0 = 1.
234 | ENDCASE.
235 |
236 | ri_packet->decode( me ).
237 |
238 | ENDMETHOD.
239 |
240 |
241 | METHOD eat_utf8.
242 |
243 | DATA: lv_len TYPE x LENGTH 2,
244 | lv_int TYPE i.
245 |
246 |
247 | lv_len = eat_hex( 2 ).
248 | lv_int = lv_len.
249 |
250 | rv_string = cl_binary_convert=>xstring_utf8_to_string( eat_hex( lv_int ) ).
251 |
252 | ENDMETHOD.
253 |
254 |
255 | METHOD get_hex.
256 |
257 | rv_hex = mv_hex.
258 |
259 | ENDMETHOD.
260 |
261 |
262 | METHOD get_length.
263 |
264 | rv_length = xstrlen( mv_hex ).
265 |
266 | ENDMETHOD.
267 |
268 |
269 | METHOD peek_hex.
270 |
271 | rv_hex = mv_hex(iv_length).
272 |
273 | ENDMETHOD.
274 | ENDCLASS.
275 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_stream.clas.testclasses.abap:
--------------------------------------------------------------------------------
1 |
2 | CLASS ltcl_eat_packet DEFINITION FOR TESTING
3 | DURATION SHORT
4 | RISK LEVEL HARMLESS FINAL.
5 |
6 | PRIVATE SECTION.
7 | DATA:
8 | mo_cut TYPE REF TO zcl_mqtt_stream.
9 |
10 | METHODS:
11 | setup,
12 | connack FOR TESTING.
13 |
14 | ENDCLASS.
15 |
16 | CLASS ltcl_eat_packet IMPLEMENTATION.
17 |
18 | METHOD setup.
19 | mo_cut = NEW #( ).
20 | ENDMETHOD.
21 |
22 | METHOD connack.
23 |
24 | DATA(li_packet) = mo_cut->add_hex( '20020000' )->eat_packet( ).
25 |
26 | cl_abap_unit_assert=>assert_equals(
27 | act = li_packet->get_type( )
28 | exp = zif_mqtt_constants=>gc_packets-connack ).
29 |
30 | ENDMETHOD.
31 |
32 | ENDCLASS.
33 |
34 |
35 | CLASS ltcl_stream DEFINITION FOR TESTING
36 | DURATION SHORT
37 | RISK LEVEL HARMLESS FINAL.
38 |
39 | PRIVATE SECTION.
40 | DATA:
41 | mo_cut TYPE REF TO zcl_mqtt_stream.
42 |
43 | METHODS:
44 | setup,
45 | utf8 FOR TESTING,
46 | peek FOR TESTING,
47 | add_n_eat FOR TESTING.
48 |
49 | ENDCLASS.
50 |
51 |
52 | CLASS ltcl_stream IMPLEMENTATION.
53 |
54 | METHOD setup.
55 | mo_cut = NEW #( ).
56 | ENDMETHOD.
57 |
58 | METHOD peek.
59 |
60 | CONSTANTS: lc_hex TYPE xstring VALUE '12'.
61 |
62 | mo_cut->add_hex( lc_hex ).
63 |
64 | cl_abap_unit_assert=>assert_equals(
65 | act = mo_cut->peek_hex( 1 )
66 | exp = lc_hex ).
67 |
68 | cl_abap_unit_assert=>assert_equals(
69 | act = mo_cut->get_length( )
70 | exp = 1 ).
71 |
72 | ENDMETHOD.
73 |
74 | METHOD utf8.
75 |
76 | CONSTANTS: lc_str TYPE string VALUE 'MQTT'.
77 |
78 | DATA(lv_hex) = mo_cut->add_utf8( lc_str )->get_hex( ).
79 |
80 | cl_abap_unit_assert=>assert_equals(
81 | act = lv_hex
82 | exp = '00044D515454' ).
83 |
84 | DATA(lv_str) = mo_cut->eat_utf8( ).
85 |
86 | cl_abap_unit_assert=>assert_equals(
87 | act = lv_str
88 | exp = lc_str ).
89 |
90 | ENDMETHOD.
91 |
92 | METHOD add_n_eat.
93 |
94 | CONSTANTS: lc_hex TYPE xstring VALUE '1122'.
95 |
96 | mo_cut->add_hex( lc_hex ).
97 |
98 | cl_abap_unit_assert=>assert_equals(
99 | act = mo_cut->get_length( )
100 | exp = 2 ).
101 |
102 | cl_abap_unit_assert=>assert_equals(
103 | act = mo_cut->eat_hex( 2 )
104 | exp = lc_hex ).
105 |
106 | cl_abap_unit_assert=>assert_equals(
107 | act = mo_cut->get_length( )
108 | exp = 0 ).
109 |
110 | ENDMETHOD.
111 |
112 | ENDCLASS.
113 |
114 |
115 | CLASS ltcl_length DEFINITION FOR TESTING
116 | DURATION SHORT
117 | RISK LEVEL HARMLESS FINAL.
118 |
119 | PRIVATE SECTION.
120 | DATA:
121 | mo_cut TYPE REF TO zcl_mqtt_stream.
122 |
123 | METHODS:
124 | setup,
125 | test IMPORTING iv_hex TYPE xstring
126 | iv_length TYPE i,
127 | test01 FOR TESTING,
128 | test02 FOR TESTING,
129 | test03 FOR TESTING,
130 | test04 FOR TESTING,
131 | test05 FOR TESTING,
132 | test06 FOR TESTING.
133 |
134 | ENDCLASS.
135 |
136 | CLASS ltcl_length IMPLEMENTATION.
137 |
138 | METHOD setup.
139 | mo_cut = NEW #( ).
140 | ENDMETHOD.
141 |
142 | METHOD test.
143 |
144 | DATA(lv_length) = mo_cut->add_hex( iv_hex )->eat_length( ).
145 |
146 | cl_abap_unit_assert=>assert_equals(
147 | act = lv_length
148 | exp = iv_length ).
149 |
150 | cl_abap_unit_assert=>assert_equals(
151 | act = mo_cut->get_length( )
152 | exp = 0 ).
153 |
154 | mo_cut->add_length( iv_length ).
155 |
156 | cl_abap_unit_assert=>assert_equals(
157 | act = mo_cut->get_hex( )
158 | exp = iv_hex ).
159 |
160 | ENDMETHOD.
161 |
162 | METHOD test01.
163 |
164 | test( iv_hex = '02'
165 | iv_length = 2 ).
166 |
167 | ENDMETHOD.
168 |
169 | METHOD test02.
170 |
171 | test( iv_hex = '8610'
172 | iv_length = 2054 ).
173 |
174 | ENDMETHOD.
175 |
176 | METHOD test03.
177 |
178 | test( iv_hex = '86808001'
179 | iv_length = 2097158 ).
180 |
181 | ENDMETHOD.
182 |
183 | METHOD test04.
184 |
185 | test( iv_hex = '80808001'
186 | iv_length = 2097152 ).
187 |
188 | ENDMETHOD.
189 |
190 | METHOD test05.
191 |
192 | test( iv_hex = '7F'
193 | iv_length = 127 ).
194 |
195 | ENDMETHOD.
196 |
197 | METHOD test06.
198 |
199 | test( iv_hex = '00'
200 | iv_length = 0 ).
201 |
202 | ENDMETHOD.
203 |
204 | ENDCLASS.
205 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zcl_mqtt_stream.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_STREAM
7 | E
8 | Stream
9 | 1
10 | X
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zif_mqtt_packet.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_mqtt_packet PUBLIC .
2 |
3 | TYPES ty_qos TYPE i .
4 | TYPES:
5 | ty_packet_identifier TYPE x LENGTH 2 .
6 | TYPES ty_topic TYPE string .
7 | TYPES:
8 | BEGIN OF ty_message,
9 | topic TYPE ty_topic,
10 | message TYPE xstring,
11 | END OF ty_message .
12 | TYPES:
13 | ty_topics_tt TYPE STANDARD TABLE OF ty_topic WITH EMPTY KEY .
14 |
15 | CONSTANTS:
16 | BEGIN OF gc_qos,
17 | at_most_once TYPE ty_qos VALUE 0,
18 | at_least_once TYPE ty_qos VALUE 1,
19 | exactly_once TYPE ty_qos VALUE 2,
20 | END OF gc_qos .
21 |
22 | METHODS get_type
23 | RETURNING
24 | VALUE(rv_value) TYPE i .
25 | METHODS encode
26 | RETURNING
27 | VALUE(ro_stream) TYPE REF TO zcl_mqtt_stream .
28 | METHODS decode
29 | IMPORTING
30 | !io_stream TYPE REF TO zcl_mqtt_stream .
31 | ENDINTERFACE.
32 |
--------------------------------------------------------------------------------
/src/mqtt/packets/zif_mqtt_packet.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_MQTT_PACKET
7 | E
8 | Packet
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/mqtt/zcl_mqtt_transport_tcp.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_transport_tcp DEFINITION
2 | PUBLIC
3 | CREATE PROTECTED .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_transport .
8 | INTERFACES if_apc_wsp_event_handler .
9 | INTERFACES if_apc_wsp_event_handler_base .
10 |
11 | CLASS-METHODS create
12 | IMPORTING
13 | !iv_host TYPE string
14 | !iv_port TYPE string
15 | iv_protocol TYPE i DEFAULT cl_apc_tcp_client_manager=>co_protocol_type_tcp
16 | RETURNING
17 | VALUE(ri_transport) TYPE REF TO zif_mqtt_transport
18 | RAISING
19 | cx_apc_error .
20 | PROTECTED SECTION.
21 |
22 | TYPES:
23 | ty_byte TYPE x LENGTH 1 .
24 |
25 | DATA:
26 | BEGIN OF ms_message,
27 | received TYPE abap_bool,
28 | message TYPE x LENGTH 1,
29 | END OF ms_message .
30 | DATA mi_client TYPE REF TO if_apc_wsp_client .
31 |
32 | METHODS receive_byte
33 | IMPORTING
34 | !iv_timeout TYPE i
35 | RETURNING
36 | VALUE(rv_byte) TYPE ty_byte
37 | RAISING
38 | zcx_mqtt_timeout .
39 | PRIVATE SECTION.
40 | ENDCLASS.
41 |
42 |
43 |
44 | CLASS ZCL_MQTT_TRANSPORT_TCP IMPLEMENTATION.
45 |
46 |
47 | METHOD create.
48 |
49 | DATA(lo_tcp) = NEW zcl_mqtt_transport_tcp( ).
50 |
51 | DATA(ls_frame) = VALUE apc_tcp_frame(
52 | frame_type = if_apc_tcp_frame_types=>co_frame_type_fixed_length
53 | fixed_length = 1 ).
54 |
55 | lo_tcp->mi_client = cl_apc_tcp_client_manager=>create(
56 | i_protocol = iv_protocol
57 | i_host = iv_host
58 | i_port = iv_port
59 | i_frame = ls_frame
60 | i_event_handler = lo_tcp ).
61 |
62 | ri_transport ?= lo_tcp.
63 |
64 | ENDMETHOD.
65 |
66 |
67 | METHOD if_apc_wsp_event_handler~on_close.
68 |
69 | * todo?
70 | RETURN.
71 |
72 | ENDMETHOD.
73 |
74 |
75 | METHOD if_apc_wsp_event_handler~on_error.
76 |
77 | * todo?
78 | RETURN.
79 |
80 | ENDMETHOD.
81 |
82 |
83 | METHOD if_apc_wsp_event_handler~on_message.
84 |
85 | ms_message-received = abap_true.
86 | TRY.
87 | ms_message-message = i_message->get_binary( ).
88 | CATCH cx_apc_error.
89 | ASSERT 0 = 1. " todo
90 | ENDTRY.
91 |
92 | ENDMETHOD.
93 |
94 |
95 | METHOD if_apc_wsp_event_handler~on_open.
96 |
97 | RETURN.
98 |
99 | ENDMETHOD.
100 |
101 |
102 | METHOD receive_byte.
103 |
104 | CLEAR ms_message.
105 | WAIT FOR PUSH CHANNELS UNTIL ms_message IS NOT INITIAL UP TO iv_timeout SECONDS.
106 | IF sy-subrc = 0.
107 | rv_byte = ms_message-message.
108 | ELSE.
109 | RAISE EXCEPTION TYPE zcx_mqtt_timeout.
110 | ENDIF.
111 |
112 | ENDMETHOD.
113 |
114 |
115 | METHOD zif_mqtt_transport~connect.
116 |
117 | mi_client->connect( ).
118 |
119 | ENDMETHOD.
120 |
121 |
122 | METHOD zif_mqtt_transport~disconnect.
123 |
124 | mi_client->close( ).
125 |
126 | ENDMETHOD.
127 |
128 |
129 | METHOD zif_mqtt_transport~listen.
130 |
131 | DATA: lv_length TYPE i,
132 | lv_multiplier TYPE i VALUE 1.
133 |
134 |
135 | DATA(lo_stream) = NEW zcl_mqtt_stream( ).
136 |
137 | DATA(lv_byte) = receive_byte( iv_timeout ).
138 | lo_stream->add_hex( lv_byte ).
139 |
140 | DO.
141 | ASSERT sy-index <= 4.
142 |
143 | lv_byte = receive_byte( iv_timeout ).
144 | lo_stream->add_hex( lv_byte ).
145 |
146 | lv_length = lv_length + ( lv_byte MOD 128 ) * lv_multiplier.
147 | lv_multiplier = lv_multiplier * 128.
148 |
149 | IF lv_byte < 128.
150 | EXIT.
151 | ENDIF.
152 | ENDDO.
153 |
154 | DO lv_length TIMES.
155 | lv_byte = receive_byte( iv_timeout ).
156 | lo_stream->add_hex( lv_byte ).
157 | ENDDO.
158 |
159 | ri_packet = lo_stream->eat_packet( ).
160 |
161 | ENDMETHOD.
162 |
163 |
164 | METHOD zif_mqtt_transport~send.
165 |
166 | DATA: li_msgmgr TYPE REF TO if_apc_wsp_message_manager.
167 |
168 | li_msgmgr ?= mi_client->get_message_manager( ).
169 | DATA(li_message) = li_msgmgr->create_message( ).
170 |
171 | DATA(lv_hex) = ii_packet->encode( )->get_hex( ).
172 |
173 | WHILE xstrlen( lv_hex ) > 0.
174 | DATA(lv_single) = lv_hex(1).
175 | li_message->set_binary( lv_single ).
176 | li_msgmgr->send( li_message ).
177 | lv_hex = lv_hex+1.
178 | ENDWHILE.
179 |
180 | ENDMETHOD.
181 | ENDCLASS.
182 |
--------------------------------------------------------------------------------
/src/mqtt/zcl_mqtt_transport_tcp.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_TRANSPORT_TCP
7 | E
8 | TCP
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 | ZCL_MQTT_TRANSPORT_TCP
17 | MI_CLIENT
18 | E
19 | APC framework: WebSocket client interface (do not implement)
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/mqtt/zcl_mqtt_transport_ws.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_mqtt_transport_ws DEFINITION
2 | PUBLIC
3 | CREATE PROTECTED .
4 |
5 | PUBLIC SECTION.
6 |
7 | INTERFACES zif_mqtt_transport .
8 | INTERFACES if_apc_wsp_event_handler .
9 | INTERFACES if_apc_wsp_event_handler_base .
10 |
11 | CLASS-METHODS create_by_url
12 | IMPORTING
13 | !iv_url TYPE string
14 | RETURNING
15 | VALUE(ri_transport) TYPE REF TO zif_mqtt_transport
16 | RAISING
17 | cx_apc_error .
18 | PROTECTED SECTION.
19 |
20 | DATA mi_client TYPE REF TO if_apc_wsp_client .
21 |
22 | DATA: BEGIN OF ms_message,
23 | received TYPE abap_bool,
24 | message TYPE xstring,
25 | END OF ms_message.
26 | PRIVATE SECTION.
27 | ENDCLASS.
28 |
29 |
30 |
31 | CLASS ZCL_MQTT_TRANSPORT_WS IMPLEMENTATION.
32 |
33 |
34 | METHOD create_by_url.
35 |
36 | DATA(lo_ws) = NEW zcl_mqtt_transport_ws( ).
37 |
38 | lo_ws->mi_client = cl_apc_wsp_client_manager=>create_by_url(
39 | i_url = iv_url
40 | i_protocol = if_apc_wsp_event_handler=>co_event_handler_type
41 | i_event_handler = lo_ws ).
42 |
43 | ri_transport ?= lo_ws.
44 |
45 | ENDMETHOD.
46 |
47 |
48 | METHOD if_apc_wsp_event_handler~on_close.
49 |
50 | * todo?
51 | RETURN.
52 |
53 | ENDMETHOD.
54 |
55 |
56 | METHOD if_apc_wsp_event_handler~on_error.
57 |
58 | * todo?
59 | RETURN.
60 |
61 | ENDMETHOD.
62 |
63 |
64 | METHOD if_apc_wsp_event_handler~on_message.
65 |
66 | ms_message-received = abap_true.
67 | TRY.
68 | ms_message-message = i_message->get_binary( ).
69 | CATCH cx_apc_error.
70 | ASSERT 0 = 1. " todo
71 | ENDTRY.
72 |
73 | ENDMETHOD.
74 |
75 |
76 | METHOD if_apc_wsp_event_handler~on_open.
77 |
78 | RETURN.
79 |
80 | ENDMETHOD.
81 |
82 |
83 | METHOD zif_mqtt_transport~connect.
84 |
85 | mi_client->connect( ).
86 |
87 | ENDMETHOD.
88 |
89 |
90 | METHOD zif_mqtt_transport~disconnect.
91 |
92 | mi_client->close( ).
93 |
94 | ENDMETHOD.
95 |
96 |
97 | METHOD zif_mqtt_transport~listen.
98 |
99 | CLEAR ms_message.
100 | WAIT FOR PUSH CHANNELS UNTIL ms_message IS NOT INITIAL UP TO iv_timeout SECONDS.
101 | IF sy-subrc = 0.
102 | ri_packet = NEW zcl_mqtt_stream( ms_message-message )->eat_packet( ).
103 | ELSE.
104 | RAISE EXCEPTION TYPE zcx_mqtt_timeout.
105 | ENDIF.
106 |
107 | ENDMETHOD.
108 |
109 |
110 | METHOD zif_mqtt_transport~send.
111 |
112 | DATA: li_msgmgr TYPE REF TO if_apc_wsp_message_manager.
113 |
114 | li_msgmgr ?= mi_client->get_message_manager( ).
115 |
116 | DATA(li_message) = li_msgmgr->create_message( ).
117 | li_message->set_binary( ii_packet->encode( )->get_hex( ) ).
118 | li_msgmgr->send( li_message ).
119 |
120 | ENDMETHOD.
121 | ENDCLASS.
122 |
--------------------------------------------------------------------------------
/src/mqtt/zcl_mqtt_transport_ws.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_MQTT_TRANSPORT_WS
7 | E
8 | Websockets
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 | ZCL_MQTT_TRANSPORT_WS
17 | MI_CLIENT
18 | E
19 | APC framework: WebSocket client interface (do not implement)
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/mqtt/zcx_mqtt.clas.abap:
--------------------------------------------------------------------------------
1 | class ZCX_MQTT definition
2 | public
3 | inheriting from CX_STATIC_CHECK
4 | abstract
5 | create public .
6 |
7 | public section.
8 |
9 | interfaces IF_T100_DYN_MSG .
10 | interfaces IF_T100_MESSAGE .
11 |
12 | methods CONSTRUCTOR
13 | importing
14 | !TEXTID like IF_T100_MESSAGE=>T100KEY optional
15 | !PREVIOUS like PREVIOUS optional .
16 | protected section.
17 | private section.
18 | ENDCLASS.
19 |
20 |
21 |
22 | CLASS ZCX_MQTT IMPLEMENTATION.
23 |
24 |
25 | method CONSTRUCTOR.
26 | CALL METHOD SUPER->CONSTRUCTOR
27 | EXPORTING
28 | PREVIOUS = PREVIOUS
29 | .
30 | clear me->textid.
31 | if textid is initial.
32 | IF_T100_MESSAGE~T100KEY = IF_T100_MESSAGE=>DEFAULT_TEXTID.
33 | else.
34 | IF_T100_MESSAGE~T100KEY = TEXTID.
35 | endif.
36 | endmethod.
37 | ENDCLASS.
38 |
--------------------------------------------------------------------------------
/src/mqtt/zcx_mqtt.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_MQTT
7 | E
8 | Abstract Exception
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 | ZCX_MQTT
18 | CONSTRUCTOR
19 | E
20 | CONSTRUCTOR
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/mqtt/zcx_mqtt_timeout.clas.abap:
--------------------------------------------------------------------------------
1 | class ZCX_MQTT_TIMEOUT definition
2 | public
3 | inheriting from ZCX_MQTT
4 | create public .
5 |
6 | public section.
7 |
8 | methods CONSTRUCTOR
9 | importing
10 | !TEXTID like IF_T100_MESSAGE=>T100KEY optional
11 | !PREVIOUS like PREVIOUS optional .
12 | protected section.
13 | private section.
14 | ENDCLASS.
15 |
16 |
17 |
18 | CLASS ZCX_MQTT_TIMEOUT IMPLEMENTATION.
19 |
20 |
21 | method CONSTRUCTOR.
22 | CALL METHOD SUPER->CONSTRUCTOR
23 | EXPORTING
24 | PREVIOUS = PREVIOUS
25 | .
26 | clear me->textid.
27 | if textid is initial.
28 | IF_T100_MESSAGE~T100KEY = IF_T100_MESSAGE=>DEFAULT_TEXTID.
29 | else.
30 | IF_T100_MESSAGE~T100KEY = TEXTID.
31 | endif.
32 | endmethod.
33 | ENDCLASS.
34 |
--------------------------------------------------------------------------------
/src/mqtt/zcx_mqtt_timeout.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_MQTT_TIMEOUT
7 | E
8 | Timeout
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 | ZCX_MQTT_TIMEOUT
18 | CONSTRUCTOR
19 | E
20 | CONSTRUCTOR
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/mqtt/zif_mqtt_constants.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_mqtt_constants
2 | PUBLIC .
3 |
4 |
5 | CONSTANTS: BEGIN OF gc_packets,
6 | connect TYPE i VALUE 1,
7 | connack TYPE i VALUE 2,
8 | publish TYPE i VALUE 3,
9 | puback TYPE i VALUE 4,
10 | pubrec TYPE i VALUE 5,
11 | pubrel TYPE i VALUE 6,
12 | pubcomp TYPE i VALUE 7,
13 | subscribe TYPE i VALUE 8,
14 | suback TYPE i VALUE 9,
15 | unsubscribe TYPE i VALUE 10,
16 | unsuback TYPE i VALUE 11,
17 | pingreq TYPE i VALUE 12,
18 | pingresp TYPE i VALUE 13,
19 | disconnect TYPE i VALUE 14,
20 | END OF gc_packets.
21 |
22 | ENDINTERFACE.
23 |
--------------------------------------------------------------------------------
/src/mqtt/zif_mqtt_constants.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_MQTT_CONSTANTS
7 | E
8 | Constants
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/mqtt/zif_mqtt_transport.intf.abap:
--------------------------------------------------------------------------------
1 | INTERFACE zif_mqtt_transport PUBLIC.
2 |
3 |
4 | METHODS connect
5 | RAISING
6 | cx_apc_error .
7 | METHODS disconnect
8 | RAISING
9 | cx_apc_error .
10 | METHODS send
11 | IMPORTING
12 | !ii_packet TYPE REF TO zif_mqtt_packet
13 | RAISING
14 | zcx_mqtt
15 | cx_apc_error .
16 | METHODS listen
17 | IMPORTING
18 | !iv_timeout TYPE i
19 | RETURNING
20 | VALUE(ri_packet) TYPE REF TO zif_mqtt_packet
21 | RAISING
22 | zcx_mqtt .
23 | ENDINTERFACE.
24 |
--------------------------------------------------------------------------------
/src/mqtt/zif_mqtt_transport.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_MQTT_TRANSPORT
7 | E
8 | Transport
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | abapMQ
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/test/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Test
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/test/zabapmq_http_client.prog.abap:
--------------------------------------------------------------------------------
1 | REPORT zabapmq_http_client.
2 |
3 | PARAMETERS: p_host TYPE text200 DEFAULT 'google.com'.
4 |
5 | CLASS lcl_apc_handler DEFINITION
6 | FINAL
7 | CREATE PUBLIC.
8 |
9 | PUBLIC SECTION.
10 | INTERFACES: if_apc_wsp_event_handler.
11 | DATA: mv_message TYPE string.
12 |
13 | ENDCLASS.
14 |
15 | CLASS lcl_apc_handler IMPLEMENTATION.
16 | METHOD if_apc_wsp_event_handler~on_open.
17 | RETURN.
18 | ENDMETHOD.
19 |
20 | METHOD if_apc_wsp_event_handler~on_message.
21 | "message handling
22 | TRY.
23 | mv_message = i_message->get_text( ).
24 | CATCH cx_apc_error INTO DATA(lx_apc_error).
25 | mv_message = 'foo' && lx_apc_error->get_text( ).
26 | ENDTRY.
27 | ENDMETHOD.
28 |
29 | METHOD if_apc_wsp_event_handler~on_close.
30 | "close handling
31 | mv_message = 'Connection closed !'(001).
32 | ENDMETHOD.
33 |
34 | METHOD if_apc_wsp_event_handler~on_error.
35 | "error/close handling
36 | RETURN.
37 | ENDMETHOD.
38 | ENDCLASS.
39 |
40 | START-OF-SELECTION.
41 | PERFORM start.
42 |
43 | FORM start.
44 | TRY.
45 | PERFORM run.
46 | CATCH cx_apc_error INTO DATA(lx_apc_error).
47 | MESSAGE lx_apc_error TYPE 'E'.
48 | ENDTRY.
49 | ENDFORM.
50 |
51 | FORM run RAISING cx_apc_error.
52 |
53 | DATA: li_message_manager TYPE REF TO if_apc_wsp_message_manager,
54 | li_message TYPE REF TO if_apc_wsp_message.
55 |
56 |
57 | DATA(lo_event_handler) = NEW lcl_apc_handler( ).
58 |
59 | DATA(ls_frame) = VALUE apc_tcp_frame(
60 | frame_type = if_apc_tcp_frame_types=>co_frame_type_fixed_length
61 | fixed_length = 1 ).
62 |
63 | DATA(li_client) = cl_apc_tcp_client_manager=>create(
64 | i_host = CONV #( p_host )
65 | i_port = '80'
66 | i_frame = ls_frame
67 | i_event_handler = lo_event_handler ).
68 |
69 | li_client->connect( ).
70 |
71 | li_message_manager ?= li_client->get_message_manager( ).
72 | li_message ?= li_message_manager->create_message( ).
73 |
74 | DATA(lv_text) = 'GET / HTTP/1.1' && cl_abap_char_utilities=>cr_lf && cl_abap_char_utilities=>cr_lf.
75 |
76 | DATA(lv_hex) = cl_binary_convert=>string_to_xstring_utf8( lv_text ).
77 |
78 | WHILE xstrlen( lv_hex ) > 0.
79 | DATA(lv_single) = lv_hex(1).
80 | li_message->set_binary( lv_single ).
81 | li_message_manager->send( li_message ).
82 | lv_hex = lv_hex+1.
83 | ENDWHILE.
84 |
85 | DATA(lv_str) = ||.
86 | DO 100 TIMES.
87 | CLEAR lo_event_handler->mv_message.
88 | WAIT FOR PUSH CHANNELS UNTIL lo_event_handler->mv_message IS NOT INITIAL UP TO 2 SECONDS.
89 | IF sy-subrc = 8.
90 | WRITE: / 'Timeout occured !'(002).
91 | EXIT.
92 | ELSE.
93 | lv_str = lv_str && lo_event_handler->mv_message.
94 | ENDIF.
95 | ENDDO.
96 | WRITE: / lv_str.
97 |
98 | WRITE: / 'Done'(003).
99 |
100 | ENDFORM.
101 |
--------------------------------------------------------------------------------
/src/test/zabapmq_http_client.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPMQ_HTTP_CLIENT
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | I
15 | 001
16 | Connection closed !
17 | 29
18 |
19 | -
20 | I
21 | 002
22 | Timeout occured !
23 | 27
24 |
25 | -
26 | I
27 | 003
28 | Done
29 | 14
30 |
31 | -
32 | R
33 | abapMQ: HTTP client over TCP
34 | 28
35 |
36 | -
37 | S
38 | P_HOST
39 | Host
40 | 12
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/test/zabapmq_mqtt.prog.abap:
--------------------------------------------------------------------------------
1 | REPORT zabapmq_mqtt.
2 |
3 | SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE TEXT-005.
4 | PARAMETERS:
5 | p_rec TYPE c RADIOBUTTON GROUP func DEFAULT 'X',
6 | p_pub TYPE c RADIOBUTTON GROUP func.
7 | SELECTION-SCREEN END OF BLOCK b3.
8 |
9 | SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
10 | PARAMETERS:
11 | p_timeou TYPE i DEFAULT 10 OBLIGATORY,
12 | p_ws TYPE c RADIOBUTTON GROUP tra DEFAULT 'X',
13 | p_url TYPE text100 DEFAULT 'ws://broker.hivemq.com:8000/mqtt' OBLIGATORY,
14 | p_tcp TYPE c RADIOBUTTON GROUP tra,
15 | p_host TYPE text100 DEFAULT 'broker.hivemq.com' OBLIGATORY,
16 | p_port TYPE text100 DEFAULT '1883' OBLIGATORY.
17 | SELECTION-SCREEN END OF BLOCK b2.
18 |
19 | SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
20 | PARAMETERS:
21 | p_topic TYPE text100 DEFAULT 'ozan/iot2' OBLIGATORY,
22 | p_count TYPE i DEFAULT 3 OBLIGATORY.
23 | SELECTION-SCREEN END OF BLOCK b1.
24 |
25 | SELECTION-SCREEN BEGIN OF BLOCK b4 WITH FRAME TITLE TEXT-006.
26 | PARAMETERS:
27 | p_ptopic TYPE text100 DEFAULT 'ABAP' OBLIGATORY,
28 | p_mess TYPE text100 DEFAULT 'hello world'.
29 | SELECTION-SCREEN END OF BLOCK b4.
30 |
31 | START-OF-SELECTION.
32 | PERFORM run.
33 |
34 | FORM run RAISING cx_apc_error.
35 |
36 | TRY.
37 | CASE abap_true.
38 | WHEN p_ws.
39 | DATA(li_transport) = zcl_mqtt_transport_ws=>create_by_url( CONV #( p_url ) ).
40 | WHEN p_tcp.
41 | li_transport = zcl_mqtt_transport_tcp=>create(
42 | iv_host = CONV #( p_host )
43 | iv_port = CONV #( p_port ) ).
44 | ENDCASE.
45 |
46 | li_transport->connect( ).
47 | li_transport->send( NEW zcl_mqtt_packet_connect( ) ).
48 |
49 | DATA(lo_connack) = CAST zcl_mqtt_packet_connack( li_transport->listen( p_timeou ) ).
50 | WRITE: / 'CONNACK return code:'(003), lo_connack->get_return_code( ).
51 |
52 | CASE abap_true.
53 | WHEN p_rec.
54 | PERFORM receive USING li_transport.
55 | WHEN p_pub.
56 | PERFORM publish USING li_transport.
57 | WHEN OTHERS.
58 | ASSERT 0 = 1.
59 | ENDCASE.
60 |
61 | li_transport->send( NEW zcl_mqtt_packet_disconnect( ) ).
62 | li_transport->disconnect( ).
63 |
64 | CATCH zcx_mqtt_timeout.
65 | WRITE: / 'timeout'.
66 | CATCH zcx_mqtt.
67 | WRITE: / 'Error'.
68 | ENDTRY.
69 |
70 | ENDFORM.
71 |
72 | FORM receive USING pi_transport TYPE REF TO zif_mqtt_transport RAISING zcx_mqtt cx_apc_error.
73 |
74 | pi_transport->send( NEW zcl_mqtt_packet_subscribe(
75 | it_topics = VALUE #( ( topic = CONV #( p_topic ) ) )
76 | iv_packet_identifier = '0001' ) ).
77 | DATA(lt_return_codes) = CAST zcl_mqtt_packet_suback( pi_transport->listen( p_timeou ) )->get_return_codes( ).
78 | WRITE: / 'SUBACK return code:'(004), lt_return_codes[ 1 ].
79 |
80 | WRITE: /.
81 | DO p_count TIMES.
82 | DATA(ls_message) = CAST zcl_mqtt_packet_publish( pi_transport->listen( p_timeou ) )->get_message( ).
83 | WRITE: / ls_message-topic, ls_message-message.
84 | WRITE: / cl_binary_convert=>xstring_utf8_to_string( ls_message-message ).
85 | ENDDO.
86 |
87 | ENDFORM.
88 |
89 | FORM publish USING pi_transport TYPE REF TO zif_mqtt_transport RAISING zcx_mqtt cx_apc_error.
90 |
91 | DATA(ls_message) = VALUE zif_mqtt_packet=>ty_message(
92 | topic = p_ptopic
93 | message = cl_binary_convert=>string_to_xstring_utf8( CONV #( p_mess ) ) ).
94 |
95 | pi_transport->send( NEW zcl_mqtt_packet_publish( is_message = ls_message ) ).
96 |
97 | ENDFORM.
98 |
--------------------------------------------------------------------------------
/src/test/zabapmq_mqtt.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPMQ_MQTT
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | I
15 | 001
16 | Receive messages
17 | 18
18 |
19 | -
20 | I
21 | 002
22 | Transport
23 | 19
24 |
25 | -
26 | I
27 | 003
28 | CONNACK return code:
29 | 40
30 |
31 | -
32 | I
33 | 004
34 | SUBACK return code:
35 | 29
36 |
37 | -
38 | I
39 | 005
40 | Function
41 | 18
42 |
43 | -
44 | I
45 | 006
46 | Publish message
47 | 25
48 |
49 | -
50 | R
51 | abapMQ: MQTT Test Client
52 | 24
53 |
54 | -
55 | S
56 | P_COUNT
57 | Count
58 | 13
59 |
60 | -
61 | S
62 | P_HOST
63 | Host
64 | 12
65 |
66 | -
67 | S
68 | P_MESS
69 | Message
70 | 15
71 |
72 | -
73 | S
74 | P_PORT
75 | Port
76 | 12
77 |
78 | -
79 | S
80 | P_PTOPIC
81 | Topic
82 | 13
83 |
84 | -
85 | S
86 | P_PUB
87 | Publish message
88 | 23
89 |
90 | -
91 | S
92 | P_REC
93 | Receive messages
94 | 24
95 |
96 | -
97 | S
98 | P_TCP
99 | TCP
100 | 11
101 |
102 | -
103 | S
104 | P_TIMEOU
105 | Timeout
106 | 15
107 |
108 | -
109 | S
110 | P_TOPIC
111 | Topic
112 | 13
113 |
114 | -
115 | S
116 | P_URL
117 | URL
118 | 11
119 |
120 | -
121 | S
122 | P_WS
123 | Websocket
124 | 17
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/src/test/zabapmq_performance.prog.abap:
--------------------------------------------------------------------------------
1 | REPORT zabapmq_performance.
2 |
3 | PARAMETERS: p_bytes TYPE i DEFAULT 10000,
4 | p_host TYPE text200 DEFAULT 'google.com',
5 | p_port TYPE text200 DEFAULT '1234'.
6 |
7 | CLASS lcl_apc_handler DEFINITION
8 | FINAL
9 | CREATE PUBLIC.
10 |
11 | PUBLIC SECTION.
12 | INTERFACES: if_apc_wsp_event_handler.
13 | DATA: mv_message TYPE string.
14 |
15 | ENDCLASS.
16 |
17 | CLASS lcl_apc_handler IMPLEMENTATION.
18 | METHOD if_apc_wsp_event_handler~on_open.
19 | RETURN.
20 | ENDMETHOD.
21 |
22 | METHOD if_apc_wsp_event_handler~on_message.
23 | "message handling
24 | TRY.
25 | mv_message = i_message->get_text( ).
26 | CATCH cx_apc_error INTO DATA(lx_apc_error).
27 | mv_message = 'foo' && lx_apc_error->get_text( ).
28 | ENDTRY.
29 | ENDMETHOD.
30 |
31 | METHOD if_apc_wsp_event_handler~on_close.
32 | "close handling
33 | mv_message = 'Connection closed !'(005).
34 | ENDMETHOD.
35 |
36 | METHOD if_apc_wsp_event_handler~on_error.
37 | "error/close handling
38 | RETURN.
39 | ENDMETHOD.
40 | ENDCLASS.
41 |
42 | START-OF-SELECTION.
43 | PERFORM start.
44 |
45 | FORM start.
46 | TRY.
47 | PERFORM run.
48 | CATCH cx_apc_error INTO DATA(lx_apc_error).
49 | MESSAGE lx_apc_error TYPE 'E'.
50 | ENDTRY.
51 | ENDFORM.
52 |
53 | FORM run RAISING cx_apc_error.
54 |
55 | DATA: li_message_manager TYPE REF TO if_apc_wsp_message_manager,
56 | li_message TYPE REF TO if_apc_wsp_message.
57 |
58 |
59 | DATA(lo_event_handler) = NEW lcl_apc_handler( ).
60 |
61 | DATA(ls_frame) = VALUE apc_tcp_frame(
62 | frame_type = if_apc_tcp_frame_types=>co_frame_type_fixed_length
63 | fixed_length = 1 ).
64 |
65 | DATA(li_client) = cl_apc_tcp_client_manager=>create(
66 | i_host = CONV #( p_host )
67 | i_port = CONV #( p_port )
68 | i_frame = ls_frame
69 | i_event_handler = lo_event_handler ).
70 |
71 | li_client->connect( ).
72 |
73 | li_message_manager ?= li_client->get_message_manager( ).
74 | li_message ?= li_message_manager->create_message( ).
75 |
76 | GET RUN TIME FIELD DATA(lv_t1).
77 | DO p_bytes TIMES.
78 | li_message->set_binary( '00' ).
79 | li_message_manager->send( li_message ).
80 | ENDDO.
81 | GET RUN TIME FIELD DATA(lv_t2).
82 |
83 | li_client->close( CONV #( 'application closed connection !'(006) ) ).
84 |
85 | lv_t1 = ( lv_t2 - lv_t1 ) / 1000000.
86 | WRITE: / lv_t1.
87 |
88 | WRITE: / 'Done'(007).
89 |
90 | ENDFORM.
91 |
--------------------------------------------------------------------------------
/src/test/zabapmq_performance.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPMQ_PERFORMANCE
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | I
15 | 005
16 | Connection closed !
17 | 29
18 |
19 | -
20 | I
21 | 006
22 | application closed connection !
23 | 62
24 |
25 | -
26 | I
27 | 007
28 | Done
29 | 14
30 |
31 | -
32 | R
33 | abapMQ: Test TCP 1 byte performance
34 | 35
35 |
36 | -
37 | S
38 | P_BYTES
39 | Bytes
40 | 13
41 |
42 | -
43 | S
44 | P_HOST
45 | Host
46 | 12
47 |
48 | -
49 | S
50 | P_PORT
51 | Port
52 | 12
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------