ua_services_nodemanagement.c 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "ua_services.h"
  2. #include "ua_statuscodes.h"
  3. #include "ua_namespace.h"
  4. #define CHECKED_ACTION(ACTION, CLEAN_UP, GOTO) do { \
  5. status |= ACTION; \
  6. if(status != UA_SUCCESS) { \
  7. CLEAN_UP; \
  8. goto GOTO; \
  9. } } while(0) \
  10. static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item) {
  11. UA_AddNodesResult *result;
  12. UA_AddNodesResult_new(&result);
  13. Namespace *parent_ns = UA_indexedList_findValue(app->namespaces, item->parentNodeId.nodeId.namespace);
  14. // TODO: search for namespaceUris and not only ns-ids.
  15. if(parent_ns == UA_NULL) {
  16. result->statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
  17. return result;
  18. }
  19. Namespace *ns = UA_NULL;
  20. UA_Boolean nodeid_isnull = UA_NodeId_isNull(&item->requestedNewNodeId.nodeId);
  21. if(nodeid_isnull) ns = parent_ns;
  22. else ns = UA_indexedList_findValue(app->namespaces, item->requestedNewNodeId.nodeId.namespace);
  23. if(ns == UA_NULL || item->requestedNewNodeId.nodeId.namespace == 0) {
  24. result->statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
  25. return result;
  26. }
  27. UA_Int32 status = UA_SUCCESS;
  28. const UA_Node *parent;
  29. Namespace_Entry_Lock *parent_lock = UA_NULL;
  30. CHECKED_ACTION(Namespace_get(parent_ns, &item->parentNodeId.nodeId, &parent, &parent_lock),
  31. result->statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID, ret);
  32. if(!nodeid_isnull && Namespace_contains(ns, &item->requestedNewNodeId.nodeId)) {
  33. result->statusCode = UA_STATUSCODE_BADNODEIDEXISTS;
  34. goto ret;
  35. }
  36. /**
  37. TODO:
  38. 1) Check for the remaining conditions
  39. Bad_ReferenceTypeIdInvalid See Table 166 for the description of this result code.
  40. Bad_ReferenceNotAllowed The reference could not be created because it violates constraints imposed by the data model.
  41. Bad_NodeClassInvalid See Table 166 for the description of this result code.
  42. Bad_BrowseNameInvalid See Table 166 for the description of this result code.
  43. Bad_BrowseNameDuplicated The browse name is not unique among nodes that share the same relationship with the parent.
  44. Bad_NodeAttributesInvalid The node Attributes are not valid for the node class.
  45. Bad_TypeDefinitionInvalid See Table 166 for the description of this result code.
  46. Bad_UserAccessDenied See Table 165 for the description of this result code
  47. 2) Parse the UA_Node from the ExtensionObject
  48. 3) Create a new entry in the namespace
  49. 4) Add the reference to the parent.
  50. */
  51. ret:
  52. Namespace_Entry_Lock_release(parent_lock);
  53. return result;
  54. }
  55. UA_Int32 Service_AddNodes(SL_Channel *channel, const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
  56. if(channel->session == UA_NULL || channel->session->application == UA_NULL)
  57. return UA_ERROR; // TODO: Return error message
  58. int nodestoaddsize = request->nodesToAddSize;
  59. if(nodestoaddsize <= 0) {
  60. response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
  61. response->resultsSize = 0;
  62. return UA_SUCCESS;
  63. }
  64. response->resultsSize = nodestoaddsize;
  65. UA_alloc((void **)&response->results, sizeof(void *) * nodestoaddsize);
  66. for(int i = 0; i < nodestoaddsize; i++) {
  67. DBG_VERBOSE(UA_QualifiedName_printf("service_addnodes - name=", &(request->nodesToAdd[i]->browseName)));
  68. response->results[i] = addSingleNode(channel->session->application, request->nodesToAdd[i]);
  69. }
  70. response->responseHeader.serviceResult = UA_STATUSCODE_GOOD;
  71. response->diagnosticInfosSize = -1;
  72. return UA_SUCCESS;
  73. }