1 /*
2  * hunt-proton: AMQP Protocol library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.proton.engine.impl.TransportLink;
13 
14 import hunt.proton.amqp.UnsignedInteger;
15 import hunt.proton.amqp.transport.Flow;
16 import hunt.proton.engine.Event;
17 import hunt.proton.engine.impl.ReceiverImpl;
18 import hunt.proton.engine.impl.TransportReceiver;
19 import hunt.proton.engine.impl.SenderImpl;
20 import hunt.proton.engine.impl.TransportSender;
21 import hunt.proton.engine.impl.TransportDelivery;
22 import hunt.proton.engine.impl.LinkImpl;
23 
24 class TransportLink
25 {
26     private UnsignedInteger _localHandle;
27     private string _name;
28     private UnsignedInteger _remoteHandle;
29     private UnsignedInteger _deliveryCount;
30     private UnsignedInteger _linkCredit  ;//= UnsignedInteger.ZERO;
31     private Object _link;
32     private UnsignedInteger _remoteDeliveryCount;
33     private UnsignedInteger _remoteLinkCredit;
34     private bool _detachReceived;
35     private bool _attachSent;
36 
37     this(Object link)
38     {
39         _link = link;
40         _linkCredit = UnsignedInteger.ZERO;
41         _name = (cast(LinkImpl)link).getName();
42     }
43 
44     static TransportLink createTransportLink(Object link)
45     {
46         ReceiverImpl r = cast(ReceiverImpl)link;
47         if (r !is null)
48         {
49             TransportReceiver tr = new TransportReceiver(r);
50             r.setTransportLink(tr);
51 
52             return cast(TransportLink) tr;
53         }
54         else
55         {
56             SenderImpl s = cast(SenderImpl) link;
57             TransportSender ts = new TransportSender(s);
58             s.setTransportLink(ts);
59 
60             return cast(TransportLink) ts;
61         }
62     }
63 
64     void unbind()
65     {
66         clearLocalHandle();
67         clearRemoteHandle();
68     }
69 
70     public UnsignedInteger getLocalHandle()
71     {
72         return _localHandle;
73     }
74 
75     public void setLocalHandle(UnsignedInteger localHandle)
76     {
77         if (_localHandle is null) {
78             (cast(LinkImpl)_link).incref();
79         }
80         _localHandle = localHandle;
81     }
82 
83     public bool isLocalHandleSet()
84     {
85         return _localHandle !is null;
86     }
87 
88     public string getName()
89     {
90         return _name;
91     }
92 
93     public void setName(string name)
94     {
95         _name = name;
96     }
97 
98     public void clearLocalHandle()
99     {
100         if (_localHandle !is null) {
101             (cast(LinkImpl)_link).decref();
102         }
103         _localHandle = null;
104     }
105 
106     public UnsignedInteger getRemoteHandle()
107     {
108         return _remoteHandle;
109     }
110 
111     public void setRemoteHandle(UnsignedInteger remoteHandle)
112     {
113         if (_remoteHandle is null) {
114             (cast(LinkImpl)_link).incref();
115         }
116         _remoteHandle = remoteHandle;
117     }
118 
119     public void clearRemoteHandle()
120     {
121         if (_remoteHandle !is null) {
122             (cast(LinkImpl)_link).decref();
123         }
124         _remoteHandle = null;
125     }
126 
127     public UnsignedInteger getDeliveryCount()
128     {
129         return _deliveryCount;
130     }
131 
132     public UnsignedInteger getLinkCredit()
133     {
134         return _linkCredit;
135     }
136 
137     public void addCredit(int credits)
138     {
139         _linkCredit = UnsignedInteger.valueOf(_linkCredit.intValue() + credits);
140     }
141 
142     public bool hasCredit()
143     {
144         return getLinkCredit() > (UnsignedInteger.ZERO);
145     }
146 
147     public Object getLink()
148     {
149         return _link;
150     }
151 
152     void handleFlow(Flow flow)
153     {
154         _remoteDeliveryCount = flow.getDeliveryCount();
155         _remoteLinkCredit = flow.getLinkCredit();
156 
157 
158         (cast(LinkImpl)_link).getConnectionImpl().put(Type.LINK_FLOW, _link);
159     }
160 
161     void setLinkCredit(UnsignedInteger linkCredit)
162     {
163         _linkCredit = linkCredit;
164     }
165 
166     public void setDeliveryCount(UnsignedInteger deliveryCount)
167     {
168         _deliveryCount = deliveryCount;
169     }
170 
171     public void settled(TransportDelivery transportDelivery)
172     {
173         (cast(LinkImpl)getLink()).getSession().getTransportSession().settled(transportDelivery);
174     }
175 
176 
177     UnsignedInteger getRemoteDeliveryCount()
178     {
179         return _remoteDeliveryCount;
180     }
181 
182     UnsignedInteger getRemoteLinkCredit()
183     {
184         return _remoteLinkCredit;
185     }
186 
187     public void setRemoteLinkCredit(UnsignedInteger remoteLinkCredit)
188     {
189         _remoteLinkCredit = remoteLinkCredit;
190     }
191 
192     void decrementLinkCredit()
193     {
194         _linkCredit = _linkCredit.subtract(UnsignedInteger.ONE);
195     }
196 
197     void incrementDeliveryCount()
198     {
199         _deliveryCount = _deliveryCount.add(UnsignedInteger.ONE);
200     }
201 
202     public void receivedDetach()
203     {
204         _detachReceived = true;
205     }
206 
207     public bool detachReceived()
208     {
209         return _detachReceived;
210     }
211 
212     public bool attachSent()
213     {
214         return _attachSent;
215     }
216 
217     public void sentAttach()
218     {
219         _attachSent = true;
220     }
221 
222     public void setRemoteDeliveryCount(UnsignedInteger remoteDeliveryCount)
223     {
224         _remoteDeliveryCount = remoteDeliveryCount;
225     }
226 }