| 135 | } |
| 136 | |
| 137 | EipStatus SetAssemblyAttributeSingle(CipInstance *const instance, |
| 138 | CipMessageRouterRequest *const message_router_request, |
| 139 | CipMessageRouterResponse *const message_router_response, |
| 140 | struct sockaddr *originator_address, |
| 141 | const int encapsulation_session) { |
| 142 | OPENER_TRACE_INFO(" setAttribute %d\n", |
| 143 | message_router_request->request_path.attribute_number); |
| 144 | |
| 145 | const EipUint8 *const router_request_data = message_router_request->data; |
| 146 | |
| 147 | message_router_response->data_length = 0; |
| 148 | message_router_response->reply_service = |
| 149 | (0x80 | message_router_request->service); |
| 150 | message_router_response->general_status = kCipErrorAttributeNotSupported; |
| 151 | message_router_response->size_of_additional_status = 0; |
| 152 | |
| 153 | CipAttributeStruct *attribute = GetCipAttribute(instance, |
| 154 | message_router_request->request_path.attribute_number); |
| 155 | |
| 156 | if( (attribute != NULL) && |
| 157 | (3 == message_router_request->request_path.attribute_number) ) { |
| 158 | if(attribute->data != NULL) { |
| 159 | CipByteArray *data = (CipByteArray *) attribute->data; |
| 160 | |
| 161 | /* TODO: check for ATTRIBUTE_SET/GETABLE MASK */ |
| 162 | if( true == IsConnectedOutputAssembly(instance->instance_number) ) { |
| 163 | OPENER_TRACE_WARN( |
| 164 | "Assembly AssemblyAttributeSingle: received data for connected output assembly\n\r"); |
| 165 | message_router_response->general_status = kCipErrorAttributeNotSetable; |
| 166 | } |
| 167 | else{ |
| 168 | if(message_router_request->request_path_size < data->length) { |
| 169 | OPENER_TRACE_INFO( |
| 170 | "Assembly setAssemblyAttributeSingle: not enough data received.\r\n"); |
| 171 | message_router_response->general_status = kCipErrorNotEnoughData; |
| 172 | } |
| 173 | else{ |
| 174 | if(message_router_request->request_path_size > data->length) { |
| 175 | OPENER_TRACE_INFO( |
| 176 | "Assembly setAssemblyAttributeSingle: too much data received.\r\n"); |
| 177 | message_router_response->general_status = kCipErrorTooMuchData; |
| 178 | } |
| 179 | else{ |
| 180 | memcpy(data->data, router_request_data, data->length); |
| 181 | |
| 182 | if(AfterAssemblyDataReceived(instance) != kEipStatusOk) { |
| 183 | /* punt early without updating the status... though I don't know |
| 184 | * how much this helps us here, as the attribute's data has already |
| 185 | * been overwritten. |
| 186 | * |
| 187 | * however this is the task of the application side which will |
| 188 | * take the data. In addition we have to inform the sender that the |
| 189 | * data was not ok. |
| 190 | */ |
| 191 | message_router_response->general_status = |
| 192 | kCipErrorInvalidAttributeValue; |
| 193 | } |
| 194 | else{ |
nothing calls this directly
no test coverage detected