RFID

Dependents:   RoboticHackathon2 RoboticHackathonFINAL

Committer:
iLyngklip
Date:
Mon Apr 07 06:23:00 2014 +0000
Revision:
0:051708395e3c
RFID

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iLyngklip 0:051708395e3c 1
iLyngklip 0:051708395e3c 2 /******************************************************************************
iLyngklip 0:051708395e3c 3 * Includes
iLyngklip 0:051708395e3c 4 ******************************************************************************/
iLyngklip 0:051708395e3c 5 #include "mbed.h"
iLyngklip 0:051708395e3c 6 #include "Rfid.h"
iLyngklip 0:051708395e3c 7
iLyngklip 0:051708395e3c 8 /******************************************************************************
iLyngklip 0:051708395e3c 9 * User API
iLyngklip 0:051708395e3c 10 ******************************************************************************/
iLyngklip 0:051708395e3c 11
iLyngklip 0:051708395e3c 12 #define uchar unsigned char
iLyngklip 0:051708395e3c 13 /**
iLyngklip 0:051708395e3c 14 * Construct RFID
iLyngklip 0:051708395e3c 15 * int chipSelectPin RFID /ENABLE pin
iLyngklip 0:051708395e3c 16 */
iLyngklip 0:051708395e3c 17 RFID::RFID() : _rfid(PTD2, PTD3, PTD1), _chipSelectPin(PTD0), _NRSTPD(PTD5)
iLyngklip 0:051708395e3c 18 {
iLyngklip 0:051708395e3c 19
iLyngklip 0:051708395e3c 20 }
iLyngklip 0:051708395e3c 21 /******************************************************************************
iLyngklip 0:051708395e3c 22 * User API
iLyngklip 0:051708395e3c 23 ******************************************************************************/
iLyngklip 0:051708395e3c 24
iLyngklip 0:051708395e3c 25 void RFID::check()
iLyngklip 0:051708395e3c 26 {
iLyngklip 0:051708395e3c 27
iLyngklip 0:051708395e3c 28 uchar status;
iLyngklip 0:051708395e3c 29 uchar str[MAX_LEN];
iLyngklip 0:051708395e3c 30 status = MFRC522Request(PICC_REQIDL, str);
iLyngklip 0:051708395e3c 31 if (status == MI_OK)
iLyngklip 0:051708395e3c 32 {
iLyngklip 0:051708395e3c 33 //Prevent conflict, return the 4 bytes Serial number of the card
iLyngklip 0:051708395e3c 34 status = anticoll(str);
iLyngklip 0:051708395e3c 35 memcpy(serNum, str, 5);
iLyngklip 0:051708395e3c 36 if (status == MI_OK){
iLyngklip 0:051708395e3c 37 card = (serNum[0]+serNum[1]);
iLyngklip 0:051708395e3c 38 }
iLyngklip 0:051708395e3c 39
iLyngklip 0:051708395e3c 40 }
iLyngklip 0:051708395e3c 41 else {card=0;}
iLyngklip 0:051708395e3c 42 }
iLyngklip 0:051708395e3c 43
iLyngklip 0:051708395e3c 44 /******************************************************************************
iLyngklip 0:051708395e3c 45 * Dr.Leong ( WWW.B2CQSHOP.COM )
iLyngklip 0:051708395e3c 46 ******************************************************************************/
iLyngklip 0:051708395e3c 47
iLyngklip 0:051708395e3c 48 void RFID::init()
iLyngklip 0:051708395e3c 49 {
iLyngklip 0:051708395e3c 50 _NRSTPD =1;
iLyngklip 0:051708395e3c 51
iLyngklip 0:051708395e3c 52 reset();
iLyngklip 0:051708395e3c 53
iLyngklip 0:051708395e3c 54 //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
iLyngklip 0:051708395e3c 55 writeMFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
iLyngklip 0:051708395e3c 56 writeMFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg
iLyngklip 0:051708395e3c 57 writeMFRC522(TReloadRegL, 30);
iLyngklip 0:051708395e3c 58 writeMFRC522(TReloadRegH, 0);
iLyngklip 0:051708395e3c 59
iLyngklip 0:051708395e3c 60 writeMFRC522(TxAutoReg, 0x40); //100%ASK
iLyngklip 0:051708395e3c 61 writeMFRC522(ModeReg, 0x3D); // CRC valor inicial de 0x6363
iLyngklip 0:051708395e3c 62 writeMFRC522(CommIEnReg, 0x00); //Enable Rx interupt
iLyngklip 0:051708395e3c 63 writeMFRC522(DivlEnReg, 0x08); //IRQ is standar CMOS output
iLyngklip 0:051708395e3c 64 writeMFRC522(CommIrqReg, 0x20); //IRQ on end of valid data stream
iLyngklip 0:051708395e3c 65 writeMFRC522(DivIrqReg, 0x08);
iLyngklip 0:051708395e3c 66 //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0
iLyngklip 0:051708395e3c 67 //writeMFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0]
iLyngklip 0:051708395e3c 68 //writeMFRC522(RFCfgReg, 0x7F); //RxGain = 48dB
iLyngklip 0:051708395e3c 69
iLyngklip 0:051708395e3c 70 antennaOn(); //Abre la antena
iLyngklip 0:051708395e3c 71
iLyngklip 0:051708395e3c 72
iLyngklip 0:051708395e3c 73 }
iLyngklip 0:051708395e3c 74 void RFID::reset()
iLyngklip 0:051708395e3c 75 {
iLyngklip 0:051708395e3c 76 writeMFRC522(CommandReg, PCD_RESETPHASE);
iLyngklip 0:051708395e3c 77 }
iLyngklip 0:051708395e3c 78
iLyngklip 0:051708395e3c 79 void RFID::writeMFRC522(unsigned char addr, unsigned char val)
iLyngklip 0:051708395e3c 80 {
iLyngklip 0:051708395e3c 81 _chipSelectPin =0;
iLyngklip 0:051708395e3c 82
iLyngklip 0:051708395e3c 83 //0XXXXXX0 formato de dirección
iLyngklip 0:051708395e3c 84 _rfid.write((addr<<1)&0x7E);
iLyngklip 0:051708395e3c 85 _rfid.write(val);
iLyngklip 0:051708395e3c 86
iLyngklip 0:051708395e3c 87 _chipSelectPin = 1;
iLyngklip 0:051708395e3c 88 }
iLyngklip 0:051708395e3c 89
iLyngklip 0:051708395e3c 90 void RFID::antennaOn(void)
iLyngklip 0:051708395e3c 91 {
iLyngklip 0:051708395e3c 92 unsigned char temp;
iLyngklip 0:051708395e3c 93
iLyngklip 0:051708395e3c 94 temp = readMFRC522(TxControlReg);
iLyngklip 0:051708395e3c 95 if (!(temp & 0x03))
iLyngklip 0:051708395e3c 96 {
iLyngklip 0:051708395e3c 97 setBitMask(TxControlReg, 0x03);
iLyngklip 0:051708395e3c 98 }
iLyngklip 0:051708395e3c 99 }
iLyngklip 0:051708395e3c 100
iLyngklip 0:051708395e3c 101 /*
iLyngklip 0:051708395e3c 102 * Read_MFRC522 Nombre de la función: Read_MFRC522
iLyngklip 0:051708395e3c 103 * Descripción: Desde el MFRC522 leer un byte de un registro de datos
iLyngklip 0:051708395e3c 104 * Los parámetros de entrada: addr - la dirección de registro
iLyngklip 0:051708395e3c 105 * Valor de retorno: Devuelve un byte de datos de lectura
iLyngklip 0:051708395e3c 106 */
iLyngklip 0:051708395e3c 107 unsigned char RFID::readMFRC522(unsigned char addr)
iLyngklip 0:051708395e3c 108 {
iLyngklip 0:051708395e3c 109 unsigned char val;
iLyngklip 0:051708395e3c 110 _chipSelectPin =0;
iLyngklip 0:051708395e3c 111 _rfid.write(((addr<<1)&0x7E) | 0x80);
iLyngklip 0:051708395e3c 112 val =_rfid.write(0x00);
iLyngklip 0:051708395e3c 113 _chipSelectPin =1;
iLyngklip 0:051708395e3c 114 return val;
iLyngklip 0:051708395e3c 115 }
iLyngklip 0:051708395e3c 116
iLyngklip 0:051708395e3c 117 void RFID::setBitMask(unsigned char reg, unsigned char mask)
iLyngklip 0:051708395e3c 118 {
iLyngklip 0:051708395e3c 119 unsigned char tmp;
iLyngklip 0:051708395e3c 120 tmp = readMFRC522(reg);
iLyngklip 0:051708395e3c 121 writeMFRC522(reg, tmp | mask); // set bit mask
iLyngklip 0:051708395e3c 122 }
iLyngklip 0:051708395e3c 123
iLyngklip 0:051708395e3c 124 void RFID::clearBitMask(unsigned char reg, unsigned char mask)
iLyngklip 0:051708395e3c 125 {
iLyngklip 0:051708395e3c 126 unsigned char tmp;
iLyngklip 0:051708395e3c 127 tmp = readMFRC522(reg);
iLyngklip 0:051708395e3c 128 writeMFRC522(reg, tmp & (~mask)); // clear bit mask
iLyngklip 0:051708395e3c 129 }
iLyngklip 0:051708395e3c 130
iLyngklip 0:051708395e3c 131 void RFID::calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
iLyngklip 0:051708395e3c 132 {
iLyngklip 0:051708395e3c 133 unsigned char i, n;
iLyngklip 0:051708395e3c 134
iLyngklip 0:051708395e3c 135 clearBitMask(DivIrqReg, 0x04); //CRCIrq = 0
iLyngklip 0:051708395e3c 136 setBitMask(FIFOLevelReg, 0x80); //Claro puntero FIFO
iLyngklip 0:051708395e3c 137 //Write_MFRC522(CommandReg, PCD_IDLE);
iLyngklip 0:051708395e3c 138
iLyngklip 0:051708395e3c 139 //Escribir datos en el FIFO
iLyngklip 0:051708395e3c 140 for (i=0; i<len; i++)
iLyngklip 0:051708395e3c 141 {
iLyngklip 0:051708395e3c 142 writeMFRC522(FIFODataReg, *(pIndata+i));
iLyngklip 0:051708395e3c 143 }
iLyngklip 0:051708395e3c 144 writeMFRC522(CommandReg, PCD_CALCCRC);
iLyngklip 0:051708395e3c 145
iLyngklip 0:051708395e3c 146 // Esperar a la finalización de cálculo del CRC
iLyngklip 0:051708395e3c 147 i = 0xFF;
iLyngklip 0:051708395e3c 148 do
iLyngklip 0:051708395e3c 149 {
iLyngklip 0:051708395e3c 150 n = readMFRC522(DivIrqReg);
iLyngklip 0:051708395e3c 151 i--;
iLyngklip 0:051708395e3c 152 }
iLyngklip 0:051708395e3c 153 while ((i!=0) && !(n&0x04)); //CRCIrq = 1
iLyngklip 0:051708395e3c 154
iLyngklip 0:051708395e3c 155 //Lea el cálculo de CRC
iLyngklip 0:051708395e3c 156 pOutData[0] = readMFRC522(CRCResultRegL);
iLyngklip 0:051708395e3c 157 pOutData[1] = readMFRC522(CRCResultRegM);
iLyngklip 0:051708395e3c 158 }
iLyngklip 0:051708395e3c 159
iLyngklip 0:051708395e3c 160 unsigned char RFID::MFRC522ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen)
iLyngklip 0:051708395e3c 161 {
iLyngklip 0:051708395e3c 162 unsigned char status = MI_ERR;
iLyngklip 0:051708395e3c 163 unsigned char irqEn = 0x00;
iLyngklip 0:051708395e3c 164 unsigned char waitIRq = 0x00;
iLyngklip 0:051708395e3c 165 unsigned char lastBits;
iLyngklip 0:051708395e3c 166 unsigned char n;
iLyngklip 0:051708395e3c 167 unsigned int i;
iLyngklip 0:051708395e3c 168
iLyngklip 0:051708395e3c 169 switch (command)
iLyngklip 0:051708395e3c 170 {
iLyngklip 0:051708395e3c 171 case PCD_AUTHENT: // Tarjetas de certificación cerca
iLyngklip 0:051708395e3c 172 {
iLyngklip 0:051708395e3c 173 irqEn = 0x12;
iLyngklip 0:051708395e3c 174 waitIRq = 0x10;
iLyngklip 0:051708395e3c 175 break;
iLyngklip 0:051708395e3c 176 }
iLyngklip 0:051708395e3c 177 case PCD_TRANSCEIVE: //La transmisión de datos FIFO
iLyngklip 0:051708395e3c 178 {
iLyngklip 0:051708395e3c 179 irqEn = 0x77;
iLyngklip 0:051708395e3c 180 waitIRq = 0x30;
iLyngklip 0:051708395e3c 181 break;
iLyngklip 0:051708395e3c 182 }
iLyngklip 0:051708395e3c 183 default:
iLyngklip 0:051708395e3c 184 break;
iLyngklip 0:051708395e3c 185 }
iLyngklip 0:051708395e3c 186
iLyngklip 0:051708395e3c 187 writeMFRC522(CommIEnReg, irqEn|0x80); //De solicitud de interrupción
iLyngklip 0:051708395e3c 188 clearBitMask(CommIrqReg, 0x80); // Borrar todos los bits de petición de interrupción
iLyngklip 0:051708395e3c 189 setBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO de inicialización
iLyngklip 0:051708395e3c 190
iLyngklip 0:051708395e3c 191 writeMFRC522(CommandReg, PCD_IDLE); //NO action;Y cancelar el comando
iLyngklip 0:051708395e3c 192
iLyngklip 0:051708395e3c 193 //Escribir datos en el FIFO
iLyngklip 0:051708395e3c 194 for (i=0; i<sendLen; i++)
iLyngklip 0:051708395e3c 195 {
iLyngklip 0:051708395e3c 196 writeMFRC522(FIFODataReg, sendData[i]);
iLyngklip 0:051708395e3c 197 }
iLyngklip 0:051708395e3c 198
iLyngklip 0:051708395e3c 199 //???? ejecutar el comando
iLyngklip 0:051708395e3c 200 writeMFRC522(CommandReg, command);
iLyngklip 0:051708395e3c 201 if (command == PCD_TRANSCEIVE)
iLyngklip 0:051708395e3c 202 {
iLyngklip 0:051708395e3c 203 setBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts
iLyngklip 0:051708395e3c 204 }
iLyngklip 0:051708395e3c 205
iLyngklip 0:051708395e3c 206 // A la espera de recibir datos para completar
iLyngklip 0:051708395e3c 207 i = 2000; //i????????,??M1???????25ms ??? i De acuerdo con el ajuste de frecuencia de reloj, el tiempo máximo de espera operación M1 25ms tarjeta??
iLyngklip 0:051708395e3c 208 do
iLyngklip 0:051708395e3c 209 {
iLyngklip 0:051708395e3c 210 //CommIrqReg[7..0]
iLyngklip 0:051708395e3c 211 //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
iLyngklip 0:051708395e3c 212 n = readMFRC522(CommIrqReg);
iLyngklip 0:051708395e3c 213 i--;
iLyngklip 0:051708395e3c 214 }
iLyngklip 0:051708395e3c 215 while ((i!=0) && !(n&0x01) && !(n&waitIRq));
iLyngklip 0:051708395e3c 216
iLyngklip 0:051708395e3c 217 clearBitMask(BitFramingReg, 0x80); //StartSend=0
iLyngklip 0:051708395e3c 218
iLyngklip 0:051708395e3c 219 if (i != 0)
iLyngklip 0:051708395e3c 220 {
iLyngklip 0:051708395e3c 221 if(!(readMFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
iLyngklip 0:051708395e3c 222 {
iLyngklip 0:051708395e3c 223 status = MI_OK;
iLyngklip 0:051708395e3c 224 if (n & irqEn & 0x01)
iLyngklip 0:051708395e3c 225 {
iLyngklip 0:051708395e3c 226 status = MI_NOTAGERR; //??
iLyngklip 0:051708395e3c 227 }
iLyngklip 0:051708395e3c 228
iLyngklip 0:051708395e3c 229 if (command == PCD_TRANSCEIVE)
iLyngklip 0:051708395e3c 230 {
iLyngklip 0:051708395e3c 231 n = readMFRC522(FIFOLevelReg);
iLyngklip 0:051708395e3c 232 lastBits = readMFRC522(ControlReg) & 0x07;
iLyngklip 0:051708395e3c 233 if (lastBits)
iLyngklip 0:051708395e3c 234 {
iLyngklip 0:051708395e3c 235 *backLen = (n-1)*8 + lastBits;
iLyngklip 0:051708395e3c 236 }
iLyngklip 0:051708395e3c 237 else
iLyngklip 0:051708395e3c 238 {
iLyngklip 0:051708395e3c 239 *backLen = n*8;
iLyngklip 0:051708395e3c 240 }
iLyngklip 0:051708395e3c 241
iLyngklip 0:051708395e3c 242 if (n == 0)
iLyngklip 0:051708395e3c 243 {
iLyngklip 0:051708395e3c 244 n = 1;
iLyngklip 0:051708395e3c 245 }
iLyngklip 0:051708395e3c 246 if (n > MAX_LEN)
iLyngklip 0:051708395e3c 247 {
iLyngklip 0:051708395e3c 248 n = MAX_LEN;
iLyngklip 0:051708395e3c 249 }
iLyngklip 0:051708395e3c 250
iLyngklip 0:051708395e3c 251 //??FIFO??????? Lea los datos recibidos en el FIFO
iLyngklip 0:051708395e3c 252 for (i=0; i<n; i++)
iLyngklip 0:051708395e3c 253 {
iLyngklip 0:051708395e3c 254 backData[i] = readMFRC522(FIFODataReg);
iLyngklip 0:051708395e3c 255 }
iLyngklip 0:051708395e3c 256 }
iLyngklip 0:051708395e3c 257 }
iLyngklip 0:051708395e3c 258 else
iLyngklip 0:051708395e3c 259 {
iLyngklip 0:051708395e3c 260 status = MI_ERR;
iLyngklip 0:051708395e3c 261 }
iLyngklip 0:051708395e3c 262
iLyngklip 0:051708395e3c 263 }
iLyngklip 0:051708395e3c 264
iLyngklip 0:051708395e3c 265 //SetBitMask(ControlReg,0x80); //timer stops
iLyngklip 0:051708395e3c 266 //Write_MFRC522(CommandReg, PCD_IDLE);
iLyngklip 0:051708395e3c 267
iLyngklip 0:051708395e3c 268 return status;
iLyngklip 0:051708395e3c 269 }
iLyngklip 0:051708395e3c 270
iLyngklip 0:051708395e3c 271
iLyngklip 0:051708395e3c 272 /*
iLyngklip 0:051708395e3c 273 * Nombre de la función: MFRC522_Request
iLyngklip 0:051708395e3c 274 * Descripción: Buscar las cartas, leer el número de tipo de tarjeta
iLyngklip 0:051708395e3c 275 * Los parámetros de entrada: reqMode - encontrar el modo de tarjeta,
iLyngklip 0:051708395e3c 276 * Tagtype - Devuelve el tipo de tarjeta
iLyngklip 0:051708395e3c 277 * 0x4400 = Mifare_UltraLight
iLyngklip 0:051708395e3c 278 * 0x0400 = Mifare_One(S50)
iLyngklip 0:051708395e3c 279 * 0x0200 = Mifare_One(S70)
iLyngklip 0:051708395e3c 280 * 0x0800 = Mifare_Pro(X)
iLyngklip 0:051708395e3c 281 * 0x4403 = Mifare_DESFire
iLyngklip 0:051708395e3c 282 * Valor de retorno: el retorno exitoso MI_OK
iLyngklip 0:051708395e3c 283 */
iLyngklip 0:051708395e3c 284 unsigned char RFID::MFRC522Request(unsigned char reqMode, unsigned char *TagType)
iLyngklip 0:051708395e3c 285 {
iLyngklip 0:051708395e3c 286 unsigned char status;
iLyngklip 0:051708395e3c 287 unsigned int backBits; // Recibió bits de datos
iLyngklip 0:051708395e3c 288
iLyngklip 0:051708395e3c 289 writeMFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ???
iLyngklip 0:051708395e3c 290
iLyngklip 0:051708395e3c 291 TagType[0] = reqMode;
iLyngklip 0:051708395e3c 292 status = MFRC522ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
iLyngklip 0:051708395e3c 293
iLyngklip 0:051708395e3c 294 if ((status != MI_OK) || (backBits != 0x10))
iLyngklip 0:051708395e3c 295 {
iLyngklip 0:051708395e3c 296 status = MI_ERR;
iLyngklip 0:051708395e3c 297 }
iLyngklip 0:051708395e3c 298
iLyngklip 0:051708395e3c 299 return status;
iLyngklip 0:051708395e3c 300 }
iLyngklip 0:051708395e3c 301
iLyngklip 0:051708395e3c 302 /**
iLyngklip 0:051708395e3c 303 * MFRC522Anticoll -> anticoll
iLyngklip 0:051708395e3c 304 * Anti-detección de colisiones, la lectura del número de serie de la tarjeta de tarjeta
iLyngklip 0:051708395e3c 305 * @param serNum - devuelve el número de tarjeta 4 bytes de serie, los primeros 5 bytes de bytes de paridad
iLyngklip 0:051708395e3c 306 * @return retorno exitoso MI_OK
iLyngklip 0:051708395e3c 307 */
iLyngklip 0:051708395e3c 308 unsigned char RFID::anticoll(unsigned char *serNum)
iLyngklip 0:051708395e3c 309 {
iLyngklip 0:051708395e3c 310 unsigned char status;
iLyngklip 0:051708395e3c 311 unsigned char i;
iLyngklip 0:051708395e3c 312 unsigned char serNumCheck=0;
iLyngklip 0:051708395e3c 313 unsigned int unLen;
iLyngklip 0:051708395e3c 314
iLyngklip 0:051708395e3c 315
iLyngklip 0:051708395e3c 316 //ClearBitMask(Status2Reg, 0x08); //TempSensclear
iLyngklip 0:051708395e3c 317 //ClearBitMask(CollReg,0x80); //ValuesAfterColl
iLyngklip 0:051708395e3c 318 writeMFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
iLyngklip 0:051708395e3c 319
iLyngklip 0:051708395e3c 320 serNum[0] = PICC_ANTICOLL;
iLyngklip 0:051708395e3c 321 serNum[1] = 0x20;
iLyngklip 0:051708395e3c 322 status = MFRC522ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
iLyngklip 0:051708395e3c 323
iLyngklip 0:051708395e3c 324 if (status == MI_OK)
iLyngklip 0:051708395e3c 325 {
iLyngklip 0:051708395e3c 326 //?????? Compruebe el número de serie de la tarjeta
iLyngklip 0:051708395e3c 327 for (i=0; i<4; i++)
iLyngklip 0:051708395e3c 328 {
iLyngklip 0:051708395e3c 329 serNumCheck ^= serNum[i];
iLyngklip 0:051708395e3c 330 }
iLyngklip 0:051708395e3c 331 if (serNumCheck != serNum[i])
iLyngklip 0:051708395e3c 332 {
iLyngklip 0:051708395e3c 333 status = MI_ERR;
iLyngklip 0:051708395e3c 334 }
iLyngklip 0:051708395e3c 335 }
iLyngklip 0:051708395e3c 336
iLyngklip 0:051708395e3c 337 //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1
iLyngklip 0:051708395e3c 338
iLyngklip 0:051708395e3c 339 return status;
iLyngklip 0:051708395e3c 340 }
iLyngklip 0:051708395e3c 341
iLyngklip 0:051708395e3c 342