void NodesManager::processMessage(const Message* message) { // check whether the node is known NodesMap::iterator nodeIt(nodes.find(message->source)); if (nodeIt == nodes.end()) { // node is not known, so ignore excepted if the message type // is node present and it is not a known mismatch protocol, // in that case, request description... if ((message->type == ASEBA_MESSAGE_NODE_PRESENT) && mismatchingNodes.find(message->source) == mismatchingNodes.end()) { GetNodeDescription getNodeDescription(message->source); sendMessage(getNodeDescription); } // or if message type is description, in that case, proceed further if (message->type != ASEBA_MESSAGE_DESCRIPTION) return; } else { // node is known, check if connected... if (!nodeIt->second.connected) { // if not, build complete, set as connected and notify client nodeIt->second.connected = true; if (nodeIt->second.isComplete()) { // only notify connections of completed known nodes nodeConnected(nodeIt->first); } } // update last seen time nodeIt->second.lastSeen = UnifiedTime(); } // if we have a disconnection message { // FIXME: handle disconnected state const Disconnected *disconnected = dynamic_cast<const Disconnected *>(message); if (disconnected) { NodesMap::iterator nodeIt = nodes.find(disconnected->source); assert (nodeIt != nodes.end()); nodes.erase(nodeIt); } } // if we have an initial description { const Description *description = dynamic_cast<const Description *>(message); if (description) { NodesMap::iterator nodeIt = nodes.find(description->source); // We can receive a description twice, for instance if there is another IDE connected if (nodeIt != nodes.end() || (mismatchingNodes.find(description->source) != mismatchingNodes.end())) return; // Call a user function when a node protocol version mismatches if ((description->protocolVersion < ASEBA_MIN_TARGET_PROTOCOL_VERSION) || (description->protocolVersion > ASEBA_PROTOCOL_VERSION)) { nodeProtocolVersionMismatch(description->source, description->name, description->protocolVersion); mismatchingNodes.insert(description->source); return; } // create node and copy description into it nodes[description->source] = Node(*description); checkIfNodeDescriptionComplete(description->source, nodes[description->source]); } } // if we have a named variable description { const NamedVariableDescription *description = dynamic_cast<const NamedVariableDescription *>(message); if (description) { NodesMap::iterator nodeIt = nodes.find(description->source); assert (nodeIt != nodes.end()); // copy description into array if array is empty if (nodeIt->second.namedVariablesReceptionCounter < nodeIt->second.namedVariables.size()) { nodeIt->second.namedVariables[nodeIt->second.namedVariablesReceptionCounter++] = *description; checkIfNodeDescriptionComplete(nodeIt->first, nodeIt->second); } } } // if we have a local event description { const LocalEventDescription *description = dynamic_cast<const LocalEventDescription *>(message); if (description) { NodesMap::iterator nodeIt = nodes.find(description->source); assert (nodeIt != nodes.end()); // copy description into array if array is empty if (nodeIt->second.localEventsReceptionCounter < nodeIt->second.localEvents.size()) { nodeIt->second.localEvents[nodeIt->second.localEventsReceptionCounter++] = *description; checkIfNodeDescriptionComplete(nodeIt->first, nodeIt->second); } } } // if we have a native function description { const NativeFunctionDescription *description = dynamic_cast<const NativeFunctionDescription *>(message); if (description) { NodesMap::iterator nodeIt = nodes.find(description->source); assert (nodeIt != nodes.end()); // copy description into array if (nodeIt->second.nativeFunctionReceptionCounter < nodeIt->second.nativeFunctions.size()) { nodeIt->second.nativeFunctions[nodeIt->second.nativeFunctionReceptionCounter++] = *description; checkIfNodeDescriptionComplete(nodeIt->first, nodeIt->second); } } } }
int main(int argc, char *argv[]) { char *cmdName; const char *opts="Dvqt:l:h:o:m:Q:i:"; char parameter[100]; char *p; EUI64 destPortGuid = -1; int c; int i; uint8 hfi = 0; uint8 port = 0; IB_PATH_RECORD path; uint16 sessionID; uint32 regValue; uint32 fanSpeed[OPASW_PSOC_FAN_CTRL_TACHS]; char tempStrs[I2C_OPASW_TEMP_SENSOR_COUNT][TEMP_STR_LENGTH]; uint32 psStatus; uint8 fwVersion[40]; vpd_fruInfo_rec_t vpdInfo; char mfgID[10]; char mfgDate[20]; char mfgTime[10]; uint8 nodeDesc[80]; opasw_ini_descriptor_get_t tableDescriptors; table_parsed_data_t *portParsedDataTable=NULL; uint32 numPorts; uint32 portEntrySize; uint8 memoryData[200]; uint8 boardID; VENDOR_MAD mad; FSTATUS status = FSUCCESS; uint32 asicVersion; uint8 chipStep; uint8 chipRev; table_parsed_data_t *portPtrs=NULL; uint32 portLinkWidthSupportedIndex; uint32 portLinkSpeedSupportedIndex; uint32 portFMEnabledIndex; uint32 portLinkCRCModeIndex; uint32 portvCUIndex; uint32 portExternalLoopbackAllowedIndex; char portLinkCRCModeValue[35]; char portLinkWidthSupportedText[20]; char portLinkSpeedSupportedText[20]; struct oib_port *oib_port_session = NULL; // determine how we've been invoked cmdName = strrchr(argv[0], '/'); // Find last '/' in path if (cmdName != NULL) { cmdName++; // Skip over last '/' } else { cmdName = argv[0]; } // Initialize // parse options and parameters while (-1 != (c = getopt(argc, argv, opts))) { switch (c) { case 'D': g_debugMode = 1; oib_set_dbg(stderr); break; case 't': errno = 0; strncpy(parameter, optarg, sizeof(parameter)-1); parameter[sizeof(parameter)-1] = 0; if ((p = strchr(parameter, ',')) != NULL) { *p = '\0'; } if (FSUCCESS != StringToUint64(&destPortGuid, parameter, NULL, 0, TRUE)) { fprintf(stderr, "%s: Error: Invalid GUID: %s\n", cmdName, optarg); usage(cmdName); } break; case 'l': #if !LIST_FILE_SUPPORTED fprintf(stderr, "Error: l option is not supported at this time\n"); exit(1); #endif break; case 'v': oib_set_dbg(stderr); g_verbose = 1; break; case 'q': g_quiet = 1; break; case 'h': if (FSUCCESS != StringToUint8(&hfi, optarg, NULL, 0, TRUE)) { fprintf(stderr, "%s: Error: Invalid HFI Number: %s\n", cmdName, optarg); usage(cmdName); } g_gotHfi = 1; break; case 'o': if (FSUCCESS != StringToUint8(&port, optarg, NULL, 0, TRUE)) { fprintf(stderr, "%s: Error: Invalid Port Number: %s\n", cmdName, optarg); usage(cmdName); } g_gotPort = 1; break; case 'Q': if (FSUCCESS != StringToUint8(&g_queryNum, optarg, NULL, 0, TRUE)) { fprintf(stderr, "%s: Error: Invalid Query Number: %s\n", cmdName, optarg); usage(cmdName); } break; case 'i': if (FSUCCESS != StringToInt8(&g_intParam, optarg, NULL, 0, TRUE) || g_intParam < 0) { fprintf(stderr, "%s: Error: Invalid integer parameter: %s\n", cmdName, optarg); usage(cmdName); } break; default: usage(cmdName); break; } } // user has requested display of help if (argc == 1) { usage(cmdName); exit(0); } if (-1 == destPortGuid) { fprintf(stderr, "%s: Error: Must specify a target GUID\n", cmdName); exit(1); } if (g_queryNum == 0) { fprintf(stderr, "%s: Error: must enter a query number\n", cmdName); exit(1); } if ((g_queryNum == 8) && ((g_intParam > MAX_PS) || (g_intParam < MIN_PS))) { fprintf(stderr, "%s: Error: Query number 8 - must use -i for valid Power Supply number %d - %d\n", cmdName, MIN_PS, MAX_PS); usage(cmdName); } if (g_quiet && (g_debugMode || g_verbose)) { fprintf(stderr, "%s: Error: Can not specify both -q and -D|-v\n", cmdName); exit(1); } // Get the path status = oib_open_port_by_num(&oib_port_session, hfi, port); if (status != 0) { fprintf(stderr, "%s: Error: Unable to open fabric interface.\n", cmdName); exit(1); } if (getDestPath(oib_port_session, destPortGuid, cmdName, &path) != FSUCCESS) { fprintf(stderr, "%s: Error: Failed to get destination path\n", cmdName); goto err_exit; } // Send a ClassPortInfo to see if the switch is responding status = sendClassPortInfoMad(oib_port_session, &path, &mad); if (status != FSUCCESS) { fprintf(stderr, "%s: Error: Failed to send/rcv ClassPortInfo\n", cmdName); goto err_exit; } // Get a session ID sessionID = getSessionID(oib_port_session, &path); if (sessionID == (uint16)-1) { fprintf(stderr, "%s: Error: Failed to obtain sessionID\n", cmdName); status = FERROR; goto err_exit; } // Send the test mad switch (g_queryNum) { case 1: fprintf(stderr, "Error: Module type query no longer supported.\n"); status = FERROR; break; case 2: status = sendRegisterAccessMad(oib_port_session, &path, &mad, sessionID, (uint8)0x6f, ®Value, 1); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to access register - status %d\n", status); break; } printf("Switch has booted from %s firmware image\n", (regValue & EEPROM_MASK) ? "failsafe" : "primary"); break; case 3: status = getFwVersion(oib_port_session, &path, &mad, sessionID, fwVersion); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to acquire fw version - status %d\n", status); break; } printf("FW Version is %s\n", fwVersion); break; case 4: status = getVPDInfo(oib_port_session, &path, &mad, sessionID, OPASW_MODULE, &vpdInfo); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to access vpd info - status %d\n", status); break; } snprintf(mfgID, sizeof(mfgID), "%02x%02x%02x", vpdInfo.mfgID[0] & 0xff, vpdInfo.mfgID[1] & 0xff, vpdInfo.mfgID[2] & 0xff); snprintf(mfgDate, sizeof(mfgDate), "%d-%02d-%d", vpdInfo.mfgMonth, vpdInfo.mfgDay, vpdInfo.mfgYear + 2000); snprintf(mfgTime, sizeof(mfgTime), "%02d:%02d", vpdInfo.mfgHours, vpdInfo.mfgMins); printf("VPD \"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", vpdInfo.serialNum, vpdInfo.partNum, vpdInfo.model, vpdInfo.version, vpdInfo.mfgName, vpdInfo.productName, mfgID, mfgDate, mfgTime); break; case 5: status = getNodeDescription(oib_port_session, &path, sessionID, nodeDesc); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to acquire node description - status %d\n", status); break; } printf("Node description is %s\n", nodeDesc); break; case 6: status = getTempReadings(oib_port_session, &path, &mad, sessionID, tempStrs); for (i=0; i<I2C_OPASW_TEMP_SENSOR_COUNT; i++) { printf("SENSOR %d: %s ", i, tempStrs[i]); } printf("\n"); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to get one or more temperature readings - status %s\n", iba_fstatus_msg(status & 0xFF)); } break; case 7: for (i = 0; i < OPASW_PSOC_FAN_CTRL_TACHS; i++) { status = getFanSpeed(oib_port_session, &path, &mad, sessionID, (uint32)i, &fanSpeed[i]); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to get fan speed for fan %d - status %d\n", i, status); break; } if (g_verbose) { printf("Fan speed is %d\n", fanSpeed[i]); } // TODO: stl1baseboard.c only reports the speed itself, not FAST/SLOW/NORMAL, so I can't confirm that this matches if (fanSpeed[i] > MAX_FAN_SPEED) printf("FAN %d:FAST ", i); else if (fanSpeed[i] < MIN_FAN_SPEED) printf("FAN %d:SLOW ", i); else printf("FAN %d:NORMAL ", i); } printf("\n"); break; case 8: status = getPowerSupplyStatus(oib_port_session, &path, &mad, sessionID, g_intParam, &psStatus); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to get power supply status for ps %d - status %d\n", g_intParam, status); break; } switch (psStatus) { case PS_ONLINE: printf("PS %d: ONLINE\n", g_intParam); break; case PS_OFFLINE: printf("PS %d: OFFLINE\n", g_intParam); break; case PS_NOT_PRESENT: printf("PS %d: NOT PRESENT\n", g_intParam); break; case PS_INVALID: printf("PS %d: INVALID\n", g_intParam); break; default: fprintf(stderr, "Error: Failed to get power supply status for ps %d\n", g_intParam); break; } break; case 9: status = getAsicVersion(oib_port_session, &path, &mad, sessionID, &asicVersion); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to get ASIC version - status %d\n", status); break; } chipStep = (asicVersion & ASIC_CHIP_STEP_MASK) >> ASIC_CHIP_STEP_SHFT; chipRev = (asicVersion & ASIC_CHIP_REV_MASK) >> ASIC_CHIP_REV_SHFT; printf("ASIC Version: V"); if (chipRev == 0) { switch (chipStep) { case ASIC_CHIP_STEP_A: printf("1\n"); break; case ASIC_CHIP_STEP_B: printf("2\n"); break; case ASIC_CHIP_STEP_C: printf("3\n"); break; default: printf("0\n"); break; } } else { printf("0\n"); } break; case 10: printf("Session ID: %d\n", sessionID); break; case 11: { /* query port 2 */ int dest_port_query=1; printf("Switch configuration values\n"); status = sendIniDescriptorGetMad(oib_port_session, &path, &mad, sessionID, &tableDescriptors); if (status != FSUCCESS) { fprintf(stderr, "%s: Error: Failed to get ini descriptors - status %d\n", cmdName, status); goto retErr; } numPorts = getNumPorts(oib_port_session, &path, sessionID); if( numPorts <= 0){ fprintf(stderr,"error in fetching port records\n"); goto retErr; } portEntrySize = tableDescriptors.portDataLen / numPorts; status = sendMemAccessGetMad(oib_port_session, &path, &mad, sessionID, tableDescriptors.portDataAddr + (dest_port_query * portEntrySize), portEntrySize*4, memoryData); if (status != FSUCCESS) { printf("Mem Access MAD Failed \n"); goto retErr; } if (g_verbose) { printf("MemoryData dump:\n"); opaswDisplayBuffer((char *)memoryData, portEntrySize * 4); } portParsedDataTable = malloc(tableDescriptors.portMetaDataLen * sizeof(table_parsed_data_t)); if(portParsedDataTable == NULL) { fprintf(stderr,"Not enough memory \n"); goto retErr; } status = parseDataTable(&portMetaData[0], memoryData, portMetaDataSize, portParsedDataTable, 0); if(status != FSUCCESS) { fprintf(stderr," failed: parseDataTable \n"); goto retErr; } portPtrs = portParsedDataTable; portLinkWidthSupportedIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "LINK_WIDTH_SUPPORTED"); portLinkSpeedSupportedIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "LINK_SPEED_SUPPORTED"); portFMEnabledIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "FM_ENABLED"); portLinkCRCModeIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "LTP_CRC_MODE_SUPPORTED"); portvCUIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "VCU"); portExternalLoopbackAllowedIndex = getMetaDataIndexByField(&portMetaData[0], tableDescriptors.portMetaDataLen, "EXTERNAL_LOOPBACK_ALLOWED"); status = getNodeDescription(oib_port_session, &path, sessionID, nodeDesc); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to acquire node description - status %d\n", status); goto retErr; } #define PRINT_REC(str,fmt,arg...) printf(" %-*s : "fmt,35,str,arg); StlLinkWidthToText(portPtrs[portLinkWidthSupportedIndex].val.intVal, portLinkWidthSupportedText, 20); StlLinkSpeedToText(portPtrs[portLinkSpeedSupportedIndex].val.intVal, portLinkSpeedSupportedText, 20); PRINT_REC("Link Width"," %s\n", portLinkWidthSupportedText); PRINT_REC("Link Speed"," %s\n", portLinkSpeedSupportedText); PRINT_REC("FM Enabled"," %s\n", portPtrs[portFMEnabledIndex].val.intVal ? "Yes" : "No"); PRINT_REC("Link CRC Mode"," %s\n", StlPortLtpCrcModeVMAToText(portPtrs[portLinkCRCModeIndex].val.intVal,portLinkCRCModeValue,sizeof(portLinkCRCModeValue))); PRINT_REC("vCU"," %d\n", portPtrs[portvCUIndex].val.intVal); PRINT_REC("External Loopback Allowed"," %s\n", portPtrs[portExternalLoopbackAllowedIndex].val.intVal ? "Yes" : "No"); PRINT_REC("Node Description"," %s\n", strlen((const char *)nodeDesc)==0?(const char *)"no description":(char *)nodeDesc); retErr: if(portParsedDataTable) free(portParsedDataTable); break; } case 12: status = getBoardID(oib_port_session, &path, &mad, sessionID, &boardID); if (status != FSUCCESS) { fprintf(stderr, "Error: Failed to get board id - status %d\n", status); break; } printf("BoardID: 0x%02x\n", boardID); break; default: fprintf(stderr, "Error: Invalid query number %d\n", g_queryNum); releaseSession(oib_port_session, &path, sessionID); usage(cmdName); break; } releaseSession(oib_port_session, &path, sessionID); printf("opaswquery completed\n"); err_exit: if (oib_port_session != NULL) { oib_close_port(oib_port_session); } if (status == FSUCCESS) exit(0); else exit(1); }