Fun 0.41.5
The programming language that makes You have fun
Loading...
Searching...
No Matches
transmit.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
19
31
32/* PCSC transmit */
34#ifdef FUN_WITH_PCSC
35 /* pops apdu array, handle_id */
36 Value vapdu = pop_value(vm);
37 Value vh = pop_value(vm);
38 int hid = (int)vh.i;
40 pcsc_card_entry *ce = pcsc_get_card(hid);
41
43 map_set(&m, "data", make_array_from_values(NULL, 0));
44 map_set(&m, "sw1", make_int(-1));
45 map_set(&m, "sw2", make_int(-1));
46 map_set(&m, "code", make_int(-1));
47
48 if (!ce || vapdu.type != VAL_ARRAY) {
49 free_value(vapdu);
50 push_value(vm, m);
51 break;
52 }
53 int n = array_length(&vapdu);
54 if (n < 0) n = 0;
55 unsigned char sbuf[4096];
56 if (n > (int)sizeof(sbuf)) n = (int)sizeof(sbuf);
57 for (int i = 0; i < n; ++i) {
58 Value tmp;
59 if (array_get_copy(&vapdu, i, &tmp)) {
60 int64_t v = tmp.type == VAL_INT ? tmp.i : 0;
61 sbuf[i] = (unsigned char)(v & 0xFF);
62 free_value(tmp);
63 } else {
64 sbuf[i] = 0;
65 }
66 }
67 free_value(vapdu);
68
69 SCARD_IO_REQUEST pio;
70 if (ce->proto == SCARD_PROTOCOL_T0)
71 pio = *SCARD_PCI_T0;
72 else if (ce->proto == SCARD_PROTOCOL_T1)
73 pio = *SCARD_PCI_T1;
74 else {
75 pio = *SCARD_PCI_T1;
76 }
77
78 unsigned char rbuf[4096];
79 DWORD rlen = sizeof(rbuf);
80 LONG rv = SCardTransmit(ce->h, &pio, sbuf, (DWORD)n, NULL, rbuf, &rlen);
81
82 int sw1 = -1, sw2 = -1;
83 int datalen = 0;
84 if (rv == SCARD_S_SUCCESS && rlen >= 2) {
85 sw1 = rbuf[rlen - 2];
86 sw2 = rbuf[rlen - 1];
87 datalen = (int)rlen - 2;
88 }
89
90 map_set(&m, "sw1", make_int(sw1));
91 map_set(&m, "sw2", make_int(sw2));
92 map_set(&m, "code", make_int((int)rv));
93
94 if (datalen > 0) {
95 Value *vals = (Value *)malloc(sizeof(Value) * (size_t)datalen);
96 if (!vals) {
97 map_set(&m, "data", make_array_from_values(NULL, 0));
98 } else {
99 for (int i = 0; i < datalen; ++i)
100 vals[i] = make_int((int64_t)rbuf[i]);
102 for (int i = 0; i < datalen; ++i)
103 free_value(vals[i]);
104 free(vals);
105 map_set(&m, "data", arr);
106 }
107 }
108
109 push_value(vm, m);
110#else
111 Value vapdu = pop_value(vm);
112 free_value(vapdu);
113 Value vh = pop_value(vm);
116 map_set(&m, "data", make_array_from_values(NULL, 0));
117 map_set(&m, "sw1", make_int(-1));
118 map_set(&m, "sw2", make_int(-1));
119 map_set(&m, "code", make_int(-2));
121#endif
122 break;
123}
@ OP_PCSC_TRANSMIT
Definition bytecode.h:189
Value v
Definition cast.c:22
array_clear & arr
Definition clear.c:38
Value m
Definition has_key.c:27
int n
Definition insert.c:41
Value * vals
Definition make_array.c:39
free(vals)
int map_set(Value *vm, const char *key, Value v)
Insert or replace a key in the map.
Definition map.c:79
Value make_map_empty(void)
Construct a new empty map Value.
Definition map.c:35
Tagged union representing a Fun value.
Definition value.h:68
int64_t i
Definition value.h:71
ValueType type
Definition value.h:69
Value vh
Definition stubs.c:44
push_value(vm, m)
free_value(vapdu)
int array_length(const Value *v)
Get the element count of an array Value.
Definition value.c:176
int array_get_copy(const Value *v, int index, Value *out)
Copy an array element into out.
Definition value.c:192
Value make_int(int64_t v)
Construct a Value representing a 64-bit integer.
Definition value.c:51
Value make_array_from_values(const Value *vals, int count)
Create an array Value by copying items from an input span.
Definition value.c:142
@ VAL_ARRAY
Definition value.h:55
@ VAL_INT
Definition value.h:51