// // Invoked from DweetWiFi to set the password. // // SETSTATE=WIFIPASSWORD:password // SETCONFIG=WIFIPASSWORD:password // int MenloWiFiArduino::WiFiPassword(char* buf, int size, bool isSet) { int length, index; if (isSet) { DBG_PRINT_NNL("WiFi Set Password "); DBG_PRINT_STRING(buf); // MenloConfigStore.h defines the sizes length = strlen(buf); if (length > (WIFI_PASSWORD_SIZE - 1)) { DBG_PRINT("WiFi SetPassword to long"); return DWEET_PARAMETER_TO_LONG; } // // Note: this writes directly into the password setting // to avoid duplicating a large stack buffer here. // for (index = 0; index < length; index++) { m_password[index] = buf[index]; } // Ensure null terminated string m_password[index] = '\0'; xDBG_PRINT_NNL("Password "); xDBG_PRINT_STRING(m_password); return 0; } else { length = strlen(m_password) + 1; if (length > size) { DBG_PRINT("WiFi GetPassword to long"); return DWEET_PARAMETER_TO_LONG; } for (index = 0; index < length; index++) { buf[index] = m_password[index]; } // Ensure null terminated string buf[index] = '\0'; return 0; } }
/** * DESCRIPTION: * * Parses a string looking for pipe characters '|'. Everything between * pipe characters is considered to be a bash command. Each call to * this function will search the string for a new command (left to * right) and populate the provided argv wiht command data. * * INPUT: * * line - a string with bash like commands separated with pipe * characters. After calling this function, the line string * will be altered since terminating nulls are insterted * (see argv bellow). * * argv - an array of string pointers. On return, this array will * be populated with the argv for the current command. The * argv will be populated with pointers within the orginal * input line. * * OUTPUT: * * The possition of the returned command is returned. * * single - a single command. * first - the first command in a chain of commands. * middle - not the first and not the last command in a chain of command. * last - the last command in a chain of commands. * * EXAMPLE USAGE: * * str = " ls -i -l | grep foo " * * pos = next_command(str, argv) ==> * * pos = first * argv[0] = "ls" * argv[1] = "-i" * argv[2] = "-l * argv[1] = NULL" * * pos = next_command(str, argv) ==> * * pos = last * argv[0] = "grep" * argv[1] = "foo" * argv[2] = NULL */ enum cmd_pos next_command(char* line, char* argv[]) // , char* sptr1, char* sptr2) { { enum parse_state {reset, resume}; DBG_PRINT_STRING(line, "before calling strtok_r"); // Allocate storage used for calls to strtok_() // NOTE: These pointers must be declared static inside this function // for the calls to strtok_r() to work. static char* save_ptr1; // Storage needed by strtok_r(). static char* save_ptr2; // Storage needed by strtok_r(). char* cmd; // Pointer to start of command within command line. char* arg; // Pointer to start of argument withing a single command. // Command position within the original command line. enum cmd_pos pos; // Number of '|' characters in the orignal string. static int unparsed_cmds = 0; static enum parse_state state = reset; // Parser state. if (state == reset) { // This is the first time the parser is called for this string. cmd = line; unparsed_cmds = count(line, '|'); // Are there more commands in the command line? state = resume; // Switch state if (unparsed_cmds == 0) // No more commands ==> the command line consists of a single command. pos = single; else // There are more commands ==> this is the first of many commands. pos = first; } else { // The parser is being called again for the same string. cmd = NULL; // tell strtok_r to continue to parse the same string as last call... unparsed_cmds--; if (unparsed_cmds > 0) // There are more commands ==> this is command is in the middle of the command chain. pos = middle; else // No more commands ==> this is the last command in a chain of commands. pos = last; } // Use strtok_r() to get the command string. cmd = trim(strtok_r(cmd, "|", &save_ptr1)); // Parse the command string and populate argv. int i; // argv index. for (i=0, arg=cmd; ; i++, arg = NULL) { arg = trim(strtok_r(arg, " \t", &save_ptr2)); if (arg == NULL) { // done, no more command data argv[i] = NULL; break; } else { argv[i] = arg; } } // Last command? if (pos == single || pos == last) state = reset; return pos; }
unsigned long LightHouseHardware::NMEAEvent(MenloDispatchObject* sender, MenloEventArgs* eventArgs) { char buf[16]; char name[16]; int length; char sensorType; MenloNMEAMessageEventArgs* nmeaArgs = (MenloNMEAMessageEventArgs*)eventArgs; unsigned long val; xDBG_PRINT("NMEAEvent Sensors"); // // nmeaArgs->dweet // nmeaArgs->prefix // nmeaArgs->cmds // nmeaArgs->buffer // // // First dispatch on the prefix type // if (strncmp_P(nmeaArgs->prefix, PSTR("$WIMWV"), 6) == 0) { // // WIMWV - Weather Instruments windspeed and direction // xDBG_PRINT("NMEAEvent WIMWV"); // // http://fort21.ru/download/NMEAdescription.pdf // // MWV Wind Speed and Angle // // Example: $WIMWV,270,T,3.5,M,A*00 // | | | | | // 1 2 3 4 5 // // $--MWV,x.x,a,x.x,a*hh // 1) Wind Angle, 0 to 360 degrees // 2) Reference, R = Relative, T = True // 3) Wind Speed // 4) Wind Speed Units, K/M/N // 5) Status, A = Data Valid // 6) Checksum // // nmeaArgs->cmds points to the start after the prefix $WIMWV, // WindAngle 0 - 360 length = ExtractNMEAWord(nmeaArgs->cmds, 1, buf, sizeof(buf)); if (length == 0) { DBG_PRINT("angle fail"); goto Done; } if (!HandleScaledBy100FractionalNumber(buf, &val)) { DBG_PRINT("scale angle fail"); goto Done; } m_winddirection = (int)val; xDBG_PRINT_NNL("windirection "); xDBG_PRINT_INT(m_winddirection); // WindSpeed 0.0 length = ExtractNMEAWord(nmeaArgs->cmds, 3, buf, sizeof(buf)); if (length == 0) { DBG_PRINT("speed fail"); goto Done; } // Handle a fractional number as an integer scaled by 100 if (!HandleScaledBy100FractionalNumber(buf, &val)) { DBG_PRINT("scale speed fail"); goto Done; } m_windspeed = (int)val; xDBG_PRINT_NNL("windspeed "); xDBG_PRINT_INT(m_windspeed); } else if (strncmp_P(nmeaArgs->prefix, PSTR("$WIXDR"), 6) == 0) { xDBG_PRINT("NMEAEvent WIXDR"); // // General transducer message // // http://www.catb.org/gpsd/NMEA.html#_xdr_transducer_measurement // // XDR - Transducer Measurement // // $WIXDR,a,x.x,a,c--c, ..... *hh<CR><LF> // | | | | | // 1 2 3 4 n // // Field Number: // // 1 Transducer Type // // 2 Measurement Data // // 3 Units of measurement // // 4 Name of transducer // // n Checksum // // May be any number of the sequence here up to line length // // // The following are transducer values produced by the // Menlo WeatherStationApp as part of the MenloFramework. // // // Type Name Units // // "T" "TEMPERATURE" "F" // "P" "BAROMETER" "K" // "H" "HUMIDITY" "P" // "R" "RAIN" "I" // "B" "BATTERY" "V" // "S" "SOLAR" "V" // "L" "LIGHT" "R" (RAW) // DBG_PRINT_NNL("XDR "); DBG_PRINT_STRING(nmeaArgs->cmds); // Transducer type sensorType = nmeaArgs->cmds[0]; // Measurement data length = ExtractNMEAWord(nmeaArgs->cmds, 2, buf, sizeof(buf)); if (length == 0 ) { DBG_PRINT("Extract data fail"); goto Done; } // Name length = ExtractNMEAWord(nmeaArgs->cmds, 4, name, sizeof(name)); if (length == 0 ) { DBG_PRINT("Extract name fail"); goto Done; } xDBG_PRINT_NNL("buf "); xDBG_PRINT_STRING(buf); // Handle a fractional number as an integer scaled by 100 if (!HandleScaledBy100FractionalNumber(buf, &val)) { DBG_PRINT("scale value fail"); goto Done; } xDBG_PRINT_NNL("sensorType"); xDBG_PRINT_INT(sensorType); xDBG_PRINT_NNL("value "); xDBG_PRINT_INT((int)val); xDBG_PRINT_NNL("Name "); xDBG_PRINT_STRING(name); // // We could validate sensor names then type, but performing // a series of strncmp_P()'s is tight on the code space. // switch(sensorType) { case 'T': m_temperature = (int)val; break; case 'P': m_barometer = (int)val; break; case 'H': m_humidity = (int)val; break; case 'R': m_rain = (int)val; break; case 'B': m_battery = (int)val; break; case 'S': m_solar = (int)val; break; case 'L': m_nmeaLight = (int)val; break; default: // Unrecognized DBG_PRINT("WIXDR Unknown sensor type"); goto Done; } } else { // Unknown NMEA 0183 sentence, we just ignore it xDBG_PRINT("NMEAEvent Unknown NMEA sentence"); } Done: return MAX_POLL_TIME; }