const char * WiFlyDevice::ip() { /* The return value is intended to be dropped directly into calls to 'print' or 'println' style methods. */ static char ip[IP_ADDRESS_BUFFER_SIZE] = ""; // TODO: Ensure we're not in a connection? enterCommandMode(); // Version 2.19 of the WiFly firmware has a "get ip a" command but // we can't use it because we want to work with 2.18 too. sendCommand(F("get ip"), false, "IP="); char newChar; byte offset = 0; // Copy the IP address from the response into our buffer while (offset < IP_ADDRESS_BUFFER_SIZE) { newChar = uart->read(); if (newChar == ':') { ip[offset] = '\x00'; break; } else if (newChar != -1) { ip[offset] = newChar; offset++; } } // This handles the case when we reach the end of the buffer // in the loop. (Which should never happen anyway.) // And hopefully this prevents us from failing completely if // there's a mistake above. ip[IP_ADDRESS_BUFFER_SIZE-1] = '\x00'; // This should skip the remainder of the output. // TODO: Handle this better? waitForResponse("<"); while (uart->read() != ' ') { // Skip the prompt } // For some reason the "sendCommand" approach leaves the system // in a state where it misses the first/next connection so for // now we don't check the response. // TODO: Fix this uart->println("exit"); //sendCommand("exit", false, "EXIT"); return ip; }
void WiFlyDevice::begin() { uart.begin(); reboot(); enterCommandMode(false); sendCommand("get uart", "Flow=0x"); while (!uart.available()) { //delay(1); } char flowControlState = uart.read(); LOG_READ(flowControlState); waitForPrompt(); if (flowControlState != '1') { sendCommand("set uart flow 1"); waitForPrompt(); sendCommand("save", "Storing in config"); waitForPrompt(); sendCommand("get uart", "Flow=0x1"); waitForPrompt(); reboot(); enterCommandMode(false); } sendCommand("set wlan join 0"); waitForPrompt(); sendCommandPart("set ip localport "); sendCommandPart(serverPort); sendCommand(""); waitForPrompt(); sendCommand("set comm remote 0"); waitForPrompt(); }
void WiFlyDevice::setConfiguration(boolean adhocMode, const char *ip) { /* */ enterCommandMode(); // TODO: Handle configuration better // Turn off auto-connect sendCommand(F("set wlan join 0")); // TODO: Turn off server functionality until needed // with "set ip protocol <something>" // Set server port sendCommand(F("set ip localport "), true); // TODO: Handle numeric arguments correctly. uart->print(serverPort); sendCommand(""); // Turn off remote connect message sendCommand(F("set comm remote 0")); sendCommand(F("set t z 23")); sendCommand(F("set time address 129.6.15.28")); sendCommand(F("set time port 123")); sendCommand(F("set t e 15")); // CDT: Enable the DHCP mode again, if the shield // was last used in AdHoc mode we won't do things correctly without // these changes. if(!adhocMode) { sendCommand(F("set wlan auth 4")); if (ip == NULL) { sendCommand(F("set ip dhcp 1")); } else { sendCommand(F("set ip address "), true); sendCommand(ip); sendCommand(F("set ip dhcp 0")); } } else { setAdhocParams(); } // Turn off status messages // sendCommand(F("set sys printlvl 0")); // TODO: Change baud rate and then re-connect? // Turn off RX data echo // TODO: Should really treat as bitmask // sendCommand(F("set uart mode 0")); }
bool CWintec::readLog() { if (m_command_mode_step != 0) { qDebug("already in command mode."); return false; } m_command_mode_step = 1; m_dev_data = new DeviceData(); enterCommandMode(m_command_mode_step); return true; }
void WiFlyDevice::useUDP() { if (commandModeFlag) { exitCommandMode(); } enterCommandMode(); sendCommand("set ip protocol 1", false); sendCommand("set ip localport 80", false); exitCommandMode(); }
void WiFlyDevice::requireFlowControl() { /* Note: If flow control has been set but not saved then this function won't handle it correctly. Note: Any other configuration changes made since the last reboot will also be saved by this function so this function should ideally be called immediately after a reboot. */ DEBUG_LOG(1, "Entered requireFlowControl"); enterCommandMode(); // TODO: Reboot here to ensure we get an accurate response and // don't unintentionally save a configuration we don't intend? sendCommand(F("get uart"), false, "Flow=0x"); while (!uart->available()) { // Wait to ensure we have the full response } char flowControlState = uart->read(); uart->flush(); if (flowControlState == '1') { return; } // Enable flow control sendCommand(F("set uart flow 1")); sendCommand(F("save"), false, "Storing in config"); // Without this (or some delay--but this seemed more useful/reliable) // the reboot will fail because we seem to lose the response from the // WiFly and end up with something like: // "*ReboWiFly Ver 2.18" // instead of the correct: // "*Reboot*WiFly Ver 2.18" // TODO: Solve the underlying problem sendCommand(F("get uart"), false, "Flow=0x1"); reboot(); }
boolean WiFlyDevice::configure(byte option, unsigned long value) { /* */ // TODO: Allow options to be supplied earlier? switch (option) { case WIFLY_BAUD: // TODO: Use more of standard command sending method? enterCommandMode(); uart->print("set uart instant "); uart->println(value); delay(10); // If we don't have this here when we specify the // baud as a number rather than a string it seems to // fail. TODO: Find out why. SPIuart.begin(value); // For some reason the following check fails if it occurs before // the change of SPI UART serial rate above--even though the // documentation says the AOK is returned at the old baud // rate. TODO: Find out why if (!findInResponse("AOK", 100)) { return false; } break; case ANTENNA_TYPE: enterCommandMode(); uart->print("set wlan extant "); uart->println(value); reboot(); default: return false; break; } return true; }
boolean WiFlyDevice::join(const char * ssid) { if (!enterCommandMode()) return false; sendCommandPart("join "); if (sendCommand(ssid, "Associated!", 30000)) { waitForPrompt(); return true; } return false; }
void CWintec::timeout() { if(m_retry_count == 0) { // fatal error qDebug() << QString("timeout ... no retries left. Aborting!"); emit readLogFailed("Timeout reading from device!"); leaveCommandMode(); } m_retry_count--; qDebug() << QString("timeout ... retries left %1. command_step_mode %2").arg(m_retry_count).arg(m_command_mode_step); m_step_complete = true; if(m_command_mode_step < 10) { enterCommandMode(m_command_mode_step); } else { readLogData(); } }
/* This function will attempt a connection to the stored remote address The first time you connect the the RN-42 HID, the master device will need to initiate the connection. The first time a connection is made the bluetooth address of the master device will be stored on the RN-42. If no remote address is stored, a connection will not be made. */ uint8_t makeyMateClass::connect() { freshStart(); // Get the module disconnected, and out of command mode while (!enterCommandMode()) { // Enter command mode delay(BLUETOOTH_RESPONSE_DELAY); } delay(BLUETOOTH_RESPONSE_DELAY); bluetooth.flush(); /* get the remote address and print it in the serial monitor */ bluetooth.print("GR"); // Get the remote address bluetooth.write('\r'); delay(BLUETOOTH_RESPONSE_DELAY); if (bluetooth.peek() == 'N') // Might say "No remote address stored */ { // (bluetooth address is hex values only, so won'te start with 'N'. Serial.println("Can't connect. No paired device!"); bluetooth.flush(); bluetooth.print("---"); // exit command mode bluetooth.write('\r'); return 0; // No connect is attempted } else if (bluetooth.available() == 0) { // If we can't communicate with the module at all, print error Serial.println("ERROR!"); return 0; // return error } /* otherwise print the address we're trying to connect to */ Serial.print("Attempting to connect to: "); while (bluetooth.available()) Serial.write(bluetooth.read()); /* Attempt to connect */ bluetooth.print("C"); // The connect command bluetooth.write('\r'); delay(BLUETOOTH_RESPONSE_DELAY); while (bluetooth.available()) Serial.write(bluetooth.read()); // Should print "TRYING" return 1; }
void WiFlyDevice::sendResponse(char* request) { Serial.print("Request is: "); Serial.println(request); uart.println("HTTP/1.1 200 OK"); uart.println("Content-Type: text/html"); uart.println(""); if (strstr(request, " /ui ") != NULL) { uart.write(UI); } else if (strstr(request, " /values/") != NULL) { sendValues(request); } else { uart.write("Go to /ui or /values"); } Serial.println("Sent response."); enterCommandMode(); uart.println("close"); uart.println("exit"); }
/* * Will eventually store a unique ID in response */ void WiFlyDevice::getDeviceID(char id[17]) { DEBUG_LOG(11,"WiFlyDevice::getDeviceID - enter"); //puts the RN131G into command mode boolean tf = enterCommandMode(); if(tf == true) { DEBUG_LOG(11,"WiFlyDevice::getDeviceID - Command Mode"); } else { DEBUG_LOG(11,"WiFlyDevice::getDeviceID - Unable to enter command mode"); return; } // This command displays the device’s MAC address. //sendCommand("get mac", false, response); uart.print("get mac"); uart.flush(); uart.println(); char response[35] = {'\n'}; //strlen("Mac Addr=00:06:66:30:88:fb") for (unsigned int offset = 0; offset < 35; offset++) { while (!uart.available()) { } response[offset] = (char)(uart.read()); } for(unsigned int i = 0; i < 17; i++) { id[i] = response[i+12]; } }
long WiFlyDevice::getTime(){ /* Returns the time based on the NTP settings and time zone. */ char newChar; byte offset = 0; char buffer[TIME_SIZE+1]; enterCommandMode(); //sendCommand("time"); // force update if it's not already updated with NTP server sendCommand(F("show t t"), false, "RTC="); // copy the time from the response into our buffer while (offset < TIME_SIZE) { newChar = uart->read(); if (newChar != -1) { buffer[offset++] = newChar; } } buffer[offset]=0; // This should skip the remainder of the output. // TODO: Handle this better? waitForResponse("<"); findInResponse(" "); // For some reason the "sendCommand" approach leaves the system // in a state where it misses the first/next connection so for // now we don't check the response. // TODO: Fix this uart->println(F("exit")); //sendCommand(F("exit"), false, "EXIT"); return strtol(buffer, NULL, 0); }
// // TODO: Revaluate if this method is actually required. Perhaps the Join method can // do all of this, and use a internal Private variable to provide all the required parameters // boolean WiFlyDevice::createAdHocNetwork(const char *ssid) { /* Create and AdHoc network with the WiFly Shield. */ DEBUG_LOG(1, "Entered WiFlyDevice::beginAdhoc()"); reboot(); // Reboot to get device into known state enterCommandMode(); // Turn on Adhoc Mode sendCommand(F("set wlan join 4")); // Set SSID of Adhoc Network sendCommand(F("set wlan ssid "),true); sendCommand(ssid); // Set Channel for Adhoc Network sendCommand(F("set wlan chan 1")); // Set IP for Adhoc Network sendCommand(F("set ip address 169.254.1.1")); sendCommand(F("set ip netmask 255.255.0.0")); // Turn off DHCP sendCommand(F("set ip dhcp 0")); // Set server port sendCommand(F("set ip localport "), true); uart->print(serverPort); sendCommand(""); // Turn off remote connect message sendCommand(F("set comm remote 0")); sendCommand(F("save"), false, "Storing in config"); //Ensures sucessful reboot. See requireFlowControl for more info. sendCommand(F("get uart"), false, "Flow=0x1"); reboot(); //After rebooting, your AdHoc network will be available. }
void WiFlyDevice::reboot() { #if USE_HARDWARE_RESET uart.ioSetDirection(0b00000010); uart.ioSetState(0b00000000); delay(10); uart.ioSetState(0b00000010); findInResponse("*READY*", 10000); #else while (true) { if (!enterCommandMode()) continue; sendCommand("reboot", ""); if (findInResponse("*READY*", 5000)) break; } #endif delay(1000); }
void WiFlySerial::reboot() { char szCommand[SMALL_COMMAND_BUFFER_SIZE]; DEBUG_LOG(1, "Entered softwareReboot"); for (int retryCount = 0; retryCount < SOFTWARE_REBOOT_RETRY_ATTEMPTS; retryCount++) { // TODO: Have the post-boot delay here rather than in enterCommandMode()? if (!enterCommandMode(isAfterBoot)) { return false; // If the included retries have failed we give up } uart->println("reboot"); // For some reason the full "*Reboot*" message doesn't always // seem to be received so we look for the later "*READY*" message instead. // TODO: Extract information from boot? e.g. version and MAC address if (findInResponse("*READY*", 2000)) { return true; } } return false; GetBuffer_P(STI_WIFLYDEVICE_REBOOT, szCommand, SMALL_COMMAND_BUFFER_SIZE); // DebugPrint(szCommand); if (!SendCommandSimple( szCommand , WiFlyFixedPrompts[WIFLY_MSG_AOK] )) { DebugPrint( GetBuffer_P(STI_WIFLYDEVICE_ERR_START_FAIL, szCommand, SMALL_COMMAND_BUFFER_SIZE)); while (1) {}; // Hang. TODO: Handle differently? } }
void WiFlyDevice::handleRequest() { int timeout = 800; unsigned long start = millis(); Serial.println("Reading request"); static char firstLine[REQUEST_LENGTH]; boolean currentLineIsBlank = true; boolean isFirstLine = true; int index = 0; while (true) { while (!uart.available()) { if (millis() > start + timeout) { enterCommandMode(); uart.println("close"); uart.println("exit"); return; } } char c = uart.read(); Serial.print(c); if (isFirstLine && index < REQUEST_LENGTH) { firstLine[index++] = c; } if (c == '\n' && currentLineIsBlank) { firstLine[index] = '\0'; sendResponse(firstLine); return; } if (c == '\n') { currentLineIsBlank = true; isFirstLine = false; } else if (c != '\r') { currentLineIsBlank = false; } } }
WiFlyDevice::Status WiFlyDevice::getStatus(boolean pauseRequired) { if (!enterCommandMode(pauseRequired) || !sendCommand("show c", "8")) { waitForPrompt(); exitCommandMode(); return StatusError; } char result[3] = {0, 0, 0}; for (int i=0; i<3;) { result[i] = uart.read(); LOG_READ(result[i]); if (result[i] <= 0 || result[i] > 128) continue; i++; } Status status; if (strchr("02468ACEace", result[1])) status = StatusNotAssociated; else if (result[2] == '3') status = StatusNoIp; else if (result[2] == '4') status = StatusConnecting; else if (result[2] == '1') status = StatusConnected; else status = StatusDisconnected; waitForPrompt(); exitCommandMode(); return status; }
boolean WiFlyDevice::join(const char * ssid, const char * passphrase, boolean isWPA) { if (!enterCommandMode()) return false; sendCommandPart("set wlan "); if (isWPA) sendCommandPart("passphrase "); else sendCommandPart("key "); sendCommand(passphrase); waitForPrompt(); sendCommandPart("join "); if (sendCommand(ssid, "Associated!", 30000)) { waitForPrompt(); return true; } return false; }
/* begin(name) This function performs all tasks required to initialize the RN-42 HID module for use with the MaKey MaKey. We set up authentication, sleep, special config settings. As well as seting the auto-connect mode. The name can also be configured with the *name* parameter. */ uint8_t makeyMateClass::begin(char * name) { bluetooth.begin(9600); // Initialize the software serial port at 9600 freshStart(); // Get the module into a known mode, non-command mode, not connected while (!enterCommandMode()) // Enter command mode delay(100); delay(BLUETOOTH_RESPONSE_DELAY); setAuthentication(1); // enable authentication setName(name); // Set the module name setMode(0); // slave mode, worth trying mode 4 (auto dtr) as well /* I'm torn on setting sleep mode. If you care about a low latency connection keep sleep mode set to 0000. You can save about 15mA of current consumption with the "80A0" setting, but I experience quite a bit more latency. */ //setSleepMode("80A0"); // Deep sleep mode, 100ms sleeps - saves about 15mA when idling setSleepMode("0000"); // Low latency, high current usage ~ 40mA setSpecialConfig(16); // optimize for low latency, short burst data /* These I wouldn't recommend changing. These settings are required for HID use and sending Keyboard and Mouse commands */ setKeyboardMouseMode(); // bluetooth.println("SH,0030"); // We must reboot if we're changing the mode to HID mode. // If you've already have the module in HID mode, this can be commented out if (!getHIDMode()) { setHIDMode(); // Set RN-42 to HID profile mode reboot(); } else { Serial.println("Already in HID mode!"); } }
boolean WiFlyDevice::configure(byte option, unsigned long value) { /* */ // TODO: Allow options to be supplied earlier? boolean result = true; switch (option) { case WIFLY_BAUD: // TODO: Use more of standard command sending method? enterCommandMode(); uart->print("set uart instant "); uart->println(value); delay(10); // If we don't have this here when we specify the // baud as a number rather than a string it seems to // fail. TODO: Find out why. SPIuart.begin(value); // For some reason the following check fails if it occurs before // the change of SPI UART serial rate above--even though the // documentation says the AOK is returned at the old baud // rate. TODO: Find out why if (!findInResponse("AOK", 100)) { return false; } break; case WAKE_TIMER: enterCommandMode(); uart->print("set sys wake "); uart->println(value); if (!findInResponse("AOK", 100)) { result = false; } uart->print("set sys wake "); break; case SLEEP_TIMER: enterCommandMode(); uart->print("set sys sleep "); uart->println(value); if (!findInResponse("AOK", 100)) { result = false; } break; case WLAN_JOIN: enterCommandMode(); uart->print("set wlan join "); uart->println(value); if (!findInResponse("AOK", 100)) { result = false; } break; case COMM_SIZE: enterCommandMode(); uart->print("set comm size "); uart->println(value); if (!findInResponse("AOK", 100)) { result = false; } break; case WLAN_RATE: enterCommandMode(); uart->print("set wlan rate "); uart->println(value); if (!findInResponse("AOK", 100)) { result = false; } break; case SLEEP: enterCommandMode(); uart->println("sleep"); if (!findInResponse("AOK", 100)) { result = false; } break; default: result = false; break; } if (option != SLEEP) { uart->println("exit"); } return true; }
int factoryReset() { int result; result = enterCommandMode(); sendString(FACTORY_RESET, 14); }