* @brief Takes an incoming SML message and responds with * an appropriate response message. * * @param pConnection The connection this message came in on. * @param pIncoming The incoming message *************************************************************/
| 632 | * @param pIncoming The incoming message |
| 633 | *************************************************************/ |
| 634 | soarxml::ElementXML* KernelSML::ProcessIncomingSML(Connection* pConnection, soarxml::ElementXML* pIncomingMsg) |
| 635 | { |
| 636 | if (!pIncomingMsg || !pConnection) |
| 637 | { |
| 638 | return NULL ; |
| 639 | } |
| 640 | |
| 641 | // Make sure only one thread is executing commands in the kernel at a time. |
| 642 | // This is really just an insurance policy as I don't think we'll ever execute |
| 643 | // commands on different threads within kernelSML because we |
| 644 | // only allow one embedded connection to the kernel, but it's nice to be sure. |
| 645 | soar_thread::Lock lock(m_pKernelMutex) ; |
| 646 | |
| 647 | #ifdef DEBUG |
| 648 | // For debugging, it's helpful to be able to look at the incoming message as an XML string |
| 649 | char* pIncomingXML = pIncomingMsg->GenerateXMLString(true) ; |
| 650 | #endif |
| 651 | |
| 652 | soarxml::ElementXML* pResponse = pConnection->CreateSMLResponse(pIncomingMsg) ; |
| 653 | |
| 654 | // Fatal error creating the response |
| 655 | if (!pResponse) |
| 656 | { |
| 657 | return NULL ; |
| 658 | } |
| 659 | |
| 660 | // Analyze the message and find important tags |
| 661 | AnalyzeXML msg ; |
| 662 | msg.Analyze(pIncomingMsg) ; |
| 663 | |
| 664 | // Get the "name" attribute from the <command> tag |
| 665 | char const* pCommandName = msg.GetCommandName() ; |
| 666 | |
| 667 | if (pCommandName) |
| 668 | { |
| 669 | ProcessCommand(pCommandName, pConnection, &msg, pResponse) ; |
| 670 | } |
| 671 | else |
| 672 | { |
| 673 | // The message wasn't something we recognize. |
| 674 | if (!msg.GetCommandTag()) |
| 675 | { |
| 676 | AddErrorMsg(pConnection, pResponse, "Incoming message did not contain a <command> tag") ; |
| 677 | } |
| 678 | else |
| 679 | { |
| 680 | AddErrorMsg(pConnection, pResponse, "Incoming message did not contain a name attribute in the <command> tag") ; |
| 681 | } |
| 682 | } |
| 683 | |
| 684 | #ifdef DEBUG |
| 685 | // For debugging, it's helpful to be able to look at the response as XML |
| 686 | char* pResponseXML = pResponse->GenerateXMLString(true) ; |
| 687 | |
| 688 | // Set a break point on this next line if you wish to see the incoming |
| 689 | // and outgoing as XML before they get deleted. |
| 690 | soarxml::ElementXML::DeleteString(pIncomingXML) ; |
| 691 | soarxml::ElementXML::DeleteString(pResponseXML) ; |
no test coverage detected