1.0

Dependencies:   EthernetInterface mbed-rtos

Committer:
HMFK03LST1
Date:
Sun Nov 22 14:18:03 2015 +0000
Revision:
5:a96e4e59c710
Parent:
4:5881695ba67a
Child:
6:abadad863420
CS to uint8

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HMFK03LST1 3:94a735c744ff 1 /** Ethernet Interface for send/receive Datastructs over udp
HMFK03LST1 3:94a735c744ff 2 *
HMFK03LST1 3:94a735c744ff 3 *
HMFK03LST1 3:94a735c744ff 4 * By Sebastian Donner
HMFK03LST1 3:94a735c744ff 5 *
HMFK03LST1 3:94a735c744ff 6 * Permission is hereby granted, free of charge, to any person
HMFK03LST1 3:94a735c744ff 7 * obtaining a copy of this software and associated documentation
HMFK03LST1 3:94a735c744ff 8 * files (the "Software"), to deal in the Software without
HMFK03LST1 3:94a735c744ff 9 * restriction, including without limitation the rights to use,
HMFK03LST1 3:94a735c744ff 10 * copy, modify, merge, publish, distribute, sublicense, and/or sell
HMFK03LST1 3:94a735c744ff 11 * copies of the Software, and to permit persons to whom the
HMFK03LST1 3:94a735c744ff 12 * Software is furnished to do so, subject to the following
HMFK03LST1 3:94a735c744ff 13 * conditions:
HMFK03LST1 3:94a735c744ff 14 *
HMFK03LST1 3:94a735c744ff 15 * The above copyright notice and this permission notice shall be
HMFK03LST1 3:94a735c744ff 16 * included in all copies or substantial portions of the Software.
HMFK03LST1 3:94a735c744ff 17 *
HMFK03LST1 3:94a735c744ff 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
HMFK03LST1 3:94a735c744ff 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
HMFK03LST1 3:94a735c744ff 20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
HMFK03LST1 3:94a735c744ff 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HMFK03LST1 3:94a735c744ff 22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
HMFK03LST1 3:94a735c744ff 23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
HMFK03LST1 3:94a735c744ff 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
HMFK03LST1 3:94a735c744ff 25 * OTHER DEALINGS IN THE SOFTWARE.
HMFK03LST1 3:94a735c744ff 26 */
HMFK03LST1 0:c0179f2ad295 27
HMFK03LST1 0:c0179f2ad295 28 #include "Telemetry.h"
HMFK03LST1 0:c0179f2ad295 29
HMFK03LST1 3:94a735c744ff 30 /**Debug Schnittstelle
HMFK03LST1 3:94a735c744ff 31 */
HMFK03LST1 0:c0179f2ad295 32 #ifdef DEBUG
HMFK03LST1 2:e19b937a29c1 33 Serial debug(USBTX, USBRX);
HMFK03LST1 3:94a735c744ff 34 debug.baud(115200);
HMFK03LST1 0:c0179f2ad295 35 #endif
HMFK03LST1 0:c0179f2ad295 36
HMFK03LST1 3:94a735c744ff 37 /**Konstruktoren
HMFK03LST1 3:94a735c744ff 38 */
HMFK03LST1 2:e19b937a29c1 39 EthernetInterface eth;
HMFK03LST1 0:c0179f2ad295 40 TCPSocketConnection sock_tcp;
HMFK03LST1 2:e19b937a29c1 41 UDPSocket sock_udp_send; //send socket
HMFK03LST1 2:e19b937a29c1 42 UDPSocket sock_udp_rec; //receive socket
HMFK03LST1 2:e19b937a29c1 43
HMFK03LST1 2:e19b937a29c1 44
HMFK03LST1 0:c0179f2ad295 45
HMFK03LST1 0:c0179f2ad295 46
HMFK03LST1 3:94a735c744ff 47 /** Create a new Ethernet interface
HMFK03LST1 3:94a735c744ff 48 *
HMFK03LST1 3:94a735c744ff 49 */
HMFK03LST1 0:c0179f2ad295 50 Telemetry::Telemetry()
HMFK03LST1 0:c0179f2ad295 51 {
HMFK03LST1 3:94a735c744ff 52 InitSucceed = false;
HMFK03LST1 0:c0179f2ad295 53 }
HMFK03LST1 0:c0179f2ad295 54
HMFK03LST1 3:94a735c744ff 55
HMFK03LST1 3:94a735c744ff 56 /** Init a Serial Debug interface
HMFK03LST1 3:94a735c744ff 57 *
HMFK03LST1 3:94a735c744ff 58 */
HMFK03LST1 0:c0179f2ad295 59 #ifdef DEBUG
HMFK03LST1 0:c0179f2ad295 60 void Telemetry::InitUSBSerialConnection()
HMFK03LST1 0:c0179f2ad295 61 {
HMFK03LST1 0:c0179f2ad295 62 serial.baud(115200);
HMFK03LST1 0:c0179f2ad295 63 }
HMFK03LST1 0:c0179f2ad295 64 #endif
HMFK03LST1 0:c0179f2ad295 65
HMFK03LST1 3:94a735c744ff 66
HMFK03LST1 3:94a735c744ff 67
HMFK03LST1 3:94a735c744ff 68
HMFK03LST1 3:94a735c744ff 69 /** Init Ethernet interface
HMFK03LST1 3:94a735c744ff 70 * mit DHCP max. 10 Sekunden
HMFK03LST1 3:94a735c744ff 71 */
HMFK03LST1 3:94a735c744ff 72 bool Telemetry::InitEthernetConnection()
HMFK03LST1 3:94a735c744ff 73 {
HMFK03LST1 3:94a735c744ff 74 bool ReturnValue = false;
HMFK03LST1 3:94a735c744ff 75 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 76 debug.printf("Initalisiere LAN Verbindung mit DHCP\r\n\r\n");
HMFK03LST1 3:94a735c744ff 77 #endif
HMFK03LST1 3:94a735c744ff 78
HMFK03LST1 3:94a735c744ff 79 //Schnittstelle nur einmal initialisieren, sonst gibt es Fehler!
HMFK03LST1 3:94a735c744ff 80 if (!InitSucceed)
HMFK03LST1 3:94a735c744ff 81 {
HMFK03LST1 3:94a735c744ff 82 if (eth.init()==0) //Init Interface
HMFK03LST1 3:94a735c744ff 83 {
HMFK03LST1 3:94a735c744ff 84 InitSucceed = true;
HMFK03LST1 3:94a735c744ff 85 }
HMFK03LST1 3:94a735c744ff 86 }
HMFK03LST1 3:94a735c744ff 87
HMFK03LST1 3:94a735c744ff 88 //Nur wenn Initialisierung erfolgreich war!
HMFK03LST1 3:94a735c744ff 89 if (InitSucceed)
HMFK03LST1 3:94a735c744ff 90 {
HMFK03LST1 3:94a735c744ff 91 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 92 serial.printf("Verbinde\r\n\r\n");
HMFK03LST1 3:94a735c744ff 93 #endif
HMFK03LST1 3:94a735c744ff 94 ip_self = eth.getIPAddress();
HMFK03LST1 3:94a735c744ff 95
HMFK03LST1 3:94a735c744ff 96 if (eth.connect(10000)==0) //CONNECT
HMFK03LST1 3:94a735c744ff 97 {
HMFK03LST1 3:94a735c744ff 98 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 99 printf("IP Adresse: %s\r\n\r\n", eth.getIPAddress());
HMFK03LST1 3:94a735c744ff 100 #endif
HMFK03LST1 3:94a735c744ff 101 ReturnValue = true;
HMFK03LST1 3:94a735c744ff 102 }
HMFK03LST1 3:94a735c744ff 103 else
HMFK03LST1 3:94a735c744ff 104 {
HMFK03LST1 3:94a735c744ff 105 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 106 serial.printf("DHCP fail!\r\n\r\n");
HMFK03LST1 3:94a735c744ff 107 #endif
HMFK03LST1 3:94a735c744ff 108 ReturnValue = false;
HMFK03LST1 3:94a735c744ff 109 }
HMFK03LST1 3:94a735c744ff 110 }
HMFK03LST1 3:94a735c744ff 111
HMFK03LST1 3:94a735c744ff 112 return ReturnValue;
HMFK03LST1 3:94a735c744ff 113 }
HMFK03LST1 3:94a735c744ff 114
HMFK03LST1 3:94a735c744ff 115
HMFK03LST1 3:94a735c744ff 116 /** Init Ethernet interface
HMFK03LST1 4:5881695ba67a 117 * ohne DHCP max. 2.5 Sekunden
HMFK03LST1 5:a96e4e59c710 118 * @param IPAddress Interface IP
HMFK03LST1 3:94a735c744ff 119 */
HMFK03LST1 4:5881695ba67a 120 bool Telemetry::InitEthernetConnection(const char* IPAddress, const char* SubNetMask, const char* GateWay)
HMFK03LST1 3:94a735c744ff 121 {
HMFK03LST1 3:94a735c744ff 122 bool ReturnValue = false;
HMFK03LST1 3:94a735c744ff 123 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 124 printf("Initalisiere LAN Verbindung ohne DHCP\r\n\r\n");
HMFK03LST1 3:94a735c744ff 125 printf("IP: %s - GateWay: %s - SubNetMask: %s\r\n\r\n",IPAdress, GateWay, SubNetMask);
HMFK03LST1 3:94a735c744ff 126 #endif
HMFK03LST1 3:94a735c744ff 127
HMFK03LST1 3:94a735c744ff 128 //Schnittstelle nur einmal initialisieren, sonst gibt es Fehler!
HMFK03LST1 3:94a735c744ff 129 if (!InitSucceed)
HMFK03LST1 3:94a735c744ff 130 {
HMFK03LST1 4:5881695ba67a 131 if (eth.init(IPAddress, SubNetMask, GateWay)==0) //Init Interface
HMFK03LST1 3:94a735c744ff 132 {
HMFK03LST1 3:94a735c744ff 133 InitSucceed = true;
HMFK03LST1 3:94a735c744ff 134 }
HMFK03LST1 3:94a735c744ff 135 }
HMFK03LST1 3:94a735c744ff 136
HMFK03LST1 3:94a735c744ff 137 //Nur wenn Initialisierung erfolgreich war!
HMFK03LST1 3:94a735c744ff 138 if (InitSucceed)
HMFK03LST1 3:94a735c744ff 139 {
HMFK03LST1 3:94a735c744ff 140 if (eth.connect(2500)==0) //CONNECT
HMFK03LST1 3:94a735c744ff 141 {
HMFK03LST1 3:94a735c744ff 142 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 143 serial.printf("Init success!");
HMFK03LST1 3:94a735c744ff 144 #endif
HMFK03LST1 3:94a735c744ff 145
HMFK03LST1 3:94a735c744ff 146 ReturnValue = true;
HMFK03LST1 3:94a735c744ff 147 }
HMFK03LST1 3:94a735c744ff 148 else
HMFK03LST1 3:94a735c744ff 149 {
HMFK03LST1 3:94a735c744ff 150 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 151 serial.printf("Init fail!");
HMFK03LST1 3:94a735c744ff 152 #endif
HMFK03LST1 3:94a735c744ff 153 ReturnValue = false;
HMFK03LST1 3:94a735c744ff 154 }
HMFK03LST1 3:94a735c744ff 155 }
HMFK03LST1 3:94a735c744ff 156
HMFK03LST1 3:94a735c744ff 157 return ReturnValue;
HMFK03LST1 3:94a735c744ff 158 }
HMFK03LST1 3:94a735c744ff 159
HMFK03LST1 3:94a735c744ff 160
HMFK03LST1 3:94a735c744ff 161 //! Close Connection
HMFK03LST1 3:94a735c744ff 162 void Telemetry::CloseEthernetConnection()
HMFK03LST1 3:94a735c744ff 163 {
HMFK03LST1 3:94a735c744ff 164 eth.disconnect();
HMFK03LST1 3:94a735c744ff 165 InitSucceed = false;
HMFK03LST1 3:94a735c744ff 166
HMFK03LST1 3:94a735c744ff 167 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 168 serial.printf("LAN Stack close\r\n\r\n");
HMFK03LST1 3:94a735c744ff 169 #endif
HMFK03LST1 3:94a735c744ff 170 }
HMFK03LST1 3:94a735c744ff 171
HMFK03LST1 3:94a735c744ff 172
HMFK03LST1 3:94a735c744ff 173 //! Connect Port TCP
HMFK03LST1 3:94a735c744ff 174 void Telemetry::ConnectSocket_tcp(Endpoint Host)
HMFK03LST1 3:94a735c744ff 175 {
HMFK03LST1 3:94a735c744ff 176 sock_tcp.connect(Host.get_address(), Host.get_port());
HMFK03LST1 3:94a735c744ff 177 sock_tcp.set_blocking(false, 0);
HMFK03LST1 3:94a735c744ff 178 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 179 serial.printf("Open TCP Socket to IP: %s:%d.\r\n\r\n",Host.get_address(), Host.get_port());
HMFK03LST1 3:94a735c744ff 180 #endif
HMFK03LST1 3:94a735c744ff 181 }
HMFK03LST1 3:94a735c744ff 182
HMFK03LST1 3:94a735c744ff 183
HMFK03LST1 3:94a735c744ff 184 //! Connect Port UDP receive
HMFK03LST1 3:94a735c744ff 185 void Telemetry::ConnectSocket_udp_rec(int Port)
HMFK03LST1 3:94a735c744ff 186 {
HMFK03LST1 3:94a735c744ff 187 sock_udp_rec.bind(Port);
HMFK03LST1 3:94a735c744ff 188 sock_udp_rec.set_blocking(false, 0);
HMFK03LST1 3:94a735c744ff 189
HMFK03LST1 3:94a735c744ff 190 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 191 serial.printf("Open UDP_receive Socket on Port:%d.\r\n\r\n",Port);
HMFK03LST1 3:94a735c744ff 192 #endif
HMFK03LST1 3:94a735c744ff 193 }
HMFK03LST1 3:94a735c744ff 194
HMFK03LST1 3:94a735c744ff 195
HMFK03LST1 3:94a735c744ff 196 //! Connect Port UDP send
HMFK03LST1 3:94a735c744ff 197 void Telemetry::ConnectSocket_udp_send()
HMFK03LST1 3:94a735c744ff 198 {
HMFK03LST1 3:94a735c744ff 199 sock_udp_send.init();
HMFK03LST1 3:94a735c744ff 200
HMFK03LST1 3:94a735c744ff 201 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 202 serial.printf("Open UDP_send Socket.\r\n\r\n");
HMFK03LST1 3:94a735c744ff 203 #endif
HMFK03LST1 3:94a735c744ff 204 }
HMFK03LST1 3:94a735c744ff 205
HMFK03LST1 3:94a735c744ff 206
HMFK03LST1 3:94a735c744ff 207 //! Close Port TCP
HMFK03LST1 3:94a735c744ff 208 void Telemetry::CloseSocket_tcp()
HMFK03LST1 3:94a735c744ff 209 {
HMFK03LST1 3:94a735c744ff 210 sock_tcp.close();
HMFK03LST1 3:94a735c744ff 211
HMFK03LST1 3:94a735c744ff 212 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 213 serial.printf("TCP Socket closed.\r\n\r\n");
HMFK03LST1 3:94a735c744ff 214 #endif
HMFK03LST1 3:94a735c744ff 215 }
HMFK03LST1 3:94a735c744ff 216
HMFK03LST1 3:94a735c744ff 217
HMFK03LST1 3:94a735c744ff 218 //! Close Port UDP receive
HMFK03LST1 3:94a735c744ff 219 void Telemetry::CloseSocket_udp_rec()
HMFK03LST1 3:94a735c744ff 220 {
HMFK03LST1 3:94a735c744ff 221 sock_udp_rec.close();
HMFK03LST1 3:94a735c744ff 222 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 223 serial.printf("UDP receive Socket closed.\r\n\r\n");
HMFK03LST1 3:94a735c744ff 224 #endif
HMFK03LST1 3:94a735c744ff 225 }
HMFK03LST1 3:94a735c744ff 226
HMFK03LST1 3:94a735c744ff 227
HMFK03LST1 3:94a735c744ff 228 //! Close Port UDP send
HMFK03LST1 3:94a735c744ff 229 void Telemetry::CloseSocket_udp_send()
HMFK03LST1 3:94a735c744ff 230 {
HMFK03LST1 3:94a735c744ff 231 sock_udp_send.close();
HMFK03LST1 3:94a735c744ff 232
HMFK03LST1 3:94a735c744ff 233 #ifdef DEBUG
HMFK03LST1 3:94a735c744ff 234 serial.printf("UDP send Socket closed.\r\n\r\n");
HMFK03LST1 3:94a735c744ff 235 #endif
HMFK03LST1 3:94a735c744ff 236 }
HMFK03LST1 3:94a735c744ff 237
HMFK03LST1 3:94a735c744ff 238
HMFK03LST1 3:94a735c744ff 239 //! Struct Check Sum calc
HMFK03LST1 5:a96e4e59c710 240 uint8_t Telemetry::do_cs(char* buffer)
HMFK03LST1 2:e19b937a29c1 241 {
HMFK03LST1 5:a96e4e59c710 242 uint8_t ck_a=0;
HMFK03LST1 5:a96e4e59c710 243 uint8_t ck_b=0;
HMFK03LST1 2:e19b937a29c1 244
HMFK03LST1 2:e19b937a29c1 245 for(int i=0; i < (buffer[0]-1); i++)
HMFK03LST1 2:e19b937a29c1 246 {
HMFK03LST1 2:e19b937a29c1 247 ck_a += buffer[i];
HMFK03LST1 2:e19b937a29c1 248 ck_b += ck_a;
HMFK03LST1 2:e19b937a29c1 249 }
HMFK03LST1 2:e19b937a29c1 250
HMFK03LST1 2:e19b937a29c1 251 return ck_b;
HMFK03LST1 2:e19b937a29c1 252 }
HMFK03LST1 2:e19b937a29c1 253
HMFK03LST1 2:e19b937a29c1 254
HMFK03LST1 3:94a735c744ff 255 //! Read UDP Packet
HMFK03LST1 2:e19b937a29c1 256 int Telemetry::Rec_Data_UDP(char *buffer, int size)
HMFK03LST1 0:c0179f2ad295 257 {
HMFK03LST1 2:e19b937a29c1 258 return sock_udp_rec.receiveFrom(input_Host, buffer, size);
HMFK03LST1 2:e19b937a29c1 259 }
HMFK03LST1 2:e19b937a29c1 260
HMFK03LST1 2:e19b937a29c1 261
HMFK03LST1 3:94a735c744ff 262 //! Check UDP Packet of containing Struct
HMFK03LST1 2:e19b937a29c1 263 bool Telemetry::Rec_Struct_UDP(char *buffer)
HMFK03LST1 2:e19b937a29c1 264 {
HMFK03LST1 2:e19b937a29c1 265 sock_udp_rec.receiveFrom(input_Host, buffer, 255);
HMFK03LST1 2:e19b937a29c1 266 if (buffer[buffer[0]-1] == do_cs(buffer)) return true;
HMFK03LST1 2:e19b937a29c1 267 else return false;
HMFK03LST1 2:e19b937a29c1 268 }
HMFK03LST1 2:e19b937a29c1 269
HMFK03LST1 2:e19b937a29c1 270
HMFK03LST1 3:94a735c744ff 271 //! Read TCP Packet
HMFK03LST1 2:e19b937a29c1 272 int Telemetry::Rec_Data_TCP(char *buffer,int size)
HMFK03LST1 2:e19b937a29c1 273 {
HMFK03LST1 2:e19b937a29c1 274 return sock_tcp.receive(buffer, size);
HMFK03LST1 2:e19b937a29c1 275 }
HMFK03LST1 2:e19b937a29c1 276
HMFK03LST1 2:e19b937a29c1 277
HMFK03LST1 3:94a735c744ff 278 //! Send UDP Packet
HMFK03LST1 2:e19b937a29c1 279 void Telemetry::Send_Data_UDP(Endpoint Server, char* Daten, int size )
HMFK03LST1 3:94a735c744ff 280 {
HMFK03LST1 2:e19b937a29c1 281 sock_udp_send.sendTo(Server, Daten, size);
HMFK03LST1 0:c0179f2ad295 282
HMFK03LST1 0:c0179f2ad295 283 #ifdef DEBUG
HMFK03LST1 0:c0179f2ad295 284 serial.printf("UDP Paket gesendet.\r\n\r\n");
HMFK03LST1 0:c0179f2ad295 285 #endif
HMFK03LST1 0:c0179f2ad295 286 }
HMFK03LST1 0:c0179f2ad295 287
HMFK03LST1 2:e19b937a29c1 288
HMFK03LST1 3:94a735c744ff 289 //! Send Struct as UDP Packet
HMFK03LST1 2:e19b937a29c1 290 void Telemetry::Send_Struct_UDP(Endpoint Server, char* Daten)
HMFK03LST1 2:e19b937a29c1 291 {
HMFK03LST1 2:e19b937a29c1 292 Daten[(*Daten - 1)] = do_cs(Daten);
HMFK03LST1 2:e19b937a29c1 293 sock_udp_send.sendTo(Server, Daten, *Daten);
HMFK03LST1 2:e19b937a29c1 294 }
HMFK03LST1 2:e19b937a29c1 295
HMFK03LST1 2:e19b937a29c1 296
HMFK03LST1 3:94a735c744ff 297 //! Send TCP Packet
HMFK03LST1 3:94a735c744ff 298 void Telemetry::Send_Data_TCP(char* Host, char* Buffer)
HMFK03LST1 0:c0179f2ad295 299 {
HMFK03LST1 0:c0179f2ad295 300
HMFK03LST1 3:94a735c744ff 301 /* Umwandeln in char*
HMFK03LST1 0:c0179f2ad295 302 const char *DataBuf = datenpaket.c_str();
HMFK03LST1 0:c0179f2ad295 303 char DataPaket[datenpaket.length()];
HMFK03LST1 0:c0179f2ad295 304 strcpy(DataPaket,DataBuf);
HMFK03LST1 3:94a735c744ff 305 */
HMFK03LST1 0:c0179f2ad295 306 #ifdef DEBUG
HMFK03LST1 0:c0179f2ad295 307 serial.printf("----\r\n%s----\r\n\r\n",DataPaket);
HMFK03LST1 0:c0179f2ad295 308 serial.printf("Sende Paket.\r\n\r\n");
HMFK03LST1 0:c0179f2ad295 309 #endif
HMFK03LST1 0:c0179f2ad295 310
HMFK03LST1 3:94a735c744ff 311 sock_tcp.send_all(Buffer, sizeof(Buffer)-1);
HMFK03LST1 0:c0179f2ad295 312
HMFK03LST1 0:c0179f2ad295 313 #ifdef DEBUG
HMFK03LST1 0:c0179f2ad295 314 serial.printf("Paket gesendet.\r\n\r\n");
HMFK03LST1 0:c0179f2ad295 315 #endif
HMFK03LST1 0:c0179f2ad295 316 }
HMFK03LST1 0:c0179f2ad295 317
HMFK03LST1 2:e19b937a29c1 318
HMFK03LST1 0:c0179f2ad295 319
HMFK03LST1 2:e19b937a29c1 320
HMFK03LST1 0:c0179f2ad295 321