Passed
Push — master ( b7a059...7a6b49 )
by Camilo
02:58
created

ConnAck::fillObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace unreal4u\MQTT\Protocol;
6
7
use unreal4u\MQTT\Exceptions\Connect\BadUsernameOrPassword;
8
use unreal4u\MQTT\Exceptions\Connect\GenericError;
9
use unreal4u\MQTT\Exceptions\Connect\IdentifierRejected;
10
use unreal4u\MQTT\Exceptions\Connect\NotAuthorized;
11
use unreal4u\MQTT\Exceptions\Connect\ServerUnavailable;
12
use unreal4u\MQTT\Exceptions\Connect\UnacceptableProtocolVersion;
13
use unreal4u\MQTT\Internals\ClientInterface;
14
use unreal4u\MQTT\Internals\ProtocolBase;
15
use unreal4u\MQTT\Internals\ReadableContent;
16
use unreal4u\MQTT\Internals\ReadableContentInterface;
17
use unreal4u\MQTT\Internals\WritableContentInterface;
18
19
/**
20
 * The CONNACK Packet is the packet sent by the Server in response to a CONNECT Packet received from a Client.
21
 */
22
final class ConnAck extends ProtocolBase implements ReadableContentInterface
23
{
24
    use ReadableContent;
25
26
    const CONTROL_PACKET_VALUE = 2;
27
28
    /**
29
     * The connect return code. If a server sends a CONNACK packet containing a non-zero return code it MUST then close
30
     * the Network Connection
31
     *
32
     * @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_3.1_-
33
     *
34
     * 0 = Connection accepted
35
     * 1 = Connection Refused, unacceptable protocol version
36
     * 2 = Connection Refused, identifier rejected
37
     * 3 = Connection Refused, Server unavailable
38
     * 4 = Connection Refused, bad user name or password
39
     * 5 = Connection Refused, not authorized
40
     * 6-255 = Reserved for future use
41
     * @var int
42
     */
43
    public $connectReturnCode;
44
45
    /**
46
     * @inheritdoc
47
     *
48
     * @param string $rawMQTTHeaders
49
     * @param ClientInterface $client
50
     * @return ReadableContentInterface
51
     * @throws \unreal4u\MQTT\Exceptions\Connect\GenericError
52
     * @throws \unreal4u\MQTT\Exceptions\Connect\NotAuthorized
53
     * @throws \unreal4u\MQTT\Exceptions\Connect\BadUsernameOrPassword
54
     * @throws \unreal4u\MQTT\Exceptions\Connect\ServerUnavailable
55
     * @throws \unreal4u\MQTT\Exceptions\Connect\IdentifierRejected
56
     * @throws \unreal4u\MQTT\Exceptions\Connect\UnacceptableProtocolVersion
57
     */
58 7
    public function fillObject(string $rawMQTTHeaders, ClientInterface $client): ReadableContentInterface
59
    {
60 7
        $this->connectReturnCode = \ord($rawMQTTHeaders{3});
61 7
        if ($this->connectReturnCode !== 0) {
62
            // We have detected a problem while connecting to the broker, send out the correct exception
63 6
            $this->throwConnectException();
64
        }
65
66 1
        return $this;
67
    }
68
69
    /**
70
     * Will throw an exception in case there is something bad with the connection
71
     *
72
     * @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc385349257
73
     *
74
     * @return ConnAck
75
     * @throws \unreal4u\MQTT\Exceptions\Connect\GenericError
76
     * @throws \unreal4u\MQTT\Exceptions\Connect\NotAuthorized
77
     * @throws \unreal4u\MQTT\Exceptions\Connect\BadUsernameOrPassword
78
     * @throws \unreal4u\MQTT\Exceptions\Connect\ServerUnavailable
79
     * @throws \unreal4u\MQTT\Exceptions\Connect\IdentifierRejected
80
     * @throws \unreal4u\MQTT\Exceptions\Connect\UnacceptableProtocolVersion
81
     */
82 6
    private function throwConnectException(): self
83
    {
84 6
        switch ($this->connectReturnCode) {
85 6
            case 1:
86 1
                throw new UnacceptableProtocolVersion(
87 1
                    'The Server does not support the level of the MQTT protocol requested by the Client'
88
                );
89 5
            case 2:
90 1
                throw new IdentifierRejected('The Client identifier is correct UTF-8 but not allowed by the Server');
91 4
            case 3:
92 1
                throw new ServerUnavailable('The Network Connection has been made but the MQTT service is unavailable');
93 3
            case 4:
94 1
                throw new BadUsernameOrPassword('The data in the user name or password is malformed');
95 2
            case 5:
96 1
                throw new NotAuthorized('The Client is not authorized to connect');
97
            default:
98 1
                throw new GenericError(sprintf(
99 1
                    'Reserved for future use or error not implemented yet (Error code: %d)',
100 1
                    $this->connectReturnCode
101
                ));
102
        }
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108 1
    public function performSpecialActions(ClientInterface $client, WritableContentInterface $originalRequest): bool
109
    {
110
        $client
111 1
            ->setConnected(true)
112 1
            ->updateLastCommunication();
113
114 1
        return true;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120 1
    public function getOriginControlPacket(): int
121
    {
122 1
        return Connect::getControlPacketValue();
123
    }
124
}
125