1537ff140SPatrick Venture #include "endian.hpp" 207c462acSRatan Gupta #include "slp.hpp" 3537ff140SPatrick Venture #include "slp_meta.hpp" 407c462acSRatan Gupta 507c462acSRatan Gupta #include <arpa/inet.h> 6ead7a3caSRatan Gupta #include <dirent.h> 707c462acSRatan Gupta #include <ifaddrs.h> 807c462acSRatan Gupta #include <net/if.h> 907c462acSRatan Gupta #include <string.h> 1007c462acSRatan Gupta 1107c462acSRatan Gupta #include <algorithm> 1207c462acSRatan Gupta 1307c462acSRatan Gupta namespace slp 1407c462acSRatan Gupta { 1507c462acSRatan Gupta namespace handler 1607c462acSRatan Gupta { 1707c462acSRatan Gupta 1807c462acSRatan Gupta namespace internal 1907c462acSRatan Gupta { 2007c462acSRatan Gupta 21f93142e8SPatrick Williams static constexpr auto SERVICE_DIR = "/etc/slp/services/"; 22f93142e8SPatrick Williams 2307c462acSRatan Gupta buffer prepareHeader(const Message& req) 2407c462acSRatan Gupta { 25537ff140SPatrick Venture uint8_t length = 26537ff140SPatrick Venture slp::header::MIN_LEN + /* 14 bytes for header */ 2707c462acSRatan Gupta req.header.langtag.length() + /* Actual length of lang tag */ 2807c462acSRatan Gupta slp::response::SIZE_ERROR; /* 2 bytes for error code */ 2907c462acSRatan Gupta 3007c462acSRatan Gupta buffer buff(length, 0); 3107c462acSRatan Gupta 3207c462acSRatan Gupta buff[slp::header::OFFSET_VERSION] = req.header.version; 3307c462acSRatan Gupta 3407c462acSRatan Gupta // will increment the function id from 1 as reply 3507c462acSRatan Gupta buff[slp::header::OFFSET_FUNCTION] = req.header.functionID + 1; 3607c462acSRatan Gupta 3707c462acSRatan Gupta std::copy_n(&length, slp::header::SIZE_LENGTH, 38537ff140SPatrick Venture buff.data() + slp::header::OFFSET_LENGTH); 3907c462acSRatan Gupta 4007c462acSRatan Gupta auto flags = endian::to_network(req.header.flags); 4107c462acSRatan Gupta 4207c462acSRatan Gupta std::copy_n((uint8_t*)&flags, slp::header::SIZE_FLAGS, 43537ff140SPatrick Venture buff.data() + slp::header::OFFSET_FLAGS); 4407c462acSRatan Gupta 4507c462acSRatan Gupta std::copy_n(req.header.extOffset.data(), slp::header::SIZE_EXT, 46537ff140SPatrick Venture buff.data() + slp::header::OFFSET_EXT); 4707c462acSRatan Gupta 4807c462acSRatan Gupta auto xid = endian::to_network(req.header.xid); 4907c462acSRatan Gupta 5007c462acSRatan Gupta std::copy_n((uint8_t*)&xid, slp::header::SIZE_XID, 51537ff140SPatrick Venture buff.data() + slp::header::OFFSET_XID); 5207c462acSRatan Gupta 5307c462acSRatan Gupta uint16_t langtagLen = req.header.langtag.length(); 5407c462acSRatan Gupta langtagLen = endian::to_network(langtagLen); 5507c462acSRatan Gupta std::copy_n((uint8_t*)&langtagLen, slp::header::SIZE_LANG, 56537ff140SPatrick Venture buff.data() + slp::header::OFFSET_LANG_LEN); 5707c462acSRatan Gupta 58537ff140SPatrick Venture std::copy_n((uint8_t*)req.header.langtag.c_str(), 59537ff140SPatrick Venture req.header.langtag.length(), 60537ff140SPatrick Venture buff.data() + slp::header::OFFSET_LANG); 6107c462acSRatan Gupta return buff; 6207c462acSRatan Gupta } 6307c462acSRatan Gupta 64537ff140SPatrick Venture std::tuple<int, buffer> processSrvTypeRequest(const Message& req) 6507c462acSRatan Gupta { 6607c462acSRatan Gupta /* 6707c462acSRatan Gupta 0 1 2 3 6807c462acSRatan Gupta 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 6907c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 7007c462acSRatan Gupta | Service Location header (function = SrvTypeRply = 10) | 7107c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 7207c462acSRatan Gupta | Error Code | length of <srvType-list> | 7307c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 7407c462acSRatan Gupta | <srvtype--list> \ 7507c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 7607c462acSRatan Gupta */ 7707c462acSRatan Gupta 7807c462acSRatan Gupta buffer buff; 7907c462acSRatan Gupta 8007c462acSRatan Gupta // read the slp service info from conf and create the service type string 8107c462acSRatan Gupta slp::handler::internal::ServiceList svcList = 82ead7a3caSRatan Gupta slp::handler::internal::readSLPServiceInfo(); 8307c462acSRatan Gupta if (svcList.size() <= 0) 8407c462acSRatan Gupta { 8507c462acSRatan Gupta buff.resize(0); 860d3e9e33SRatan Gupta std::cerr << "SLP unable to read the service info\n"; 8707c462acSRatan Gupta return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff); 8807c462acSRatan Gupta } 8907c462acSRatan Gupta 9007c462acSRatan Gupta std::string service; 9107c462acSRatan Gupta bool firstIteration = true; 9207c462acSRatan Gupta for_each(svcList.cbegin(), svcList.cend(), 93537ff140SPatrick Venture [&service, &firstIteration](const auto& svc) { 9407c462acSRatan Gupta if (firstIteration == true) 9507c462acSRatan Gupta { 9607c462acSRatan Gupta service = svc.first; 9707c462acSRatan Gupta firstIteration = false; 9807c462acSRatan Gupta } 9907c462acSRatan Gupta else 10007c462acSRatan Gupta { 10107c462acSRatan Gupta service += ","; 10207c462acSRatan Gupta service += svc.first; 10307c462acSRatan Gupta } 10407c462acSRatan Gupta }); 10507c462acSRatan Gupta 10607c462acSRatan Gupta buff = prepareHeader(req); 10707c462acSRatan Gupta 10807c462acSRatan Gupta /* Need to modify the length and the function type field of the header 10907c462acSRatan Gupta * as it is dependent on the handler of the service */ 11007c462acSRatan Gupta 11107c462acSRatan Gupta std::cout << "service=" << service.c_str() << "\n"; 11207c462acSRatan Gupta 113*eebd0815SAndrew Geissler // See if total response size exceeds our max 114*eebd0815SAndrew Geissler uint32_t totalLength = 115*eebd0815SAndrew Geissler buff.size() + /* 14 bytes header + length of langtag */ 116*eebd0815SAndrew Geissler slp::response::SIZE_ERROR + /* 2 byte err code */ 117*eebd0815SAndrew Geissler slp::response::SIZE_SERVICE + /* 2 byte srvtype len */ 118*eebd0815SAndrew Geissler service.length(); 119*eebd0815SAndrew Geissler if (totalLength > slp::MAX_LEN) 120*eebd0815SAndrew Geissler { 121*eebd0815SAndrew Geissler std::cerr << "Message response size exceeds maximum allowed: " 122*eebd0815SAndrew Geissler << totalLength << " / " << slp::MAX_LEN << std::endl; 123*eebd0815SAndrew Geissler buff.resize(0); 124*eebd0815SAndrew Geissler return std::make_tuple((int)slp::Error::PARSE_ERROR, buff); 125*eebd0815SAndrew Geissler } 126*eebd0815SAndrew Geissler 12707c462acSRatan Gupta uint8_t length = buff.size() + /* 14 bytes header + length of langtag */ 12807c462acSRatan Gupta slp::response::SIZE_ERROR + /* 2 byte err code */ 12907c462acSRatan Gupta slp::response::SIZE_SERVICE + /* 2 byte srvtype len */ 13007c462acSRatan Gupta service.length(); 13107c462acSRatan Gupta 13207c462acSRatan Gupta buff.resize(length); 13307c462acSRatan Gupta 13407c462acSRatan Gupta std::copy_n(&length, slp::header::SIZE_LENGTH, 135537ff140SPatrick Venture buff.data() + slp::header::OFFSET_LENGTH); 13607c462acSRatan Gupta 13707c462acSRatan Gupta /* error code is already set to 0 moving to service type len */ 13807c462acSRatan Gupta 13907c462acSRatan Gupta uint16_t serviceTypeLen = service.length(); 14007c462acSRatan Gupta serviceTypeLen = endian::to_network(serviceTypeLen); 14107c462acSRatan Gupta 14207c462acSRatan Gupta std::copy_n((uint8_t*)&serviceTypeLen, slp::response::SIZE_SERVICE, 143537ff140SPatrick Venture buff.data() + slp::response::OFFSET_SERVICE_LEN); 14407c462acSRatan Gupta 14507c462acSRatan Gupta /* service type data */ 14607c462acSRatan Gupta std::copy_n((uint8_t*)service.c_str(), service.length(), 147537ff140SPatrick Venture (buff.data() + slp::response::OFFSET_SERVICE)); 14807c462acSRatan Gupta 14907c462acSRatan Gupta return std::make_tuple(slp::SUCCESS, buff); 15007c462acSRatan Gupta } 15107c462acSRatan Gupta 152537ff140SPatrick Venture std::tuple<int, buffer> processSrvRequest(const Message& req) 15307c462acSRatan Gupta { 15407c462acSRatan Gupta /* 15507c462acSRatan Gupta Service Reply 15607c462acSRatan Gupta 0 1 2 3 15707c462acSRatan Gupta 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 15807c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15907c462acSRatan Gupta | Service Location header (function = SrvRply = 2) | 16007c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16107c462acSRatan Gupta | Error Code | URL Entry count | 16207c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16307c462acSRatan Gupta | <URL Entry 1> ... <URL Entry N> \ 16407c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 16507c462acSRatan Gupta 16607c462acSRatan Gupta URL Entry 16707c462acSRatan Gupta 0 1 2 3 16807c462acSRatan Gupta 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 16907c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17007c462acSRatan Gupta | Reserved | Lifetime | URL Length | 17107c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17207c462acSRatan Gupta |URL len, contd.| URL (variable length) \ 17307c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17407c462acSRatan Gupta |# of URL auths | Auth. blocks (if any) \ 17507c462acSRatan Gupta +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17607c462acSRatan Gupta */ 17707c462acSRatan Gupta 17807c462acSRatan Gupta buffer buff; 17907c462acSRatan Gupta // Get all the services which are registered 18007c462acSRatan Gupta slp::handler::internal::ServiceList svcList = 181ead7a3caSRatan Gupta slp::handler::internal::readSLPServiceInfo(); 18207c462acSRatan Gupta if (svcList.size() <= 0) 18307c462acSRatan Gupta { 18407c462acSRatan Gupta buff.resize(0); 1850d3e9e33SRatan Gupta std::cerr << "SLP unable to read the service info\n"; 18607c462acSRatan Gupta return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff); 18707c462acSRatan Gupta } 18807c462acSRatan Gupta 18907c462acSRatan Gupta // return error if serice type doesn't match 19007c462acSRatan Gupta auto& svcName = req.body.srvrqst.srvType; 19107c462acSRatan Gupta auto svcIt = svcList.find(svcName); 19207c462acSRatan Gupta if (svcIt == svcList.end()) 19307c462acSRatan Gupta { 19407c462acSRatan Gupta buff.resize(0); 1950d3e9e33SRatan Gupta std::cerr << "SLP unable to find the service=" << svcName << "\n"; 19607c462acSRatan Gupta return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff); 19707c462acSRatan Gupta } 19807c462acSRatan Gupta // Get all the interface address 19907c462acSRatan Gupta auto ifaddrList = slp::handler::internal::getIntfAddrs(); 20007c462acSRatan Gupta if (ifaddrList.size() <= 0) 20107c462acSRatan Gupta { 20207c462acSRatan Gupta buff.resize(0); 2030d3e9e33SRatan Gupta std::cerr << "SLP unable to read the interface address\n"; 20407c462acSRatan Gupta return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff); 20507c462acSRatan Gupta } 20607c462acSRatan Gupta 20707c462acSRatan Gupta buff = prepareHeader(req); 20807c462acSRatan Gupta // Calculate the length and resize the buffer 20907c462acSRatan Gupta uint8_t length = buff.size() + /* 14 bytes header + length of langtag */ 21007c462acSRatan Gupta slp::response::SIZE_ERROR + /* 2 bytes error code */ 21107c462acSRatan Gupta slp::response::SIZE_URL_COUNT; /* 2 bytes srvtype len */ 21207c462acSRatan Gupta 21307c462acSRatan Gupta buff.resize(length); 21407c462acSRatan Gupta 21507c462acSRatan Gupta // Populate the url count 21607c462acSRatan Gupta uint16_t urlCount = ifaddrList.size(); 21707c462acSRatan Gupta urlCount = endian::to_network(urlCount); 21807c462acSRatan Gupta 21907c462acSRatan Gupta std::copy_n((uint8_t*)&urlCount, slp::response::SIZE_URL_COUNT, 220537ff140SPatrick Venture buff.data() + slp::response::OFFSET_URL_ENTRY); 22107c462acSRatan Gupta 22207c462acSRatan Gupta // Find the service 22307c462acSRatan Gupta const slp::ConfigData& svc = svcIt->second; 2241f12e380SGunnar Mills // Populate the URL Entries 22507c462acSRatan Gupta auto pos = slp::response::OFFSET_URL_ENTRY + slp::response::SIZE_URL_COUNT; 22607c462acSRatan Gupta for (const auto& addr : ifaddrList) 22707c462acSRatan Gupta { 228aa902c6eSPatrick Williams std::string url = svc.name + ':' + svc.type + "//" + addr + ',' + 229aa902c6eSPatrick Williams svc.port; 23007c462acSRatan Gupta 231*eebd0815SAndrew Geissler // See if total response size exceeds our max 232*eebd0815SAndrew Geissler uint32_t totalLength = buff.size() + slp::response::SIZE_URL_ENTRY + 233*eebd0815SAndrew Geissler url.length(); 234*eebd0815SAndrew Geissler if (totalLength > slp::MAX_LEN) 235*eebd0815SAndrew Geissler { 236*eebd0815SAndrew Geissler std::cerr << "Message response size exceeds maximum allowed: " 237*eebd0815SAndrew Geissler << totalLength << " / " << slp::MAX_LEN << std::endl; 238*eebd0815SAndrew Geissler buff.resize(0); 239*eebd0815SAndrew Geissler return std::make_tuple((int)slp::Error::PARSE_ERROR, buff); 240*eebd0815SAndrew Geissler } 241*eebd0815SAndrew Geissler 242537ff140SPatrick Venture buff.resize(buff.size() + slp::response::SIZE_URL_ENTRY + url.length()); 24307c462acSRatan Gupta 24407c462acSRatan Gupta uint8_t reserved = 0; 24507c462acSRatan Gupta uint16_t auth = 0; 24607c462acSRatan Gupta uint16_t lifetime = endian::to_network<uint16_t>(slp::LIFETIME); 24707c462acSRatan Gupta uint16_t urlLength = url.length(); 24807c462acSRatan Gupta 24907c462acSRatan Gupta std::copy_n((uint8_t*)&reserved, slp::response::SIZE_RESERVED, 25007c462acSRatan Gupta buff.data() + pos); 25107c462acSRatan Gupta 25207c462acSRatan Gupta pos += slp::response::SIZE_RESERVED; 25307c462acSRatan Gupta 25407c462acSRatan Gupta std::copy_n((uint8_t*)&lifetime, slp::response::SIZE_LIFETIME, 25507c462acSRatan Gupta buff.data() + pos); 25607c462acSRatan Gupta 25707c462acSRatan Gupta pos += slp::response::SIZE_LIFETIME; 25807c462acSRatan Gupta 25907c462acSRatan Gupta urlLength = endian::to_network(urlLength); 26007c462acSRatan Gupta std::copy_n((uint8_t*)&urlLength, slp::response::SIZE_URLLENGTH, 26107c462acSRatan Gupta buff.data() + pos); 26207c462acSRatan Gupta pos += slp::response::SIZE_URLLENGTH; 26307c462acSRatan Gupta 264537ff140SPatrick Venture std::copy_n((uint8_t*)url.c_str(), url.length(), buff.data() + pos); 26507c462acSRatan Gupta pos += url.length(); 26607c462acSRatan Gupta 26707c462acSRatan Gupta std::copy_n((uint8_t*)&auth, slp::response::SIZE_AUTH, 26807c462acSRatan Gupta buff.data() + pos); 26907c462acSRatan Gupta pos += slp::response::SIZE_AUTH; 27007c462acSRatan Gupta } 27107c462acSRatan Gupta uint8_t packetLength = buff.size(); 27207c462acSRatan Gupta std::copy_n((uint8_t*)&packetLength, slp::header::SIZE_VERSION, 273537ff140SPatrick Venture buff.data() + slp::header::OFFSET_LENGTH); 27407c462acSRatan Gupta 27507c462acSRatan Gupta return std::make_tuple((int)slp::SUCCESS, buff); 27607c462acSRatan Gupta } 27707c462acSRatan Gupta 27807c462acSRatan Gupta std::list<std::string> getIntfAddrs() 27907c462acSRatan Gupta { 28007c462acSRatan Gupta std::list<std::string> addrList; 28107c462acSRatan Gupta 28207c462acSRatan Gupta struct ifaddrs* ifaddr; 28307c462acSRatan Gupta // attempt to fill struct with ifaddrs 28407c462acSRatan Gupta if (getifaddrs(&ifaddr) == -1) 28507c462acSRatan Gupta { 28607c462acSRatan Gupta return addrList; 28707c462acSRatan Gupta } 28807c462acSRatan Gupta 289537ff140SPatrick Venture slp::deleted_unique_ptr<ifaddrs> ifaddrPtr( 290537ff140SPatrick Venture ifaddr, [](ifaddrs* addr) { freeifaddrs(addr); }); 29107c462acSRatan Gupta 29207c462acSRatan Gupta ifaddr = nullptr; 29307c462acSRatan Gupta 29407c462acSRatan Gupta for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next) 29507c462acSRatan Gupta { 29607c462acSRatan Gupta // walk interfaces 29707c462acSRatan Gupta if (ifa->ifa_addr == nullptr) 29807c462acSRatan Gupta { 29907c462acSRatan Gupta continue; 30007c462acSRatan Gupta } 30107c462acSRatan Gupta 30207c462acSRatan Gupta // get only INET interfaces not ipv6 30307c462acSRatan Gupta if (ifa->ifa_addr->sa_family == AF_INET) 30407c462acSRatan Gupta { 30507c462acSRatan Gupta // if loopback, or not running ignore 30607c462acSRatan Gupta if ((ifa->ifa_flags & IFF_LOOPBACK) || 30707c462acSRatan Gupta !(ifa->ifa_flags & IFF_RUNNING)) 30807c462acSRatan Gupta { 30907c462acSRatan Gupta continue; 31007c462acSRatan Gupta } 31107c462acSRatan Gupta 31207c462acSRatan Gupta char tmp[INET_ADDRSTRLEN] = {0}; 31307c462acSRatan Gupta 31407c462acSRatan Gupta inet_ntop(AF_INET, 315537ff140SPatrick Venture &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr), tmp, 31607c462acSRatan Gupta sizeof(tmp)); 31707c462acSRatan Gupta addrList.emplace_back(tmp); 31807c462acSRatan Gupta } 31907c462acSRatan Gupta } 32007c462acSRatan Gupta 32107c462acSRatan Gupta return addrList; 32207c462acSRatan Gupta } 32307c462acSRatan Gupta 324ead7a3caSRatan Gupta slp::handler::internal::ServiceList readSLPServiceInfo() 32507c462acSRatan Gupta { 32607c462acSRatan Gupta using namespace std::string_literals; 32707c462acSRatan Gupta slp::handler::internal::ServiceList svcLst; 32807c462acSRatan Gupta slp::ConfigData service; 329ead7a3caSRatan Gupta struct dirent* dent = nullptr; 330ead7a3caSRatan Gupta 331ead7a3caSRatan Gupta // Open the services dir and get the service info 332ead7a3caSRatan Gupta // from service files. 333ead7a3caSRatan Gupta // Service File format would be "ServiceName serviceType Port" 334ead7a3caSRatan Gupta DIR* dir = opendir(SERVICE_DIR); 335ead7a3caSRatan Gupta // wrap the pointer into smart pointer. 336537ff140SPatrick Venture slp::deleted_unique_ptr<DIR> dirPtr(dir, [](DIR* dir) { 337ead7a3caSRatan Gupta if (!dir) 338ead7a3caSRatan Gupta { 339ead7a3caSRatan Gupta closedir(dir); 340ead7a3caSRatan Gupta } 341ead7a3caSRatan Gupta }); 342ead7a3caSRatan Gupta dir = nullptr; 343ead7a3caSRatan Gupta 344ead7a3caSRatan Gupta if (dirPtr.get()) 345ead7a3caSRatan Gupta { 346ead7a3caSRatan Gupta while ((dent = readdir(dirPtr.get())) != NULL) 347ead7a3caSRatan Gupta { 348ead7a3caSRatan Gupta if (dent->d_type == DT_REG) // regular file 349ead7a3caSRatan Gupta { 350ead7a3caSRatan Gupta auto absFileName = std::string(SERVICE_DIR) + dent->d_name; 351ead7a3caSRatan Gupta std::ifstream readFile(absFileName); 352ead7a3caSRatan Gupta readFile >> service; 353ead7a3caSRatan Gupta service.name = "service:"s + service.name; 35407c462acSRatan Gupta svcLst.emplace(service.name, service); 35507c462acSRatan Gupta } 356ead7a3caSRatan Gupta } 357ead7a3caSRatan Gupta } 35807c462acSRatan Gupta return svcLst; 35907c462acSRatan Gupta } 36007c462acSRatan Gupta } // namespace internal 36107c462acSRatan Gupta 362537ff140SPatrick Venture std::tuple<int, buffer> processRequest(const Message& msg) 36307c462acSRatan Gupta { 36407c462acSRatan Gupta int rc = slp::SUCCESS; 36507c462acSRatan Gupta buffer resp(0); 366537ff140SPatrick Venture std::cout << "SLP Processing Request=" << msg.header.functionID << "\n"; 3670d3e9e33SRatan Gupta 368b5e632a1SBrad Bishop switch (msg.header.functionID) 369b5e632a1SBrad Bishop { 37007c462acSRatan Gupta case (uint8_t)slp::FunctionType::SRVTYPERQST: 371aa902c6eSPatrick Williams std::tie(rc, 372aa902c6eSPatrick Williams resp) = slp::handler::internal::processSrvTypeRequest(msg); 37307c462acSRatan Gupta break; 37407c462acSRatan Gupta case (uint8_t)slp::FunctionType::SRVRQST: 37507c462acSRatan Gupta std::tie(rc, resp) = slp::handler::internal::processSrvRequest(msg); 37607c462acSRatan Gupta break; 37707c462acSRatan Gupta default: 37807c462acSRatan Gupta rc = (uint8_t)slp::Error::MSG_NOT_SUPPORTED; 37907c462acSRatan Gupta } 38007c462acSRatan Gupta return std::make_tuple(rc, resp); 38107c462acSRatan Gupta } 38207c462acSRatan Gupta 383537ff140SPatrick Venture buffer processError(const Message& req, uint8_t err) 38407c462acSRatan Gupta { 38507c462acSRatan Gupta buffer buff; 38607c462acSRatan Gupta buff = slp::handler::internal::prepareHeader(req); 38707c462acSRatan Gupta 388edf88cb2SPatrick Williams static_assert(sizeof(err) == 1, "Errors should be 1 byte."); 389edf88cb2SPatrick Williams 390edf88cb2SPatrick Williams // Since this is network order, the err should go in the 2nd byte of the 391edf88cb2SPatrick Williams // error field. This is immediately after the langtag. 392edf88cb2SPatrick Williams buff[slp::header::MIN_LEN + req.header.langtag.length() + 1] = err; 393edf88cb2SPatrick Williams 39407c462acSRatan Gupta return buff; 39507c462acSRatan Gupta } 39607c462acSRatan Gupta } // namespace handler 39707c462acSRatan Gupta } // namespace slp 398