00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <stdarg.h>
00035 #include <stdlib.h>
00036 #include <ctype.h>
00037
00038 #include "pigpio.h"
00039 #include "command.h"
00040
00041 cmdInfo_t cmdInfo[]=
00042 {
00043
00044
00045 {PI_CMD_BC1, "BC1", 111, 1},
00046 {PI_CMD_BC2, "BC2", 111, 1},
00047
00048 {PI_CMD_BI2CC, "BI2CC", 112, 0},
00049 {PI_CMD_BI2CO, "BI2CO", 131, 0},
00050 {PI_CMD_BI2CZ, "BI2CZ", 193, 6},
00051
00052 {PI_CMD_BR1, "BR1", 101, 3},
00053 {PI_CMD_BR2, "BR2", 101, 3},
00054
00055 {PI_CMD_BS1, "BS1", 111, 1},
00056 {PI_CMD_BS2, "BS2", 111, 1},
00057
00058 {PI_CMD_BSCX, "BSCX", 193, 8},
00059
00060 {PI_CMD_BSPIC, "BSPIC", 112, 0},
00061 {PI_CMD_BSPIO, "BSPIO", 134, 0},
00062 {PI_CMD_BSPIX, "BSPIX", 193, 6},
00063
00064 {PI_CMD_CF1, "CF1", 195, 2},
00065 {PI_CMD_CF2, "CF2", 195, 6},
00066
00067 {PI_CMD_CGI, "CGI", 101, 4},
00068 {PI_CMD_CSI, "CSI", 111, 1},
00069
00070 {PI_CMD_EVM, "EVM", 122, 1},
00071 {PI_CMD_EVT, "EVT", 112, 0},
00072
00073 {PI_CMD_FC, "FC", 112, 0},
00074
00075 {PI_CMD_FG, "FG", 121, 0},
00076
00077 {PI_CMD_FL, "FL", 127, 6},
00078
00079 {PI_CMD_FN, "FN", 131, 0},
00080
00081 {PI_CMD_FO, "FO", 127, 2},
00082 {PI_CMD_FR, "FR", 121, 6},
00083 {PI_CMD_FS, "FS", 133, 2},
00084 {PI_CMD_FW, "FW", 193, 0},
00085
00086 {PI_CMD_GDC, "GDC", 112, 2},
00087 {PI_CMD_GPW, "GPW", 112, 2},
00088
00089 {PI_CMD_HELP, "H", 101, 5},
00090 {PI_CMD_HELP, "HELP", 101, 5},
00091
00092 {PI_CMD_HC, "HC", 121, 0},
00093 {PI_CMD_HP, "HP", 131, 0},
00094
00095 {PI_CMD_HWVER, "HWVER", 101, 4},
00096
00097 {PI_CMD_I2CC, "I2CC", 112, 0},
00098 {PI_CMD_I2CO, "I2CO", 131, 2},
00099
00100 {PI_CMD_I2CPC, "I2CPC", 131, 2},
00101 {PI_CMD_I2CPK, "I2CPK", 194, 6},
00102
00103 {PI_CMD_I2CRB, "I2CRB", 121, 2},
00104 {PI_CMD_I2CRD, "I2CRD", 121, 6},
00105 {PI_CMD_I2CRI, "I2CRI", 131, 6},
00106 {PI_CMD_I2CRK, "I2CRK", 121, 6},
00107 {PI_CMD_I2CRS, "I2CRS", 112, 2},
00108 {PI_CMD_I2CRW, "I2CRW", 121, 2},
00109
00110 {PI_CMD_I2CWB, "I2CWB", 131, 0},
00111 {PI_CMD_I2CWD, "I2CWD", 193, 0},
00112 {PI_CMD_I2CWI, "I2CWI", 194, 0},
00113 {PI_CMD_I2CWK, "I2CWK", 194, 0},
00114 {PI_CMD_I2CWQ, "I2CWQ", 121, 0},
00115 {PI_CMD_I2CWS, "I2CWS", 121, 0},
00116 {PI_CMD_I2CWW, "I2CWW", 131, 0},
00117
00118 {PI_CMD_I2CZ, "I2CZ", 193, 6},
00119
00120 {PI_CMD_MICS, "MICS", 112, 0},
00121 {PI_CMD_MILS, "MILS", 112, 0},
00122
00123 {PI_CMD_MODEG, "MG" , 112, 2},
00124 {PI_CMD_MODEG, "MODEG", 112, 2},
00125
00126 {PI_CMD_MODES, "M", 125, 0},
00127 {PI_CMD_MODES, "MODES", 125, 0},
00128
00129 {PI_CMD_NB, "NB", 122, 0},
00130 {PI_CMD_NC, "NC", 112, 0},
00131 {PI_CMD_NO, "NO", 101, 2},
00132 {PI_CMD_NP, "NP", 112, 0},
00133
00134 {PI_CMD_PADG, "PADG", 112, 2},
00135 {PI_CMD_PADS, "PADS", 121, 0},
00136
00137 {PI_CMD_PARSE, "PARSE", 115, 0},
00138
00139 {PI_CMD_PFG, "PFG", 112, 2},
00140 {PI_CMD_PFS, "PFS", 121, 2},
00141
00142 {PI_CMD_PIGPV, "PIGPV", 101, 4},
00143
00144 {PI_CMD_PRG, "PRG", 112, 2},
00145
00146 {PI_CMD_PROC, "PROC", 115, 2},
00147 {PI_CMD_PROCD, "PROCD", 112, 0},
00148 {PI_CMD_PROCP, "PROCP", 112, 7},
00149 {PI_CMD_PROCR, "PROCR", 191, 0},
00150 {PI_CMD_PROCS, "PROCS", 112, 0},
00151 {PI_CMD_PROCU, "PROCU", 191, 0},
00152
00153 {PI_CMD_PRRG, "PRRG", 112, 2},
00154 {PI_CMD_PRS, "PRS", 121, 2},
00155
00156 {PI_CMD_PUD, "PUD", 126, 0},
00157
00158 {PI_CMD_PWM, "P", 121, 0},
00159 {PI_CMD_PWM, "PWM", 121, 0},
00160
00161 {PI_CMD_READ, "R", 112, 2},
00162 {PI_CMD_READ, "READ", 112, 2},
00163
00164 {PI_CMD_SERRB, "SERRB", 112, 2},
00165 {PI_CMD_SERWB, "SERWB", 121, 0},
00166 {PI_CMD_SERC, "SERC", 112, 0},
00167 {PI_CMD_SERDA, "SERDA", 112, 2},
00168 {PI_CMD_SERO, "SERO", 132, 2},
00169 {PI_CMD_SERR, "SERR", 121, 6},
00170 {PI_CMD_SERW, "SERW", 193, 0},
00171
00172 {PI_CMD_SERVO, "S", 121, 0},
00173 {PI_CMD_SERVO, "SERVO", 121, 0},
00174
00175 {PI_CMD_SHELL, "SHELL", 128, 2},
00176
00177 {PI_CMD_SLR, "SLR", 121, 6},
00178 {PI_CMD_SLRC, "SLRC", 112, 0},
00179 {PI_CMD_SLRO, "SLRO", 131, 0},
00180 {PI_CMD_SLRI, "SLRI", 121, 0},
00181
00182 {PI_CMD_SPIC, "SPIC", 112, 0},
00183 {PI_CMD_SPIO, "SPIO", 131, 2},
00184 {PI_CMD_SPIR, "SPIR", 121, 6},
00185 {PI_CMD_SPIW, "SPIW", 193, 0},
00186 {PI_CMD_SPIX, "SPIX", 193, 6},
00187
00188 {PI_CMD_TICK, "T", 101, 4},
00189 {PI_CMD_TICK, "TICK", 101, 4},
00190
00191 {PI_CMD_TRIG, "TRIG", 131, 0},
00192
00193 {PI_CMD_WDOG, "WDOG", 121, 0},
00194
00195 {PI_CMD_WRITE, "W", 121, 0},
00196 {PI_CMD_WRITE, "WRITE", 121, 0},
00197
00198 {PI_CMD_WVAG, "WVAG", 192, 2},
00199 {PI_CMD_WVAS, "WVAS", 196, 2},
00200 {PI_CMD_WVTAT, "WVTAT", 101, 2},
00201 {PI_CMD_WVBSY, "WVBSY", 101, 2},
00202 {PI_CMD_WVCHA, "WVCHA", 197, 0},
00203 {PI_CMD_WVCLR, "WVCLR", 101, 0},
00204 {PI_CMD_WVCRE, "WVCRE", 101, 2},
00205 {PI_CMD_WVDEL, "WVDEL", 112, 0},
00206 {PI_CMD_WVGO, "WVGO" , 101, 2},
00207 {PI_CMD_WVGOR, "WVGOR", 101, 2},
00208 {PI_CMD_WVHLT, "WVHLT", 101, 0},
00209 {PI_CMD_WVNEW, "WVNEW", 101, 0},
00210 {PI_CMD_WVSC, "WVSC", 112, 2},
00211 {PI_CMD_WVSM, "WVSM", 112, 2},
00212 {PI_CMD_WVSP, "WVSP", 112, 2},
00213 {PI_CMD_WVTX, "WVTX", 112, 2},
00214 {PI_CMD_WVTXM, "WVTXM", 121, 2},
00215 {PI_CMD_WVTXR, "WVTXR", 112, 2},
00216
00217 {PI_CMD_ADD , "ADD" , 111, 0},
00218 {PI_CMD_AND , "AND" , 111, 0},
00219 {PI_CMD_CALL , "CALL" , 114, 0},
00220 {PI_CMD_CMDR ,"CMDR" , 111, 0},
00221 {PI_CMD_CMDW , "CMDW" , 111, 0},
00222 {PI_CMD_CMP , "CMP" , 111, 0},
00223 {PI_CMD_DCR , "DCR" , 113, 0},
00224 {PI_CMD_DCRA , "DCRA" , 101, 0},
00225 {PI_CMD_DIV , "DIV" , 111, 0},
00226 {PI_CMD_EVTWT, "EVTWT", 111, 0},
00227 {PI_CMD_HALT , "HALT" , 101, 0},
00228 {PI_CMD_INR , "INR" , 113, 0},
00229 {PI_CMD_INRA , "INRA" , 101, 0},
00230 {PI_CMD_JM , "JM" , 114, 0},
00231 {PI_CMD_JMP , "JMP" , 114, 0},
00232 {PI_CMD_JNZ , "JNZ" , 114, 0},
00233 {PI_CMD_JP , "JP" , 114, 0},
00234 {PI_CMD_JZ , "JZ" , 114, 0},
00235 {PI_CMD_LD , "LD" , 123, 0},
00236 {PI_CMD_LDA , "LDA" , 111, 0},
00237 {PI_CMD_LDAB , "LDAB" , 111, 0},
00238 {PI_CMD_MLT , "MLT" , 111, 0},
00239 {PI_CMD_MOD , "MOD" , 111, 0},
00240 {PI_CMD_NOP , "NOP" , 101, 0},
00241 {PI_CMD_OR , "OR" , 111, 0},
00242 {PI_CMD_POP , "POP" , 113, 0},
00243 {PI_CMD_POPA , "POPA" , 101, 0},
00244 {PI_CMD_PUSH , "PUSH" , 113, 0},
00245 {PI_CMD_PUSHA, "PUSHA", 101, 0},
00246 {PI_CMD_RET , "RET" , 101, 0},
00247 {PI_CMD_RL , "RL" , 123, 0},
00248 {PI_CMD_RLA , "RLA" , 111, 0},
00249 {PI_CMD_RR , "RR" , 123, 0},
00250 {PI_CMD_RRA , "RRA" , 111, 0},
00251 {PI_CMD_STA , "STA" , 113, 0},
00252 {PI_CMD_STAB , "STAB" , 111, 0},
00253 {PI_CMD_SUB , "SUB" , 111, 0},
00254 {PI_CMD_SYS , "SYS" , 116, 0},
00255 {PI_CMD_TAG , "TAG" , 114, 0},
00256 {PI_CMD_WAIT , "WAIT" , 111, 0},
00257 {PI_CMD_X , "X" , 124, 0},
00258 {PI_CMD_XA , "XA" , 113, 0},
00259 {PI_CMD_XOR , "XOR" , 111, 0},
00260
00261 };
00262
00263
00264 char * cmdUsage = "\n\
00265 BC1 bits Clear GPIO in bank 1\n\
00266 BC2 bits Clear GPIO in bank 2\n\
00267 BI2CC sda Close bit bang I2C\n\
00268 BI2CO sda scl baud | Open bit bang I2C\n\
00269 BI2CZ sda ... I2C bit bang multiple transactions\n\
00270 \n\
00271 BSPIC cs Close bit bang SPI\n\
00272 BSPIO cs miso mosi sclk baud flag | Open bit bang SPI\n\
00273 BSPIX cs ... SPI bit bang transfer\n\
00274 \n\
00275 BR1 Read bank 1 GPIO\n\
00276 BR2 Read bank 2 GPIO\n\
00277 \n\
00278 BS1 bits Set GPIO in bank 1\n\
00279 BS2 bits Set GPIO in bank 2\n\
00280 \n\
00281 BSCX bctl bvs BSC I2C/SPI transfer\n\
00282 \n\
00283 CF1 ... Custom function 1\n\
00284 CF2 ... Custom function 2\n\
00285 \n\
00286 CGI Configuration get internals\n\
00287 CSI v Configuration set internals\n\
00288 \n\
00289 EVM h bits Set events to monitor\n\
00290 EVT n Trigger event\n\
00291 \n\
00292 FC h Close file handle\n\
00293 FG g steady Set glitch filter on GPIO\n\
00294 FL pat n List files which match pattern\n\
00295 FN g steady active | Set noise filter on GPIO\n\
00296 FO file mode Open a file in mode\n\
00297 FR h n Read bytes from file handle\n\
00298 FS h n from Seek to file handle position\n\
00299 FW h ... Write bytes to file handle\n\
00300 \n\
00301 GDC g Get PWM dutycycle for GPIO\n\
00302 GPW g Get servo pulsewidth for GPIO\n\
00303 \n\
00304 H/HELP Display command help\n\
00305 HC g f Set hardware clock frequency\n\
00306 HP g f dc Set hardware PWM frequency and dutycycle\n\
00307 HWVER Get hardware version\n\
00308 \n\
00309 I2CC h Close I2C handle\n\
00310 I2CO bus device flags | Open I2C bus and device with flags\n\
00311 I2CPC h r word SMBus Process Call: exchange register with word\n\
00312 I2CPK h r ... SMBus Block Process Call: exchange data bytes with register\n\
00313 I2CRB h r SMBus Read Byte Data: read byte from register\n\
00314 I2CRD h n I2C Read bytes\n\
00315 I2CRI h r n SMBus Read I2C Block Data: read bytes from register\n\
00316 I2CRK h r SMBus Read Block Data: read data from register\n\
00317 I2CRS h SMBus Read Byte: read byte\n\
00318 I2CRW h r SMBus Read Word Data: read word from register\n\
00319 I2CWB h r byte SMBus Write Byte Data: write byte to register\n\
00320 I2CWD h ... I2C Write data\n\
00321 I2CWI h r ... SMBus Write I2C Block Data\n\
00322 I2CWK h r ... SMBus Write Block Data: write data to register\n\
00323 I2CWQ h b SMBus Write Quick: write bit\n\
00324 I2CWS h b SMBus Write Byte: write byte\n\
00325 I2CWW h r word SMBus Write Word Data: write word to register\n\
00326 I2CZ h ... I2C multiple transactions\n\
00327 \n\
00328 M/MODES g mode Set GPIO mode\n\
00329 MG/MODEG g Get GPIO mode\n\
00330 MICS n Delay for microseconds\n\
00331 MILS n Delay for milliseconds\n\
00332 \n\
00333 NB h bits Start notification\n\
00334 NC h Close notification\n\
00335 NO Request a notification\n\
00336 NP h Pause notification\n\
00337 \n\
00338 P/PWM g v Set GPIO PWM value\n\
00339 PADG pad Get pad drive strength\n\
00340 PADS pad v Set pad drive strength\n\
00341 PARSE text Validate script\n\
00342 PFG g Get GPIO PWM frequency\n\
00343 PFS g v Set GPIO PWM frequency\n\
00344 PIGPV Get pigpio library version\n\
00345 PRG g Get GPIO PWM range\n\
00346 PROC text Store script\n\
00347 PROCD sid Delete script\n\
00348 PROCP sid Get script status and parameters\n\
00349 PROCR sid ... Run script\n\
00350 PROCS sid Stop script\n\
00351 PROCU sid ... Set script parameters\n\
00352 PRRG g Get GPIO PWM real range\n\
00353 PRS g v Set GPIO PWM range\n\
00354 PUD g pud Set GPIO pull up/down\n\
00355 \n\
00356 R/READ g Read GPIO level\n\
00357 \n\
00358 S/SERVO g v Set GPIO servo pulsewidth\n\
00359 SERC h Close serial handle\n\
00360 SERDA h Check for serial data ready to read\n\
00361 SERO text baud flags | Open serial device at baud with flags\n\
00362 SERR h n Read bytes from serial handle\n\
00363 SERRB h Read byte from serial handle\n\
00364 SERW h ... Write bytes to serial handle\n\
00365 SERWB h byte Write byte to serial handle\n\
00366 SHELL name str Execute a shell command\n\
00367 SLR g v Read bit bang serial data from GPIO\n\
00368 SLRC g Close GPIO for bit bang serial data\n\
00369 SLRO g baud bitlen | Open GPIO for bit bang serial data\n\
00370 SLRI g invert Invert serial logic (1 invert, 0 normal)\n\
00371 SPIC h SPI close handle\n\
00372 SPIO channel baud flags | SPI open channel at baud with flags\n\
00373 SPIR h v SPI read bytes from handle\n\
00374 SPIW h ... SPI write bytes to handle\n\
00375 SPIX h ... SPI transfer bytes to handle\n\
00376 \n\
00377 T/TICK Get current tick\n\
00378 TRIG g micros l Trigger level for micros on GPIO\n\
00379 \n\
00380 W/WRITE g l Write level to GPIO\n\
00381 WDOG g millis Set millisecond watchdog on GPIO\n\
00382 WVAG triplets Wave add generic pulses\n\
00383 WVAS g baud bitlen stopbits offset ... | Wave add serial data\n\
00384 WVBSY Check if wave busy\n\
00385 WVCHA Transmit a chain of waves\n\
00386 WVCLR Wave clear\n\
00387 WVCRE Create wave from added pulses\n\
00388 WVDEL wid Delete waves w and higher\n\
00389 WVGO Wave transmit (DEPRECATED)\n\
00390 WVGOR Wave transmit repeatedly (DEPRECATED)\n\
00391 WVHLT Wave stop\n\
00392 WVNEW Start a new empty wave\n\
00393 WVSC 0,1,2 Wave get DMA control block stats\n\
00394 WVSM 0,1,2 Wave get micros stats\n\
00395 WVSP 0,1,2 Wave get pulses stats\n\
00396 WVTAT Returns the current transmitting wave\n\
00397 WVTX wid Transmit wave as one-shot\n\
00398 WVTXM wid wmde Transmit wave using mode\n\
00399 WVTXR wid Transmit wave repeatedly\n\
00400 \n\
00401 Numbers may be entered as hex (prefix 0x), octal (prefix 0),\n\
00402 otherwise they are assumed to be decimal.\n\
00403 \n\
00404 Examples\n\
00405 \n\
00406 pigs w 4 1 # set GPIO 4 high\n\
00407 pigs r 5 # read GPIO 5\n\
00408 pigs t # get current tick\n\
00409 pigs i2co 1 0x20 0 # get handle to device 0x20 on I2C bus 1\n\
00410 \n\
00411 man pigs for full details.\n\
00412 \n";
00413
00414 typedef struct
00415 {
00416 int error;
00417 char * str;
00418 } errInfo_t;
00419
00420 static errInfo_t errInfo[]=
00421 {
00422 {PI_INIT_FAILED , "pigpio initialisation failed"},
00423 {PI_BAD_USER_GPIO , "GPIO not 0-31"},
00424 {PI_BAD_GPIO , "GPIO not 0-53"},
00425 {PI_BAD_MODE , "mode not 0-7"},
00426 {PI_BAD_LEVEL , "level not 0-1"},
00427 {PI_BAD_PUD , "pud not 0-2"},
00428 {PI_BAD_PULSEWIDTH , "pulsewidth not 0 or 500-2500"},
00429 {PI_BAD_DUTYCYCLE , "dutycycle not 0-range (default 255)"},
00430 {PI_BAD_TIMER , "timer not 0-9"},
00431 {PI_BAD_MS , "ms not 10-60000"},
00432 {PI_BAD_TIMETYPE , "timetype not 0-1"},
00433 {PI_BAD_SECONDS , "seconds < 0"},
00434 {PI_BAD_MICROS , "micros not 0-999999"},
00435 {PI_TIMER_FAILED , "gpioSetTimerFunc failed"},
00436 {PI_BAD_WDOG_TIMEOUT , "timeout not 0-60000"},
00437 {PI_NO_ALERT_FUNC , "DEPRECATED"},
00438 {PI_BAD_CLK_PERIPH , "clock peripheral not 0-1"},
00439 {PI_BAD_CLK_SOURCE , "DEPRECATED"},
00440 {PI_BAD_CLK_MICROS , "clock micros not 1, 2, 4, 5, 8, or 10"},
00441 {PI_BAD_BUF_MILLIS , "buf millis not 100-10000"},
00442 {PI_BAD_DUTYRANGE , "dutycycle range not 25-40000"},
00443 {PI_BAD_SIGNUM , "signum not 0-63"},
00444 {PI_BAD_PATHNAME , "can't open pathname"},
00445 {PI_NO_HANDLE , "no handle available"},
00446 {PI_BAD_HANDLE , "unknown handle"},
00447 {PI_BAD_IF_FLAGS , "ifFlags > 4"},
00448 {PI_BAD_CHANNEL , "DMA channel not 0-14"},
00449 {PI_BAD_SOCKET_PORT , "socket port not 1024-30000"},
00450 {PI_BAD_FIFO_COMMAND , "unknown fifo command"},
00451 {PI_BAD_SECO_CHANNEL , "DMA secondary channel not 0-14"},
00452 {PI_NOT_INITIALISED , "function called before gpioInitialise"},
00453 {PI_INITIALISED , "function called after gpioInitialise"},
00454 {PI_BAD_WAVE_MODE , "waveform mode not 0-1"},
00455 {PI_BAD_CFG_INTERNAL , "bad parameter in gpioCfgInternals call"},
00456 {PI_BAD_WAVE_BAUD , "baud rate not 50-250K(RX)/50-1M(TX)"},
00457 {PI_TOO_MANY_PULSES , "waveform has too many pulses"},
00458 {PI_TOO_MANY_CHARS , "waveform has too many chars"},
00459 {PI_NOT_SERIAL_GPIO , "no bit bang serial read in progress on GPIO"},
00460 {PI_BAD_SERIAL_STRUC , "bad (null) serial structure parameter"},
00461 {PI_BAD_SERIAL_BUF , "bad (null) serial buf parameter"},
00462 {PI_NOT_PERMITTED , "no permission to update GPIO"},
00463 {PI_SOME_PERMITTED , "no permission to update one or more GPIO"},
00464 {PI_BAD_WVSC_COMMND , "bad WVSC subcommand"},
00465 {PI_BAD_WVSM_COMMND , "bad WVSM subcommand"},
00466 {PI_BAD_WVSP_COMMND , "bad WVSP subcommand"},
00467 {PI_BAD_PULSELEN , "trigger pulse length not 1-100"},
00468 {PI_BAD_SCRIPT , "invalid script"},
00469 {PI_BAD_SCRIPT_ID , "unknown script id"},
00470 {PI_BAD_SER_OFFSET , "add serial data offset > 30 minute"},
00471 {PI_GPIO_IN_USE , "GPIO already in use"},
00472 {PI_BAD_SERIAL_COUNT , "must read at least a byte at a time"},
00473 {PI_BAD_PARAM_NUM , "script parameter id not 0-9"},
00474 {PI_DUP_TAG , "script has duplicate tag"},
00475 {PI_TOO_MANY_TAGS , "script has too many tags"},
00476 {PI_BAD_SCRIPT_CMD , "illegal script command"},
00477 {PI_BAD_VAR_NUM , "script variable id not 0-149"},
00478 {PI_NO_SCRIPT_ROOM , "no more room for scripts"},
00479 {PI_NO_MEMORY , "can't allocate temporary memory"},
00480 {PI_SOCK_READ_FAILED , "socket read failed"},
00481 {PI_SOCK_WRIT_FAILED , "socket write failed"},
00482 {PI_TOO_MANY_PARAM , "too many script parameters (> 10)"},
00483 {PI_SCRIPT_NOT_READY , "script initialising"},
00484 {PI_BAD_TAG , "script has unresolved tag"},
00485 {PI_BAD_MICS_DELAY , "bad MICS delay (too large)"},
00486 {PI_BAD_MILS_DELAY , "bad MILS delay (too large)"},
00487 {PI_BAD_WAVE_ID , "non existent wave id"},
00488 {PI_TOO_MANY_CBS , "No more CBs for waveform"},
00489 {PI_TOO_MANY_OOL , "No more OOL for waveform"},
00490 {PI_EMPTY_WAVEFORM , "attempt to create an empty waveform"},
00491 {PI_NO_WAVEFORM_ID , "no more waveform ids"},
00492 {PI_I2C_OPEN_FAILED , "can't open I2C device"},
00493 {PI_SER_OPEN_FAILED , "can't open serial device"},
00494 {PI_SPI_OPEN_FAILED , "can't open SPI device"},
00495 {PI_BAD_I2C_BUS , "bad I2C bus"},
00496 {PI_BAD_I2C_ADDR , "bad I2C address"},
00497 {PI_BAD_SPI_CHANNEL , "bad SPI channel"},
00498 {PI_BAD_FLAGS , "bad i2c/spi/ser open flags"},
00499 {PI_BAD_SPI_SPEED , "bad SPI speed"},
00500 {PI_BAD_SER_DEVICE , "bad serial device name"},
00501 {PI_BAD_SER_SPEED , "bad serial baud rate"},
00502 {PI_BAD_PARAM , "bad i2c/spi/ser parameter"},
00503 {PI_I2C_WRITE_FAILED , "I2C write failed"},
00504 {PI_I2C_READ_FAILED , "I2C read failed"},
00505 {PI_BAD_SPI_COUNT , "bad SPI count"},
00506 {PI_SER_WRITE_FAILED , "ser write failed"},
00507 {PI_SER_READ_FAILED , "ser read failed"},
00508 {PI_SER_READ_NO_DATA , "ser read no data available"},
00509 {PI_UNKNOWN_COMMAND , "unknown command"},
00510 {PI_SPI_XFER_FAILED , "spi xfer/read/write failed"},
00511 {PI_BAD_POINTER , "bad (NULL) pointer"},
00512 {PI_NO_AUX_SPI , "no auxiliary SPI on Pi A or B"},
00513 {PI_NOT_PWM_GPIO , "GPIO is not in use for PWM"},
00514 {PI_NOT_SERVO_GPIO , "GPIO is not in use for servo pulses"},
00515 {PI_NOT_HCLK_GPIO , "GPIO has no hardware clock"},
00516 {PI_NOT_HPWM_GPIO , "GPIO has no hardware PWM"},
00517 {PI_BAD_HPWM_FREQ , "hardware PWM frequency not 1-125M"},
00518 {PI_BAD_HPWM_DUTY , "hardware PWM dutycycle not 0-1M"},
00519 {PI_BAD_HCLK_FREQ , "hardware clock frequency not 4689-250M"},
00520 {PI_BAD_HCLK_PASS , "need password to use hardware clock 1"},
00521 {PI_HPWM_ILLEGAL , "illegal, PWM in use for main clock"},
00522 {PI_BAD_DATABITS , "serial data bits not 1-32"},
00523 {PI_BAD_STOPBITS , "serial (half) stop bits not 2-8"},
00524 {PI_MSG_TOOBIG , "socket/pipe message too big"},
00525 {PI_BAD_MALLOC_MODE , "bad memory allocation mode"},
00526 {PI_TOO_MANY_SEGS , "too many I2C transaction segments"},
00527 {PI_BAD_I2C_SEG , "an I2C transaction segment failed"},
00528 {PI_BAD_SMBUS_CMD , "SMBus command not supported by driver"},
00529 {PI_NOT_I2C_GPIO , "no bit bang I2C in progress on GPIO"},
00530 {PI_BAD_I2C_WLEN , "bad I2C write length"},
00531 {PI_BAD_I2C_RLEN , "bad I2C read length"},
00532 {PI_BAD_I2C_CMD , "bad I2C command"},
00533 {PI_BAD_I2C_BAUD , "bad I2C baud rate, not 50-500k"},
00534 {PI_CHAIN_LOOP_CNT , "bad chain loop count"},
00535 {PI_BAD_CHAIN_LOOP , "empty chain loop"},
00536 {PI_CHAIN_COUNTER , "too many chain counters"},
00537 {PI_BAD_CHAIN_CMD , "bad chain command"},
00538 {PI_BAD_CHAIN_DELAY , "bad chain delay micros"},
00539 {PI_CHAIN_NESTING , "chain counters nested too deeply"},
00540 {PI_CHAIN_TOO_BIG , "chain is too long"},
00541 {PI_DEPRECATED , "deprecated function removed"},
00542 {PI_BAD_SER_INVERT , "bit bang serial invert not 0 or 1"},
00543 {PI_BAD_EDGE , "bad ISR edge, not 1, 1, or 2"},
00544 {PI_BAD_ISR_INIT , "bad ISR initialisation"},
00545 {PI_BAD_FOREVER , "loop forever must be last chain command"},
00546 {PI_BAD_FILTER , "bad filter parameter"},
00547 {PI_BAD_PAD , "bad pad number"},
00548 {PI_BAD_STRENGTH , "bad pad drive strength"},
00549 {PI_FIL_OPEN_FAILED , "file open failed"},
00550 {PI_BAD_FILE_MODE , "bad file mode"},
00551 {PI_BAD_FILE_FLAG , "bad file flag"},
00552 {PI_BAD_FILE_READ , "bad file read"},
00553 {PI_BAD_FILE_WRITE , "bad file write"},
00554 {PI_FILE_NOT_ROPEN , "file not open for read"},
00555 {PI_FILE_NOT_WOPEN , "file not open for write"},
00556 {PI_BAD_FILE_SEEK , "bad file seek"},
00557 {PI_NO_FILE_MATCH , "no files match pattern"},
00558 {PI_NO_FILE_ACCESS , "no permission to access file"},
00559 {PI_FILE_IS_A_DIR , "file is a directory"},
00560 {PI_BAD_SHELL_STATUS , "bad shell return status"},
00561 {PI_BAD_SCRIPT_NAME , "bad script name"},
00562 {PI_BAD_SPI_BAUD , "bad SPI baud rate, not 50-500k"},
00563 {PI_NOT_SPI_GPIO , "no bit bang SPI in progress on GPIO"},
00564 {PI_BAD_EVENT_ID , "bad event id"},
00565 {PI_CMD_INTERRUPTED , "command interrupted, Python"},
00566
00567 };
00568
00569 static char * fmtMdeStr="RW540123";
00570 static char * fmtPudStr="ODU";
00571
00572 static int cmdMatch(char *str)
00573 {
00574 int i;
00575
00576 for (i=0; i<(sizeof(cmdInfo)/sizeof(cmdInfo_t)); i++)
00577 {
00578 if (strcasecmp(str, cmdInfo[i].name) == 0) return i;
00579 }
00580 return CMD_UNKNOWN_CMD;
00581 }
00582
00583 static int getNum(char *str, uint32_t *val, int8_t *opt)
00584 {
00585 int f, n;
00586 intmax_t v;
00587
00588 *opt = 0;
00589
00590 f = sscanf(str, " %ji %n", &v, &n);
00591
00592 if (f == 1)
00593 {
00594 *val = v;
00595 *opt = CMD_NUMERIC;
00596 return n;
00597 }
00598
00599 f = sscanf(str, " v%ji %n", &v, &n);
00600
00601 if (f == 1)
00602 {
00603 *val = v;
00604 if (v < PI_MAX_SCRIPT_VARS) *opt = CMD_VAR;
00605 else *opt = -CMD_VAR;
00606 return n;
00607 }
00608
00609 f = sscanf(str, " p%ji %n", &v, &n);
00610
00611 if (f == 1)
00612 {
00613 *val = v;
00614 if (v < PI_MAX_SCRIPT_PARAMS) *opt = CMD_PAR;
00615 else *opt = -CMD_PAR;
00616 return n;
00617 }
00618
00619 return 0;
00620 }
00621
00622 static char intCmdStr[32];
00623
00624 char *cmdStr(void)
00625 {
00626 return intCmdStr;
00627 }
00628
00629 int cmdParse(
00630 char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl)
00631 {
00632 int f, valid, idx, val, pp, pars, n, n2;
00633 char *p8;
00634 int32_t *p32;
00635 char c;
00636 uint32_t tp1=0, tp2=0, tp3=0, tp4=0, tp5=0;
00637 int8_t to1, to2, to3, to4, to5;
00638 int eaten;
00639
00640
00641 if (ext_len < (4 * CMD_MAX_PARAM)) return CMD_EXT_TOO_SMALL;
00642
00643 bzero(&ctl->opt, sizeof(ctl->opt));
00644
00645 sscanf(buf+ctl->eaten, " %31s %n", intCmdStr, &pp);
00646
00647 ctl->eaten += pp;
00648
00649 p[0] = -1;
00650
00651 idx = cmdMatch(intCmdStr);
00652
00653 if (idx < 0) return idx;
00654
00655 valid = 0;
00656
00657 p[0] = cmdInfo[idx].cmd;
00658 p[1] = 0;
00659 p[2] = 0;
00660 p[3] = 0;
00661
00662 switch (cmdInfo[idx].vt)
00663 {
00664 case 101:
00665
00666
00667
00668
00669
00670
00671 valid = 1;
00672
00673 break;
00674
00675 case 111:
00676
00677
00678
00679
00680
00681 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00682
00683 if (ctl->opt[1] > 0) valid = 1;
00684
00685 break;
00686
00687 case 112:
00688
00689
00690
00691
00692
00693
00694 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00695
00696 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0)) valid = 1;
00697
00698 break;
00699
00700 case 113:
00701
00702
00703
00704 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00705
00706 if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS)) valid = 1;
00707
00708 break;
00709
00710 case 114:
00711
00712
00713
00714 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00715 if (ctl->opt[1] == CMD_NUMERIC) valid = 1;
00716
00717 break;
00718
00719 case 115:
00720
00721
00722
00723 p[3] = strlen(buf+ctl->eaten);
00724 memcpy(ext, buf+ctl->eaten, p[3]);
00725 ctl->eaten += p[3];
00726 valid = 1;
00727
00728 break;
00729
00730 case 116:
00731
00732
00733
00734 f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00735 if ((f >= 0) && n)
00736 {
00737 p[3] = n;
00738 ctl->opt[3] = CMD_NUMERIC;
00739 memcpy(ext, buf+ctl->eaten, n);
00740 ctl->eaten += n2;
00741 valid = 1;
00742 }
00743
00744 break;
00745
00746 case 121:
00747
00748
00749
00750
00751
00752 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00753 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00754
00755 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00756 (ctl->opt[2] > 0) && ((int)p[2] >= 0)) valid = 1;
00757
00758 break;
00759
00760 case 122:
00761
00762
00763
00764 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00765 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00766
00767 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00768 (ctl->opt[2] > 0)) valid = 1;
00769
00770 break;
00771
00772 case 123:
00773
00774
00775
00776 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00777 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00778
00779 if ((ctl->opt[1] > 0) &&
00780 (p[1] < PI_MAX_SCRIPT_VARS) &&
00781 (ctl->opt[2] > 0)) valid = 1;
00782
00783 break;
00784
00785 case 124:
00786
00787
00788
00789 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00790 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00791
00792 if ((ctl->opt[1] > 0) && (p[1] < PI_MAX_SCRIPT_VARS) &&
00793 (ctl->opt[2] > 0) && (p[2] < PI_MAX_SCRIPT_VARS)) valid = 1;
00794
00795 break;
00796
00797 case 125:
00798
00799
00800
00801 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00802
00803 f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
00804
00805 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) && (f >= 1))
00806 {
00807 ctl->eaten += n;
00808 val = toupper(c);
00809 p8 = strchr(fmtMdeStr, val);
00810
00811 if (p8 != NULL)
00812 {
00813 val = p8 - fmtMdeStr;
00814 p[2] = val;
00815 valid = 1;
00816 }
00817 }
00818
00819 break;
00820
00821 case 126:
00822
00823
00824
00825 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00826
00827 f = sscanf(buf+ctl->eaten, " %c %n", &c, &n);
00828
00829 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) && (f >= 1))
00830 {
00831 ctl->eaten += n;
00832 val = toupper(c);
00833 p8 = strchr(fmtPudStr, val);
00834 if (p8 != NULL)
00835 {
00836 val = p8 - fmtPudStr;
00837 p[2] = val;
00838 valid = 1;
00839 }
00840 }
00841
00842 break;
00843
00844 case 127:
00845
00846
00847
00848 f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00849 if ((f >= 0) && n)
00850 {
00851 p[3] = n;
00852 ctl->opt[2] = CMD_NUMERIC;
00853 memcpy(ext, buf+ctl->eaten, n);
00854 ctl->eaten += n2;
00855
00856 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00857
00858 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0))
00859 valid = 1;
00860 }
00861
00862 break;
00863
00864 case 128:
00865
00866
00867
00868
00869 f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00870
00871 if ((f >= 0) && n)
00872 {
00873 valid = 1;
00874
00875 p[1] = n;
00876 memcpy(ext, buf+ctl->eaten, n);
00877 ctl->eaten += n;
00878 ext[n] = 0;
00879
00880 n2 = strlen(buf+ctl->eaten+1);
00881 memcpy(ext+n+1, buf+ctl->eaten+1, n2);
00882 ctl->eaten += n2;
00883 ctl->eaten ++;
00884 p[3] = p[1] + n2 + 1;
00885 }
00886
00887 break;
00888
00889 case 131:
00890
00891
00892
00893
00894 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00895 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00896 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &ctl->opt[3]);
00897
00898 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00899 (ctl->opt[2] > 0) && ((int)p[2] >= 0) &&
00900 (ctl->opt[3] > 0) && ((int)tp1 >= 0))
00901 {
00902 p[3] = 4;
00903 memcpy(ext, &tp1, 4);
00904 valid = 1;
00905 }
00906
00907 break;
00908
00909 case 132:
00910
00911
00912
00913 f = sscanf(buf+ctl->eaten, " %*s%n %n", &n, &n2);
00914 if ((f >= 0) && n)
00915 {
00916 p[3] = n;
00917 ctl->opt[2] = CMD_NUMERIC;
00918 memcpy(ext, buf+ctl->eaten, n);
00919 ctl->eaten += n2;
00920
00921 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00922 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00923
00924 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00925 (ctl->opt[2] > 0) && ((int)p[2] >= 0))
00926 valid = 1;
00927 }
00928
00929 break;
00930
00931 case 133:
00932
00933
00934
00935
00936 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00937 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
00938 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00939
00940 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00941 (ctl->opt[2] > 0) &&
00942 (to1 == CMD_NUMERIC) && ((int)tp1 >= 0))
00943 {
00944 p[3] = 4;
00945 memcpy(ext, &tp1, 4);
00946 valid = 1;
00947 }
00948
00949 break;
00950
00951 case 134:
00952
00953
00954
00955
00956 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00957 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00958 ctl->eaten += getNum(buf+ctl->eaten, &tp2, &to2);
00959 ctl->eaten += getNum(buf+ctl->eaten, &tp3, &to3);
00960 ctl->eaten += getNum(buf+ctl->eaten, &tp4, &to4);
00961 ctl->eaten += getNum(buf+ctl->eaten, &tp5, &to5);
00962
00963 if ((ctl->opt[1] > 0) && ((int)p[1] >= 0) &&
00964 (to1 == CMD_NUMERIC) && ((int)tp1 >= 0) &&
00965 (to2 == CMD_NUMERIC) && ((int)tp2 >= 0) &&
00966 (to3 == CMD_NUMERIC) && ((int)tp3 >= 0) &&
00967 (to4 == CMD_NUMERIC) && ((int)tp4 >= 0) &&
00968 (to5 == CMD_NUMERIC))
00969 {
00970 p[3] = 5 * 4;
00971 memcpy(ext+ 0, &tp1, 4);
00972 memcpy(ext+ 4, &tp2, 4);
00973 memcpy(ext+ 8, &tp3, 4);
00974 memcpy(ext+12, &tp4, 4);
00975 memcpy(ext+16, &tp5, 4);
00976 valid = 1;
00977 }
00978
00979 break;
00980
00981 case 191:
00982
00983
00984
00985
00986 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
00987
00988 if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
00989 {
00990 pars = 0;
00991 p32 = (int32_t *)ext;
00992
00993 while (pars < PI_MAX_SCRIPT_PARAMS)
00994 {
00995 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
00996 if (to1 == CMD_NUMERIC)
00997 {
00998 pars++;
00999 *p32++ = tp1;
01000 }
01001 else break;
01002 }
01003
01004 p[3] = pars * 4;
01005
01006 valid = 1;
01007 }
01008
01009 break;
01010
01011 case 192:
01012
01013
01014
01015
01016
01017 pars = 0;
01018 p32 = (int32_t *)ext;
01019
01020 while (pars < CMD_MAX_PARAM)
01021 {
01022 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
01023 if (to1 == CMD_NUMERIC)
01024 {
01025 pars++;
01026 *p32++ = tp1;
01027 }
01028 else break;
01029 }
01030
01031 p[3] = pars * 4;
01032
01033 if (pars && ((pars % 3) == 0)) valid = 1;
01034
01035 break;
01036
01037 case 193:
01038
01039
01040
01041
01042
01043
01044 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01045
01046 if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0))
01047 {
01048 pars = 0;
01049 p8 = ext;
01050
01051 while (pars < CMD_MAX_PARAM)
01052 {
01053 eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01054 if (to1 == CMD_NUMERIC)
01055 {
01056 if (((int)tp1>=0) && ((int)tp1<=255))
01057 {
01058 pars++;
01059 *p8++ = tp1;
01060 ctl->eaten += eaten;
01061 }
01062 else break;
01063 }
01064 else break;
01065 }
01066
01067 p[3] = pars;
01068
01069 if (pars || (p[0]==PI_CMD_BSCX)) valid = 1;
01070 }
01071
01072 break;
01073
01074 case 194:
01075
01076
01077
01078
01079 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01080 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01081
01082 if ((ctl->opt[1] == CMD_NUMERIC) &&
01083 (ctl->opt[2] == CMD_NUMERIC) &&
01084 ((int)p[1]>=0) && ((int)p[2]>=0) && ((int)p[2]<=255))
01085 {
01086 pars = 0;
01087 p8 = ext;
01088
01089 while (pars < 32)
01090 {
01091 eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01092 if (to1 == CMD_NUMERIC)
01093 {
01094 if (((int)tp1>=0) && ((int)tp1<=255))
01095 {
01096 pars++;
01097 *p8++ = tp1;
01098 ctl->eaten += eaten;
01099 }
01100 else break;
01101 }
01102 else break;
01103 }
01104
01105 p[3] = pars;
01106
01107 if (pars > 0) valid = 1;
01108 }
01109
01110 break;
01111
01112 case 195:
01113
01114
01115
01116 valid = 1;
01117
01118 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01119
01120 if (ctl->opt[1] == CMD_NUMERIC)
01121 {
01122 if ((int)p[1] >= 0)
01123 {
01124 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01125
01126 if (ctl->opt[2] == CMD_NUMERIC)
01127 {
01128 if ((int)p[2] >= 0)
01129 {
01130 pars = 0;
01131 p8 = ext;
01132
01133 while (pars < CMD_MAX_PARAM)
01134 {
01135 eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01136 if (to1 == CMD_NUMERIC)
01137 {
01138 if (((int)tp1>=0) && ((int)tp1<=255))
01139 {
01140 pars++;
01141 *p8++ = tp1;
01142 ctl->eaten += eaten;
01143 }
01144 else break;
01145 }
01146 else break;
01147 }
01148
01149 p[3] = pars;
01150 }
01151 else valid = 0;
01152 }
01153 }
01154 else valid = 0;
01155 }
01156
01157 break;
01158
01159 case 196:
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 ctl->eaten += getNum(buf+ctl->eaten, &p[1], &ctl->opt[1]);
01173 ctl->eaten += getNum(buf+ctl->eaten, &p[2], &ctl->opt[2]);
01174 ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
01175 ctl->eaten += getNum(buf+ctl->eaten, &tp2, &to2);
01176 ctl->eaten += getNum(buf+ctl->eaten, &tp3, &to3);
01177
01178 if ((ctl->opt[1] == CMD_NUMERIC) && ((int)p[1] >= 0) &&
01179 (ctl->opt[2] == CMD_NUMERIC) && ((int)p[2] > 0) &&
01180 (to1 == CMD_NUMERIC) &&
01181 (to2 == CMD_NUMERIC) &&
01182 (to3 == CMD_NUMERIC))
01183 {
01184 pars = 0;
01185
01186 memcpy(ext, &tp1, 4);
01187 memcpy(ext+4, &tp2, 4);
01188 memcpy(ext+8, &tp3, 4);
01189 p8 = ext + 12;
01190 while (pars < CMD_MAX_PARAM)
01191 {
01192 eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01193 if (to1 == CMD_NUMERIC)
01194 {
01195 if (((int)tp1>=0) && ((int)tp1<=255))
01196 {
01197 *p8++ = tp1;
01198 pars++;
01199 ctl->eaten += eaten;
01200 }
01201 else break;
01202 }
01203 else break;
01204 }
01205
01206 p[3] = pars + 12;
01207
01208 if (pars > 0) valid = 1;
01209 }
01210
01211 break;
01212
01213 case 197:
01214
01215
01216
01217 pars = 0;
01218 p8 = ext;
01219
01220 while (pars < CMD_MAX_PARAM)
01221 {
01222 eaten = getNum(buf+ctl->eaten, &tp1, &to1);
01223 if (to1 == CMD_NUMERIC)
01224 {
01225 if (((int)tp1>=0) && ((int)tp1<=255))
01226 {
01227 pars++;
01228 *p8++ = tp1;
01229 ctl->eaten += eaten;
01230 }
01231 else break;
01232 }
01233 else break;
01234 }
01235
01236 p[3] = pars;
01237
01238 if (pars) valid = 1;
01239
01240 break;
01241
01242
01243 }
01244
01245 if (valid) return idx; else return CMD_BAD_PARAMETER;
01246 }
01247
01248 char * cmdErrStr(int error)
01249 {
01250 int i;
01251
01252 for (i=0; i<(sizeof(errInfo)/sizeof(errInfo_t)); i++)
01253 {
01254 if (errInfo[i].error == error) return errInfo[i].str;
01255 }
01256 return "unknown error";
01257 }
01258
01259 int cmdParseScript(char *script, cmdScript_t *s, int diags)
01260 {
01261 int idx, len, b, i, j, tags, resolved;
01262 int status;
01263 uint32_t p[10];
01264 cmdInstr_t instr;
01265 cmdCtlParse_t ctl;
01266 char v[CMD_MAX_EXTENSION];
01267
01268 ctl.eaten = 0;
01269
01270 status = 0;
01271
01272 cmdTagStep_t tag_step[PI_MAX_SCRIPT_TAGS];
01273
01274 len = strlen(script);
01275
01276
01277
01278 b = (sizeof(int) * (PI_MAX_SCRIPT_PARAMS + PI_MAX_SCRIPT_VARS)) +
01279 (sizeof(cmdInstr_t) * (len + 2) / 2) + len;
01280
01281 s->par = calloc(1, b);
01282
01283 if (s->par == NULL) return -1;
01284
01285 s->var = s->par + PI_MAX_SCRIPT_PARAMS;
01286
01287 s->instr = (cmdInstr_t *)(s->var + PI_MAX_SCRIPT_VARS);
01288
01289 s->str_area = (char *)(s->instr + ((len + 2) / 2));
01290
01291 s->str_area_len = len;
01292 s->str_area_pos = 0;
01293
01294 s->instrs = 0;
01295
01296 tags = 0;
01297
01298 idx = 0;
01299
01300 while (ctl.eaten<len)
01301 {
01302 idx = cmdParse(script, p, CMD_MAX_EXTENSION, v, &ctl);
01303
01304 if (idx >= 0)
01305 {
01306 if (p[3])
01307 {
01308 memcpy(s->str_area + s->str_area_pos, v, p[3]);
01309 s->str_area[s->str_area_pos + p[3]] = 0;
01310 p[4] = (intptr_t) s->str_area + s->str_area_pos;
01311 s->str_area_pos += (p[3] + 1);
01312 }
01313
01314 memcpy(&instr.p, p, sizeof(instr.p));
01315
01316 if (instr.p[0] == PI_CMD_TAG)
01317 {
01318 if (tags < PI_MAX_SCRIPT_TAGS)
01319 {
01320
01321 for (j=0; j<tags; j++)
01322 {
01323 if (tag_step[j].tag == instr.p[1])
01324 {
01325 if (diags)
01326 {
01327 fprintf(stderr, "Duplicate tag: %d\n", instr.p[1]);
01328 }
01329
01330 if (!status) status = PI_DUP_TAG;
01331 idx = -1;
01332 }
01333 }
01334
01335 tag_step[tags].tag = instr.p[1];
01336 tag_step[tags].step = s->instrs;
01337 tags++;
01338 }
01339 else
01340 {
01341 if (diags)
01342 {
01343 fprintf(stderr, "Too many tags: %d\n", instr.p[1]);
01344 }
01345 if (!status) status = PI_TOO_MANY_TAGS;
01346 idx = -1;
01347 }
01348 }
01349 }
01350 else
01351 {
01352 if (diags)
01353 {
01354 if (idx == CMD_UNKNOWN_CMD)
01355 fprintf(stderr, "Unknown command: %s\n", cmdStr());
01356 else
01357 fprintf(stderr, "Bad parameter to %s\n", cmdStr());
01358 }
01359 if (!status) status = PI_BAD_SCRIPT_CMD;
01360 }
01361
01362 if (idx >= 0)
01363 {
01364 if (instr.p[0] != PI_CMD_TAG)
01365 {
01366 memcpy(instr.opt, &ctl.opt, sizeof(instr.opt));
01367 s->instr[s->instrs++] = instr;
01368 }
01369 }
01370 }
01371
01372 for (i=0; i<s->instrs; i++)
01373 {
01374 instr = s->instr[i];
01375
01376
01377
01378 if ((instr.p[0] == PI_CMD_JMP) || (instr.p[0] == PI_CMD_CALL) ||
01379 (instr.p[0] == PI_CMD_JZ) || (instr.p[0] == PI_CMD_JNZ) ||
01380 (instr.p[0] == PI_CMD_JM) || (instr.p[0] == PI_CMD_JP))
01381 {
01382 resolved = 0;
01383
01384 for (j=0; j<tags; j++)
01385 {
01386 if (instr.p[1] == tag_step[j].tag)
01387 {
01388 s->instr[i].p[1] = tag_step[j].step;
01389 resolved = 1;
01390 break;
01391 }
01392 }
01393
01394 if (!resolved)
01395 {
01396 if (diags)
01397 {
01398 fprintf(stderr, "Can't resolve tag %d\n", instr.p[1]);
01399 }
01400 if (!status) status = PI_BAD_TAG;
01401 }
01402 }
01403 }
01404 return status;
01405 }
01406