void Terminal::PollUART() { #ifdef ENABLE_TERMINAL if (!terminalIsInitialized) return; static char readBuffer[250] = { 0 }; static char testCopy[250] = {0}; readBuffer[0] = 0; if (simple_uart_get_with_timeout(0, (u8*) readBuffer)) { //Output query string and typed symbol to terminal if (promptAndEchoMode) { simple_uart_putstring((const u8*) EOL "mhTerm: "); //Display prompt simple_uart_put(readBuffer[0]); //echo back symbol } //Read line from uart ReadlineUART(readBuffer, 250, 1); //FIXME: remove after finding problem memcpy(testCopy, readBuffer, 250); //Clear previous command commandName.clear(); commandArgs.clear(); //Tokenize input string into vector char* token = strtok(readBuffer, " "); if (token != NULL) commandName.assign(token); while (token != NULL) { token = strtok(NULL, " "); if (token != NULL) commandArgs.push_back(string(token)); } //Check for clear screen if (commandName == "cls") { //Send Escape sequence simple_uart_put(27); //ESC simple_uart_putstring((const u8*) "[2J"); //Clear Screen simple_uart_put(27); //ESC simple_uart_putstring((const u8*) "[H"); //Cursor to Home } else { //Call all callbacks int handled = 0; for(u32 i=0; i<registeredCallbacks->size(); i++){ handled += ((TerminalCommandListener*)registeredCallbacks->GetItemAt(i))->TerminalCommandHandler(commandName, commandArgs); } if (handled == 0){ if(promptAndEchoMode){ simple_uart_putstring((const u8*)"Command not found" EOL); } else { uart_error(Logger::COMMAND_NOT_FOUND); } //FIXME: to find problems with uart input uart("ERROR", "{\"user_input\":\"%s\"}" SEP, testCopy); } } } #endif }
bool Node::TerminalCommandHandler(string commandName, vector<string> commandArgs) { /************* SYSTEM ***************/ if (commandName == "reset") { sd_nvic_SystemReset(); } else if (commandName == "startterm") { Terminal::promptAndEchoMode = true; } else if (commandName == "stopterm") { Terminal::promptAndEchoMode = false; Logger::getInstance().disableAll(); } /************* NODE ***************/ else if (commandName == "status") { PrintStatus(); } else if (commandName == "bufferstat") { PrintBufferStatus(); } else if (commandName == "stat") { PrintSingleLineStatus(); } else if (commandName == "data") { nodeID receiverId = 0; if(commandArgs.size() > 0){ if(commandArgs[0] == "sink") receiverId = NODE_ID_SHORTEST_SINK; else if(commandArgs[0] == "hop") receiverId = NODE_ID_HOPS_BASE + 1; else receiverId = NODE_ID_BROADCAST; } //Send data over all connections connPacketData1 data; data.header.messageType = MESSAGE_TYPE_DATA_1; data.header.sender = persistentConfig.nodeId; data.header.receiver = receiverId; data.payload.length = 7; data.payload.data[0] = 1; data.payload.data[1] = 3; data.payload.data[2] = 3; bool reliable = (commandArgs.size() == 0) ? false : true; cm->SendMessageToReceiver(NULL, (u8*) &data, SIZEOF_CONN_PACKET_DATA_1, reliable); } else if(commandName == "datal") { //Send some large data that is split over messages const u8 dataLength = 45; u8 _packet[dataLength]; connPacketHeader* packet = (connPacketHeader*)_packet; packet->messageType = MESSAGE_TYPE_DATA_1; packet->receiver = 0; packet->sender = persistentConfig.nodeId; for(u32 i=0; i< dataLength-5; i++){ _packet[i+5] = i+1; } cm->SendMessageToReceiver(NULL, _packet, dataLength, true); } else if (commandName == "loss") { //Simulate connection loss this->persistentConfig.connectionLossCounter++; clusterId = this->GenerateClusterID(); this->UpdateJoinMePacket(NULL); } else if (commandName == "settime") { u64 timeStamp = (atoi(commandArgs[0].c_str()) * (u64)APP_TIMER_CLOCK_FREQ); //Set the time for our node globalTime = timeStamp; app_timer_cnt_get(&globalTimeSetAt); } else if(commandName == "gettime") { u32 rtc1; app_timer_cnt_get(&rtc1); char timestring[50]; Logger::getInstance().convertTimestampToString(globalTime, timestring); trace("Time is currently %s, setAt:%d, rtc1:%u" EOL, timestring, globalTimeSetAt, rtc1); } else if (commandName == "sendtime") { //Generate a timestamp packet and send it to all other nodes connPacketUpdateTimestamp packet; packet.header.messageType = MESSAGE_TYPE_UPDATE_TIMESTAMP; packet.header.sender = persistentConfig.nodeId; packet.header.receiver = 0; //Data must not be filled because it is set in the fillTransmitBuffers method //Because it might still take some time from filling the buffer to sending the packet //We should use the radio event or estimate the sending based on the connetion parameters //It is then received and processed in the Connectionmanager::messageReceivedCallback cm->SendMessageToReceiver(NULL, (u8*)&packet, SIZEOF_CONN_PACKET_UPDATE_TIMESTAMP, true); } else if (commandName == "discovery") { if (commandArgs.size() < 1 || commandArgs[0] == "high") { noNodesFoundCounter = 0; ChangeState(discoveryState::DISCOVERY_HIGH); } else if (commandArgs[0] == "low") { noNodesFoundCounter = 50; ChangeState(discoveryState::DISCOVERY_LOW); } else if (commandArgs[0] == "off") { ChangeState(discoveryState::DISCOVERY_OFF); } } else if (commandName == "discover") { ChangeState(discoveryState::DISCOVERY_HIGH); } else if (commandName == "discoverylow") { noNodesFoundCounter = 50; } //Trigger this to save the current node configuration else if (commandName == "savenode") { persistentConfig.reserved++; Storage::getInstance().QueuedWrite((u8*) &persistentConfig, sizeof(NodeConfiguration), 0, this); } else if (commandName == "stop") { DisableStateMachine(true); } else if (commandName == "start") { DisableStateMachine(false); } else if (commandName == "break") { Config->breakpointToggleActive = !Config->breakpointToggleActive; } else if (commandName == "connect") { for (int i = 0; i <NUM_TEST_DEVICES ; i++) { if (strcmp(commandArgs[0].c_str(), testDevices[i].name) == 0) { trace("Trying to connecting to node %s", testDevices[i].name); cm->ConnectAsMaster(testDevices[i].id, &testDevices[i].addr, 14); } } } else if (commandName == "disconnect") { if (commandArgs.size() > 0) { u8 connectionNumber = atoi(commandArgs[0].c_str()); cm->connections[connectionNumber]->Disconnect(); } } else if (commandName == "heap") { Utility::CheckFreeHeap(); return true; } else if (commandName == "modules") { for(u32 i=0; i<MAX_MODULE_COUNT; i++) { if(activeModules[i] != NULL) log("Module: %s", activeModules[i]->moduleName); } return true; } else if (commandName == "yousink") { this->persistentConfig.deviceType = deviceTypes::DEVICE_TYPE_SINK; return true; } else if (commandName == "set_nodeid") { this->persistentConfig.nodeId = atoi(commandArgs[0].c_str()); return true; } /************* UART COMMANDS ***************/ else if (commandName == "uart_set_campaign") { if (commandArgs.size() > 0){ AdvertisingController::SetScanResponseData(this, commandArgs[0]); } else { uart_error(Logger::ARGUMENTS_WRONG); } } else { return false; } return true; }