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); } }
int InitializeChannelOutputs(void) { Json::Value root; Json::Reader reader; int i = 0; channelOutputFrame = 0; for (i = 0; i < FPPD_MAX_CHANNEL_OUTPUTS; i++) { bzero(&channelOutputs[i], sizeof(channelOutputs[i])); } // Reset index so we can start populating the outputs array i = 0; if (FPDOutput.isConfigured()) { channelOutputs[i].startChannel = getSettingInt("FPDStartChannelOffset"); channelOutputs[i].outputOld = &FPDOutput; if (FPDOutput.open("", &channelOutputs[i].privData)) { channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData); i++; } else { LogErr(VB_CHANNELOUT, "ERROR Opening FPD Channel Output\n"); } } if (((getFPPmode() != BRIDGE_MODE) || (getSettingInt("E131Bridging"))) && (E131Output.isConfigured())) { channelOutputs[i].startChannel = 0; channelOutputs[i].outputOld = &E131Output; if (E131Output.open("", &channelOutputs[i].privData)) { channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData); i++; } else { LogErr(VB_CHANNELOUT, "ERROR Opening E1.31 Channel Output\n"); } } FILE *fp; char filename[1024]; char buf[2048]; // Parse the channeloutputs.json config file strcpy(filename, getMediaDirectory()); strcat(filename, "/config/channeloutputs.json"); LogDebug(VB_CHANNELOUT, "Loading %s\n", filename); if (FileExists(filename)) { std::ifstream t(filename); std::stringstream buffer; buffer << t.rdbuf(); std::string config = buffer.str(); bool success = reader.parse(buffer.str(), root); if (!success) { LogErr(VB_CHANNELOUT, "Error parsing %s\n", filename); return 0; } const Json::Value outputs = root["channelOutputs"]; std::string type; int start = 0; int count = 0; for (int c = 0; c < outputs.size(); c++) { type = outputs[c]["type"].asString(); if (!outputs[c]["enabled"].asInt()) { LogDebug(VB_CHANNELOUT, "Skipping Disabled Channel Output: %s\n", type.c_str()); continue; } start = outputs[c]["startChannel"].asInt(); count = outputs[c]["channelCount"].asInt(); // internally we start channel counts at zero start -= 1; channelOutputs[i].startChannel = start; channelOutputs[i].channelCount = count; if (type == "LEDPanelMatrix") { #if defined(PLATFORM_PI) || defined(PLATFORM_ODROID) if (outputs[c]["subType"] == "RGBMatrix") channelOutputs[i].output = new RGBMatrixOutput(start, count); else { LogErr(VB_CHANNELOUT, "%s subType not valid on Pi\n", outputs[c]["subType"].asString().c_str()); continue; } #endif #ifdef PLATFORM_BBB if (outputs[c]["subType"] == "LEDscapeMatrix") channelOutputs[i].output = new LEDscapeMatrixOutput(start, count); else { LogErr(VB_CHANNELOUT, "%s subType not valid on BBB\n", outputs[c]["subType"].asString().c_str()); continue; } } else if (type == "BBB48String") { channelOutputs[i].output = new BBB48StringOutput(start, count); } else if (type == "BBBSerial") { channelOutputs[i].output = new BBBSerialOutput(start, count); #endif #ifdef USEOLA } else if (type == "OLA") { channelOutputs[i].output = new OLAOutput(start, count); #endif } else if (type == "USBRelay") { channelOutputs[i].output = new USBRelayOutput(start, count); #if defined(PLATFORM_PI) } else if (type == "Hill320") { channelOutputs[i].output = new Hill320Output(start, count); #endif #ifdef USE_X11Matrix } else if (type == "X11Matrix") { channelOutputs[i].output = new X11MatrixOutput(start, count); #endif } else { LogErr(VB_CHANNELOUT, "Unknown Channel Output type: %s\n", type.c_str()); continue; } if (channelOutputs[i].output->Init(outputs[c])) { i++; } else { LogErr(VB_CHANNELOUT, "ERROR Opening %s Channel Output\n", type.c_str()); } } } // Parse the channeloutputs config file strcpy(filename, getMediaDirectory()); strcat(filename, "/channeloutputs"); if (FileExists(filename)) { LogDebug(VB_CHANNELOUT, "Loading %s\n", filename); fp = fopen(filename, "r"); if (fp == NULL) { LogErr(VB_CHANNELOUT, "Could not open Channel Outputs config file %s: %s\n", filename, strerror(errno)); channelOutputCount = 0; return 0; } while(fgets(buf, 2048, fp) != NULL) { int enabled = 0; char type[32]; int start = 0; int count = 0; char deviceConfig[160]; if (buf[0] == '#') // Allow # comments for testing continue; int fields = sscanf(buf, "%d,%[^,],%d,%d,%s", &enabled, type, &start, &count, deviceConfig); if (fields != 5) { LogErr(VB_CHANNELOUT, "Invalid line in channeloutputs config file: %s\n", buf); continue; } if (!enabled) { LogDebug(VB_CHANNELOUT, "Skipping disabled channel output: %s", buf); continue; } if (count > (FPPD_MAX_CHANNELS - start)) { LogWarn(VB_CHANNELOUT, "Channel Output config, start (%d) + count (%d) exceeds max (%d) channel\n", start, count, FPPD_MAX_CHANNELS); count = FPPD_MAX_CHANNELS - start; LogWarn(VB_CHANNELOUT, "Count suppressed to %d for config line: %s\n", count, buf); } if (strlen(deviceConfig)) strcat(deviceConfig, ";"); strcat(deviceConfig, "type="); strcat(deviceConfig, type); LogDebug(VB_CHANNELOUT, "ChannelOutput: %d %s %d %d %s\n", enabled, type, start, count, deviceConfig); // internally we start channel counts at zero start -= 1; channelOutputs[i].startChannel = start; channelOutputs[i].channelCount = count; if ((!strcmp(type, "Pixelnet-Lynx")) || (!strcmp(type, "Pixelnet-Open"))) { channelOutputs[i].output = new USBPixelnetOutput(start, count); } else if ((!strcmp(type, "DMX-Pro")) || (!strcmp(type, "DMX-Open"))) { channelOutputs[i].output = new USBDMXOutput(start, count); } else if ((!strcmp(type, "VirtualMatrix")) || (!strcmp(type, "FBMatrix"))) { channelOutputs[i].output = new FBMatrixOutput(start, count); } else if (!strcmp(type, "GPIO")) { channelOutputs[i].output = new GPIOOutput(start, count); } else if (!strcmp(type, "GenericSerial")) { channelOutputs[i].output = new GenericSerialOutput(start, count); } else if (!strcmp(type, "LOR")) { channelOutputs[i].outputOld = &LOROutput; } else if (!strcmp(type, "Renard")) { channelOutputs[i].outputOld = &USBRenardOutput; #ifdef PLATFORM_PI } else if (!strcmp(type, "RPIWS281X")) { channelOutputs[i].output = new RPIWS281xOutput(start, count); #endif } else if (!strcmp(type, "SPI-WS2801")) { channelOutputs[i].output = new SPIws2801Output(start, count); } else if (!strcmp(type, "SPI-nRF24L01")) { channelOutputs[i].outputOld = &SPInRF24L01Output; } else if (!strcmp(type, "Triks-C")) { channelOutputs[i].outputOld = &TriksCOutput; } else if (!strcmp(type, "GPIO-595")) { channelOutputs[i].output = new GPIO595Output(start, count); } else if (!strcmp(type, "Debug")) { channelOutputs[i].output = new DebugOutput(start, count); } else { LogErr(VB_CHANNELOUT, "Unknown Channel Output type: %s\n", type); continue; } if ((channelOutputs[i].outputOld) && (channelOutputs[i].outputOld->open(deviceConfig, &channelOutputs[i].privData))) { if (channelOutputs[i].channelCount > channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData)) { LogWarn(VB_CHANNELOUT, "Channel Output config, count (%d) exceeds max (%d) channel for configured output\n", channelOutputs[i].channelCount, channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData)); channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData); LogWarn(VB_CHANNELOUT, "Count suppressed to %d for config: %s\n", channelOutputs[i].channelCount, buf); } i++; } else if ((channelOutputs[i].output) && (channelOutputs[i].output->Init(deviceConfig))) { i++; } else { LogErr(VB_CHANNELOUT, "ERROR Opening %s Channel Output\n", type); } } } channelOutputCount = i; LogDebug(VB_CHANNELOUT, "%d Channel Outputs configured\n", channelOutputCount); LoadChannelRemapData(); return 1; }