static unsigned int t1_build(t1_state_t * t1, unsigned char *block, unsigned char dad, unsigned char pcb, ct_buf_t * bp, size_t * lenp) { unsigned int len; len = bp ? ct_buf_avail(bp) : 0; if (len > t1->ifsc) { pcb |= T1_MORE_BLOCKS; len = t1->ifsc; } /* Add the sequence number */ switch (t1_block_type(pcb)) { case T1_R_BLOCK: pcb |= t1->nr << T1_R_SEQ_SHIFT; break; case T1_I_BLOCK: pcb |= t1->ns << T1_I_SEQ_SHIFT; break; } block[0] = dad; block[1] = pcb; block[2] = len; if (len) memcpy(block + 3, ct_buf_head(bp), len); if (lenp) *lenp = len; return t1_compute_checksum(t1, block, len + 3); }
/* * Eat initial white space from buffer */ static int skipws(void) { unsigned int m, n, in_comment = 0; char *s; again: s = (char *)ct_buf_head(&config_buf); n = ct_buf_avail(&config_buf); for (m = 0; m < n; m++, s++) { if (*s == '#') { in_comment = 1; } else if (!in_comment && !isspace((int)*s)) { break; } else if (*s == '\n') { config_line++; in_comment = 0; } } ct_buf_get(&config_buf, NULL, m); if (in_comment) { if (ct_buf_read(&config_buf, config_fd) < 0) { ct_error("%s: error while reading file: %m", config_filename); return -1; } goto again; } return 0; }
static int do_transact_old(ifd_reader_t * reader, int unit, ct_buf_t * args, ct_buf_t * resp) { int rc; rc = ifd_card_command(reader, unit, ct_buf_head(args), ct_buf_avail(args), ct_buf_tail(resp), ct_buf_tailroom(resp)); if (rc < 0) return rc; ct_buf_put(resp, NULL, rc); return 0; }
static int t0_send(ifd_protocol_t * prot, ct_buf_t * bp, int count) { int n, avail; avail = ct_buf_avail(bp); if (count < 0) count = avail; if (count > avail || !avail) return -1; n = ifd_send_command(prot, ct_buf_head(bp), count); if (n >= 0) ct_buf_get(bp, NULL, count); return n; }
/* * Tokenizer */ static int get_token(char **tok) { static char buffer[512]; unsigned int m, n, copy, retry = 1; char *s; /* consume initial white space */ if (skipws() < 0) return -1; again: s = (char *)ct_buf_head(&config_buf); n = ct_buf_avail(&config_buf); if (n && issepa(*s)) { m = 1; } else { for (m = 0; !isspace((int)s[m]) && !issepa(s[m]) && m < n; m++) ; } /* If we hit the end of the buffer while scanning * for white space, read more data and try * again */ if (m >= n && retry) { if (ct_buf_read(&config_buf, config_fd) < 0) { ct_error("%s: error while reading file: %m", config_filename); return -1; } retry = 0; goto again; } if (m == 0) return -1; if ((copy = m) >= sizeof(buffer)) copy = sizeof(buffer) - 1; memcpy(buffer, s, copy); buffer[copy] = '\0'; ct_buf_get(&config_buf, NULL, m); ifd_debug(5, "ifd_config_parse: token=\"%s\"", buffer); *tok = buffer; return 0; }
unsigned int t1_build(t1_state_t * t1, unsigned char *block, unsigned char dad, unsigned char pcb, ct_buf_t *bp, size_t *lenp) { unsigned int len; char more = FALSE; len = bp ? ct_buf_avail(bp) : 0; if (len > t1->ifsc) { pcb |= T1_MORE_BLOCKS; len = t1->ifsc; more = TRUE; } /* Add the sequence number */ switch (t1_block_type(pcb)) { case T1_R_BLOCK: pcb |= t1->nr << T1_R_SEQ_SHIFT; break; case T1_I_BLOCK: pcb |= t1->ns << T1_I_SEQ_SHIFT; t1->more = more; DEBUG_COMM2("more bit: %d", more); break; } block[0] = dad; block[1] = pcb; block[2] = len; if (len) memcpy(block + 3, ct_buf_head(bp), len); if (lenp) *lenp = len; len = t1_compute_checksum(t1, block, len + 3); /* memorize the last sent block */ /* only 4 bytes since we are only interesed in R-blocks */ memcpy(t1->previous_block, block, 4); return len; }
/* * Parse TLV data */ int ct_tlv_parse(ct_tlv_parser_t * parser, ct_buf_t * bp) { unsigned int avail, len; unsigned char *p, tag; /* Code below relies on it */ assert(((ifd_tag_t) - 1) == 255); while ((avail = ct_buf_avail(bp)) != 0) { unsigned int header = 2; if (avail < 2) return -1; p = (unsigned char *)ct_buf_head(bp); tag = p[0]; len = p[1]; if (tag & __CT_TAG_LARGE) { parser->use_large_tags = 1; tag &= ~__CT_TAG_LARGE; if (avail < 3) return -1; len = (len << 8) | p[header++]; } if (len == 0 || header + len > avail) return -1; parser->val[tag] = p + header; parser->len[tag] = len; ct_buf_get(bp, NULL, header + len); } return 0; }
/* * Process commands from local clients (i.e. those allowed * to claim a device). */ static int ria_svc_app_handler(ct_socket_t * sock, header_t * hdr, ct_buf_t * args, ct_buf_t * resp) { unsigned char cmd; ria_peer_t *clnt, *peer; int rc; clnt = (ria_peer_t *) sock->user_data; ria_print_packet(sock, 2, "app >>", hdr, args); if (ct_buf_get(args, &cmd, 1) < 0) return IFD_ERROR_INVALID_MSG; switch (cmd) { case RIA_MGR_LIST: peer = &clients; ifd_debug(1, "%s requests a device listing", clnt->device.address); while ((peer = peer->next) != &clients) { if (peer->device.name[0] != '\0') ct_buf_put(resp, &peer->device, sizeof(peer->device)); } return 0; case RIA_MGR_INFO: peer = ria_find_device((const char *)ct_buf_head(args), ct_buf_avail(args)); if (peer == NULL) return IFD_ERROR_UNKNOWN_DEVICE; ct_buf_put(resp, &peer->device, sizeof(peer->device)); return 0; case RIA_MGR_CLAIM: peer = ria_find_device((const char *)ct_buf_head(args), ct_buf_avail(args)); if (peer == NULL) return IFD_ERROR_UNKNOWN_DEVICE; if (peer->peer) return IFD_ERROR_DEVICE_BUSY; ifd_debug(1, "%s claimed %s device %s/%s", clnt->device.address, peer->device.type, peer->device.address, peer->device.name); ct_buf_put(resp, &peer->device, sizeof(peer->device)); clnt->peer = peer; peer->peer = clnt; return 0; } if (cmd < __RIA_PEER_CMD_BASE) return IFD_ERROR_INVALID_CMD; /* All subsequent commands require a device */ if ((peer = clnt->peer) == NULL) return IFD_ERROR_NOT_CONNECTED; /* Push back the command byte */ ct_buf_push(args, &cmd, 1); rc = ct_socket_put_packet(peer->sock, hdr, args); /* Tell the caller not to send a response */ hdr->xid = 0; return rc; }