int USBRelayOutput::RawSendData(unsigned char *channelData) { LogExcess(VB_CHANNELOUT, "USBRelayOutput::RawSendData(%p)\n", channelData); char out = 0x00; int shiftBits = 0; for (int i = 0; i < m_relayCount; i++) { if ((i > 0) && ((i % 8) == 0)) { // Write out previous byte HexDump("out", &out, 1); write(m_fd, &out, 1); out = 0x00; shiftBits = 0; } out |= (channelData[i] ? 1 : 0) << shiftBits; shiftBits++; } // Write out any unwritten bits if (m_relayCount) { write(m_fd, &out, 1); HexDump("out", &out, 1); } return m_relayCount; }
int getSettingInt(const char *setting) { const char *valueStr = getSetting(setting); int value = strtol(valueStr, NULL, 10); LogExcess(VB_SETTING, "getSettingInt(%s) returning %d\n", setting, value); return value; }
int GPIOOutput::RawSendData(unsigned char *channelData) { LogExcess(VB_CHANNELOUT, "GPIOOutput::RawSendData(%p)\n", channelData); if (m_invertOutput) digitalWrite(m_GPIOPin, !channelData[0]); else digitalWrite(m_GPIOPin, channelData[0]); return m_channelCount; }
TestPatternRGBChase::TestPatternRGBChase() : m_colorPatternStr(""), m_colorPatternSize(0), m_patternOffset(0), m_rgbTriplets(0), m_lastTripletOffset(0), m_lastPatternOffset(0) { LogExcess(VB_CHANNELOUT, "TestPatternRGBChase::TestPatternRGBChase()\n"); m_testPatternName = "RGBChase"; }
const char *getSetting(const char *setting) { if (!setting) { LogErr(VB_SETTING, "getSetting() called with NULL value\n"); return ""; } if (settings.keyVal[setting] != nullptr) { return settings.keyVal[setting]; } LogExcess(VB_SETTING, "getSetting(%s) returned setting not found\n", setting); return ""; }
TestPatternBase::TestPatternBase() : m_testEnabled(0), m_testPatternName("basePattern"), m_minChannels(2), m_testData(NULL), m_nextCycleTime(0), m_cycleMS(0), m_channelCount(0), m_configChanged(0) { LogExcess(VB_CHANNELOUT, "TestPatternBase::TestPatternBase()\n"); // Give room for an extra RGB Triplet to make coding test patterns easier m_testData = new char[FPPD_MAX_CHANNELS + 3]; }
int RHLDVIE131Output::RawSendData(unsigned char *channelData) { LogExcess(VB_CHANNELOUT, "RHLDVIE131Output::RawSendData(%p)\n", channelData); // FIXME unsigned char *in = channelData; unsigned char *out = (unsigned char *)m_data; unsigned char *sR = NULL; unsigned char *sG = NULL; unsigned char *sB = NULL; unsigned char *dR = NULL; unsigned char *dG = NULL; unsigned char *dB = NULL; // FIXME, more universes on real card for (unsigned int i = 0; i < 8; i++) { sR = in + 0; sG = in + 1; sB = in + 2; dR = out + 2; dG = out + 1; dB = out + 0; // 480 channels is 160 RGB triplets we need to flip while copying for (int x = 0; x < 160; x++) { *dR = *sR; *dG = *sG; *dB = *sB; sR += 3; sG += 3; sB += 3; dR += 3; dG += 3; dB += 3; } // FIXME, this should be our universe size, adapter always does 480 in += 480; out += m_width * m_bytesPerPixel; } return m_channelCount; }
int OLAOutput::RawSendData(unsigned char *channelData) { LogExcess(VB_CHANNELOUT, "OLAOutput::RawSendData(%p)\n", channelData); for (int universe = 0 ; universe < m_universes.size(); universe++) { Universe u = m_universes[universe]; if (u.active) { m_buffer.Set(channelData + u.startChannel, u.channelCount); if (!m_client->SendDmx(u.universe, m_buffer)) { LogErr(VB_CHANNELOUT, "OLA SendDMX failed!\n"); } } } return m_channelCount; }
void *RunFPDOutputThread(void *data) { LogDebug(VB_CHANNELOUT, "RunFPDOutputThread()\n"); long long wakeTime = GetTime(); struct timeval tv; struct timespec ts; FPDPrivData *privData = (FPDPrivData *)data; privData->threadIsRunning = 1; LogDebug(VB_CHANNELOUT, "FPD output thread started\n"); while (privData->runThread) { // Wait for more data pthread_mutex_lock(&privData->sendLock); LogExcess(VB_CHANNELOUT, "FPD output thread: sent: %lld, elapsed: %lld\n", GetTime(), GetTime() - wakeTime); pthread_mutex_lock(&privData->bufLock); if (privData->dataWaiting) { pthread_mutex_unlock(&privData->bufLock); gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = (tv.tv_usec + 200000) * 1000; if (ts.tv_nsec >= 1000000000) { ts.tv_sec += 1; ts.tv_nsec -= 1000000000; } pthread_cond_timedwait(&privData->sendCond, &privData->sendLock, &ts); } else { pthread_mutex_unlock(&privData->bufLock); pthread_cond_wait(&privData->sendCond, &privData->sendLock); } wakeTime = GetTime(); LogExcess(VB_CHANNELOUT, "FPD output thread: woke: %lld\n", GetTime()); pthread_mutex_unlock(&privData->sendLock); if (!privData->runThread) continue; // See if there is any data waiting to process or if we timed out pthread_mutex_lock(&privData->bufLock); if (privData->dataWaiting) { pthread_mutex_unlock(&privData->bufLock); SendOutputBuffer(privData); } else { pthread_mutex_unlock(&privData->bufLock); } } LogDebug(VB_CHANNELOUT, "FPD output thread complete\n"); privData->threadIsRunning = 0; }
void Bridge_Initialize(int &eSock, int &dSock) { LogExcess(VB_E131BRIDGE, "Bridge_Initialize()\n"); // prepare the msg receive buffers memset(msgs, 0, sizeof(msgs)); for (int i = 0; i < MAX_MSG; i++) { iovecs[i].iov_base = buffers[i]; iovecs[i].iov_len = BUFSIZE; msgs[i].msg_hdr.msg_iov = &iovecs[i]; msgs[i].msg_hdr.msg_iovlen = 1; } /* Initialize our Universe Index lookup cache */ for (int i = 0; i < 65536; i++) UniverseCache[i] = BRIDGE_INVALID_UNIVERSE_INDEX; LoadInputUniversesFromFile(); LogInfo(VB_E131BRIDGE, "Universe Count = %d\n",InputUniverseCount); InputUniversesPrint(); // FIXME FIXME FIXME FIXME // This is a total hack to get a file descriptor greater than 2 // because otherwise, the bind() call later will fail for some reason. // FIXME FIXME FIXME FIXME int i1 = socket(AF_INET, SOCK_DGRAM, 0); int i2 = socket(AF_INET, SOCK_DGRAM, 0); int i3 = socket(AF_INET, SOCK_DGRAM, 0); ddpSock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); if (ddpSock < 0) { LogDebug(VB_E131BRIDGE, "e131bridge DDP socket failed: %s", strerror(errno)); exit(1); } memset((char *)&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(DDP_PORT); addrlen = sizeof(addr); // Bind the socket to address/port if (bind(ddpSock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { LogDebug(VB_E131BRIDGE, "e131bridge DDP bind failed: %s", strerror(errno)); exit(1); } int UniverseOctet[2]; struct ip_mreq mreq; char strMulticastGroup[16]; /* set up socket */ bridgeSock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); if (bridgeSock < 0) { LogDebug(VB_E131BRIDGE, "e131bridge socket failed: %s", strerror(errno)); exit(1); } // FIXME, move this to /etc/sysctl.conf or our startup script system("sudo sysctl net/ipv4/igmp_max_memberships=512"); memset((char *)&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(E131_DEST_PORT); addrlen = sizeof(addr); // Bind the socket to address/port if (bind(bridgeSock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { LogDebug(VB_E131BRIDGE, "e131bridge bind failed: %s", strerror(errno)); exit(1); } //get all the addresses struct ifaddrs *interfaces,*tmp; getifaddrs(&interfaces); char address[16]; address[0] = 0; // Join the multicast groups for(int i = 0; i < InputUniverseCount; i++) { if (InputUniverses[i].type == E131_TYPE_MULTICAST) { UniverseOctet[0] = InputUniverses[i].universe/256; UniverseOctet[1] = InputUniverses[i].universe%256; sprintf(strMulticastGroup, "239.255.%d.%d", UniverseOctet[0],UniverseOctet[1]); mreq.imr_multiaddr.s_addr = inet_addr(strMulticastGroup); LogInfo(VB_E131BRIDGE, "Adding group %s\n", strMulticastGroup); // add group to groups to listen for on eth0 and wlan0 if it exists int multicastJoined = 0; tmp = interfaces; //loop through all the interfaces and subscribe to the group while (tmp) { //struct sockaddr_in *sin = (struct sockaddr_in *)tmp->ifa_addr; //strcpy(address, inet_ntoa(sin->sin_addr)); if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) { GetInterfaceAddress(tmp->ifa_name, address, NULL, NULL); if (strcmp(address, "127.0.0.1")) { LogDebug(VB_E131BRIDGE, " Adding interface %s - %s\n", tmp->ifa_name, address); mreq.imr_interface.s_addr = inet_addr(address); if (setsockopt(bridgeSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { LogWarn(VB_E131BRIDGE, " Could not setup Multicast Group for interface %s\n", tmp->ifa_name); } multicastJoined = 1; } } else if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) { //FIXME for ipv6 multicast //LogDebug(VB_E131BRIDGE, " Inet6 interface %s\n", tmp->ifa_name); } tmp = tmp->ifa_next; } if (!multicastJoined) { LogDebug(VB_E131BRIDGE, " Binding to default interface\n"); mreq.imr_interface.s_addr = htonl(INADDR_ANY); if (setsockopt(bridgeSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq)) < 0) { LogWarn(VB_E131BRIDGE, " Could not setup Multicast Group\n"); } } } } freeifaddrs(interfaces); StartChannelOutputThread(); if (i1 >= 0) close(i1); if (i2 >= 0) close(i2); if (i3 >= 0) close(i3); eSock = bridgeSock; dSock = ddpSock; }
void ProcessCommand(char *command) { char *s; char *s2; char *s3; char *s4; char *response2 = NULL; int i; char NextPlaylist[128] = "No playlist scheduled."; char NextScheduleStartText[64] = ""; char CommandStr[64]; LogExcess(VB_COMMAND, "CMD: %s\n", command); s = strtok(command,","); strcpy(CommandStr, s); if (!strcmp(CommandStr, "s")) { Json::Value info = player->GetCurrentPlaylistInfo(); char currentEntryType = 'u'; // Unknown const char *currentSequenceName = NULL; const char *currentMediaName = NULL; if (info["currentEntry"].isMember("sequenceName")) currentSequenceName = info["currentEntry"]["sequenceName"].asString().c_str(); if (info["currentEntry"].isMember("mediaFilename")) currentMediaName = info["currentEntry"]["mediaFilename"].asString().c_str(); if (info["currentEntry"].isMember("type")) { std::string type = info["currentEntry"]["type"].asString(); if (type == "both") currentEntryType = 'b'; else if (type == "event") currentEntryType = 'e'; else if (type == "media") currentEntryType = 'm'; else if (type == "pause") currentEntryType = 'p'; else if (type == "plugin") currentEntryType = 'P'; else if (type == "sequence") currentEntryType = 's'; } player->GetNextScheduleStartText(NextScheduleStartText); player->GetNextPlaylistText(NextPlaylist); if(FPPstatus==FPP_STATUS_IDLE) { if (getFPPmode() == REMOTE_MODE) { sprintf(response,"%d,%d,%d,%s,%s,%d,%d\n", getFPPmode(), 0, getVolume(), currentSequenceName, currentMediaName, player->GetPlaybackSecondsElapsed(), player->GetPlaybackSecondsRemaining()); } else { sprintf(response,"%d,%d,%d,%s,%s\n", getFPPmode(),0,getVolume(), NextPlaylist,NextScheduleStartText); } } else { sprintf(response,"%d,%d,%d,%s,%c,%s,%s,%d,%d,%d,%d,%s,%s,%d\n", getFPPmode(),FPPstatus,getVolume(), info["name"].asString().c_str(), currentEntryType, currentSequenceName, currentMediaName, info["currentPosition"].asInt() + 1, info["size"].asInt(), info["currentEntry"]["secondsElapsed"].asInt(), info["currentEntry"]["secondsRemaining"].asInt(), NextPlaylist,NextScheduleStartText, info["repeat"].asInt()); } } else if ((!strcmp(CommandStr, "p")) || (!strcmp(CommandStr, "P"))) { if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY) { player->PlaylistStopNow(); sleep(1); } s = strtok(NULL,","); if (s) { std::string playlistName(s); int repeat = !strcmp(CommandStr, "p") ? 1 : 0; int position = 0; s = strtok(NULL,","); if (s) position = atoi(s); if (player->PlaylistStart(playlistName, position, repeat)) { sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Playlist Start Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else { sprintf(response,"%d,%d,Unknown Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "S")) { if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING) { player->PlaylistStopGracefully(); player->ReLoadCurrentScheduleInfo(); sprintf(response,"%d,%d,Playlist Stopping Gracefully,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,Not playing,,,,,,,,,,,\n",COMMAND_FAILED); } } else if (!strcmp(CommandStr, "d")) { if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY) { player->PlaylistStopNow(); player->ReLoadCurrentScheduleInfo(); sprintf(response,"%d,%d,Playlist Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Not playing,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "R")) { if(FPPstatus==FPP_STATUS_IDLE) { player->ReLoadCurrentScheduleInfo(); } player->ReLoadNextScheduleInfo(); sprintf(response,"%d,%d,Reloading Schedule,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if (!strcmp(CommandStr, "v")) { s = strtok(NULL,","); if (s) { setVolume(atoi(s)); sprintf(response,"%d,%d,Setting Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Invalid Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "w")) { LogInfo(VB_SETTING, "Sending Falcon hardware config\n"); if (!DetectFalconHardware(1)) SendFPDConfig(); } else if (!strcmp(CommandStr, "r")) { WriteBytesReceivedFile(); sprintf(response,"true\n"); } else if (!strcmp(CommandStr, "q")) { // Quit/Shutdown fppd ShutdownFPPD(); } else if (!strcmp(CommandStr, "e")) { // Start an Effect s = strtok(NULL,","); s2 = strtok(NULL,","); s3 = strtok(NULL,","); if (s && s2) { i = StartEffect(s, atoi(s2), atoi(s3)); if (i >= 0) sprintf(response,"%d,%d,Starting Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "t")) { // Trigger an event s = strtok(NULL,","); pluginCallbackManager.eventCallback(s, "command"); i = TriggerEventByID(s); if (i >= 0) sprintf(response,"%d,%d,Event Triggered,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Event Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "GetTestMode")) { strcpy(response, channelTester->GetConfig().c_str()); strcat(response, "\n"); } else if (!strcmp(CommandStr, "SetTestMode")) { if (channelTester->SetupTest(std::string(s + strlen(s) + 1))) { sprintf(response, "0,%d,Test Mode Activated,,,,,,,,,\n", COMMAND_SUCCESS); } else { sprintf(response, "0,%d,Test Mode Deactivated,,,,,,,,,\n", COMMAND_SUCCESS); } } else if (!strcmp(CommandStr, "LogLevel")) { s = strtok(NULL,","); if (SetLogLevel(s)) { sprintf(response,"%d,%d,Log Level Updated,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_SUCCESS,logLevel,logMask); } else { sprintf(response,"%d,%d,Error Updating Log Level,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_FAILED,logLevel,logMask); } } else if (!strcmp(CommandStr, "LogMask")) { s = strtok(NULL,","); if ((s && SetLogMask(s)) || SetLogMask("")) { sprintf(response,"%d,%d,Log Mask Updated,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_SUCCESS,logLevel,logMask); } else { sprintf(response,"%d,%d,Error Updating Log Mask,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_FAILED,logLevel,logMask); } } else if (!strcmp(CommandStr, "SetSetting")) { char name[128]; s = strtok(NULL,","); if (s) { strcpy(name, s); s = strtok(NULL,","); if (s) parseSetting(name, s); } } else if (!strcmp(CommandStr, "StopAllEffects")) { StopAllEffects(); sprintf(response,"%d,%d,All Effects Stopped,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if (!strcmp(CommandStr, "StopEffectByName")) { s = strtok(NULL,","); if (strlen(s)) { if (StopEffect(s)) sprintf(response,"%d,%d,Stopping Effect,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,s); else sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "StopEffect")) { s = strtok(NULL,","); i = atoi(s); if (StopEffect(i)) sprintf(response,"%d,%d,Stopping Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "GetRunningEffects")) { sprintf(response,"%d,%d,Running Effects",getFPPmode(),COMMAND_SUCCESS); GetRunningEffects(response, &response2); } else if (!strcmp(CommandStr, "ReloadChannelRemapData")) { if ((FPPstatus==FPP_STATUS_IDLE) && (LoadChannelRemapData())) { sprintf(response,"%d,%d,Channel Remap Data Reloaded,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Failed to reload Channel Remap Data,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "GetFPPDUptime")) { sprintf(response,"%d,%d,FPPD Uptime,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS, time(NULL) - fppdStartTime); } else if (!strcmp(CommandStr, "StartSequence")) { s = strtok(NULL,","); s2 = strtok(NULL,","); if (s && s2) { i = atoi(s2); player->StartSequence(s, 0, i); sprintf(response,"%d,%d,Sequence Started,,,,,,,,,,,,\n", getFPPmode(), COMMAND_SUCCESS); } else { LogErr(VB_COMMAND, "Tried to start a sequence when a playlist or " "sequence is already running\n"); sprintf(response,"%d,%d,Sequence Failed,,,,,,,,,,,,\n", getFPPmode(), COMMAND_FAILED); } } else if (!strcmp(CommandStr, "StopSequence")) { s = strtok(NULL,","); if (s) { player->StopSequence(s); sprintf(response,"%d,%d,Sequence Stopped,,,,,,,,,,,,\n", getFPPmode(), COMMAND_SUCCESS); } else { LogDebug(VB_COMMAND, "Invalid command: %s\n", command); sprintf(response,"%d,%d,Sequence Name Missing,,,,,,,,,,,,\n", getFPPmode(), COMMAND_FAILED); } } else if (!strcmp(CommandStr, "ToggleSequencePause")) { if ((player->SequencesRunning()) && ((FPPstatus == FPP_STATUS_IDLE) || (FPPstatus != FPP_STATUS_IDLE))) { player->ToggleSequencePause(); } } else if (!strcmp(CommandStr, "SingleStepSequence")) { if ((player->SequencesRunning()) && (player->SequencesArePaused()) && ((FPPstatus == FPP_STATUS_IDLE) || ((FPPstatus != FPP_STATUS_IDLE)))) { player->SingleStepSequences(); } } else if (!strcmp(CommandStr, "SingleStepSequenceBack")) { if ((player->SequencesRunning()) && (player->SequencesArePaused()) && ((FPPstatus == FPP_STATUS_IDLE) || ((FPPstatus != FPP_STATUS_IDLE)))) { player->SingleStepSequencesBack(); } } else if (!strcmp(CommandStr, "NextPlaylistItem")) { switch (FPPstatus) { case FPP_STATUS_IDLE: sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED); break; case FPP_STATUS_PLAYLIST_PLAYING: sprintf(response,"%d,%d,Skipping to next playlist item\n",getFPPmode(),COMMAND_SUCCESS); player->NextPlaylistItem(); break; case FPP_STATUS_STOPPING_GRACEFULLY: sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED); break; } } else if (!strcmp(CommandStr, "PrevPlaylistItem")) { switch (FPPstatus) { case FPP_STATUS_IDLE: sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED); break; case FPP_STATUS_PLAYLIST_PLAYING: sprintf(response,"%d,%d,Skipping to previous playlist item\n",getFPPmode(),COMMAND_SUCCESS); player->PrevPlaylistItem(); break; case FPP_STATUS_STOPPING_GRACEFULLY: sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED); break; } } else if (!strcmp(CommandStr, "SetupExtGPIO")) { // Configure the given GPIO to the given mode s = strtok(NULL,","); s2 = strtok(NULL,","); if (s && s2) { if (!SetupExtGPIO(atoi(s), s2)) { sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2); } else { sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2); } } } else if (!strcmp(CommandStr, "ExtGPIO")) { s = strtok(NULL,","); s2 = strtok(NULL,","); s3 = strtok(NULL,","); if (s && s2 && s3) { i = ExtGPIO(atoi(s), s2, atoi(s3)); if (i >= 0) { sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,%d,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2,atoi(s3),i); } else { sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2,atoi(s3)); } } } else { sprintf(response,"Invalid command: '%s'\n", CommandStr); } if (response2) { bytes_sent = sendto(socket_fd, response2, strlen(response2), 0, (struct sockaddr *) &(client_address), sizeof(struct sockaddr_un)); LogDebug(VB_COMMAND, "%s %s", CommandStr, response2); free(response2); response2 = NULL; } else { bytes_sent = sendto(socket_fd, response, strlen(response), 0, (struct sockaddr *) &(client_address), sizeof(struct sockaddr_un)); LogDebug(VB_COMMAND, "%s %s", CommandStr, response); } }
void PluginCallbackManager::init() { DIR *dp; struct dirent *ep; dp = opendir(getPluginDirectory()); if (dp != NULL) { while (ep = readdir(dp)) { int location = strstr(ep->d_name,".") - ep->d_name; // We're one of ".", "..", or hidden, so let's skip if ( location == 0 ) continue; LogDebug(VB_PLUGIN, "Found Plugin: (%s)\n", ep->d_name); std::string filename = std::string(getPluginDirectory()) + "/" + ep->d_name + "/callbacks"; bool found = false; if ( FileExists(filename.c_str()) ) { printf("Found callback with no extension"); found = true; } else { std::vector<std::string> extensions; extensions.push_back(std::string(".sh")); extensions.push_back(std::string(".pl")); extensions.push_back(std::string(".php")); extensions.push_back(std::string(".py")); for ( std::vector<std::string>::iterator i = extensions.begin(); i != extensions.end(); ++i) { std::string tmpFilename = filename + *i; if ( FileExists( tmpFilename.c_str() ) ) { filename += *i; found = true; } } } std::string eventScript = std::string(getFPPDirectory()) + "/scripts/eventScript"; if ( !found ) { LogExcess(VB_PLUGIN, "No callbacks supported by plugin: '%s'\n", ep->d_name); continue; } LogDebug(VB_PLUGIN, "Processing Callbacks (%s) for plugin: '%s'\n", filename.c_str(), ep->d_name); int output_pipe[2], pid, bytes_read; char readbuffer[128]; std::string callback_list = ""; if (pipe(output_pipe) == -1) { LogErr(VB_PLUGIN, "Failed to make pipe\n"); exit(EXIT_FAILURE); } if ((pid = fork()) == -1 ) { LogErr(VB_PLUGIN, "Failed to fork\n"); exit(EXIT_FAILURE); } if ( pid == 0 ) { dup2(output_pipe[1], STDOUT_FILENO); close(output_pipe[1]); execl(eventScript.c_str(), "eventScript", filename.c_str(), "--list", NULL); LogErr(VB_PLUGIN, "We failed to exec our callbacks query!\n"); exit(EXIT_FAILURE); } else { close(output_pipe[1]); while (true) { bytes_read = read(output_pipe[0], readbuffer, sizeof(readbuffer)-1); if (bytes_read <= 0) break; readbuffer[bytes_read] = '\0'; callback_list += readbuffer; } boost::trim(callback_list); LogExcess(VB_PLUGIN, "Callback output: (%s)\n", callback_list.c_str()); wait(NULL); } boost::char_separator<char> sep(","); boost::tokenizer< boost::char_separator<char> > tokens(callback_list, sep); BOOST_FOREACH (const std::string& type, tokens) { if (type == "media") { LogDebug(VB_PLUGIN, "Plugin %s supports media callback.\n", ep->d_name); MediaCallback *media = new MediaCallback(std::string(ep->d_name), filename); mCallbacks.push_back(media); } else if (type == "playlist") { LogDebug(VB_PLUGIN, "Plugin %s supports playlist callback.\n", ep->d_name); PlaylistCallback *playlist = new PlaylistCallback(std::string(ep->d_name), filename); mCallbacks.push_back(playlist); } else if (type == "nextplaylist") { LogDebug(VB_PLUGIN, "Plugin %s supports nextplaylist callback.\n", ep->d_name); NextPlaylistEntryCallback *nextplaylistentry = new NextPlaylistEntryCallback(std::string(ep->d_name), filename); mCallbacks.push_back(nextplaylistentry); } else if (type == "event") { LogDebug(VB_PLUGIN, "Plugin %s supports event callback.\n", ep->d_name); EventCallback *eventcallback = new EventCallback(std::string(ep->d_name), filename); mCallbacks.push_back(eventcallback); } } plugin_count += 1; } closedir(dp); } else {
TestPatternRGBChase::~TestPatternRGBChase() { LogExcess(VB_CHANNELOUT, "TestPatternRGBChase::~TestPatternRGBChase()\n"); }
char *ProcessCommand(char *command, char *response) { char *s; char *s2; char *s3; char *s4; char *response2 = NULL; int i; char NextPlaylist[128] = "No playlist scheduled."; char NextScheduleStartText[64] = ""; char CommandStr[64]; LogExcess(VB_COMMAND, "CMD: %s\n", command); s = strtok(command,","); strcpy(CommandStr, s); if (!strcmp(CommandStr, "s")) { scheduler->GetNextScheduleStartText(NextScheduleStartText); scheduler->GetNextPlaylistText(NextPlaylist); if(FPPstatus==FPP_STATUS_IDLE) { if (getFPPmode() == REMOTE_MODE) { int secsElapsed = 0; int secsRemaining = 0; char seqFilename[1024]; char mediaFilename[1024]; if (sequence->IsSequenceRunning()) { strcpy(seqFilename, sequence->m_seqFilename); secsElapsed = sequence->m_seqSecondsElapsed; secsRemaining = sequence->m_seqSecondsRemaining; } else { strcpy(seqFilename, ""); } if (mediaOutput) { strcpy(mediaFilename, mediaOutput->m_mediaFilename.c_str()); secsElapsed = mediaOutputStatus.secondsElapsed; secsRemaining = mediaOutputStatus.secondsRemaining; } else { strcpy(mediaFilename, ""); } sprintf(response,"%d,%d,%d,%s,%s,%d,%d\n", getFPPmode(), 0, getVolume(), seqFilename, mediaFilename, secsElapsed, secsRemaining); } else if (sequence->IsSequenceRunning()) { sprintf(response,"%d,%d,%d,,,%s,,0,0,%d,%d,%s,%s,0\n", getFPPmode(), 1, getVolume(), sequence->m_seqFilename, sequence->m_seqSecondsElapsed, sequence->m_seqSecondsRemaining, NextPlaylist, NextScheduleStartText); } else { sprintf(response,"%d,%d,%d,%s,%s\n",getFPPmode(),0,getVolume(),NextPlaylist,NextScheduleStartText); } } else { Json::Value pl = playlist->GetInfo(); if (pl["currentEntry"].isMember("dynamic")) pl["currentEntry"] = pl["currentEntry"]["dynamic"]; if ((pl["currentEntry"]["type"] == "both") || (pl["currentEntry"]["type"] == "media")) { //printf(" %s\n", pl.toStyledString().c_str()); sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n", getFPPmode(), FPPstatus, getVolume(), pl["name"].asString().c_str(), pl["currentEntry"]["type"].asString().c_str(), pl["currentEntry"]["type"].asString() == "both" ? pl["currentEntry"]["sequence"]["sequenceName"].asString().c_str() : "", pl["currentEntry"]["type"].asString() == "both" ? pl["currentEntry"]["media"]["mediaFilename"].asString().c_str() : pl["currentEntry"]["mediaFilename"].asString().c_str() , // pl["currentEntry"]["entryID"].asInt() + 1, playlist->GetPosition(), pl["size"].asInt(), pl["currentEntry"]["type"].asString() == "both" ? pl["currentEntry"]["media"]["secondsElapsed"].asInt() : pl["currentEntry"]["secondsElapsed"].asInt(), pl["currentEntry"]["type"].asString() == "both" ? pl["currentEntry"]["media"]["secondsRemaining"].asInt() : pl["currentEntry"]["secondsRemaining"].asInt(), NextPlaylist, NextScheduleStartText, pl["repeat"].asInt()); } else if (pl["currentEntry"]["type"] == "sequence") { sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n", getFPPmode(), FPPstatus, getVolume(), pl["name"].asString().c_str(), pl["currentEntry"]["type"].asString().c_str(), pl["currentEntry"]["sequenceName"].asString().c_str(), "", // pl["currentEntry"]["entryID"].asInt() + 1, playlist->GetPosition(), pl["size"].asInt(), sequence->m_seqSecondsElapsed, sequence->m_seqSecondsRemaining, NextPlaylist, NextScheduleStartText, pl["repeat"].asInt()); } else { sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n", getFPPmode(), FPPstatus, getVolume(), pl["name"].asString().c_str(), pl["currentEntry"]["type"].asString().c_str(), "", "", // pl["currentEntry"]["entryID"].asInt() + 1, playlist->GetPosition(), pl["size"].asInt(), pl["currentEntry"]["type"].asString() == "pause" ? pl["currentEntry"]["duration"].asInt() - pl["currentEntry"]["remaining"].asInt() : 0, pl["currentEntry"]["type"].asString() == "pause" ? pl["currentEntry"]["remaining"].asInt() : 0, NextPlaylist, NextScheduleStartText, pl["repeat"].asInt()); } } } else if ((!strcmp(CommandStr, "P")) || (!strcmp(CommandStr, "p"))) { s = strtok(NULL,","); s2 = strtok(NULL,","); int entry = 0; if (s2 && s2[0]) entry = atoi(s2); if (s) { int repeat = strcmp(CommandStr, "p") ? 0 : 1; int scheduledRepeat = 0; std::string playlistName = scheduler->GetPlaylistThatShouldBePlaying(scheduledRepeat); if ((playlistName == s) && (repeat == scheduledRepeat)) { // Use CheckIfShouldBePlayingNow() so the scheduler knows when // to stop the playlist scheduler->CheckIfShouldBePlayingNow(1); sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if (playlist->Play(s, entry, repeat, 0)) { FPPstatus = FPP_STATUS_PLAYLIST_PLAYING; sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Error Starting Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else { sprintf(response,"%d,%d,Unknown Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if ((!strcmp(CommandStr, "S")) || (!strcmp(CommandStr, "StopGracefully"))) { if (FPPstatus==FPP_STATUS_PLAYLIST_PLAYING) { playlist->StopGracefully(1); scheduler->ReLoadCurrentScheduleInfo(); sprintf(response,"%d,%d,Playlist Stopping Gracefully,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,Not playing,,,,,,,,,,,\n",COMMAND_FAILED); } } else if ((!strcmp(CommandStr, "d")) || (!strcmp(CommandStr, "StopNow"))) { if (FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY) { playlist->StopNow(1); scheduler->ReLoadCurrentScheduleInfo(); sprintf(response,"%d,%d,Playlist Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if ((FPPstatus == FPP_STATUS_IDLE) && (sequence->IsSequenceRunning())) { sequence->CloseSequenceFile(); sprintf(response,"%d,%d,Sequence Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Not playing,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "R")) { scheduler->ReLoadNextScheduleInfo(); if (FPPstatus==FPP_STATUS_IDLE) { scheduler->ReLoadCurrentScheduleInfo(); scheduler->CheckIfShouldBePlayingNow(); } sprintf(response,"%d,%d,Reloading Schedule,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if (!strcmp(CommandStr, "v")) { s = strtok(NULL,","); if (s) { setVolume(atoi(s)); sprintf(response,"%d,%d,Setting Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else { sprintf(response,"%d,%d,Invalid Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "q")) { // Quit/Shutdown fppd if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) || (FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY)) { playlist->StopNow(1); sleep(2); } ShutdownFPPD(); sleep(1); } else if (!strcmp(CommandStr, "e")) { // Start an Effect s = strtok(NULL,","); s2 = strtok(NULL,","); s3 = strtok(NULL,","); if (s && s2) { i = StartEffect(s, atoi(s2), atoi(s3)); if (i >= 0) sprintf(response,"%d,%d,Starting Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "t")) { // Trigger an event s = strtok(NULL,","); pluginCallbackManager.eventCallback(s, "command"); i = TriggerEventByID(s); if (i >= 0) sprintf(response,"%d,%d,Event Triggered,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Event Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "GetTestMode")) { strcpy(response, channelTester->GetConfig().c_str()); strcat(response, "\n"); } else if (!strcmp(CommandStr, "SetTestMode")) { if (channelTester->SetupTest(std::string(s + strlen(s) + 1))) { sprintf(response, "0,%d,Test Mode Activated,,,,,,,,,\n", COMMAND_SUCCESS); } else { sprintf(response, "0,%d,Test Mode Deactivated,,,,,,,,,\n", COMMAND_SUCCESS); } } else if (!strcmp(CommandStr, "LogLevel")) { s = strtok(NULL,","); if (SetLogLevel(s)) { sprintf(response,"%d,%d,Log Level Updated,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_SUCCESS,logLevel,logMask); } else { sprintf(response,"%d,%d,Error Updating Log Level,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_FAILED,logLevel,logMask); } } else if (!strcmp(CommandStr, "LogMask")) { s = strtok(NULL,","); if ((s && SetLogMask(s)) || SetLogMask("")) { sprintf(response,"%d,%d,Log Mask Updated,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_SUCCESS,logLevel,logMask); } else { sprintf(response,"%d,%d,Error Updating Log Mask,%d,%d,,,,,,,,,\n", getFPPmode(),COMMAND_FAILED,logLevel,logMask); } } else if (!strcmp(CommandStr, "SetSetting")) { char name[128]; s = strtok(NULL,","); if (s) { strcpy(name, s); s = strtok(NULL,","); if (s) parseSetting(name, s); } } else if (!strcmp(CommandStr, "StopAllEffects")) { StopAllEffects(); sprintf(response,"%d,%d,All Effects Stopped,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS); } else if (!strcmp(CommandStr, "StopEffectByName")) { s = strtok(NULL,","); if (strlen(s)) { if (StopEffect(s)) sprintf(response,"%d,%d,Stopping Effect,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,s); else sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } } else if (!strcmp(CommandStr, "StopEffect")) { s = strtok(NULL,","); i = atoi(s); if (StopEffect(i)) sprintf(response,"%d,%d,Stopping Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i); else sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED); } else if (!strcmp(CommandStr, "GetRunningEffects")) { sprintf(response,"%d,%d,Running Effects",getFPPmode(),COMMAND_SUCCESS); GetRunningEffects(response, &response2); } else if (!strcmp(CommandStr, "GetFPPDUptime")) { sprintf(response,"%d,%d,FPPD Uptime,%ld,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS, time(NULL) - fppdStartTime); } else if (!strcmp(CommandStr, "StartSequence")) { if ((FPPstatus == FPP_STATUS_IDLE) && (!sequence->IsSequenceRunning())) { s = strtok(NULL,","); s2 = strtok(NULL,","); if (s && s2) { i = atoi(s2); sequence->OpenSequenceFile(s, 0, i); } else { LogDebug(VB_COMMAND, "Invalid command: %s\n", command); } } else { LogErr(VB_COMMAND, "Tried to start a sequence when a playlist or " "sequence is already running\n"); } } else if (!strcmp(CommandStr, "StopSequence")) { if ((FPPstatus == FPP_STATUS_IDLE) && (sequence->IsSequenceRunning())) { sequence->CloseSequenceFile(); } else { LogDebug(VB_COMMAND, "Tried to stop a sequence when no sequence is running\n"); } } else if (!strcmp(CommandStr, "ToggleSequencePause")) { if ((sequence->IsSequenceRunning()) && ((FPPstatus == FPP_STATUS_IDLE) || ((FPPstatus != FPP_STATUS_IDLE) && (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) { sequence->ToggleSequencePause(); } } else if (!strcmp(CommandStr, "SingleStepSequence")) { if ((sequence->IsSequenceRunning()) && (sequence->SequenceIsPaused()) && ((FPPstatus == FPP_STATUS_IDLE) || ((FPPstatus != FPP_STATUS_IDLE) && (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) { sequence->SingleStepSequence(); } } else if (!strcmp(CommandStr, "SingleStepSequenceBack")) { if ((sequence->IsSequenceRunning()) && (sequence->SequenceIsPaused()) && ((FPPstatus == FPP_STATUS_IDLE) || ((FPPstatus != FPP_STATUS_IDLE) && (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) { sequence->SingleStepSequenceBack(); } } else if (!strcmp(CommandStr, "NextPlaylistItem")) { switch (FPPstatus) { case FPP_STATUS_IDLE: sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED); break; case FPP_STATUS_PLAYLIST_PLAYING: sprintf(response,"%d,%d,Skipping to next playlist item\n",getFPPmode(),COMMAND_SUCCESS); playlist->NextItem(); break; case FPP_STATUS_STOPPING_GRACEFULLY: sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED); break; } } else if (!strcmp(CommandStr, "PrevPlaylistItem")) { switch (FPPstatus) { case FPP_STATUS_IDLE: sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED); break; case FPP_STATUS_PLAYLIST_PLAYING: sprintf(response,"%d,%d,Skipping to previous playlist item\n",getFPPmode(),COMMAND_SUCCESS); playlist->PrevItem(); break; case FPP_STATUS_STOPPING_GRACEFULLY: sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED); break; } } else if (!strcmp(CommandStr, "SetupExtGPIO")) { // Configure the given GPIO to the given mode s = strtok(NULL,","); s2 = strtok(NULL,","); if (s && s2) { if (!SetupExtGPIO(atoi(s), s2)) { sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2); } else { sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2); } } } else if (!strcmp(CommandStr, "ExtGPIO")) { s = strtok(NULL,","); s2 = strtok(NULL,","); s3 = strtok(NULL,","); if (s && s2 && s3) { i = ExtGPIO(atoi(s), s2, atoi(s3)); if (i >= 0) { sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,%d,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2,atoi(s3),i); } else { sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2,atoi(s3)); } } } else { sprintf(response,"Invalid command: '%s'\n", CommandStr); } return response2; }
TestPatternBase::~TestPatternBase() { LogExcess(VB_CHANNELOUT, "TestPatternBase::~TestPatternBase()\n"); delete [] m_testData; }
void ogg123Output::ParseTimes() { static int lastRemoteSync = 0; int result; int secs; int mins; int subSecs; char tmp[3]; tmp[2]= '\0'; // Mins tmp[0] = m_ogg123_strTime[1]; tmp[1] = m_ogg123_strTime[2]; sscanf(tmp,"%d",&mins); // Secs tmp[0] = m_ogg123_strTime[4]; tmp[1] = m_ogg123_strTime[5]; sscanf(tmp,"%d",&secs); m_mediaOutputStatus->secondsElapsed = 60*mins + secs; // Subsecs tmp[0] = m_ogg123_strTime[7]; tmp[1] = m_ogg123_strTime[8]; sscanf(tmp,"%d",&m_mediaOutputStatus->subSecondsElapsed); // Mins Remaining tmp[0] = m_ogg123_strTime[11]; tmp[1] = m_ogg123_strTime[12]; sscanf(tmp,"%d",&mins); // Secs Remaining tmp[0] = m_ogg123_strTime[14]; tmp[1] = m_ogg123_strTime[15]; sscanf(tmp,"%d",&secs); m_mediaOutputStatus->secondsRemaining = 60*mins + secs; // Subsecs remaining tmp[0] = m_ogg123_strTime[17]; tmp[1] = m_ogg123_strTime[18]; sscanf(tmp,"%d",&m_mediaOutputStatus->subSecondsRemaining); // Total Mins tmp[0] = m_ogg123_strTime[24]; tmp[1] = m_ogg123_strTime[25]; sscanf(tmp,"%d",&m_mediaOutputStatus->minutesTotal); // Total Secs tmp[0] = m_ogg123_strTime[27]; tmp[1] = m_ogg123_strTime[28]; sscanf(tmp,"%d",&m_mediaOutputStatus->secondsTotal); m_mediaOutputStatus->mediaSeconds = (float)((float)m_mediaOutputStatus->secondsElapsed + ((float)m_mediaOutputStatus->subSecondsElapsed/(float)100)); if (getFPPmode() == MASTER_MODE) { if ((m_mediaOutputStatus->secondsElapsed > 0) && (lastRemoteSync != m_mediaOutputStatus->secondsElapsed)) { SendMediaSyncPacket(m_mediaFilename.c_str(), 0, m_mediaOutputStatus->mediaSeconds); lastRemoteSync = m_mediaOutputStatus->secondsElapsed; } } if ((sequence->IsSequenceRunning()) && (m_mediaOutputStatus->secondsElapsed > 0)) { LogExcess(VB_MEDIAOUT, "Elapsed: %.2d.%.2d Remaining: %.2d Total %.2d:%.2d.\n", m_mediaOutputStatus->secondsElapsed, m_mediaOutputStatus->subSecondsElapsed, m_mediaOutputStatus->secondsRemaining, m_mediaOutputStatus->minutesTotal, m_mediaOutputStatus->secondsTotal); CalculateNewChannelOutputDelay(m_mediaOutputStatus->mediaSeconds); } }