/* $Id: envch.c,v 1.3 2004/04/01 05:38:49 jmuelmen Exp $ */ #include #include #include #include #include #include #include #include #include /* use these ports for reading and writing */ #define ENV_READ_PORT 14163 #define ENV_WRITE_PORT 14164 #define BUFSIZE 1024 /* check the first byte of the datagram you receive: */ enum env_cmd { ENV_CMD_GET_T = 0x00, ENV_CMD_GET_STAT, ENV_CMD_SET_PRE_CYC = 0x80, ENV_CMD_SET_TINT, ENV_CMD_SET_START, ENV_CMD_SET_END, ENV_CMD_SET_STEP_SIZE, ENV_CMD_SET_CYCLES, ENV_CMD_SET_DWELL_TIME, ENV_CMD_SET_STAB_INT, ENV_CMD_SET_TOL }; static pthread_mutex_t _mut; static int _init = 0; static int _sock; static struct sockaddr_in _sn, _rn; /* if the command is a getter, return the command byte in the first byte of the return datagram, a status byte as the second byte (1 for failure, 0 for success) and then the return value: - return the temperature as %e would print it - return the cycle number as an unsigned 16-bit int, followed by one byte to indicate whether the cycle is complete (1) or incomplete (0) */ /* if the command is a setter, then pass all bytes following the first byte to atof to turn them into a double, except in the case of ENV_CMD_SET_CYCLES, in which case you should use the second byte as an unsigned char to get the number of cycles. If the command is a setter, send back a datagram whose first byte is the command received and whose second byte is a status byte (0 for success, 1 for failure). */ int envch_init () { #ifdef HAVE_ENVCH int length; char buf[BUFSIZE]; if (pthread_mutex_init(&_mut, NULL)) { perror("Initializing environmental chamber mutex"); } /* Create socket. */ _sock = socket(AF_INET, SOCK_DGRAM, 0); if (_sock < 0) { perror("opening datagram socket"); return 1; } /* bind the socket to the ENVCH_WRITE_PORT (since this is the socket that the environmental chamber will send to) */ _rn.sin_family = AF_INET; _rn.sin_addr.s_addr = INADDR_ANY; _rn.sin_port = htons(ENV_WRITE_PORT); if (bind(_sock, (struct sockaddr *)&_rn, sizeof(_rn))) { perror("binding datagram socket"); return 1; } length = sizeof(_rn); if (getsockname(_sock, (struct sockaddr *)&_rn, &length)) { perror("getting socket name"); return 1; } printf("Socket has port %d... ", ntohs(_rn.sin_port)); if (ntohs(_rn.sin_port) != ENV_WRITE_PORT) { printf("we're unhappy.\n"); return 1; } else printf("we're happy.\n"); /* now make a sockaddr_in to send to */ _sn.sin_addr.s_addr = inet_addr("127.0.0.1"); printf("Sending to host 0x%x\n", ntohl(_sn.sin_addr.s_addr)); _sn.sin_family = AF_INET; _sn.sin_port = htons(ENV_READ_PORT); _init = 1; fflush(stdout); #endif return 0; } static int ec_lock () { int ret = pthread_mutex_lock(&_mut); if (ret) perror("Locking environmental chamber mutex"); return ret; } static int ec_unlock () { int ret = pthread_mutex_unlock(&_mut); if (ret) perror("Unlocking environmental chamber mutex"); return ret; } static int ec_wr (unsigned char *buf, int count) { #ifdef HAVE_ENVCH int length; if ((length = sendto(_sock, buf, count, 0, &_sn, sizeof(_sn))) <= 0) { perror("Sending to environmental chamber"); } return length; #endif return 0; } static int ec_rd (unsigned char *buf, int count) { #ifdef HAVE_ENVCH int length; if ((length = recv(_sock, buf, count, 0)) <= 0) { perror("Reading from environmental chamber"); } return length; #endif return 0; } static void ec_rd_err () { fprintf(stderr, "Got something funny back from the ec\n"); } double envch_get_temp () { int length; unsigned char buf[BUFSIZE]; unsigned char cmd = ENV_CMD_GET_T; ec_lock(); buf[0] = cmd; if (ec_wr(buf, 1) <= 0) { ec_unlock(); return -1; } if ((length = ec_rd(buf, BUFSIZE)) <= 0) { ec_unlock(); return -1; } if (buf[0] != cmd) { ec_rd_err(); ec_unlock(); return -1; } if (buf[1]) { ec_unlock(); return -1; } ec_unlock(); return atof((char *)buf + 2); } int envch_cycle_comp () { int length; unsigned char buf[BUFSIZE]; unsigned char cmd = ENV_CMD_GET_STAT; ec_lock(); buf[0] = cmd; if (ec_wr(buf, 1) <= 0) { ec_unlock(); return -1; } if ((length = ec_rd(buf, BUFSIZE)) <= 0) { ec_unlock(); return -1; } if (buf[0] != cmd) { ec_rd_err(); ec_unlock(); return -1; } if (buf[1]) { ec_unlock(); return -1; } ec_unlock(); return buf[3]; } int envch_cycle_num () { int length; unsigned char buf[BUFSIZE]; unsigned char cmd = ENV_CMD_GET_STAT; ec_lock(); buf[0] = cmd; if (ec_wr(buf, 1) <= 0) { ec_unlock(); return -1; } if ((length = ec_rd(buf, BUFSIZE)) <= 0) { ec_unlock(); return -1; } if (buf[0] != cmd) { ec_rd_err(); ec_unlock(); return -1; } if (buf[1]) { ec_unlock(); return -1; } ec_unlock(); return buf[2]; } int envch_set_cycles (int num) { int length; unsigned char buf[BUFSIZE]; unsigned char cmd = ENV_CMD_SET_CYCLES; ec_lock(); buf[0] = cmd; buf[1] = num; if (ec_wr(buf, 2) <= 0) { ec_unlock(); return -1; } if ((length = ec_rd(buf, BUFSIZE)) <= 0) { ec_unlock(); return -1; } if (buf[0] != cmd) { ec_rd_err(); ec_unlock(); return -1; } ec_unlock(); return buf[2]; } #define TAPDANCE \ int length; \ unsigned char buf[BUFSIZE]; \ \ ec_lock(); \ buf[0] = cmd; \ length = snprintf((char *)buf + 1, BUFSIZE - 1, "%e", v); \ if (ec_wr(buf, length) <= 0) { \ ec_unlock(); \ return -1; \ } \ if ((length = ec_rd(buf, BUFSIZE)) <= 0) { \ ec_unlock(); \ return -1; \ } \ if (buf[0] != cmd) { \ ec_rd_err(); \ ec_unlock(); \ return -1; \ } \ ec_unlock(); \ return buf[2] \ int envch_set_pre_cyc (double v) { unsigned char cmd = ENV_CMD_SET_PRE_CYC; TAPDANCE; } int envch_set_tint (double v) { unsigned char cmd = ENV_CMD_SET_TINT; TAPDANCE; } int envch_set_start (double v) { unsigned char cmd = ENV_CMD_SET_START; TAPDANCE; } int envch_set_end (double v) { unsigned char cmd = ENV_CMD_SET_END; TAPDANCE; } int envch_set_step (double v) { unsigned char cmd = ENV_CMD_SET_STEP_SIZE; TAPDANCE; } int envch_set_dwell (double v) { unsigned char cmd = ENV_CMD_SET_DWELL_TIME; TAPDANCE; } int envch_set_stab (double v) { unsigned char cmd = ENV_CMD_SET_STAB_INT; TAPDANCE; } int envch_set_tol (double v) { unsigned char cmd = ENV_CMD_SET_TOL; TAPDANCE; }