00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00023 #include <stdio.h>
00024 #include <unistd.h>
00025 #include <string.h>
00026 #include <stdlib.h>
00027
00028 #include <sys/types.h>
00029 #include <sys/socket.h>
00030 #include <arpa/inet.h>
00031
00032 #include "erdm.h"
00033 #include "erdminternal.h"
00034 #include "erdmlog.h"
00035 #include "display.h"
00036
00037 int dmGetServerPort(int *port)
00038 {
00039 *port = DMPORT;
00040 return 0;
00041 }
00042
00043
00044
00045
00046
00047 int initServer(int *sockfd, int local)
00048 {
00049 int error;
00050 int port;
00051 struct sockaddr_in serverAdr;
00052
00053 *sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00054 dmGetServerPort(&port);
00055
00056 bzero(&serverAdr, sizeof(serverAdr));
00057 serverAdr.sin_family = AF_INET;
00058
00059
00060
00061
00062
00063 if (local == 1)
00064 {
00065 serverAdr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00066 }
00067 else
00068 {
00069 serverAdr.sin_addr.s_addr = htonl(INADDR_ANY);
00070 }
00071 serverAdr.sin_port = htons(port);
00072
00073 error = bind(*sockfd, (struct sockaddr *) &serverAdr, sizeof(serverAdr));
00074 if (error)
00075 {
00076 perror("Error invoking bind");
00077 return -1;
00078 }
00079 else
00080 {
00081 char szServerIP[INET_ADDRSTRLEN + 1];
00082
00083 inet_ntop(AF_INET, &serverAdr.sin_addr, szServerIP, sizeof(szServerIP));
00084 ERDM_WARNPRINTF("Bound successfully to %s:%d.", szServerIP, port);
00085 }
00086 return 0;
00087 }
00088
00089 int dmValidateCommand(uDmCommand * dmCommand)
00090 {
00091 if (dmCommand->dmCmdGeneric.cmd == dmCcDisplayPartial)
00092 {
00093 int xUp = dmCommand->dmCmdDisplayPartial.xUp;
00094 int xDown = dmCommand->dmCmdDisplayPartial.xDown;
00095 int yUp = dmCommand->dmCmdDisplayPartial.yUp;
00096 int yDown = dmCommand->dmCmdDisplayPartial.yDown;
00097
00098
00099 if (xUp < 0 || xUp > SCREEN_WIDTH)
00100 {
00101 ERDM_ERRORPRINTF("Invalid coordinate xUp (%d)", xUp);
00102 return -1;
00103 }
00104 if (xDown < 0 || xDown > SCREEN_WIDTH)
00105 {
00106 ERDM_ERRORPRINTF("Invalid coordinate xDown (%d)", xDown);
00107 return -1;
00108 }
00109 if (yUp < 0 || yUp > SCREEN_HEIGHT)
00110 {
00111 ERDM_ERRORPRINTF("Invalid coordinate yUp (%d)", yUp);
00112 return -1;
00113 }
00114 if (yDown < 0 || yDown > SCREEN_HEIGHT)
00115 {
00116 ERDM_ERRORPRINTF("Invalid coordinate yDown (%d)", yDown);
00117 return -1;
00118 }
00119
00120
00121 if (xUp == xDown || yUp == yDown)
00122 {
00123 ERDM_ERRORPRINTF("Trying to do a partial update of a line (%d,%d):(%d,%d)", xUp, yUp, xDown, yDown);
00124 return -1;
00125 }
00126 }
00127
00128 switch (dmCommand->dmCmdGeneric.cmd)
00129 {
00130 case dmCcDisplay:
00131 case dmCcDisplayPartial:
00132
00133 if ((int) dmCommand->dmCmdDisplay.priority < 0 || (int) dmCommand->dmCmdDisplay.priority > (int) dmCmdPriorUrgent)
00134 {
00135 ERDM_ERRORPRINTF("priority out of range (%d)", (int) dmCommand->dmCmdDisplay.priority);
00136 return -1;
00137 }
00138 if ((int) dmCommand->dmCmdDisplay.qual < 0 || (int) dmCommand->dmCmdDisplay.qual > dmQUndefined)
00139 {
00140 ERDM_ERRORPRINTF("quality out of range (%d)", (int) dmCommand->dmCmdDisplay.qual);
00141 return -1;
00142 }
00143 break;
00144
00145 case dmCcDump:
00146 ERDM_WARNPRINTF("Dump command not yet validated");
00147 break;
00148
00149 case dmCcEraseToWhite:
00150 if ((int) dmCommand->dmCmdDisplay.priority < 0 || (int) dmCommand->dmCmdDisplay.priority > (int) dmCmdPriorUrgent)
00151 {
00152 ERDM_ERRORPRINTF("priority out of range (%d)", (int) dmCommand->dmCmdDisplay.priority);
00153 return -1;
00154 }
00155 break;
00156
00157 case dmCcUndefined:
00158 ERDM_WARNPRINTF("Undefined command");
00159 return -1;
00160 break;
00161
00162 default:
00163 return -1;
00164 break;
00165 }
00166
00167 return 0;
00168 }
00169
00170 int dmParseCommand(erDmCmd_t * pCmd, uDmCommand * dmCommand)
00171 {
00172 switch (pCmd->cc)
00173 {
00174 case (int) dmCcDisplay:
00175 ERDM_LOGPRINTF("%s(%s,%s)", pCmd->name, pCmd->arg[0], pCmd->arg[1]);
00176 dmCommand->dmCmdDisplay.cmd = dmCcDisplay;
00177 dmCommand->dmCmdDisplay.priority = (eDmCmdPriority) atoi(pCmd->arg[0]);
00178 dmCommand->dmCmdDisplay.qual = (eDmQuality) atoi(pCmd->arg[1]);
00179 break;
00180
00181 case (int) dmCcDisplayPartial:
00182 ERDM_LOGPRINTF("%s(%s,%s,%s,%s,%s,%s)", pCmd->name, pCmd->arg[0], pCmd->arg[1], pCmd->arg[2], pCmd->arg[3], pCmd->arg[4],
00183 pCmd->arg[5]);
00184 dmCommand->dmCmdDisplayPartial.cmd = dmCcDisplayPartial;
00185 dmCommand->dmCmdDisplayPartial.priority = (eDmCmdPriority) atoi(pCmd->arg[0]);
00186 dmCommand->dmCmdDisplayPartial.qual = (eDmQuality) atoi(pCmd->arg[1]);
00187 dmCommand->dmCmdDisplayPartial.xUp = atoi(pCmd->arg[2]);
00188 dmCommand->dmCmdDisplayPartial.yUp = atoi(pCmd->arg[3]);
00189 dmCommand->dmCmdDisplayPartial.xDown = atoi(pCmd->arg[4]);
00190 dmCommand->dmCmdDisplayPartial.yDown = atoi(pCmd->arg[5]);
00191 break;
00192
00193 case (int) dmCcDump:
00194 ERDM_LOGPRINTF("%s(%s)", pCmd->name, pCmd->arg[0]);
00195 dmCommand->dmCmdDump.cmd = dmCcDump;
00196 dmCommand->dmCmdDump.priority = (eDmCmdPriority) atoi(pCmd->arg[0]);
00197 break;
00198
00199 case (int) dmCcEraseToWhite:
00200 ERDM_LOGPRINTF("%s(%s)", pCmd->name, pCmd->arg[0]);
00201 dmCommand->dmCmdDump.cmd = dmCcEraseToWhite;
00202 dmCommand->dmCmdDump.priority = (eDmCmdPriority) atoi(pCmd->arg[0]);
00203 break;
00204
00205 case (int) dmCcUndefined:
00206 ERDM_ERRORPRINTF("Undefined command");
00207 dmCommand->dmCmdGeneric.cmd = dmCcUndefined;
00208 return -1;
00209 break;
00210 }
00211 return 0;
00212 }
00213
00214
00215 int dmParseMessage(char *szCommand, erDmCmd_t * pCmd)
00216 {
00217 int i;
00218 char *pChar;
00219 char szToken[DM_MAXCHARONLINE];
00220 int nReqArgs = 0;
00221
00222 pCmd->cc = (int) dmCcUndefined;
00223 for (i = 0; i < DM_N_ARG; i++)
00224 {
00225 strcpy(pCmd->arg[i], "");
00226 }
00227
00228
00229
00230 if (szCommand[0] != '!')
00231 {
00232 ERDM_ERRORPRINTF("Command should start with \'!\'. (%s)", szCommand);
00233 return -1;
00234 }
00235
00236 pChar = szCommand + 1;
00237 i = 0;
00238 while (*pChar != '\0')
00239 {
00240 szToken[i] = '\0';
00241 if (*pChar == ',')
00242 {
00243 pChar++;
00244 break;
00245 }
00246 szToken[i] = *pChar++;
00247 i++;
00248 szToken[i] = '\0';
00249 }
00250
00251
00252 if (!strcmp(szToken, "dmDisplay") || !strcmp(szToken, "0"))
00253 {
00254 strcpy(pCmd->name, szToken);
00255 pCmd->cc = (int) dmCcDisplay;
00256 nReqArgs = 2;
00257 pCmd->nArg = 2;
00258 }
00259 else if (!strcmp(szToken, "dmDisplayPartial") || !strcmp(szToken, "1"))
00260 {
00261 strcpy(pCmd->name, szToken);
00262 pCmd->cc = (int) dmCcDisplayPartial;
00263 nReqArgs = 6;
00264 pCmd->nArg = 6;
00265 }
00266 else if (!strcmp(szToken, "dmDump") || !strcmp(szToken, "2"))
00267 {
00268 strcpy(pCmd->name, szToken);
00269 pCmd->cc = (int) dmCcDump;
00270 nReqArgs = 1;
00271 pCmd->nArg = 1;
00272 }
00273 else if (!strcmp(szToken, "dmEraseToWhite") || !strcmp(szToken, "3"))
00274 {
00275 strcpy(pCmd->name, szToken);
00276 pCmd->cc = (int) dmCcEraseToWhite;
00277 nReqArgs = 1;
00278 pCmd->nArg = 1;
00279 }
00280 else
00281 {
00282 strcpy(pCmd->name, "Undefined");
00283 pCmd->cc = (int) dmCcUndefined;
00284 ERDM_ERRORPRINTF("Command %s \n", szToken);
00285 ERDM_ERRORPRINTF("Error parsing (%s). Command undefined\n", szCommand);
00286 pCmd->nArg = -1;
00287 return -1;
00288 }
00289
00290 if (nReqArgs > 0)
00291 {
00292 erDmGetArgs(pChar, pCmd, nReqArgs);
00293 }
00294 return 0;
00295 }
00296
00297 int dmMessageParser(char *szMessage, uDmCommand * dmCommand)
00298 {
00299
00300 erDmCmd_t cmd;
00301 int nRet;
00302
00303 nRet = dmParseMessage(szMessage, &cmd);
00304 if (nRet != 0)
00305 {
00306 ERDM_ERRORPRINTF("dmParseMessage failed with errorcode %d", nRet);
00307 return -1;
00308 }
00309
00310 nRet = dmParseCommand(&cmd, dmCommand);
00311 if (nRet != 0)
00312 {
00313 ERDM_ERRORPRINTF("dmParseCommand failed with errorcode %d", nRet);
00314 return -1;
00315 }
00316
00317 nRet = dmValidateCommand(dmCommand);
00318 if (nRet != 0)
00319 {
00320 ERDM_ERRORPRINTF("dmValidateCommand failed with errorcode %d", nRet);
00321 return -1;
00322 }
00323 return 0;
00324 }