ua_services_attribute.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "ua_services.h"
  2. #include "ua_statuscodes.h"
  3. enum UA_AttributeId {
  4. UA_ATTRIBUTEID_NODEID = 1,
  5. UA_ATTRIBUTEID_NODECLASS = 2,
  6. UA_ATTRIBUTEID_BROWSENAME = 3,
  7. UA_ATTRIBUTEID_DISPLAYNAME = 4,
  8. UA_ATTRIBUTEID_DESCRIPTION = 5,
  9. UA_ATTRIBUTEID_WRITEMASK = 6,
  10. UA_ATTRIBUTEID_USERWRITEMASK = 7,
  11. UA_ATTRIBUTEID_ISABSTRACT = 8,
  12. UA_ATTRIBUTEID_SYMMETRIC = 9,
  13. UA_ATTRIBUTEID_INVERSENAME = 10,
  14. UA_ATTRIBUTEID_CONTAINSNOLOOPS = 11,
  15. UA_ATTRIBUTEID_EVENTNOTIFIER = 12,
  16. UA_ATTRIBUTEID_VALUE = 13,
  17. UA_ATTRIBUTEID_DATATYPE = 14,
  18. UA_ATTRIBUTEID_VALUERANK = 15,
  19. UA_ATTRIBUTEID_ARRAYDIMENSIONS = 16,
  20. UA_ATTRIBUTEID_ACCESSLEVEL = 17,
  21. UA_ATTRIBUTEID_USERACCESSLEVEL = 18,
  22. UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL = 19,
  23. UA_ATTRIBUTEID_HISTORIZING = 20,
  24. UA_ATTRIBUTEID_EXECUTABLE = 21,
  25. UA_ATTRIBUTEID_USEREXECUTABLE = 22
  26. };
  27. static UA_DataValue * service_read_node(Application *app, const UA_ReadValueId *id) {
  28. UA_DataValue *v; UA_DataValue_new(&v);
  29. DBG(printf("service_read_node - entered with ns=%d,id=%d,attr=%i\n",id->nodeId.namespace, id->nodeId.identifier.numeric, id->attributeId));
  30. namespace *ns = UA_indexedList_findValue(app->namespaces, id->nodeId.namespace);
  31. if (ns == UA_NULL) {
  32. DBG_VERBOSE(printf("service_read_node - unknown namespace %d\n",id->nodeId.namespace));
  33. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  34. v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
  35. return v;
  36. }
  37. DBG_VERBOSE(UA_String_printf(",namespaceUri=",&(ns->namespaceUri)));
  38. UA_Node const *node = UA_NULL;
  39. ns_lock *lock = UA_NULL;
  40. DBG_VERBOSE(UA_NodeId_printf("service_read_node - search for ",&(id->nodeId)));
  41. UA_Int32 result = get_node(ns, &(id->nodeId), &node, &lock);
  42. if(result != UA_SUCCESS || node == UA_NULL) {
  43. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  44. v->status = UA_STATUSCODE_BADNODEIDUNKNOWN;
  45. return v;
  46. }
  47. DBG_VERBOSE(UA_NodeId_printf("service_read_node - found node=",&(node->nodeId)));
  48. switch(id->attributeId) {
  49. case UA_ATTRIBUTEID_NODEID:
  50. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  51. v->status = UA_STATUSCODE_BADNOTREADABLE;
  52. break;
  53. case UA_ATTRIBUTEID_NODECLASS:
  54. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  55. v->status = UA_STATUSCODE_BADNOTREADABLE;
  56. break;
  57. case UA_ATTRIBUTEID_BROWSENAME:
  58. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  59. v->status = UA_STATUSCODE_BADNOTREADABLE;
  60. break;
  61. case UA_ATTRIBUTEID_DISPLAYNAME:
  62. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  63. v->status = UA_STATUSCODE_BADNOTREADABLE;
  64. break;
  65. case UA_ATTRIBUTEID_DESCRIPTION:
  66. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  67. v->status = UA_STATUSCODE_BADNOTREADABLE;
  68. break;
  69. case UA_ATTRIBUTEID_WRITEMASK:
  70. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  71. v->status = UA_STATUSCODE_BADNOTREADABLE;
  72. break;
  73. case UA_ATTRIBUTEID_USERWRITEMASK:
  74. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  75. v->status = UA_STATUSCODE_BADNOTREADABLE;
  76. break;
  77. case UA_ATTRIBUTEID_ISABSTRACT:
  78. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  79. v->status = UA_STATUSCODE_BADNOTREADABLE;
  80. break;
  81. case UA_ATTRIBUTEID_SYMMETRIC:
  82. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  83. v->status = UA_STATUSCODE_BADNOTREADABLE;
  84. break;
  85. case UA_ATTRIBUTEID_INVERSENAME:
  86. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  87. v->status = UA_STATUSCODE_BADNOTREADABLE;
  88. break;
  89. case UA_ATTRIBUTEID_CONTAINSNOLOOPS:
  90. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  91. v->status = UA_STATUSCODE_BADNOTREADABLE;
  92. break;
  93. case UA_ATTRIBUTEID_EVENTNOTIFIER:
  94. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  95. v->status = UA_STATUSCODE_BADNOTREADABLE;
  96. break;
  97. case UA_ATTRIBUTEID_VALUE:
  98. if (node->nodeClass != UA_NODECLASS_VARIABLE) {
  99. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  100. v->status = UA_STATUSCODE_BADNOTREADABLE;
  101. break;
  102. }
  103. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE | UA_DATAVALUE_ENCODINGMASK_VARIANT;
  104. v->status = UA_STATUSCODE_GOOD;
  105. // be careful not to release the node before encoding the message
  106. UA_VariableNode * vn = (UA_VariableNode*) node;
  107. // FIXME: delete will be called later on on on all the members of v, so essentially
  108. // the item's data will be removed from the namespace-object. We would need
  109. // something like a deep copy function just as we have it for the strings
  110. // UA_Variant_copy(UA_Variant* src, UA_Variant* dst);
  111. // FIXME: mockup code - we know that for 2255 we simply need to copy the array
  112. if (node->nodeId.identifier.numeric == 2255) {
  113. v->value = vn->value;
  114. UA_Array_copy((void const*const*)vn->value.data,vn->value.arrayLength,UA_toIndex(vn->value.vt->ns0Id),(void***)&v->value.data);
  115. } else {
  116. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  117. v->status = UA_STATUSCODE_BADNOTREADABLE;
  118. }
  119. break;
  120. case UA_ATTRIBUTEID_DATATYPE:
  121. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  122. v->status = UA_STATUSCODE_BADNOTREADABLE;
  123. break;
  124. case UA_ATTRIBUTEID_VALUERANK:
  125. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  126. v->status = UA_STATUSCODE_BADNOTREADABLE;
  127. break;
  128. case UA_ATTRIBUTEID_ARRAYDIMENSIONS:
  129. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  130. v->status = UA_STATUSCODE_BADNOTREADABLE;
  131. break;
  132. case UA_ATTRIBUTEID_ACCESSLEVEL:
  133. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  134. v->status = UA_STATUSCODE_BADNOTREADABLE;
  135. break;
  136. case UA_ATTRIBUTEID_USERACCESSLEVEL:
  137. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  138. v->status = UA_STATUSCODE_BADNOTREADABLE;
  139. break;
  140. case UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL:
  141. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  142. v->status = UA_STATUSCODE_BADNOTREADABLE;
  143. break;
  144. case UA_ATTRIBUTEID_HISTORIZING:
  145. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  146. v->status = UA_STATUSCODE_BADNOTREADABLE;
  147. break;
  148. case UA_ATTRIBUTEID_EXECUTABLE:
  149. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  150. v->status = UA_STATUSCODE_BADNOTREADABLE;
  151. break;
  152. case UA_ATTRIBUTEID_USEREXECUTABLE:
  153. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  154. v->status = UA_STATUSCODE_BADNOTREADABLE;
  155. break;
  156. default:
  157. v->encodingMask = UA_DATAVALUE_ENCODINGMASK_STATUSCODE;
  158. v->status = UA_STATUSCODE_BADATTRIBUTEIDINVALID;
  159. break;
  160. }
  161. release_node(lock);
  162. return v;
  163. }
  164. UA_Int32 Service_Read(SL_Channel *channel, const UA_ReadRequest *request, UA_ReadResponse *response ) {
  165. if(channel->session == UA_NULL || channel->session->application == UA_NULL) return UA_ERROR; // TODO: Return error message
  166. int readsize = request->nodesToReadSize > 0 ? request->nodesToReadSize : 0;
  167. response->resultsSize = readsize;
  168. UA_alloc((void **)&response->results, sizeof(void *)*readsize);
  169. for(int i=0;i<readsize;i++) {
  170. DBG_VERBOSE(printf("service_read - attributeId=%d\n",request->nodesToRead[i]->attributeId));
  171. DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=",&(request->nodesToRead[i]->nodeId)));
  172. response->results[i] = service_read_node(channel->session->application, request->nodesToRead[i]);
  173. }
  174. response->diagnosticInfosSize = -1;
  175. return UA_SUCCESS;
  176. }