int main(int argc, char *argv[]) { comedi_cmd cmd; int i; struct parsed_options options; init_parsed_options(&options); parse_options(&options, argc, argv); device = comedi_open(options.filename); if(!device){ perror(options.filename); exit(1); } fcntl(comedi_fileno(device), F_SETFL, O_NONBLOCK); for(i = 0; i < n_chans; i++){ chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref); } prepare_cmd(device, &cmd, options.subdevice); do_cmd(device, &cmd); return 0; }
/* CMD : POWER RESET */ static int card_power_rst(int CARD) { int ret; struct card_send_buf *send_buf; struct card_res_buf *res_buf; send_buf = prepare_cmd(CARD, CARD_RST_CMD, 0, NULL); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; if (res_buf->res_buf.data[0] != 0x3B && res_buf->res_buf.data[1] != 0x7A) return -ETAX_BAD_SW; return SUCCESS; }
static int do_cmd(lua_State *L, buffer *b, int narg, enum cmd c) { int pos; switch (c) { case cmd_append: pos = b->len; break; case cmd_insert: case cmd_set: pos = real_offset(luaL_checkint(L, narg++), b->len); break; default: pos = 0; break; } if (lb_isbufferorstring(L, narg)) { size_t len; const char *str = lb_tolstring(L, narg, &len); size_t i = real_range(L, narg+1, &len); if (prepare_cmd(L, b, c, pos, len)) memcpy(&b->str[pos], &str[i], len); } else if (lua_type(L, narg) == LUA_TNUMBER) { size_t fill_len = lua_tointeger(L, narg); size_t len = 0; const char *str = NULL; if (!lua_isnoneornil(L, narg+1)) { if ((str = lb_tolstring(L, narg+1, &len)) != NULL) str += real_range(L, narg+2, &len); else if ((str = udtolstring(L, narg+1, &len)) == NULL) luaL_typerror(L, narg+1, "string, buffer or userdata"); } if (prepare_cmd(L, b, c, pos, fill_len)) fill_str(b, pos, fill_len, str, len); } else if (lua_isuserdata(L, narg)) { size_t len = 0; const char *str = udtolstring(L, narg, &len); if (prepare_cmd(L, b, c, pos, len)) memcpy(&b->str[pos], str, len); } else if (!lua_isnoneornil(L, narg)) luaL_typerror(L, narg, "string, buffer, number or userdata"); lua_settop(L, narg-1); return 1; }
/* * CMD : ISSUE INVOICE * -- This is a specical command for fiscal card */ static int card_issue_invoice(struct issue_invoice *info, struct issue_invoice_res * res) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF2; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x2C; memcpy(cmd_buf.cond_body + 1, (uchar *)info, sizeof(*info)); cmd_buf.cond_body[0x2C + 1] = 0x08; cmd_size = 6 + sizeof(*info); send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 61 6A 93 * SW2 08 82 03 */ if (res_buf->res_buf.sw1 != 0x61 && res_buf->res_buf.sw2 != 0x08) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; if (res_buf->res_buf.sw1 == 0x93 && res_buf->res_buf.sw2 == 0x03) return -ETAX_FC_PIN_LOCK; if (res_buf->res_buf.sw1 == 0x94 && res_buf->res_buf.sw2 == 0x01) return -ETAX_MON_OUT_RANG; return -ETAX_BAD_SW; } /* save respon data */ int i; for (i = 0; i < 8; i++) { res->half_top[i] = res_buf->res_buf.data[i]; // Be careful with this code } return SUCCESS; }
/* * CMD : TERMINAL REGISTER * -- This is a specical command for fiscal card */ static int card_terminal_register(struct register_info * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF1; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x04; memcpy(cmd_buf.cond_body + 1, info->mac2, 4); cmd_buf.cond_body[5] = 0x08; cmd_size = 10; send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 6A 93 * SW2 00 82 03 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; if (res_buf->res_buf.sw1 == 0x93 && res_buf->res_buf.sw2 == 0x03) return -ETAX_FC_PIN_LOCK; return -ETAX_BAD_SW; } /* Save user password*/ int i; for (i = 0; i < 8; i++) { info->pin[i] = res_buf->res_buf.data[i]; } return SUCCESS; }
/* * CMD : READ_BINARY * Notice this: * -- Read Binnary in GB can select file by short file ID with P1 set as 0x8x; * but we were not going to support this function. * So, whenever you want to use this function, plz select the file you want * to read before invoke it. * */ static int card_read_binary(int CARD, int offset, int size, uchar *res) { int ret; int cmd_size; assert(res_buf != NULL); struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; /* We were not intend to support select file by short file ID */ /* reand current file */ cmd_buf.CLA = 0x00; cmd_buf.INS = 0xB0; offset &= 0xFFFF; cmd_buf.P1 = (uchar)(offset >> 8); cmd_buf.P2 = (uchar)offset; cmd_buf.cond_body[0] = (uchar)size; cmd_size = 5; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 * SW2 00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; return -ETAX_BAD_SW; } /* copy data to recive buffer */ memcpy(res_buf, res_buf->res_buf.data, size); return SUCCESS; }
/* * CMD : GET_REGISTER_NB * -- This is a specical command for fiscal card */ static int card_get_register_nb(struct register_info * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF0; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x10; cmd_size = 5; send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 6A 93 * SW2 00 82 03 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; if (res_buf->res_buf.sw1 == 0x93 && res_buf->res_buf.sw2 == 0x03) return -ETAX_FC_PIN_LOCK; return -ETAX_BAD_SW; } memcpy(info->random, res_buf->res_buf.data, 4); memcpy(info->card_nb, res_buf->res_buf.data + 4, 8); memcpy(info->mac1, res_buf->res_buf.data + 12, 4); return SUCCESS; }
/* * CMD : VERIFY_FISCAL_PIN * -- This is special command fur fiscal card */ static int card_verify_fiscal_pin(uchar *old_pin, uchar * new_pin) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF9; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x08; memcpy(cmd_buf.cond_body + 1, old_pin, 8); cmd_buf.cond_body[0x08 + 1] = 0x8E; cmd_size = 6 + 0x08; send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 69 * SW2 00 83 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x69 && res_buf->res_buf.sw2 == 0x83) return -ETAX_FC_PIN_LOCK; else return -ETAX_BAD_SW; } /* save new pin*/ int i; for (i = 0; i < 8; i++) new_pin[i] = res_buf->res_buf.data[i]; return SUCCESS; }
/* CMD : SELECT FILE */ static int card_select_file_by_df(int CARD, const char *file_name) { int ret; int cmd_size; if (!file_name) return -ETAX_WR_FILENAME; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0x00; cmd_buf.INS = 0xA4; cmd_buf.P1 = 0x04; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = strlen(file_name); memcpy(cmd_buf.cond_body + 1, file_name, cmd_buf.cond_body[0]); cmd_size = cmd_buf.cond_body[0] + 5; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 : 90 6A 6A 6A * SW2 : 00 81 82 86 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x81) return -ETAX_CARD_PIN_LOCK; if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; return -ETAX_BAD_SW; } return SUCCESS; }
STATIC EFI_STATUS EFIAPI SasV1ExtScsiPassThruFunction ( IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This, IN UINT8 *Target, IN UINT64 Lun, IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet, IN EFI_EVENT Event OPTIONAL ) { SAS_V1_INFO *SasV1Info = SAS_FROM_PASS_THRU(This); struct hisi_hba *hba = SasV1Info->hba; return prepare_cmd(hba, Packet); }
/* * CMD : DISTRIBUTE_INVOICE_NB * -- This is a special command for user card */ static int card_distribute_invoice_nb(struct invoice_roll_info * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xE9; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x00; cmd_buf.cond_body[1] = 0x16; cmd_size = 6; send_buf = prepare_cmd(USER_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 0x90 * SW2 0x00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x94 && res_buf->res_buf.sw2 != 0x01) return -ETAX_UC_EMPTY; return -ETAX_BAD_SW; } /* save invoice information */ int i; for (i = 0; i < sizeof(*info); i++) info->invoice_code[i] = res_buf->res_buf.data[i]; return SUCCESS; }
/* * CMD : REGISTER_SIGN * -- This is a special command for user card */ static int card_register_sign(struct register_info * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xE4; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x10; memcpy(cmd_buf.cond_body + 1, info->random, 4); memcpy(cmd_buf.cond_body + 5, info->card_nb, 8); memcpy(cmd_buf.cond_body + 13,info->mac1, 4); cmd_buf.cond_body[17] = 0x04; cmd_size = 18; send_buf = prepare_cmd(USER_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 0x61 * SW2 0x04 */ if (res_buf->res_buf.sw1 != 0x61 && res_buf->res_buf.sw2 != 0x04) return -ETAX_BAD_SW; /* save mac2 */ info->mac2[0] = res_buf->res_buf.data[0]; info->mac2[1] = res_buf->res_buf.data[1]; info->mac2[2] = res_buf->res_buf.data[2]; info->mac2[3] = res_buf->res_buf.data[3]; return SUCCESS; }
/* CMD : SELECT FILE */ static int card_select_file_by_id(int CARD, int file_id) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0x00; cmd_buf.INS = 0xA4; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 2; cmd_buf.cond_body[1] = (uchar)(file_id >> 8); cmd_buf.cond_body[2] = (uchar)(file_id); cmd_size = cmd_buf.cond_body[0] + 5; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 : 90 6A 6A 6A * SW2 : 00 81 82 86 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x81) return -ETAX_CARD_PIN_LOCK; if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; return -ETAX_BAD_SW; } return SUCCESS; }
/* * CMD : GET CHALLENGE */ static int card_get_challenge(int CARD, uchar size, uchar *randon) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0x00; cmd_buf.INS = 0x84; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = size; cmd_size = 5; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 * SW2 00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) return -ETAX_BAD_SW; int i; for (i = 0; i < size; i++) *randon++ = res_buf->res_buf.data[i]; return SUCCESS; }
/* * CMD : READ_RECORD * Notice this: * -- Read Binnary in GB can select file by short file ID with P1 set as 0x8x; * but we were not going to support this function. * So, whenever you want to use this function, plz select the file you want * to read before invoke it. */ static int card_read_record(int CARD, uchar record_nb, int size, uchar *res) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0x00; cmd_buf.INS = 0xB2; cmd_buf.P1 = record_nb; cmd_buf.P2 = 0x04; cmd_buf.cond_body[0] = (uchar)size; cmd_size = 4 + size; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 * SW2 00 */ if (!(res_buf->res_buf.sw1 == 0x90 && res_buf->res_buf.sw2 == 0x00)) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x83) return -ETAX_NO_CARD_REC; return -ETAX_BAD_SW; } memcpy(res_buf, res_buf->res_buf.data, size); return SUCCESS; }
/* * CMD : DATA_COLLECT * -- This is a special command for user card */ static int card_data_collect(struct data_collect * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xE6; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0xDC; memcpy(cmd_buf.cond_body + 1, (uchar *)info, sizeof(*info)); cmd_size = 5 + sizeof(*info); send_buf = prepare_cmd(USER_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 0x90 * SW2 0x00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) return -ETAX_BAD_SW; return SUCCESS; }
/* * CMD : INPUT_INVOICE_NB * -- This is special command fur fiscal card */ static int card_input_invoice_nb(struct invoice_roll_info * info) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF7; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x16; memcpy(cmd_buf.cond_body + 1, (uchar *)info, sizeof(*info)); cmd_size = 5 + sizeof(*info); send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 * SW2 00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) return -ETAX_BAD_SW; return SUCCESS; }
/* CMD : POWER ON */ static int card_power_on(int CARD) { int ret; struct card_send_buf *send_buf; struct card_res_buf *res_buf; struct fiscal_card * card; if (CARD == FISCAL_CARD) { card = get_fiscal_card(); } else if (CARD == USER_CARD) { card = (struct fiscal_card *)get_user_card(); } else { return -ETAX_BAD_CARD_TYPE; } if (card->power_mark == POSITIVE) return SUCCESS; send_buf = prepare_cmd(CARD, CARD_PWR_ON_CMD, 0, NULL); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* set card power mark */ card->power_mark = POSITIVE; return SUCCESS; }
int main(int argc, char *argv[]) { int ret; comedi_cmd cmd; struct parsed_options options; init_parsed_options(&options); parse_options(&options, argc, argv); device = comedi_open(options.filename); if(!device){ perror(options.filename); exit(1); } out_subd = 0; config_output(); ret = fcntl(comedi_fileno(device),F_SETFL,O_NONBLOCK|O_ASYNC); if(ret<0)perror("fcntl"); #if 0 { struct sched_param p; memset(&p,0,sizeof(p)); p.sched_priority = 1; ret = sched_setscheduler(0,SCHED_FIFO,&p); if(ret<0)perror("sched_setscheduler"); } #endif prepare_cmd(device, &cmd, options.subdevice); do_cmd(device,&cmd); return 0; }
int main() { it=comedi_open("/dev/comedi0"); int ret; if(cmd==NULL) { cmd=malloc(sizeof(*cmd)); if(cmd==NULL) return -1; } else { if(cmd->chanlist) free(cmd->chanlist); } comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); ret = prepare_cmd(COMEDI_SUBD_AI,cmd,freq); printf("B");fflush(stdout); //comedi_get_cmd_generic_timed(dev,subdevice,cmd,0,1e9/freq); if(ret<0){ printf("comedi_get_cmd_generic_timed failed\n"); return ret; } /* Modify parts of the command */ cmd->scan_end_arg = 0; cmd->stop_arg = 0; setup_read_wave(COMEDI_SUBD_AI, 0, 0, 100); ret = comedi_command(it,cmd); if(ret) printf("comedi_command (acq): %d\n", ret); internal_trigger(); comedi_cancel(it, 0); comedi_cancel(it, 1); }
/* * CMD : EXTERNAL_AUTHENTICATION */ static int card_external_authentication(int CARD, uchar key_id, uchar *serect) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0x00; cmd_buf.INS = 0x82; cmd_buf.P1 = 0x00; cmd_buf.P2 = key_id; cmd_buf.cond_body[0] = 0x08; memcpy(cmd_buf.cond_body + 1, serect, 8); cmd_size = 5 + 0x08; send_buf = prepare_cmd(CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 90 * SW2 00 */ if (res_buf->res_buf.sw1 != 0x90 && res_buf->res_buf.sw2 != 0x00) return -ETAX_BAD_SW; return SUCCESS; }
int main(int argc, char* argv[]) { char serial[250] = DEFAULT_SERIAL; int port = XDR_TCP_DEFAULT_PORT; int c; server.background = 0; server.guest = 0; server.password = NULL; server.maxusers = DEFAULT_USERS; server.f_exec = NULL; server.l_exec = NULL; server.online = 0; server.online_auth = 0; server.head = NULL; tuner_defaults(); pthread_mutex_init(&server.mutex, NULL); pthread_mutex_init(&server.mutex_s, NULL); #ifdef __WIN32__ WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData)) { server_log(LOG_ERR, "main: WSAStartup"); exit(EXIT_FAILURE); } #else if(getuid() == 0) { fprintf(stderr, "error: running the server as root is a bad idea, giving up!\n"); exit(EXIT_FAILURE); } #endif while((c = getopt(argc, argv, "hbgxt:s:u:p:f:l:")) != -1) { switch(c) { case 'h': show_usage(argv[0]); #ifndef __WIN32__ case 'b': server.background = 1; break; #endif case 'g': server.guest = 1; break; case 'x': server.poweroff = 1; break; case 't': port = atoi(optarg); break; case 's': #ifdef __WIN32__ snprintf(serial, sizeof(serial), "\\\\.\\%s", optarg); #else snprintf(serial, sizeof(serial), "%s", optarg); #endif break; case 'u': server.maxusers = atoi(optarg); break; case 'p': server.password = optarg; break; case 'f': server.f_exec = prepare_cmd(optarg); break; case 'l': server.l_exec = prepare_cmd(optarg); break; case ':': case '?': show_usage(argv[0]); } } if(port < 1024 || port > 65535) { fprintf(stderr, "error: the tcp port must be in 1024-65535 range\n"); show_usage(argv[0]); } if(!server.password || !strlen(server.password)) { fprintf(stderr, "error: no password specified\n"); show_usage(argv[0]); } #ifndef __WIN32__ if(server.background) { switch(fork()) { case -1: server_log(LOG_ERR, "fork"); exit(EXIT_FAILURE); case 0: close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); umask(0); break; default: exit(EXIT_SUCCESS); } if(open("/dev/null", O_RDONLY) == -1 || open("/dev/null", O_WRONLY) == -1 || open("/dev/null", O_RDWR) == -1) { server_log(LOG_ERR, "open /dev/null"); exit(EXIT_FAILURE); } if(setsid() < 0) { server_log(LOG_ERR, "setsid"); exit(EXIT_FAILURE); } if(chdir("/") < 0) { server_log(LOG_ERR, "chdir"); exit(EXIT_FAILURE); } } #endif server_log(LOG_INFO, "xdrd " VERSION " is starting using %s and TCP port: %d", serial, port); server_init(port); serial_init(serial); serial_loop(); #ifdef __WIN32__ WSACleanup(); #endif server_log(LOG_ERR, "lost connection with tuner"); return EXIT_FAILURE; }
int start_command(struct child_process *cmd) { int need_in, need_out, need_err; int fdin[2], fdout[2], fderr[2]; int failed_errno; char *str; if (!cmd->argv) cmd->argv = cmd->args.argv; if (!cmd->env) cmd->env = cmd->env_array.argv; /* * In case of errors we must keep the promise to close FDs * that have been passed in via ->in and ->out. */ need_in = !cmd->no_stdin && cmd->in < 0; if (need_in) { if (pipe(fdin) < 0) { failed_errno = errno; if (cmd->out > 0) close(cmd->out); str = "standard input"; goto fail_pipe; } cmd->in = fdin[1]; } need_out = !cmd->no_stdout && !cmd->stdout_to_stderr && cmd->out < 0; if (need_out) { if (pipe(fdout) < 0) { failed_errno = errno; if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); str = "standard output"; goto fail_pipe; } cmd->out = fdout[0]; } need_err = !cmd->no_stderr && cmd->err < 0; if (need_err) { if (pipe(fderr) < 0) { failed_errno = errno; if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); str = "standard error"; fail_pipe: error("cannot create %s pipe for %s: %s", str, cmd->argv[0], strerror(failed_errno)); child_process_clear(cmd); errno = failed_errno; return -1; } cmd->err = fderr[0]; } trace_argv_printf(cmd->argv, "trace: run_command:"); fflush(NULL); #ifndef GIT_WINDOWS_NATIVE { int notify_pipe[2]; int null_fd = -1; char **childenv; struct argv_array argv = ARGV_ARRAY_INIT; struct child_err cerr; struct atfork_state as; if (pipe(notify_pipe)) notify_pipe[0] = notify_pipe[1] = -1; if (cmd->no_stdin || cmd->no_stdout || cmd->no_stderr) { null_fd = open("/dev/null", O_RDWR | O_CLOEXEC); if (null_fd < 0) die_errno(_("open /dev/null failed")); set_cloexec(null_fd); } prepare_cmd(&argv, cmd); childenv = prep_childenv(cmd->env); atfork_prepare(&as); /* * NOTE: In order to prevent deadlocking when using threads special * care should be taken with the function calls made in between the * fork() and exec() calls. No calls should be made to functions which * require acquiring a lock (e.g. malloc) as the lock could have been * held by another thread at the time of forking, causing the lock to * never be released in the child process. This means only * Async-Signal-Safe functions are permitted in the child. */ cmd->pid = fork(); failed_errno = errno; if (!cmd->pid) { int sig; /* * Ensure the default die/error/warn routines do not get * called, they can take stdio locks and malloc. */ set_die_routine(child_die_fn); set_error_routine(child_error_fn); set_warn_routine(child_warn_fn); close(notify_pipe[0]); set_cloexec(notify_pipe[1]); child_notifier = notify_pipe[1]; if (cmd->no_stdin) child_dup2(null_fd, 0); else if (need_in) { child_dup2(fdin[0], 0); child_close_pair(fdin); } else if (cmd->in) { child_dup2(cmd->in, 0); child_close(cmd->in); } if (cmd->no_stderr) child_dup2(null_fd, 2); else if (need_err) { child_dup2(fderr[1], 2); child_close_pair(fderr); } else if (cmd->err > 1) { child_dup2(cmd->err, 2); child_close(cmd->err); } if (cmd->no_stdout) child_dup2(null_fd, 1); else if (cmd->stdout_to_stderr) child_dup2(2, 1); else if (need_out) { child_dup2(fdout[1], 1); child_close_pair(fdout); } else if (cmd->out > 1) { child_dup2(cmd->out, 1); child_close(cmd->out); } if (cmd->dir && chdir(cmd->dir)) child_die(CHILD_ERR_CHDIR); /* * restore default signal handlers here, in case * we catch a signal right before execve below */ for (sig = 1; sig < NSIG; sig++) { /* ignored signals get reset to SIG_DFL on execve */ if (signal(sig, SIG_DFL) == SIG_IGN) signal(sig, SIG_IGN); } if (sigprocmask(SIG_SETMASK, &as.old, NULL) != 0) child_die(CHILD_ERR_SIGPROCMASK); /* * Attempt to exec using the command and arguments starting at * argv.argv[1]. argv.argv[0] contains SHELL_PATH which will * be used in the event exec failed with ENOEXEC at which point * we will try to interpret the command using 'sh'. */ execve(argv.argv[1], (char *const *) argv.argv + 1, (char *const *) childenv); if (errno == ENOEXEC) execve(argv.argv[0], (char *const *) argv.argv, (char *const *) childenv); if (errno == ENOENT) { if (cmd->silent_exec_failure) child_die(CHILD_ERR_SILENT); child_die(CHILD_ERR_ENOENT); } else { child_die(CHILD_ERR_ERRNO); } } atfork_parent(&as); if (cmd->pid < 0) error_errno("cannot fork() for %s", cmd->argv[0]); else if (cmd->clean_on_exit) mark_child_for_cleanup(cmd->pid, cmd); /* * Wait for child's exec. If the exec succeeds (or if fork() * failed), EOF is seen immediately by the parent. Otherwise, the * child process sends a child_err struct. * Note that use of this infrastructure is completely advisory, * therefore, we keep error checks minimal. */ close(notify_pipe[1]); if (xread(notify_pipe[0], &cerr, sizeof(cerr)) == sizeof(cerr)) { /* * At this point we know that fork() succeeded, but exec() * failed. Errors have been reported to our stderr. */ wait_or_whine(cmd->pid, cmd->argv[0], 0); child_err_spew(cmd, &cerr); failed_errno = errno; cmd->pid = -1; } close(notify_pipe[0]); if (null_fd >= 0) close(null_fd); argv_array_clear(&argv); free(childenv); } #else { int fhin = 0, fhout = 1, fherr = 2; const char **sargv = cmd->argv; struct argv_array nargv = ARGV_ARRAY_INIT; if (cmd->no_stdin) fhin = open("/dev/null", O_RDWR); else if (need_in) fhin = dup(fdin[0]); else if (cmd->in) fhin = dup(cmd->in); if (cmd->no_stderr) fherr = open("/dev/null", O_RDWR); else if (need_err) fherr = dup(fderr[1]); else if (cmd->err > 2) fherr = dup(cmd->err); if (cmd->no_stdout) fhout = open("/dev/null", O_RDWR); else if (cmd->stdout_to_stderr) fhout = dup(fherr); else if (need_out) fhout = dup(fdout[1]); else if (cmd->out > 1) fhout = dup(cmd->out); if (cmd->git_cmd) cmd->argv = prepare_git_cmd(&nargv, cmd->argv); else if (cmd->use_shell) cmd->argv = prepare_shell_cmd(&nargv, cmd->argv); cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, (char**) cmd->env, cmd->dir, fhin, fhout, fherr); failed_errno = errno; if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) error_errno("cannot spawn %s", cmd->argv[0]); if (cmd->clean_on_exit && cmd->pid >= 0) mark_child_for_cleanup(cmd->pid, cmd); argv_array_clear(&nargv); cmd->argv = sargv; if (fhin != 0) close(fhin); if (fhout != 1) close(fhout); if (fherr != 2) close(fherr); } #endif if (cmd->pid < 0) { if (need_in) close_pair(fdin); else if (cmd->in) close(cmd->in); if (need_out) close_pair(fdout); else if (cmd->out) close(cmd->out); if (need_err) close_pair(fderr); else if (cmd->err) close(cmd->err); child_process_clear(cmd); errno = failed_errno; return -1; } if (need_in) close(fdin[0]); else if (cmd->in) close(cmd->in); if (need_out) close(fdout[1]); else if (cmd->out) close(cmd->out); if (need_err) close(fderr[1]); else if (cmd->err) close(cmd->err); return 0; }
int main(int argc, char **argv) { int rc = 0; int devport = -1; /* */ memset(devnduid, 0, sizeof(devnduid)); memset(devsnid, 0, sizeof(devsnid)); /* options */ rc = parse_opt(argc, argv); if (rc) { return rc; } /* save current attributes */ saveconsole(); /* sockets */ rc = init_sockets(); if (rc) { return 1; } do { /* get the device list */ int devlistfd = connect_socket(serverip, serverport); if (devlistfd < 0) { fprintf(stderr, "failed to connect to server\n"); return 1; } /* dump the list if we're in device list mode */ if (listdev) { list_devices(devlistfd); return 0; } /* find our device (or the default one) and return the port to connect to */ devport = find_device(devlistfd, device); /* we do not need the device list port anymore */ close(devlistfd); if (devport < 0) { if (waitfordevice) { /* wait a bit and retry */ usleep(500000); continue; } else { fprintf(stderr, "unable to find device\n"); return 1; } } /* found device, abort the loop */ break; } while (1); //Port Forwarding Mode Begins if (portforwardmode) { initTcpRelay(serverip, devport); startTcpRelay(); return 0; } /* if we're in device list mode, dont bother extracting the command */ if (!listdev && !devcmd) { if (argc - optind < 1) { usage(argc, argv, 0); } /* construct the command from the rest of the arguments */ int i; command[0] = 0; for (i = optind; i < argc; i++) { if (i != optind) strcat(command, " "); strcat(command, argv[i]); } strcat(command, "\n"); #ifdef DEBUG_NOVACOM printf("command is %s\n", command); #endif } else if (devcmd) { int rc; /*host control cmd */ if( !strncmp(devcmd, "list", 4)) { snprintf(command, sizeof(command), "list host://"); devport = NOVACOM_CTRLPORT; } else if ( !strncmp(devcmd, "login", 5)) { /*device control cmd */ rc = prepare_cmd(devcmd, 5); if (!rc) { devport = NOVACOM_CTRLPORT; } else { return rc; } } else if (!strncmp(devcmd, "logout", 5)) { /*device control cmd */ /* command */ snprintf(command, sizeof(command), "logout dev://%s\n", devnduid); devport = NOVACOM_CTRLPORT; } else if (!strncmp(devcmd, "add", 3)) { /*device control cmd */ rc = prepare_cmd(devcmd, 3); if (!rc) { devport = NOVACOM_CTRLPORT; } else { return rc; } } else if (!strncmp(devcmd, "remove", 6)) { /*device control cmd */ rc = prepare_cmd(devcmd, 6); if (!rc) { devport = NOVACOM_CTRLPORT; } else { return rc; } } else { fprintf(stderr, "unsupported command(%s)\n", devcmd); return 1; } } /* connect to the device port */ int fd = connect_socket(serverip, devport); if (fd < 0) { fprintf(stderr, "failed to connect to server\n"); return 1; } /* put the tty into interactive mode */ if (term_mode) { setconsole(CONMODE_TERMSUPPORT); } /* signals */ if (dosignals || dosigwinch) { struct sigaction sa; int retVal = pipe(signalpipe); if (-1 != retVal) { fcntl(signalpipe[PIPE_READ], F_SETFL, fcntl(signalpipe[PIPE_READ], F_GETFL) | O_NONBLOCK); memset(&sa, 0, sizeof(sa)); sa.sa_handler = &signal_to_pipe; sa.sa_flags = SA_RESTART; // install signal handlers if (dosigwinch) sigaction(SIGWINCH, &sa, NULL); if (dosignals) { sigaction(SIGINT, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); } } else { fprintf(stderr, "failed to establish pipe \n"); close(fd); return 1; } } /* send the command */ if ( send(fd, command, strlen(command), 0) < 0) { fprintf(stderr, "novacom: unable to send command to server\n"); } /* parse it */ if (parse_response(fd) < 0) { close(fd); return 1; } else if(devcmd) { /* command executed, just exit */ close(fd); return 0; } rc = data_xfer(fd); if(rc != 0) { fprintf(stderr, "novacom: unexpected EOF from server\n"); } close(fd); return rc; }
/* * CMD : DECLARE_DUTY * -- This is special command fur fiscal card */ static int card_declare_duty(struct declare_duty * info, struct declare_res * res) { int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xF4; cmd_buf.P1 = 0x00; cmd_buf.P2 = 0x00; cmd_buf.cond_body[0] = 0x47; memcpy(cmd_buf.cond_body + 1, (uchar *)info, sizeof(*info)); cmd_buf.cond_body[0x47 + 1] = 0x8E; cmd_size = 6 + sizeof(*info); send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 61 * SW2 8E */ if (res_buf->res_buf.sw1 != 0x61 && res_buf->res_buf.sw2 != 0x8E) { if (res_buf->res_buf.sw1 == 0x6A && res_buf->res_buf.sw2 == 0x82) return -ETAX_NO_CARD_FILE; if (res_buf->res_buf.sw1 == 0x93 && res_buf->res_buf.sw2 == 0x03) return -ETAX_FC_PIN_LOCK; return -ETAX_BAD_SW; } /*check xor */ uchar xor_value = 0; int i; for (i = 0; i < 0x8E - 1; i++) { xor_value ^= res_buf->res_buf.data[i]; } if (xor_value != res_buf->res_buf.data[i]) return -ETAX_BAD_XOR; /* save respon data */ for (i = 0; i < 0x8E; i++) { res->total_valid[i] = res_buf->res_buf.data[i]; // Be careful with this code } return SUCCESS; }
/* * CMD : DATA_COLLECT_SIGN * fiscal card commond */ static int card_data_collect_sign(struct data_collect * info, struct daily_collect_res * res) { #if 0 int ret; int cmd_size; struct apdu_cmd_send cmd_buf; struct card_send_buf *send_buf; struct card_res_buf *res_buf; cmd_buf.CLA = 0xC0; cmd_buf.INS = 0xFB; cmd_buf.P1 = 0x00; #ifdef CONFIG_CARD_DEBUG assert(info != NULL); assert(res != NULL); #else if (!sign) return -ETAX_NUL_SEND_BUF; if (!res) return -ETAX_NUL_RES_BUF; #endif /* CONFIG_CARD_DEBUG */ cmd_buf.P2 = 0x01; cmd_buf.cond_body[0] = 0x81; memcpy(cmd_buf.cond_body + 1, sign, 128 + 1); cmd_buf.cond_body[0x81 + 1] = 0x81; cmd_size = 6 + 128 + 1; send_buf = prepare_cmd(FISCAL_CARD, CARD_OS_CMD, cmd_size, &cmd_buf); if (send_buf == NULL) return -ETAX_NUL_SEND_BUF; ret = card_send_cmd(send_buf); if (ret < 0) return ret; res_buf = get_res_buf(); ret = card_get_res(res_buf); if (ret < 0) return ret; /* * SW1 61 * SW2 81 */ if (res_buf->res_buf.sw1 != 0x61 && res_buf->res_buf.sw2 != 0x81) return -ETAX_BAD_SW; /*check xor */ uchar xor_value = 0; int i; for (i = 0; i < 0x81 - 1; i++) { xor_value ^= res_buf->res_buf.data[i]; } if (xor_value != res_buf->res_buf.data[i]) return -ETAX_BAD_XOR; /* save respon data */ for (i = 0; i < 0x81; i++) { res->sign[i] = res_buf->res_buf.data[i]; // Be careful with this code } #endif return SUCCESS; }