| 234 | } |
| 235 | |
| 236 | int HandleReceivedExplictUdpData(const int socket, |
| 237 | const struct sockaddr_in *from_address, |
| 238 | const EipUint8 *buffer, |
| 239 | const size_t buffer_length, |
| 240 | int *number_of_remaining_bytes, |
| 241 | bool unicast, |
| 242 | ENIPMessage *const outgoing_message) { |
| 243 | EipStatus status = kEipStatusOk; |
| 244 | EncapsulationData encapsulation_data = { 0 }; |
| 245 | /* eat the encapsulation header*/ |
| 246 | /* the structure contains a pointer to the encapsulated data*/ |
| 247 | /* returns how many bytes are left after the encapsulated data*/ |
| 248 | *number_of_remaining_bytes = CreateEncapsulationStructure(buffer, |
| 249 | buffer_length, |
| 250 | &encapsulation_data); |
| 251 | |
| 252 | if (kEncapsulationHeaderOptionsFlag == encapsulation_data.options) /*TODO generate appropriate error response*/ |
| 253 | { |
| 254 | if (*number_of_remaining_bytes >= 0) /* check if the message is corrupt: header size + claimed payload size > than what we actually received*/ |
| 255 | { |
| 256 | /* full package or more received */ |
| 257 | encapsulation_data.status = kEncapsulationProtocolSuccess; |
| 258 | status = kEipStatusOkSend; |
| 259 | /* most of these functions need a reply to be send */ |
| 260 | switch (encapsulation_data.command_code) { |
| 261 | case (kEncapsulationCommandListServices): |
| 262 | OPENER_TRACE_INFO("List Service\n"); |
| 263 | HandleReceivedListServicesCommand(&encapsulation_data, |
| 264 | outgoing_message); |
| 265 | break; |
| 266 | |
| 267 | case (kEncapsulationCommandListIdentity): |
| 268 | OPENER_TRACE_INFO("List Identity\n"); |
| 269 | if (unicast == true) { |
| 270 | HandleReceivedListIdentityCommandTcp(&encapsulation_data, |
| 271 | outgoing_message); |
| 272 | } else { |
| 273 | HandleReceivedListIdentityCommandUdp(socket, |
| 274 | from_address, |
| 275 | &encapsulation_data, |
| 276 | outgoing_message); |
| 277 | status = kEipStatusOk; |
| 278 | } /* as the response has to be delayed do not send it now */ |
| 279 | break; |
| 280 | |
| 281 | case (kEncapsulationCommandListInterfaces): |
| 282 | OPENER_TRACE_INFO("List Interfaces\n"); |
| 283 | HandleReceivedListInterfacesCommand(&encapsulation_data, |
| 284 | outgoing_message); |
| 285 | break; |
| 286 | |
| 287 | /* The following commands are not to be sent via UDP */ |
| 288 | case (kEncapsulationCommandNoOperation): |
| 289 | case (kEncapsulationCommandRegisterSession): |
| 290 | case (kEncapsulationCommandUnregisterSession): |
| 291 | case (kEncapsulationCommandSendRequestReplyData): |
| 292 | case (kEncapsulationCommandSendUnitData): |
| 293 | default: |
no test coverage detected