| 73 | } |
| 74 | |
| 75 | EipStatus NotifyClass(const CipClass *RESTRICT const cip_class, |
| 76 | CipMessageRouterRequest *const message_router_request, |
| 77 | CipMessageRouterResponse *const message_router_response, |
| 78 | struct sockaddr *originator_address, |
| 79 | const int encapsulation_session) { |
| 80 | |
| 81 | /* find the instance: if instNr==0, the class is addressed, else find the instance */ |
| 82 | EipUint16 instance_number = |
| 83 | message_router_request->request_path.instance_number; /* get the instance number */ |
| 84 | CipInstance *instance = GetCipInstance(cip_class, instance_number); /* look up the instance (note that if inst==0 this will be the class itself) */ |
| 85 | if (instance) /* if instance is found */ |
| 86 | { |
| 87 | OPENER_TRACE_INFO("notify: found instance %d%s\n", instance_number, |
| 88 | instance_number == 0 ? " (class object)" : ""); |
| 89 | |
| 90 | CipServiceStruct *service = instance->cip_class->services; /* get pointer to array of services */ |
| 91 | if (NULL != service) /* if services are defined */ |
| 92 | { |
| 93 | for (size_t i = 0; i < instance->cip_class->number_of_services; i++) /* seach the services list */ |
| 94 | { |
| 95 | if (message_router_request->service == service->service_number) /* if match is found */ |
| 96 | { |
| 97 | /* call the service, and return what it returns */ |
| 98 | OPENER_TRACE_INFO("notify: calling %s service\n", |
| 99 | service->name); |
| 100 | OPENER_ASSERT(NULL != service->service_function) |
| 101 | return service->service_function(instance, |
| 102 | message_router_request, |
| 103 | message_router_response, |
| 104 | originator_address, |
| 105 | encapsulation_session); |
| 106 | } else { |
| 107 | service++; |
| 108 | } |
| 109 | } |
| 110 | } |
| 111 | OPENER_TRACE_WARN("notify: service 0x%x not supported\n", |
| 112 | message_router_request->service); |
| 113 | message_router_response->general_status = kCipErrorServiceNotSupported; /* if no services or service not found, return an error reply*/ |
| 114 | } else { |
| 115 | OPENER_TRACE_WARN("notify: instance number %d unknown\n", |
| 116 | instance_number); |
| 117 | /* if instance not found, return an error reply */ |
| 118 | message_router_response->general_status = |
| 119 | kCipErrorPathDestinationUnknown; |
| 120 | /* according to the test tool this is the correct error flag instead of CIP_ERROR_OBJECT_DOES_NOT_EXIST */ |
| 121 | } |
| 122 | |
| 123 | /* handle error replies*/ |
| 124 | message_router_response->size_of_additional_status = 0; /* fill in the rest of the reply with not much of anything*/ |
| 125 | message_router_response->data_length = 0; |
| 126 | message_router_response->reply_service = (0x80 |
| 127 | | message_router_request->service); /* except the reply code is an echo of the command + the reply flag */ |
| 128 | |
| 129 | return kEipStatusOkSend; |
| 130 | } |
| 131 | |
| 132 | CipInstance *AddCipInstances(CipClass *RESTRICT const cip_class, |
no test coverage detected