static void handle_power_command(bus_t busnumber) { buses[busnumber].power_changed = 0; char msg[110]; infoPower(busnumber, msg); enqueueInfoMessage(msg); buses[busnumber].watchdog++; if ( buses[busnumber].power_state == 0 && __dccar->mode == DCCAR ) { unsigned char command[] = {240,240,0}; write_command(command, sizeof(command), fd, busnumber); } }
int unlockGA(bus_t busnumber, int addr, sessionid_t sessionid) { if (ga[busnumber].gastate[addr].locked_by == sessionid || ga[busnumber].gastate[addr].locked_by == 0) { char msg[256]; ga[busnumber].gastate[addr].locked_by = 0; gettimeofday(&ga[busnumber].gastate[addr].locktime, NULL); sprintf(msg, "%lu.%.3lu 102 INFO %ld LOCK GA %d %ld\n", ga[busnumber].gastate[addr].locktime.tv_sec, ga[busnumber].gastate[addr].locktime.tv_usec / 1000, busnumber, addr, sessionid); enqueueInfoMessage(msg); return SRCP_OK; } else { return SRCP_DEVICELOCKED; } }
int lockGA(bus_t busnumber, int addr, long int duration, sessionid_t sessionid) { char msg[256]; if (ga[busnumber].gastate[addr].locked_by == sessionid || ga[busnumber].gastate[addr].locked_by == 0) { ga[busnumber].gastate[addr].locked_by = sessionid; ga[busnumber].gastate[addr].lockduration = duration; gettimeofday(&ga[busnumber].gastate[addr].locktime, NULL); describeLOCKGA(busnumber, addr, msg); enqueueInfoMessage(msg); return SRCP_OK; } else { return SRCP_DEVICELOCKED; } /* unreached */ return SRCP_UNSUPPORTEDOPERATION; }
/* ******************** * SRCP commands */ int setGA(bus_t busnumber, int addr, ga_state_t a) { int number_ga = get_number_ga(busnumber); if ((addr > 0) && (addr <= number_ga)) { char msg[1000]; if (!isInitializedGA(busnumber, addr)) initGA(busnumber, addr, 'P', 0); ga[busnumber].gastate[addr].id = a.id; ga[busnumber].gastate[addr].action = a.action; ga[busnumber].gastate[addr].port = a.port; gettimeofday(&ga[busnumber].gastate[addr]. tv[ga[busnumber].gastate[addr].port], NULL); infoGA(busnumber, addr, a.port, msg); enqueueInfoMessage(msg); return SRCP_OK; } else { return SRCP_NODATA; } }
int initGA(bus_t busnumber, long addr, char protocol, long type) { int i = 0; int rc = SRCP_OK; int number_ga = get_number_ga(busnumber); syslog_bus(busnumber, DBG_INFO, "init GA: %d %c", addr, protocol); if ((addr > 0) && (addr <= number_ga)) { char msg[100]; rc = bus_supports_protocol(busnumber, protocol); if (rc != SRCP_OK) { return rc; } ga[busnumber].gastate[addr].protocol = protocol; gettimeofday(&ga[busnumber].gastate[addr].inittime, NULL); ga[busnumber].gastate[addr].activetime = 0; ga[busnumber].gastate[addr].action = 0; ga[busnumber].gastate[addr].type = type; ga[busnumber].gastate[addr].id = addr; for (i = 0; i < MAXGAPORT; i++) { ga[busnumber].gastate[addr].tv[i].tv_sec = 0; ga[busnumber].gastate[addr].tv[i].tv_usec = 0; } if (buses[busnumber].init_ga_func != NULL) rc = (*buses[busnumber].init_ga_func) (&ga[busnumber]. gastate[addr]); if (rc == SRCP_OK) { ga[busnumber].gastate[addr].state = 1; describeGA(busnumber, addr, msg); enqueueInfoMessage(msg); } return rc; } else { return SRCP_UNSUPPORTEDDEVICE; } }
/* * * The main worker-thread for the i2c-dev device * Enters an endless loop that waits for commands and * executes them. * * Currently we only support GA-devices * */ void *thr_sendrec_I2C_DEV(void *v) { char msg[1000]; ga_state_t gatmp; int last_cancel_state, last_cancel_type; bus_thread_t *btd = (bus_thread_t *) malloc(sizeof(bus_thread_t)); if (btd == NULL) pthread_exit((void *) 1); btd->bus = (bus_t) v; btd->fd = -1; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &last_cancel_state); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &last_cancel_type); /*register cleanup routine */ pthread_cleanup_push((void *) end_bus_thread, (void *) btd); syslog_bus(btd->bus, DBG_INFO, "i2c-dev bus started (device = %s).", buses[btd->bus].device.file.path); I2CDEV_DATA *data = buses[btd->bus].driverdata; int ga_reset_devices = data->ga_reset_devices; buses[btd->bus].watchdog = 1; /* command processing starts here */ while (true) { /* process POWER changes */ if (buses[btd->bus].power_changed == 1) { /* dummy select, power state is directly read by select_bus() */ select_bus(0, btd->bus); buses[btd->bus].power_changed = 0; infoPower(btd->bus, msg); enqueueInfoMessage(msg); if ((ga_reset_devices == 1) && (buses[btd->bus].power_state == 1)) { reset_ga(btd->bus); } } /* do nothing, if power is off */ if (buses[btd->bus].power_state == 0) { if (usleep(1000) == -1) { syslog_bus(btd->bus, DBG_ERROR, "usleep() failed: %s (errno = %d)\n", strerror(errno), errno); } continue; } buses[btd->bus].watchdog = 4; /* process GA commands */ if (!queue_GA_isempty(btd->bus)) { dequeueNextGA(btd->bus, &gatmp); handle_i2c_set_ga(btd->bus, &gatmp); setGA(btd->bus, gatmp.id, gatmp); select_bus(0, btd->bus); buses[btd->bus].watchdog = 6; } if (usleep(1000) == -1) { syslog_bus(btd->bus, DBG_ERROR, "usleep() failed: %s (errno = %d)\n", strerror(errno), errno); } } /*run the cleanup routine */ pthread_cleanup_pop(1); return NULL; }