//----------------------------------------------------------------------------- // <ManufacturerSpecific::LoadProductXML> // Load the XML that maps manufacturer and product IDs to human-readable names //----------------------------------------------------------------------------- bool ManufacturerSpecific::LoadProductXML ( ) { s_bXmlLoaded = true; // Parse the Z-Wave manufacturer and product XML file. string configPath; Options::Get()->GetOptionAsString( "ConfigPath", &configPath ); string filename = configPath + "manufacturer_specific.xml"; TiXmlDocument* pDoc = new TiXmlDocument(); if( !pDoc->LoadFile( filename.c_str(), TIXML_ENCODING_UTF8 ) ) { delete pDoc; Log::Write( LogLevel_Info, "Unable to load %s", filename.c_str() ); return false; } TiXmlElement const* root = pDoc->RootElement(); char const* str; char* pStopChar; TiXmlElement const* manufacturerElement = root->FirstChildElement(); while( manufacturerElement ) { str = manufacturerElement->Value(); if( str && !strcmp( str, "Manufacturer" ) ) { // Read in the manufacturer attributes str = manufacturerElement->Attribute( "id" ); if( !str ) { Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing manufacturer id attribute", manufacturerElement->Row() ); delete pDoc; return false; } uint16 manufacturerId = (uint16)strtol( str, &pStopChar, 16 ); str = manufacturerElement->Attribute( "name" ); if( !str ) { Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing manufacturer name attribute", manufacturerElement->Row() ); delete pDoc; return false; } // Add this manufacturer to the map s_manufacturerMap[manufacturerId] = str; // Parse all the products for this manufacturer TiXmlElement const* productElement = manufacturerElement->FirstChildElement(); while( productElement ) { str = productElement->Value(); if( str && !strcmp( str, "Product" ) ) { str = productElement->Attribute( "type" ); if( !str ) { Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product type attribute", productElement->Row() ); delete pDoc; return false; } uint16 productType = (uint16)strtol( str, &pStopChar, 16 ); str = productElement->Attribute( "id" ); if( !str ) { Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product id attribute", productElement->Row() ); delete pDoc; return false; } uint16 productId = (uint16)strtol( str, &pStopChar, 16 ); str = productElement->Attribute( "name" ); if( !str ) { Log::Write( LogLevel_Info, "Error in manufacturer_specific.xml at line %d - missing product name attribute", productElement->Row() ); delete pDoc; return false; } string productName = str; // Optional config path string configPath; str = productElement->Attribute( "config" ); if( str ) { configPath = str; } // Add the product to the map Product* product = new Product( manufacturerId, productType, productId, productName, configPath ); if ( s_productMap[product->GetKey()] != NULL ) { Product *c = s_productMap[product->GetKey()]; Log::Write( LogLevel_Info, "Product name collision: %s type %x id %x manufacturerid %x, collides with %s, type %x id %x manufacturerid %x", productName.c_str(), productType, productId, manufacturerId, c->GetProductName().c_str(), c->GetProductType(), c->GetProductId(), c->GetManufacturerId()); delete product; } else { s_productMap[product->GetKey()] = product; } } // Move on to the next product. productElement = productElement->NextSiblingElement(); } } // Move on to the next manufacturer. manufacturerElement = manufacturerElement->NextSiblingElement(); } delete pDoc; return true; }