1 /* 2 * This file is part of the openHiTLS project. 3 * 4 * openHiTLS is licensed under the Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * See the Mulan PSL v2 for more details. 14 */ 15 16 /** 17 * @defgroup bsl_uio 18 * @ingroup bsl 19 * @brief uio module 20 */ 21 22 #ifndef BSL_UIO_H 23 #define BSL_UIO_H 24 25 #include <stddef.h> 26 #include <stdint.h> 27 #include <stdbool.h> 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /** 34 * @ingroup bsl_uio 35 * @brief UIO module control structure 36 */ 37 typedef struct UIO_ControlBlock BSL_UIO; 38 39 /** 40 * @ingroup bsl_uio 41 * @brief BSL_UIO_BufMem structure 42 */ 43 typedef struct { 44 size_t length; 45 char *data; 46 size_t max; 47 } BSL_UIO_BufMem; 48 49 typedef int32_t (*BslUioWriteCb)(BSL_UIO *uio, const void *buf, uint32_t len, uint32_t *writeLen); 50 typedef int32_t (*BslUioReadCb)(BSL_UIO *uio, void *buf, uint32_t len, uint32_t *readLen); 51 typedef int32_t (*BslUioCtrlCb)(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg); 52 typedef int32_t (*BslUioCreateCb)(BSL_UIO *uio); 53 typedef int32_t (*BslUioDestroyCb)(BSL_UIO *uio); 54 typedef int32_t (*BslUioPutsCb)(BSL_UIO *uio, const char *buf, uint32_t *writeLen); 55 typedef int32_t (*BslUioGetsCb)(BSL_UIO *uio, char *buf, uint32_t *readLen); 56 57 typedef struct BSL_UIO_MethodStruct BSL_UIO_Method; 58 59 /** 60 * @ingroup bsl_uio 61 * @brief userData release function 62 */ 63 typedef void (*BSL_UIO_USERDATA_FREE_FUNC)(void *); 64 65 /** 66 * @ingroup bsl_uio 67 * @brief Transmission protocol enumeration 68 */ 69 typedef enum { 70 BSL_UIO_TCP, 71 BSL_UIO_UDP, 72 BSL_UIO_SCTP, 73 BSL_UIO_MEM, 74 BSL_UIO_BUFFER, 75 BSL_UIO_UNKNOWN, /* Unknown protocol should not appear */ 76 77 BSL_UIO_EXTEND = 10000, /* extension value */ 78 } BSL_UIO_TransportType; 79 80 #define IS_TRANSTYPE_DATAGRAM(transportType) ((transportType) == BSL_UIO_SCTP || (transportType) == BSL_UIO_UDP) 81 82 /** 83 * @ingroup bsl_uio 84 * @brief Sctp auth key, hitls Use the BSL_UIO_Method.ctrl method to transfer the BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY 85 * instruction to notify the user that the auth key needs to be set. 86 */ 87 typedef struct { 88 uint16_t shareKeyId; 89 uint16_t authKeySize; 90 const uint8_t *authKey; 91 } BSL_UIO_SctpAuthKey; 92 93 /** 94 * @ingroup bsl_uio 95 * @brief BSL_UIO_CtrlParameter controls the I/O callback function. Hitls notifies the 96 * user of the function to be implemented 97 */ 98 typedef enum { 99 /* The cmd(0-0x99) used by the abstraction layer and the uio 100 * implemented by the user cannot reuse these values. */ 101 BSL_UIO_GET_INIT = 0x0, 102 BSL_UIO_GET_WRITE_NUM, 103 BSL_UIO_GET_READ_NUM, 104 105 /* Public use 0x100 */ 106 BSL_UIO_SET_PEER_IP_ADDR = 0x100, 107 BSL_UIO_GET_PEER_IP_ADDR, 108 BSL_UIO_SET_FD, 109 BSL_UIO_GET_FD, 110 BSL_UIO_FLUSH, 111 BSL_UIO_RESET, 112 BSL_UIO_PENDING, 113 BSL_UIO_WPENDING, 114 BSL_UIO_SET_BUFFER_SIZE, 115 116 /* UDP uses 0x2XX */ 117 BSL_UIO_UDP_SET_CONNECTED = 0x200, 118 119 /* SCTP uses 0x3XX */ 120 BSL_UIO_SCTP_CHECK_PEER_AUTH = 0x300, 121 BSL_UIO_SCTP_ADD_AUTH_SHARED_KEY, 122 BSL_UIO_SCTP_ACTIVE_AUTH_SHARED_KEY, 123 BSL_UIO_SCTP_DEL_PRE_AUTH_SHARED_KEY, 124 BSL_UIO_SCTP_SND_BUFF_IS_EMPTY, 125 BSL_UIO_SCTP_GET_SEND_STREAM_ID, 126 BSL_UIO_SCTP_SET_APP_STREAM_ID, 127 BSL_UIO_SCTP_MASK_APP_MESSAGE, 128 BSL_UIO_SCTP_SET_CALLBACK, 129 /* MEM uses 0x4XX */ 130 BSL_UIO_MEM_NEW_BUF = 0x400, 131 BSL_UIO_MEM_GET_PTR, 132 BSL_UIO_MEM_SET_EOF, 133 BSL_UIO_MEM_GET_EOF, 134 BSL_UIO_MEM_GET_INFO, 135 } BSL_UIO_CtrlParameter; 136 137 typedef enum { 138 BSL_UIO_CREATE_CB, 139 BSL_UIO_DESTROY_CB, 140 BSL_UIO_WRITE_CB, 141 BSL_UIO_READ_CB, 142 BSL_UIO_CTRL_CB, 143 BSL_UIO_PUTS_CB, 144 BSL_UIO_GETS_CB, 145 } BSL_UIO_METHOD_TYPE; 146 147 #define BSL_UIO_FILE_READ 0x02 148 #define BSL_UIO_FILE_WRITE 0x04 149 #define BSL_UIO_FILE_APPEND 0x08 150 #define BSL_UIO_FILE_TEXT 0x10 151 152 #define BSL_UIO_FLAGS_READ 0x01 153 #define BSL_UIO_FLAGS_WRITE 0x02 154 #define BSL_UIO_FLAGS_IO_SPECIAL 0x04 155 #define BSL_UIO_FLAGS_RWS (BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_IO_SPECIAL) 156 #define BSL_UIO_FLAGS_SHOULD_RETRY 0x08 157 158 #define BSL_UIO_FLAGS_MEM_READ_ONLY 0x10 /* This flag can be set only by uio_mem */ 159 160 #define BSL_UIO_FLAGS_BASE64_NO_NEWLINE 0x20 161 #define BSL_UIO_FLAGS_BASE64_PEM 0x40 162 163 164 typedef struct { 165 uint8_t *addr; 166 uint32_t size; 167 } BSL_UIO_CtrlGetPeerIpAddrParam; 168 169 /** 170 * @ingroup bsl_uio 171 * @brief Creating uio method structure 172 * 173 * @retval uio method structure pointer 174 */ 175 BSL_UIO_Method *BSL_UIO_NewMethod(void); 176 177 /** 178 * @ingroup bsl_uio 179 * @brief set uio method type 180 * 181 * @param meth [IN] uio method structure 182 * @param type [IN] type 183 * @retval #BSL_SUCCESS 184 * @retval #BSL_NULL_INPUT 185 */ 186 int32_t BSL_UIO_SetMethodType(BSL_UIO_Method *meth, int32_t type); 187 188 /** 189 * @ingroup bsl_uio 190 * @brief set uio method callback 191 * 192 * @param meth [IN] uio method structure 193 * @param type [IN] callback type 194 * @param func [IN] callback pointer 195 * @retval #BSL_SUCCESS 196 * @retval #BSL_INVALID_ARG 197 */ 198 int32_t BSL_UIO_SetMethod(BSL_UIO_Method *meth, int32_t type, void *func); 199 200 /** 201 * @ingroup bsl_uio 202 * @brief free uio Method 203 * 204 * @param meth [IN] uio method structure 205 * @retval void 206 */ 207 void BSL_UIO_FreeMethod(BSL_UIO_Method *meth); 208 209 /** 210 * @ingroup bsl_uio 211 * @brief obtain the default MEM UIO 212 * 213 * @retval pointer to the MEM UIO method 214 */ 215 const BSL_UIO_Method *BSL_UIO_MemMethod(void); 216 217 /** 218 * @ingroup bsl_uio 219 * @brief obtain the default SCTP UIO 220 * 221 * @retval pointer to the SCTP UIO method 222 */ 223 const BSL_UIO_Method *BSL_UIO_SctpMethod(void); 224 225 /** 226 * @ingroup bsl_uio 227 * @brief obtain the default TCP UIO method 228 * 229 * @retval pointer to the TCP UIO method 230 */ 231 const BSL_UIO_Method *BSL_UIO_TcpMethod(void); 232 233 /** 234 * @ingroup bsl_uio 235 * @brief obtain the default UDP UIO method 236 * 237 * @retval pointer to the UDP UIO method 238 */ 239 const BSL_UIO_Method *BSL_UIO_UdpMethod(void); 240 241 /** 242 * @ingroup bsl_uio 243 * @brief obtain the default buffer UIO 244 * 245 * @retval pointer to the Buffer UIO method 246 */ 247 const BSL_UIO_Method *BSL_UIO_BufferMethod(void); 248 249 /** 250 * @ingroup bsl_uio 251 * @brief Create a UIO object 252 * 253 * @param method [IN] UIO method structure 254 * @retval UIO, created successfully 255 * @retval NULL UIO, creation failure 256 */ 257 BSL_UIO *BSL_UIO_New(const BSL_UIO_Method *method); 258 259 /** 260 * @ingroup bsl_uio 261 * @brief Release the UIO object. 262 * 263 * @param uio [IN] UIO object. 264 */ 265 void BSL_UIO_Free(BSL_UIO *uio); 266 267 /** 268 * @ingroup bsl_uio 269 * @brief Write data to the UIO object 270 * 271 * @param uio [IN] uio object. 272 * @param data [IN] Data to be written. 273 * @param len [IN] Data length. 274 * @param writeLen [OUT] Length of the data that is successfully written. 275 * @retval #BSL_SUCCESS, indicating that the data is successfully written. 276 * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. 277 * @retval #BSL_UIO_IO_BUSY, indicating that the underlying I/O is busy. 278 * @retval #BSL_UIO_IO_EXCEPTION, The I/O is abnormal. 279 * @retval #BSL_UIO_FAIL,invalid parameter. 280 */ 281 int32_t BSL_UIO_Write(BSL_UIO *uio, const void *data, uint32_t len, uint32_t *writeLen); 282 283 /** 284 * @ingroup bsl_uio 285 * @brief Read data from the UIO object. 286 * 287 * @param uio [IN] uio object. 288 * @param data [IN] Buffer for receiving data 289 * @param len [IN] Length of the received data buffer. 290 * @param readLen [OUT] Length of the received data. 291 * @retval #BSL_SUCCESS, The data is read successfully(Determined based on the actual receive length, 292 * if the length is 0 means no data is read.) 293 * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. 294 * @retval #BSL_UIO_FAIL, invalid parameter. 295 * @retval #BSL_UIO_IO_EXCEPTION, IO is abnormal. 296 */ 297 int32_t BSL_UIO_Read(BSL_UIO *uio, void *data, uint32_t len, uint32_t *readLen); 298 299 /** 300 * @ingroup bsl_uio 301 * @brief Process specific UIO implementations by cmd 302 * 303 * @param uio [IN] UIO object 304 * @param cmd [IN] Different cmd processes perform different operations on UIO objects. 305 * @param larg [IN] Determined by cmd. For details, see the following 306 * @param parg [IN/OUT] Determined by cmd. For details, see the following 307 * @retval #BSL_SUCCESS 308 * @retval Non-BSL_SUCCESS, for details, see bsl_errno.h. 309 * 310 * @brief set the peer IP address in the UIO object 311 * 312 * The address format is a binary address in network byte order, with a length of 4 or 16 bytes. 313 * A generated cookie will be provided for use by the HelloVerifyRequest for dtls. 314 * 315 * @param uio [IN] UIO object 316 * @param cmd [IN] BSL_UIO_SET_PEER_IP_ADDR 317 * @param larg [IN] Size of the peer address: The length must be 4 or 16 318 * @param parg [IN] Peer address 319 * 320 * @brief Obtain the peer IP address from the UIO object 321 * 322 * The obtained address is in the network byte order binary address format. 323 * The input length must be greater than the configured size. 324 * The purpose is to provide a generated cookie for use by the HelloVerifyRequest of the dtls. 325 * 326 * @param uio [IN] UIO object 327 * @param cmd [IN] BSL_UIO_GET_PEER_IP_ADDR 328 * @param larg [IN] 0 329 * @param parg [IN] BSL_UIO_CtrlGetPeerIpAddrParam *, include: 330 * addr [IN/OUT] Peer address, 331 * size [IN/OUT] IN: size of the input buffer OUT: size of the output peer address 332 * 333 * @brief Obtain the stream ID sent by the SCTP from the UIO object. 334 * 335 * This API needs to be called by users in BSL_UIO_Method.write 336 * and send SCTP messages based on the obtained stream ID 337 * 338 * @param uio [IN] UIO object 339 * @param cmd [IN] BSL_UIO_SCTP_GET_SEND_STREAM_ID 340 * @param larg [IN] 0 341 * @param parg [IN/OUT] ID of the sent stream, uint16_t* Type 342 * 343 * @brief Set the stream ID of the app message sent by the SCTP in the UIO object. 344 * 345 * If a service message needs to be processed by a specific stream ID, this interface can be called. 346 * 347 * @param uio [IN] UIO object 348 * @param cmd [IN] BSL_UIO_SCTP_SET_APP_STREAM_ID 349 * @param larg [IN] App stream ID. The value ranges from 0 to 65535 350 * @param parg [IN] NULL 351 */ 352 int32_t BSL_UIO_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg); 353 354 /** 355 * @ingroup bsl_uio 356 * @brief Write a string to the UIO object. 357 * 358 * @param uio [IN] uio object. 359 * @param buf [IN] A null-terminated string to be written. 360 * @param writeLen [OUT] Length of the data that is successfully written. 361 * @retval #BSL_SUCCESS, Writing succeeded. 362 * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. 363 * @retval #BSL_UIO_IO_BUSY, indicating that the underlying I/O is busy. 364 * @retval #BSL_UIO_IO_EXCEPTION, IO abnormal. 365 * @retval #BSL_UIO_FAIL, invalid parameter. 366 */ 367 int32_t BSL_UIO_Puts(BSL_UIO *uio, const char *buf, uint32_t *writeLen); 368 369 /** 370 * @ingroup bsl_uio 371 * @brief Reads a string from the UIO object 372 * 373 * @param uio [IN] uio object. 374 * @param buf [IN] Buffer that accepts a line of strings 375 * @param readLen [IN/OUT] Length of the buffer for receiving data/Length of the data that is successfully read 376 * @retval #BSL_SUCCESS (Determine the value based on the actual receive length. 377 * if the length is 0 means no data is read.) 378 * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. 379 * @retval #BSL_UIO_FAIL, invalid parameter. 380 * @retval #BSL_UIO_IO_EXCEPTION, IO abnormal. 381 */ 382 int32_t BSL_UIO_Gets(BSL_UIO *uio, char *buf, uint32_t *readLen); 383 384 /** 385 * @ingroup bsl_uio 386 * @brief Set the UIO init. 387 * 388 * @param uio [IN] UIO object 389 * @param init [IN] init value 390 */ 391 void BSL_UIO_SetInit(BSL_UIO *uio, bool init); 392 393 /** 394 * @ingroup bsl_uio 395 * @brief Obtain the UIO transmission protocol type 396 * 397 * @param uio [IN] UIO object. 398 * @retval protocol type 399 */ 400 int32_t BSL_UIO_GetTransportType(const BSL_UIO *uio); 401 402 /** 403 * @ingroup bsl_uio 404 * 405 * @brief Obtain the UIO transmission protocol type 406 * @param uio [IN] UIO object. 407 * @param uioType [IN] Type of the protocol to be obtained. 408 * @return TRUE, Succeeded in obtaining the UIO type. 409 * @return FALSE, Failed to obtain the UIO type. 410 */ 411 bool BSL_UIO_GetUioChainTransportType(BSL_UIO *uio, const BSL_UIO_TransportType uioType); 412 413 /** 414 * @ingroup bsl_uio 415 * @brief Set the user data in the UIO object 416 * 417 * UIO will not modify the user data, user can add some information 418 * for the UIO, and get the information by use BSL_UIO_GetUserData function; After you set user data by calling 419 * BSL_UIO_SetUserData, you need to call BSL_UIO_SetUserData again before calling BSL_UIO_Free to set 420 * user data to null to ensure that all memory is released. 421 * 422 * @param uio [IN] UIO object. 423 * @param data [IN] User data pointer 424 * @retval #BSL_SUCCESS, success. 425 * @retval #BSL_NULL_INPUT, invalid null pointer. 426 */ 427 int32_t BSL_UIO_SetUserData(BSL_UIO *uio, void *data); 428 429 /** 430 * @ingroup bsl_uio 431 * @brief Release the user data set in the UIO object. 432 * 433 * Free uio->userData at BSL_UIO_Free. 434 * 435 * @param uio [IN] UIO object 436 * @param data [IN] Pointer to the function for releasing user data 437 * @retval #BSL_SUCCESS, success. 438 * @retval #BSL_NULL_INPUT, invalid null pointer. 439 */ 440 int32_t BSL_UIO_SetUserDataFreeFunc(BSL_UIO *uio, BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc); 441 442 /** 443 * @ingroup bsl_uio 444 * @brief Obtain the user data in the UIO object. 445 * 446 * The user data comes from users, and tls will not change any thing 447 * for user data, user can add some customize information. 448 * 449 * @param uio [IN] UIO object. 450 * @retval Succeeded in obtaining the data structure pointer stored by the user. 451 * @retval NULL, the obtained data does not exist. 452 */ 453 void *BSL_UIO_GetUserData(const BSL_UIO *uio); 454 455 /** 456 * @ingroup bsl_uio 457 * @brief Obtains whether resources associated with the UIO are closed by the UIO. 458 * 459 * @param uio [OUT] UIO object 460 * @retval ture The resources associated with the UIO are closed by the UIO. 461 * @retval false The resources associated with the UIO are not closed by the UIO. 462 */ 463 bool BSL_UIO_GetIsUnderlyingClosedByUio(const BSL_UIO *uio); 464 465 /** 466 * @ingroup bsl_uio 467 * @brief Set whether resources associated with the UIO are closed by the UIO. 468 * 469 * @param uio [IN/OUT] UIO object 470 * @param close [IN] true UIO-associated resources are closed by the UIO. 471 * false The resources associated with the UIO are not closed by the UIO. 472 */ 473 void BSL_UIO_SetIsUnderlyingClosedByUio(BSL_UIO *uio, bool close); 474 475 /** 476 * @ingroup bsl_uio 477 * @brief Method for obtaining the UIO 478 * 479 * @param uio [IN/OUT] UIO object 480 * @retval UIO method 481 */ 482 const BSL_UIO_Method *BSL_UIO_GetMethod(const BSL_UIO *uio); 483 484 /** 485 * @ingroup bsl_uio 486 * @brief Obtain the implementation-related context. 487 * 488 * @param uio [IN] UIO object 489 * @retval Implementation-related context pointer 490 */ 491 void *BSL_UIO_GetCtx(const BSL_UIO *uio); 492 493 /** 494 * @ingroup bsl_uio 495 * @brief Set the implementation-related context. 496 * 497 * @param uio [IN] UIO object 498 * @param ctx [IN] Implement the relevant context pointer. 499 */ 500 void BSL_UIO_SetCtx(BSL_UIO *uio, void *ctx); 501 502 /** 503 * @ingroup bsl_uio 504 * @brief Set the fd of the UIO object 505 * 506 * @param uio [IN] UIO object 507 * @param fd [IN] File Descriptor fd 508 */ 509 void BSL_UIO_SetFD(BSL_UIO *uio, int fd); 510 511 /** 512 * @ingroup bsl_uio 513 * @brief Set the UIO object flag. 514 * 515 * @param uio [IN] UIO object 516 * @param flags [IN] flag 517 * @retval #BSL_SUCCESS, succeeded. 518 * @retval Other reference: bsl_errno.h. 519 */ 520 int32_t BSL_UIO_SetFlags(BSL_UIO *uio, uint32_t flags); 521 522 /** 523 * @ingroup bsl_uio 524 * @brief Clear the UIO object flag 525 * 526 * @param uio [IN] UIO object 527 * @param flags [IN] flag 528 * @retval #BSL_SUCCESS, succeeded. 529 * @retval Other reference: bsl_errno.h. 530 */ 531 int32_t BSL_UIO_ClearFlags(BSL_UIO *uio, uint32_t flags); 532 533 /** 534 * @ingroup bsl_uio 535 * @brief Check the UIO object flag 536 * 537 * @param uio [IN] UIO object 538 * @param flags [IN] To-be-checked flag 539 * @param out [OUT] Mark the detection result 540 * @retval #BSL_SUCCESS, succeeded. 541 * @retval Other reference: bsl_errno.h 542 */ 543 uint32_t BSL_UIO_TestFlags(const BSL_UIO *uio, uint32_t flags, uint32_t *out); 544 545 /** 546 * @ingroup bsl_uio 547 * @brief Set the value of uio reference counting to 1 548 * 549 * @attention Call BSL_UIO_Free to decrease the value of reference counting by 1 550 * @param uio [IN] uio object 551 * @retval #BSL_SUCCESS, the setting is successful. 552 * @retval #BSL_INTERNAL_EXCEPTION, an unexpected internal error occurs. 553 * @retval #BSL_UIO_REF_MAX, The number of UIO objects has reached the maximum. 554 */ 555 int32_t BSL_UIO_UpRef(BSL_UIO *uio); 556 557 /** 558 * @ingroup bsl_uio 559 * @brief Add a UIO object to the tail of the chain. 560 * 561 * @attention The reference counting of the added UIO object will not increase by 1. 562 * @param uio [IN] uio object 563 * @param tail [IN] UIO object added to the tail 564 * @retval #BSL_SUCCESS, success. 565 * @retval Non-BSL_SUCCESS, failure. For details, see bsl_errno.h. 566 */ 567 int32_t BSL_UIO_Append(BSL_UIO *uio, BSL_UIO *tail); 568 569 /** 570 * @ingroup bsl_uio 571 * @brief Pop UIO object from the chain. 572 * 573 * @attention The reference counting of the added UIO object does not decrease by 1. 574 * @param uio [IN] UIO object of the pop-up link. 575 * @retval The next UIO object in the chain. 576 */ 577 BSL_UIO *BSL_UIO_PopCurrent(BSL_UIO *uio); 578 579 /** 580 * @ingroup bsl_uio 581 * @brief Release UIO object b and its subsequent chains. 582 * 583 * @attention: The release starts from b. 584 * If the reference counting of a UIO object in the chain is greater than or equal to 1, the release stops 585 * @param uio [IN] First UIO object in the UIO object chain to be released 586 */ 587 void BSL_UIO_FreeChain(BSL_UIO *uio); 588 589 /** 590 * @ingroup bsl_uio 591 * @brief Obtain the next UIO object in the chain. 592 * 593 * @param uio [IN] UIO object 594 * @retval Next UIO object in the chain. 595 */ 596 BSL_UIO *BSL_UIO_Next(BSL_UIO *uio); 597 598 #ifdef __cplusplus 599 } 600 #endif 601 602 #endif // BSL_UIO_H 603