make "frametype" a parameter of transcieve functions
[librfid] / rfid_proto_tcl.c
1 /* ISO 14443-4 (T=CL) implementation, PCD side.
2  *
3  * (C) 2005 by Harald Welte <laforge@gnumonks.org>
4  *
5  */
6
7 /*
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 
10  *  as published by the Free Software Foundation
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include <rfid/rfid.h>
29 #include <rfid/rfid_protocol_tcl.h>
30 #include <rfid/rfid_protocol.h>
31 #include <rfid/rfid_layer2.h>
32 #include <rfid/rfid_layer2_iso14443b.h>
33
34 #include <rfid/rfid_asic.h>
35 #include <rfid/rfid_reader.h>
36
37 #include "rfid_iso14443_common.h"
38
39
40 static unsigned int sfgi_to_sfgt(struct rfid_protocol_handle *h, 
41                                  unsigned char sfgi)
42 {
43         unsigned int multiplier;
44         unsigned int tmp;
45
46         if (sfgi > 14)
47                 sfgi = 14;
48
49         multiplier = 1 << sfgi; /* 2 to the power of sfgi */
50
51         /* ISO 14443-4:2000(E) Section 5.2.5:
52          * (256 * 16 / h->l2h->rh->ah->fc) * (2 ^ sfgi) */
53         tmp = (unsigned int) 1000000 * 256 * 16;
54
55         return (tmp / h->l2h->rh->ah->fc) * multiplier;
56 }
57
58 static unsigned int fwi_to_fwt(struct rfid_protocol_handle *h, 
59                                 unsigned char fwi)
60 {
61         unsigned int multiplier, tmp;
62
63         if (fwi > 14)
64                 fwi = 14;
65
66         multiplier  = 1 << fwi; /* 2 to the power of fwi */
67
68         /* ISO 14443-4:2000(E) Section 7.2.:
69          * (256*16 / h->l2h->rh->ah->fc) * (2 ^ fwi) */
70
71         tmp = (unsigned int) 1000000 * 256 * 16;
72
73         return (tmp / h->l2h->rh->ah->fc) * multiplier;
74 }
75
76 /* 4.9seconds as microseconds (4.9 billion seconds) exceeds 2^32 */
77 #define activation_fwt(x) (((u_int64_t)1000000 * 65536 / x->l2h->rh->ah->fc))
78 #define deactivation_fwt(x) activation_fwt(x)
79
80 static int
81 tcl_parse_ats(struct rfid_protocol_handle *h, 
82                 unsigned char *ats, unsigned int size)
83 {
84         unsigned char len = ats[0];
85         unsigned char t0;
86         unsigned char *cur;
87
88         if (len == 0 || size == 0) 
89                 return -1;
90
91         if (size < len)
92                 len = size;
93
94         h->priv.tcl.ta = 0;
95
96         if (len == 1) {
97                 /* FIXME: assume some default values */
98                 h->priv.tcl.fsc = 32;
99                 h->priv.tcl.ta = 0x80;  /* 0x80 (same d for both dirs) */
100                 h->priv.tcl.sfgt = sfgi_to_sfgt(h, 0);
101                 if (h->l2h->l2->id == RFID_LAYER2_ISO14443A) {
102                         /* Section 7.2: fwi default for type A is 4 */
103                         h->priv.tcl.fwt = fwi_to_fwt(h, 4);
104                 } else {
105                         /* Section 7.2: fwi for type B is always in ATQB */
106                         /* Value is assigned in tcl_connect() */
107                         /* This function is never called for Type B, since it has no (R)ATS */
108                 }
109                 return 0;
110         }
111
112         /* guarateed to be at least 2 bytes in size */
113
114         t0 = ats[1];
115         cur = &ats[2];
116
117         iso14443_fsdi_to_fsd(&h->priv.tcl.fsc, t0 & 0x0f);
118
119         if (t0 & (1 << 4)) {
120                 /* TA is transmitted */
121                 h->priv.tcl.ta = *cur++;
122         }
123
124         if (t0 & (1 << 5)) {
125                 /* TB is transmitted */
126                 h->priv.tcl.sfgt = sfgi_to_sfgt(h, *cur & 0x0f);
127                 h->priv.tcl.fwt = fwi_to_fwt(h, (*cur & 0xf0) >> 4);
128                 cur++;
129         }
130
131         if (t0 & (1 << 6)) {
132                 /* TC is transmitted */
133                 if (*cur & 0x01)
134                         h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
135                 if (*cur & 0x02)
136                         h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
137                 cur++;
138         }
139
140         h->priv.tcl.historical_len = (ats+len) - cur;
141         h->priv.tcl.historical_bytes = cur;
142
143         return 0;
144 }
145
146
147 /* request an ATS from the PICC */
148 static int
149 tcl_request_ats(struct rfid_protocol_handle *h)
150 {
151         int ret;
152         unsigned char rats[2];
153         unsigned char fsdi;
154
155         if (h->priv.tcl.state != TCL_STATE_INITIAL)
156                 return -1;
157
158         ret = iso14443_fsd_to_fsdi(&fsdi, h->priv.tcl.fsd);
159         if (ret < 0) {
160                 DEBUGP("unable to encode FSD of %u as FSDI\n", h->priv.tcl.fsd);
161                 return ret;
162         }
163
164         rats[0] = 0xe0;
165         rats[1] = (h->priv.tcl.cid & 0x0f) | ((fsdi << 4) & 0xf0);
166
167         /* transcieve (with CRC) */
168         ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
169                                         rats, 2, h->priv.tcl.ats,
170                                        &h->priv.tcl.ats_len, activation_fwt(h),
171                                        TCL_TRANSP_F_TX_CRC);
172         if (ret < 0) {
173                 DEBUGP("transcieve of rats failed\n");
174                 h->priv.tcl.state = TCL_STATE_RATS_SENT;
175                 /* FIXME: retransmit */
176                 return ret;
177         }
178         h->priv.tcl.state = TCL_STATE_ATS_RCVD;
179
180         ret = tcl_parse_ats(h, h->priv.tcl.ats, h->priv.tcl.ats_len);
181         if (ret < 0) {
182                 DEBUGP("parsing of ats failed\n");
183                 return ret;
184         }
185
186         return 0;
187 }
188
189 #define ATS_TA_DIV_2    1
190 #define ATS_TA_DIV_4    2
191 #define ATS_TA_DIV_8    4
192
193 #define PPS_DIV_8       3
194 #define PPS_DIV_4       2
195 #define PPS_DIV_2       1
196 #define PPS_DIV_1       0
197 static unsigned char d_to_di(struct rfid_protocol_handle *h, unsigned char D)
198 {
199         static char DI;
200         unsigned int speed = h->l2h->rh->reader->iso14443a.speed;
201         
202         if ((D & ATS_TA_DIV_8) && (speed & RFID_READER_SPEED_848K))
203                 DI = PPS_DIV_8;
204         else if ((D & ATS_TA_DIV_4) && (speed & RFID_READER_SPEED_424K))
205                 DI = PPS_DIV_4;
206         else if ((D & ATS_TA_DIV_2) && (speed & RFID_READER_SPEED_212K))
207                 DI = PPS_DIV_2;
208         else
209                 DI = PPS_DIV_1;
210
211         return DI;
212 }
213
214
215 /* start a PSS run (autimatically configure highest possible speed */
216 static int 
217 tcl_do_pps(struct rfid_protocol_handle *h)
218 {
219 #if 0
220         int ret;
221         unsigned char ppss[3];
222         unsigned char pps_response[1];
223         unsigned int rx_len = 1;
224         unsigned char Dr, Ds, DrI, DsI;
225
226         if (h->priv.tcl.state != TCL_STATE_ATS_RCVD)
227                 return -1;
228
229         Dr = h->priv.tcl.ta & 0x07;
230         Ds = h->priv.tcl.ta & 0x70 >> 4;
231
232         if (Dr != Ds && !(h->priv.tcl.ta & 0x80)) {
233                 /* device supports different divisors for rx and tx, but not ?!? */
234                 DEBUGP("PICC has contradictory TA, aborting PPS\n");
235                 return -1;
236         };
237
238         /* ISO 14443-4:2000(E) Section 5.3. */
239
240         ppss[0] = 0xd0 & (h->priv.tcl.cid & 0x0f);
241         ppss[1] = 0x11;
242
243         /* FIXME: deal with different speed for each direction */
244         DrI = d_to_di(h, Dr);
245         DsI = d_to_di(h, Ds);
246
247         ppss[2] = (ppss[2] & 0xf0) | (DrI | DsI << 2);
248
249         ret = h->l2h->l2->fn.transcieve(h->l2h, ppss, 3, pps_response,
250                                         &rx_len, h->priv.tcl.fwt,
251                                         TCL_TRANSP_F_TX_CRC);
252         if (ret < 0)
253                 return ret;
254
255         if (pps_response[0] != ppss[0]) {
256                 DEBUGP("PPS Response != PPSS\n");
257                 return -1;
258         }
259         
260         h->priv.tcl.state = TCL_STATE_ESTABLISHED;
261 #endif
262         return 0;
263 }
264
265
266 static int
267 tcl_build_prologue2(struct tcl_handle *th, 
268                     unsigned char *prlg, unsigned int *prlg_len, 
269                     unsigned char pcb)
270 {
271         *prlg_len = 1;
272
273         *prlg = pcb;
274
275         if (th->toggle) {
276                 /* we've sent a toggle bit last time */
277                 th->toggle = 0;
278         } else {
279                 /* we've not sent a toggle last time: send one */
280                 th->toggle = 1;
281                 *prlg |= 0x01;
282         }
283
284         if (th->flags & TCL_HANDLE_F_CID_USED) {
285                 /* ISO 14443-4:2000(E) Section 7.1.1.2 */
286                 *prlg |= TCL_PCB_CID_FOLLOWING;
287                 (*prlg_len)++;
288                 prlg[*prlg_len] = th->cid & 0x0f;
289         }
290
291         /* nad only for I-block (0xc0 == 00) */
292         if ((th->flags & TCL_HANDLE_F_NAD_USED) &&
293             ((pcb & 0xc0) == 0x00)) {
294                 /* ISO 14443-4:2000(E) Section 7.1.1.3 */
295                 /* FIXME: in case of chaining only for first frame */
296                 *prlg |= TCL_PCB_NAD_FOLLOWING;
297                 prlg[*prlg_len] = th->nad;
298                 (*prlg_len)++;
299         }
300
301         return 0;
302 }
303
304 static int
305 tcl_build_prologue_i(struct tcl_handle *th,
306                      unsigned char *prlg, unsigned int *prlg_len)
307 {
308         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
309         return tcl_build_prologue2(th, prlg, prlg_len, 0x02);
310 }
311
312 static int
313 tcl_build_prologue_r(struct tcl_handle *th,
314                      unsigned char *prlg, unsigned int *prlg_len,
315                      unsigned int nak)
316 {
317         unsigned char pcb = 0xa2;
318         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
319
320         if (nak)
321                 pcb |= 0x10;
322
323         return tcl_build_prologue2(th, prlg, prlg_len, pcb);
324 }
325
326 static int
327 tcl_build_prologue_s(struct tcl_handle *th,
328                      unsigned char *prlg, unsigned int *prlg_len)
329 {
330         /* ISO 14443-4:2000(E) Section 7.1.1.1 */
331
332         /* the only S-block from PCD->PICC is DESELECT,
333          * well, actually there is the S(WTX) response. */
334         return tcl_build_prologue2(th, prlg, prlg_len, 0xc2);
335 }
336
337 /* FIXME: WTXM implementation */
338
339 static int tcl_prlg_len(struct tcl_handle *th)
340 {
341         int prlg_len = 1;
342
343         if (th->flags & TCL_HANDLE_F_CID_USED)
344                 prlg_len++;
345
346         if (th->flags & TCL_HANDLE_F_NAD_USED)
347                 prlg_len++;
348
349         return prlg_len;
350 }
351
352 #define max_net_tx_framesize(x) (x->fsc - tcl_prlg_len(x))
353
354 static int
355 tcl_connect(struct rfid_protocol_handle *h)
356 {
357         int ret; 
358
359         if (h->priv.tcl.state != TCL_STATE_DESELECTED &&
360             h->priv.tcl.state != TCL_STATE_INITIAL)
361                 return -1;
362
363         switch (h->l2h->l2->id) {
364         case RFID_LAYER2_ISO14443A:
365                 /* Start Type A T=CL Activation Sequence */
366                 ret = tcl_request_ats(h);
367                 if (ret < 0)
368                         return ret;
369
370                 /* Only do PPS if any non-default divisors supported */
371                 if (h->priv.tcl.ta & 0x77) {
372                         ret = tcl_do_pps(h);
373                         if (ret < 0)
374                                 return ret;
375                 }
376                 break;
377         case RFID_LAYER2_ISO14443B:
378                 /* initialized T=CL state from Type B Activation Data */
379                 h->priv.tcl.cid = h->l2h->priv.iso14443b.cid;
380                 h->priv.tcl.fsc = h->l2h->priv.iso14443b.fsc;
381                 h->priv.tcl.fsd = h->l2h->priv.iso14443b.fsd;
382                 h->priv.tcl.fwt = h->l2h->priv.iso14443b.fwt;
383
384                 /* what about ta? sfgt? */
385
386                 if (h->l2h->priv.iso14443b.flags & ISO14443B_CID_SUPPORTED)
387                         h->priv.tcl.flags |= TCL_HANDLE_F_CID_SUPPORTED;
388                 if (h->l2h->priv.iso14443b.flags & ISO14443B_NAD_SUPPORTED)
389                         h->priv.tcl.flags |= TCL_HANDLE_F_NAD_SUPPORTED;
390
391                 switch (h->l2h->priv.iso14443b.state) {
392                         case ISO14443B_STATE_SELECTED:
393                                 h->priv.tcl.state = TCL_STATE_ATS_RCVD;
394                                 break;
395                         case ISO14443B_STATE_ATTRIB_SENT:
396                                 h->priv.tcl.state = TCL_STATE_RATS_SENT;
397                                 break;
398                 }
399
400                 /* PUPI will be presented as ATS/historical bytes */
401                 memcpy(h->priv.tcl.ats, h->l2h->uid, 4);
402                 h->priv.tcl.ats_len = 4;
403                 h->priv.tcl.historical_bytes = h->priv.tcl.ats;
404
405                 break;
406         default:
407                 DEBUGP("unsupported l2: %u\n", h->l2h->l2->id);
408                 return -1;
409                 break;
410         }
411
412         return 0;
413 }
414
415 static int
416 tcl_deselect(struct rfid_protocol_handle *h)
417 {
418         /* ISO 14443-4:2000(E) Section 8 */
419         int ret;
420         unsigned char frame[3];         /* 3 bytes prologue, no information */
421         unsigned char rx[3];
422         unsigned int rx_len = sizeof(rx);
423         unsigned int prlg_len;
424         struct tcl_handle *th = &h->priv.tcl;
425
426         if (th->state != TCL_STATE_ESTABLISHED) {
427                 /* FIXME: not sure whether deselect is possible here,
428                  * probably better send a HLTA? */
429         }
430
431         /* build DESELECT S-block */
432         ret = tcl_build_prologue_s(th, frame, &prlg_len);
433         if (ret < 0)
434                 return ret;
435
436         ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
437                                         frame, prlg_len, rx,
438                                      &rx_len, deactivation_fwt(h),
439                                      TCL_TRANSP_F_TX_CRC);
440         if (ret < 0) {
441                 /* FIXME: retransmit, HLT(A|B) */
442                 return ret;
443         }
444
445         th->state = TCL_STATE_DESELECTED;
446
447         return 0;
448 }
449
450 #define is_s_block(x) ((x & 0xc0) == 0xc0)
451 #define is_r_block(x) ((x & 0xc0) == 0x80)
452 #define is_i_block(x) ((x & 0xc0) == 0x00)
453
454 static int
455 tcl_transcieve(struct rfid_protocol_handle *h,
456                 const unsigned char *tx_data, unsigned int tx_len,
457                 unsigned char *rx_data, unsigned int *rx_len,
458                 unsigned int timeout, unsigned int flags)
459 {
460         int ret;
461         unsigned char *tx_buf, *rx_buf;
462         unsigned int prlg_len;
463         struct tcl_handle *th = &h->priv.tcl;
464
465         unsigned char *_tx;
466         unsigned int _tx_len, _timeout;
467         unsigned char wtx_resp[3];
468         unsigned char ack[10];
469         unsigned int ack_len;
470
471         if (tx_len > max_net_tx_framesize(th)) {
472                 /* slow path: we need to use chaining */
473                 return -1;
474         }
475
476         tx_buf = malloc(tcl_prlg_len(th) + tx_len);
477         if (!tx_buf) {
478                 ret = -ENOMEM;
479                 goto out;
480         }
481         rx_buf = malloc(tcl_prlg_len(th) + *rx_len);
482         if (!rx_buf) {
483                 ret = -ENOMEM;
484                 goto out_txb;
485         }
486
487         if (tcl_build_prologue_i(th, tx_buf, &prlg_len) < 0) {
488                 ret = -1;
489                 goto out_rxb;
490         }
491         memcpy(tx_buf + prlg_len, tx_data, tx_len);
492
493         /* intialize to data-to-be-transferred */
494         _tx = tx_buf;
495         _tx_len = tx_len+prlg_len;
496         _timeout = th->fwt;
497
498 do_tx:
499         ret = h->l2h->l2->fn.transcieve(h->l2h, RFID_14443A_FRAME_REGULAR,
500                                         _tx, _tx_len,
501                                         rx_buf, rx_len, _timeout, 0);
502         DEBUGP("l2 transcieve finished\n");
503         if (ret < 0)
504                 goto out_rxb;
505
506         if ((*rx_buf & 0x01) != h->priv.tcl.toggle) {
507                 DEBUGP("response with wrong toggle bit\n");
508                 goto out_rxb;
509         }
510
511         if (is_r_block(*rx_buf)) {
512                 unsigned int txed = _tx - tx_buf;
513                 DEBUGP("R-Block\n");
514                 /* Handle ACK frame in case of chaining */
515                 if (*rx_buf & TCL_PCB_CID_FOLLOWING) {
516                         if (*(rx_buf+1) != h->priv.tcl.cid) {
517                                 DEBUGP("CID %u is not valid\n", *(rx_buf)+1);
518                                 goto out_rxb;
519                         }
520                 }
521                 /* set up parameters for next frame in chain */
522                 if (txed < tx_len) {
523                         /* move tx pointer by the amount of bytes transferred
524                          * in last frame */
525                         _tx += _tx_len;
526                         _tx_len = (tx_len - txed);
527                         if (_tx_len > max_net_tx_framesize(th)) {
528                                 /* not last frame in chain */
529                                 _tx_len = max_net_tx_framesize(th);
530                         } else {
531                                 /* last frame in chain */
532                         }
533                         goto do_tx;
534                 } else {
535                         DEBUGP("Received ACK in response to last frame in "
536                                "chain?!? Expected I-frame.\n");
537                         ret = -1;
538                         goto out_rxb;
539                 }
540         } else if (is_s_block(*rx_buf)) {
541                 unsigned char inf;
542                 unsigned int prlg_len;
543
544                 DEBUGP("S-Block\n");
545                 /* Handle Wait Time Extension */
546                 if (*rx_buf & TCL_PCB_CID_FOLLOWING) {
547                         if (*rx_len < 3) {
548                                 DEBUGP("S-Block with CID but short len\n");
549                                 ret = -1;
550                                 goto out_rxb;
551                         }
552                         if (*(rx_buf+1) != h->priv.tcl.cid) {
553                                 DEBUGP("CID %u is not valid\n", *(rx_buf)+1);
554                                 goto out_rxb;
555                         }
556                         inf = *(rx_buf+2);
557                 } else
558                         inf = *(rx_buf+1);
559
560                 if ((*rx_buf & 0x30) != 0x30) {
561                         DEBUGP("S-Block but not WTX?\n");
562                         ret = -1;
563                         goto out_rxb;
564                 }
565                 inf &= 0x3f;    /* only lower 6 bits code WTXM */
566                 if (inf == 0 || (inf >= 60 && inf <= 63)) {
567                         DEBUGP("WTXM %u is RFU!\n", inf);
568                         ret = -1;
569                         goto out_rxb;
570                 }
571                 
572                 /* Acknowledge WTXM */
573                 tcl_build_prologue_s(&h->priv.tcl, wtx_resp, &prlg_len);
574                 /* set two bits that make this block a wtx */
575                 wtx_resp[0] |= 0x30;
576                 wtx_resp[prlg_len] = inf;
577                 _tx = wtx_resp;
578                 _tx_len = prlg_len+1;
579                 _timeout = th->fwt * inf;
580
581                 /* start over with next transcieve */
582                 goto do_tx; /* FIXME: do transcieve locally since we use
583                                 totally different buffer */
584
585         } else if (is_i_block(*rx_buf)) {
586                 unsigned char *inf = rx_buf+1;
587                 /* we're actually receiving payload data */
588
589                 DEBUGP("I-Block\n");
590                 if (*rx_buf & TCL_PCB_CID_FOLLOWING) {
591                         if (*(rx_buf+1) != h->priv.tcl.cid) {
592                                 DEBUGP("CID %u is not valid\n", *(rx_buf)+1);
593                                 goto out_rxb;
594                         }
595                         inf++;
596                 }
597                 if (*rx_buf & TCL_PCB_NAD_FOLLOWING) {
598                         inf++;
599                 }
600                 memcpy(rx_data, inf, *rx_len - (inf - rx_buf));
601
602                 if (*rx_buf & 0x10) {
603                         /* we're not the last frame in the chain, continue rx */
604                         DEBUGP("we're not the last frame in the chain, continue\n");
605                         ack_len = sizeof(ack);
606                         tcl_build_prologue_r(&h->priv.tcl, ack, &ack_len, 0);
607                         _tx = ack;
608                         _tx_len = ack_len;
609                         goto do_tx;
610                 }
611         }
612
613 out_rxb:
614         free(rx_buf);
615 out_txb:
616         free(tx_buf);
617 out:
618         return ret;
619 }
620
621 #if 0
622 int
623 tcl_send(struct tcl_handle *th)
624 {
625         return -1;
626 }
627
628 int
629 tcl_recv()
630 {
631         return -1;
632 }
633 #endif
634
635 static struct rfid_protocol_handle *
636 tcl_init(struct rfid_layer2_handle *l2h)
637 {
638         struct rfid_protocol_handle *th;
639         unsigned int mru = l2h->rh->ah->mru;
640
641         th = malloc(sizeof(struct rfid_protocol_handle) + mru);
642         if (!th)
643                 return NULL;
644
645         /* FIXME: mru should be attribute of layer2 (in case it adds/removes
646          * some overhead */
647         memset(th, 0, sizeof(struct rfid_protocol_handle) + mru);
648
649         /* maximum received ats length equals mru of asic/reader */
650         th->priv.tcl.state = TCL_STATE_INITIAL;
651         th->priv.tcl.ats_len = mru;
652         th->priv.tcl.toggle = 1;
653
654         th->priv.tcl.fsd = iso14443_fsd_approx(mru);
655
656         return th;
657 }
658
659 static int
660 tcl_fini(struct rfid_protocol_handle *ph)
661 {
662         free(ph);
663         return 0;
664 }
665
666 struct rfid_protocol rfid_protocol_tcl = {
667         .id     = RFID_PROTOCOL_TCL,
668         .name   = "ISO 14443-4 / T=CL",
669         .fn     = {
670                 .init = &tcl_init,
671                 .open = &tcl_connect,
672                 .transcieve = &tcl_transcieve,
673                 .close = &tcl_deselect,
674                 .fini = &tcl_fini,
675         },
676 };