diff options
Diffstat (limited to 'stack/obx/hdrs')
-rw-r--r-- | stack/obx/hdrs/obx_dauth.c | 149 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_dbtp.c | 189 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_dopt.c | 52 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_dunic.c | 64 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_dutf.c | 91 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_dwchar.c | 91 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_ebtp.c | 177 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_eopt.c | 51 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_eunic.c | 64 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_eutf.c | 111 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_ewchar.c | 100 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_gen.c | 896 | ||||
-rw-r--r-- | stack/obx/hdrs/obx_wchar.c | 84 | ||||
-rw-r--r-- | stack/obx/hdrs/utfc.c | 245 |
14 files changed, 2364 insertions, 0 deletions
diff --git a/stack/obx/hdrs/obx_dauth.c b/stack/obx/hdrs/obx_dauth.c new file mode 100644 index 0000000..91d4bd7 --- /dev/null +++ b/stack/obx/hdrs/obx_dauth.c @@ -0,0 +1,149 @@ +/***************************************************************************** +** +** Name: obx_dauth.c +** +** File: OBEX Authentication related functions +** +** Copyright (c) 2003-2008, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> +#include "bt_target.h" +#include "obx_api.h" + + + + + +#if (OBX_CLIENT_INCLUDED == TRUE) + +/******************************************************************************* +** +** Function OBX_ReadChallenge +** +** Description This function is called by the client to read the Realm and +** options of the Authentication Challenge Header in the +** given OBEX packet ( from an OBX_PASSWORD_EVT event). +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadChallenge(BT_HDR *p_pkt, tOBX_CHARSET *p_charset, + UINT8 **p_realm, UINT8 *p_len, + tOBX_AUTH_OPT *p_option) +{ + BOOLEAN status; + tOBX_TRIPLET triplet[OBX_MAX_NUM_AUTH_TRIPLET]; + UINT8 num_trip = OBX_MAX_NUM_AUTH_TRIPLET; + UINT8 xx; + + /* The coverity complaints on this function is not correct. + * The value in triplet[] is set/initialized by OBX_ReadTriplet if it returns TRUE. + * leave this unnecessary memset here */ + memset( triplet, 0, sizeof(triplet )); + + *p_len = 0; + *p_option = OBX_AO_NONE; + *p_realm = NULL; + *p_charset = OBX_RCS_ASCII; /* 0 */ + status = OBX_ReadTriplet(p_pkt, OBX_HI_CHALLENGE, triplet, &num_trip); + if(status) + { + for(xx=0; xx<num_trip; xx++) + { + switch(triplet[xx].tag) + { + case OBX_OPTIONS_CHLNG_TAG: + *p_option = triplet[xx].p_array[0]; + break; + case OBX_REALM_CHLNG_TAG: + *p_charset = triplet[xx].p_array[0]; + *p_len = triplet[xx].len - 1; + *p_realm = &(triplet[xx].p_array[1]); + break; + /* The user does not need to know the nonce value + case OBX_NONCE_CHLNG_TAG: + break; + */ + } + } + } + + return status; +} +#endif + + + +#if (OBX_SERVER_INCLUDED == TRUE) +/******************************************************************************* +** +** Function OBX_ReadAuthParams +** +** Description This function is called by the server to read the User ID of +** the Authentication Response Header in the given OBEX packet +** ( from an OBX_PASSWORD_EVT event). +** This function also +** checks if the authentication challenge header exists and +** checks the authentication challenge options. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadAuthParams(BT_HDR *p_pkt, UINT8 **p_userid, UINT8 *p_len, + BOOLEAN *is_challenged, tOBX_AUTH_OPT *p_option) +{ + BOOLEAN status; + tOBX_TRIPLET triplet[OBX_MAX_NUM_AUTH_TRIPLET]; + UINT8 num_trip = OBX_MAX_NUM_AUTH_TRIPLET; + UINT8 xx; + + /* The coverity complaints on this function is not correct. + * The value in triplet[] is set/initialized by OBX_ReadTriplet if it returns TRUE. + * leave this unnecessary memset here */ + memset( triplet, 0, sizeof(triplet )); + + *p_userid = NULL; + *p_len = 0; + *is_challenged = FALSE; + *p_option = OBX_AO_NONE; + status = OBX_ReadTriplet(p_pkt, OBX_HI_AUTH_RSP, triplet, &num_trip); + if(status) + { + /* found authentication response, but we do not know if it has user id. + * assume no user id */ + *p_len = 0; + for(xx=0; xx<num_trip; xx++) + { + if(triplet[xx].tag == OBX_USERID_RSP_TAG) + { + *p_len = triplet[xx].len; + *p_userid = triplet[xx].p_array; + break; + } + } + + /* read the authentication challenge header, + * only if the authentication response header exists */ + if( OBX_ReadTriplet(p_pkt, OBX_HI_CHALLENGE, triplet, &num_trip) == TRUE) + { + *is_challenged = TRUE; + for(xx=0; xx<num_trip; xx++) + { + if(triplet[xx].tag == OBX_OPTIONS_CHLNG_TAG) + { + *p_option = triplet[xx].p_array[0]; + break; + } + } + } + } + return status; +} +#endif + + + diff --git a/stack/obx/hdrs/obx_dbtp.c b/stack/obx/hdrs/obx_dbtp.c new file mode 100644 index 0000000..fbf473d --- /dev/null +++ b/stack/obx/hdrs/obx_dbtp.c @@ -0,0 +1,189 @@ +/***************************************************************************** +** +** Name: obx_dbtp.c +** +** File: OBEX Headers Decode Utility functions +** - for current Bluetooth profiles +** +** Copyright (c) 2003-2008, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> +#include "bt_target.h" +#include "obx_api.h" +#include "obx_int.h" + + + + +/******************************************************************************* +** +** Function OBX_ReadTypeHdr +** +** Description This function is called to get the Type Header in the given +** OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadTypeHdr(BT_HDR *p_pkt, UINT8 **p_type, UINT16 *p_len) +{ + return OBX_ReadByteStrHdr(p_pkt, OBX_HI_TYPE, p_type, p_len, 0); +} + +/******************************************************************************* +** +** Function OBX_ReadLengthHdr +** +** Description This function is called to get the Length Header in the given +** OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadLengthHdr(BT_HDR *p_pkt, UINT32 *p_len) +{ + return OBX_Read4ByteHdr(p_pkt, OBX_HI_LENGTH, p_len); +} + +/******************************************************************************* +** +** Function OBX_ReadTargetHdr +** +** Description This function is called to get the Target Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadTargetHdr(BT_HDR *p_pkt, UINT8 **p_target, UINT16 *p_len, UINT8 next) +{ + return OBX_ReadByteStrHdr(p_pkt, OBX_HI_TARGET, p_target, p_len, next); +} + +/******************************************************************************* +** +** Function OBX_ReadBodyHdr +** +** Description This function is called to get the Body Header in the +** given OBEX packet. +** +** Returns 1, if a single header is in the OBEX packet. +** 2, if a end of body header is in the OBEX packet. +** 0, (FALSE) otherwise. +** +*******************************************************************************/ +UINT8 OBX_ReadBodyHdr(BT_HDR *p_pkt, UINT8 **p_body, UINT16 *p_len, BOOLEAN *p_end) +{ + BOOLEAN status; + UINT8 *p_body2; + UINT16 len2; + UINT8 num; + + *p_end = FALSE; + num = OBX_ReadByteStrHdr(p_pkt, OBX_HI_BODY, p_body, p_len, 0); + status = OBX_ReadByteStrHdr(p_pkt, OBX_HI_BODY_END, &p_body2, &len2, 0); + if(num == FALSE && status == TRUE) + { + *p_body = p_body2; + *p_len = len2; + *p_end = TRUE; + } + num += status; + + return num; +} + +/******************************************************************************* +** +** Function OBX_ReadWhoHdr +** +** Description This function is called to get the Who Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadWhoHdr(BT_HDR *p_pkt, UINT8 **p_who, UINT16 *p_len) +{ + return OBX_ReadByteStrHdr(p_pkt, OBX_HI_WHO, p_who, p_len, 0); +} + +/******************************************************************************* +** +** Function OBX_ReadAppParamHdr +** +** Description This function is called to get the Application Parameter Header +** in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadAppParamHdr(BT_HDR *p_pkt, UINT8 *p_tag, UINT8 **p_app_param, UINT8 *p_len, UINT8 next) +{ + BOOLEAN status; + tOBX_TRIPLET triplet[OBX_MAX_TRIPLET]; + UINT8 num = OBX_MAX_TRIPLET; + + /* The coverity complaints on this function is not correct. + * The value in triplet[] is set/initialized by OBX_ReadTriplet if it returns TRUE. + * leave this unnecessary memset here */ + memset( triplet, 0, sizeof(triplet )); + + status = OBX_ReadTriplet(p_pkt, OBX_HI_APP_PARMS, triplet, &num); + if(status == TRUE) + { + if(next >= num) + { + status = FALSE; + } + else + { + *p_tag = triplet[next].tag; + *p_app_param = triplet[next].p_array; + *p_len = triplet[next].len; + OBX_TRACE_DEBUG3( "OBX_ReadAppParamHdr: next: %d, tag: %x, len: %d", + next, *p_tag, *p_len); + } + } + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadPermissionHdr +** +** Description This function is called to get the Application Parameter Header +** in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadPermissionHdr(BT_HDR *p_pkt, UINT8 *p_user, UINT8 *p_group, UINT8 *p_other) +{ + UINT32 permission; + BOOLEAN status = FALSE; + + if (OBX_Read4ByteHdr(p_pkt, OBX_HI_PERMISSION, &permission)) + { + *p_other = (permission & 0xFF); + permission >>= 8; + *p_group = (permission & 0xFF); + permission >>= 8; + *p_user = (permission & 0xFF); + status = TRUE; + } + + return status; +} + + + + diff --git a/stack/obx/hdrs/obx_dopt.c b/stack/obx/hdrs/obx_dopt.c new file mode 100644 index 0000000..e3d0d27 --- /dev/null +++ b/stack/obx/hdrs/obx_dopt.c @@ -0,0 +1,52 @@ +/***************************************************************************** +** +** Name: obx_dopt.c +** +** File: OBEX Headers Decode Utility functions +** - optional functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "obx_api.h" + + + + + + +/******************************************************************************* +** +** Function OBX_ReadTimeHdr +** +** Description This function is called to get the Time Header in the given +** OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadTimeHdr(BT_HDR *p_pkt, UINT8 **p_time, UINT16 *p_len) +{ + return OBX_ReadByteStrHdr(p_pkt, OBX_HI_TIME, p_time, p_len, 0); +} + + +/******************************************************************************* +** +** Function OBX_ReadHttpHdr +** +** Description This function is called to get the HTTP Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadHttpHdr(BT_HDR *p_pkt, UINT8 **p_http, UINT16 *p_len, UINT8 next) +{ + return OBX_ReadByteStrHdr(p_pkt, OBX_HI_HTTP, p_http, p_len, next); +} + diff --git a/stack/obx/hdrs/obx_dunic.c b/stack/obx/hdrs/obx_dunic.c new file mode 100644 index 0000000..c8f6b12 --- /dev/null +++ b/stack/obx/hdrs/obx_dunic.c @@ -0,0 +1,64 @@ +/***************************************************************************** +** +** Name: obx_dunic.c +** +** File: OBEX Headers Decode Utility functions +** - Unicode functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "obx_api.h" + + + + +/******************************************************************************* +** +** Function OBX_ReadNameHdr +** +** Description This function is called to get the Name Header in the given +** OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadNameHdr(BT_HDR *p_pkt, UINT16 *p_name, UINT16 *p_len) +{ + return OBX_ReadUnicodeHdr(p_pkt, OBX_HI_NAME, p_name, p_len); +} + +/******************************************************************************* +** +** Function OBX_ReadDescrHdr +** +** Description This function is called to get the Description Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadDescrHdr(BT_HDR *p_pkt, UINT16 *p_descr, UINT16 *p_len) +{ + return OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_descr, p_len); +} + +/******************************************************************************* +** +** Function OBX_ReadDestNameHdr +** +** Description This function is called to get the DestName Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadDestNameHdr(BT_HDR *p_pkt, UINT16 *p_dest, UINT16 *p_len) +{ + return OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_dest, p_len); +} diff --git a/stack/obx/hdrs/obx_dutf.c b/stack/obx/hdrs/obx_dutf.c new file mode 100644 index 0000000..a800428 --- /dev/null +++ b/stack/obx/hdrs/obx_dutf.c @@ -0,0 +1,91 @@ +/***************************************************************************** +** +** Name: obx_dutf.c +** +** File: OBEX Headers Decode Utility functions +** - Unicode conversion functions +** +** Copyright (c) 2003-2009, Broadcom Corp., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "gki.h" +#include "obx_api.h" + + +/******************************************************************************* +** +** Function OBX_ReadUtf8NameHdr +** +** Description This function is called to get the Name Header in the given +** OBEX packet. If Name header exists in the given OBEX packet, +** it is converted to UTF8 format and copied into p_name. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadUtf8NameHdr(BT_HDR *p_pkt, UINT8 *p_name, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_NAME, p_unicode, &len); + utfc_16_to_8(p_name, max_len, p_unicode, len); + GKI_freebuf(p_unicode); + return status; +} + + + +/******************************************************************************* +** +** Function OBX_ReadUtf8DescrHdr +** +** Description This function is called to get the Description Header in the +** given OBEX packet. If Description header exists in the given +** OBEX packet, it is converted to UTF8 format and copied into +** p_descr. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadUtf8DescrHdr(BT_HDR *p_pkt, UINT8 *p_descr, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_unicode, &len); + utfc_16_to_8(p_descr, max_len, p_unicode, len); + GKI_freebuf(p_unicode); + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadUtf8DestNameHdr +** +** Description This function is called to get the DestName Header in the +** given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadUtf8DestNameHdr(BT_HDR *p_pkt, UINT8 *p_dest, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_unicode, &len); + utfc_16_to_8(p_dest, max_len, p_unicode, len); + GKI_freebuf(p_unicode); + return status; +} + + diff --git a/stack/obx/hdrs/obx_dwchar.c b/stack/obx/hdrs/obx_dwchar.c new file mode 100644 index 0000000..2aa5ebd --- /dev/null +++ b/stack/obx/hdrs/obx_dwchar.c @@ -0,0 +1,91 @@ +/***************************************************************************** +** +** Name: obx_dwchar.c +** +** File: OBEX Headers Decode Utility functions +** - Unicode conversion functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "gki.h" +#include "obx_api.h" + + +/******************************************************************************* +** +** Function OBX_ReadAsciiNameHdr +** +** Description This function is called to get the Name Header in the given +** OBEX packet. If Name header exists in the given OBEX packet, +** it is converted to ASCII format and copied into p_name. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadAsciiNameHdr(BT_HDR *p_pkt, char *p_name, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_NAME, p_unicode, &len); + OBX_WcharToChar(p_name, p_unicode, max_len); + GKI_freebuf(p_unicode); + return status; +} + + + +/******************************************************************************* +** +** Function OBX_ReadAsciiDescrHdr +** +** Description This function is called to get the Description Header in the +** given OBEX packet. If Description header exists in the given +** OBEX packet, it is converted to ASCII format and copied into +** p_descr. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadAsciiDescrHdr(BT_HDR *p_pkt, char *p_descr, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_unicode, &len); + OBX_WcharToChar(p_descr, p_unicode, max_len); + GKI_freebuf(p_unicode); + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadAsciiDestNameHdr +** +** Description This function is called to get the DestName Header in the +** given OBEX packet. If DestName header exists in the given +** OBEX packet, it is converted to ASCII format and copied into +** p_descr. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadAsciiDestNameHdr(BT_HDR *p_pkt, char *p_dest, UINT16 max_len) +{ + BOOLEAN status; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)((max_len + 1) * 2)); + UINT16 len = max_len; + + status = OBX_ReadUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_unicode, &len); + OBX_WcharToChar(p_dest, p_unicode, max_len); + GKI_freebuf(p_unicode); + return status; +} diff --git a/stack/obx/hdrs/obx_ebtp.c b/stack/obx/hdrs/obx_ebtp.c new file mode 100644 index 0000000..93dd988 --- /dev/null +++ b/stack/obx/hdrs/obx_ebtp.c @@ -0,0 +1,177 @@ +/***************************************************************************** +** +** Name: obx_ebtp.c +** +** File: OBEX Headers Encode Utility functions +** - for current Bluetooth profiles +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> + +#include "bt_target.h" +#include "obx_api.h" + + + +/******************************************************************************* +** +** Function OBX_AddTypeHdr +** +** Description This function is called to add an OBEX Type header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddTypeHdr(BT_HDR *p_pkt, char *p_type) +{ + return OBX_AddByteStrHdr(p_pkt, OBX_HI_TYPE, (UINT8*)p_type, (UINT16)(strlen(p_type)+1)); +} + +/******************************************************************************* +** +** Function OBX_AddLengthHdr +** +** Description This function is called to add an OBEX Length header to an OBEX +** packet. The Length header describes the total length in bytes of +** the object. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddLengthHdr(BT_HDR *p_pkt, UINT32 len) +{ + return OBX_Add4ByteHdr(p_pkt, OBX_HI_LENGTH, len); +} + +/******************************************************************************* +** +** Function OBX_AddTargetHdr +** +** Description This function is called to add an OBEX Target header to an OBEX +** packet. This header is most commonly used in Connect packets. +** +** NOTE: The target header must be the first header in an OBEX message. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddTargetHdr(BT_HDR *p_pkt, UINT8 *p_target, UINT16 len) +{ + BOOLEAN add = FALSE; + UINT8 *p; + + if (p_pkt->len == 0) + { + add = TRUE; + } + else if (p_pkt->len == 2) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset; + if ((*p) == OBX_HI_SESSION_SN) + add = TRUE; + + } + /* allow SSN to preceed target header */ + if (add) + return OBX_AddByteStrHdr(p_pkt, OBX_HI_TARGET, p_target, len); + else + { + BT_ERROR_TRACE_1(TRACE_LAYER_OBEX, "Target header must be the first:%d", p_pkt->len) ; + return FALSE; + } +} + +/******************************************************************************* +** +** Function OBX_AddBodyHdr +** +** Description This function is called to add an OBEX body header +** to an OBEX packet. +** +** NOTE: The body header must be the last header in an OBEX message. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddBodyHdr(BT_HDR *p_pkt, UINT8 *p_body, UINT16 len, BOOLEAN end) +{ + UINT8 id = (end)?OBX_HI_BODY_END:OBX_HI_BODY; + return OBX_AddByteStrHdr(p_pkt, id, p_body, len); +} + + +/******************************************************************************* +** +** Function OBX_AddWhoHdr +** +** Description This function is called to add an OBEX Who header to an OBEX +** packet. +** +** Note: Who header is typically used in an OBEX CONNECT response packet +** to indicate the UUID of the service that has accepted the +** directed connection. If the server calls OBX_StartServer() with +** specified target header, this OBEX implementation automatically +** adds this WHO header to the CONNECT response packet. If +** OBX_StartServer() is called with target header length as 0, the +** OBEX API user is responsible to add the WHO header. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddWhoHdr(BT_HDR *p_pkt, UINT8 *p_who, UINT16 len) +{ + return OBX_AddByteStrHdr(p_pkt, OBX_HI_WHO, p_who, len); +} + +/******************************************************************************* +** +** Function OBX_AddAppParamHdr +** +** Description This function is called to add an OBEX Application Parameter +** header to an OBEX packet. This header is used by the application +** layer above OBEX to convey application specific information. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddAppParamHdr(BT_HDR *p_pkt, tOBX_TRIPLET *p_triplet, UINT8 num) +{ + return OBX_AddTriplet(p_pkt, OBX_HI_APP_PARMS, p_triplet, num); +} + +/******************************************************************************* +** +** Function OBX_AddPermissionHdr +** +** Description This function is called to add an OBEX Permission header to an OBEX +** packet. +** bit 0 is set for read permission +** bit 1 is set for write permission +** bit 2 is set for delete permission +** bit 7 is set for modify permission +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddPermissionHdr(BT_HDR *p_pkt, UINT8 user, UINT8 group, UINT8 other) +{ + UINT32 permission = user; + permission <<= 8; + permission |= group; + permission <<= 8; + permission |= other; + return OBX_Add4ByteHdr(p_pkt, OBX_HI_PERMISSION, permission); +} + + diff --git a/stack/obx/hdrs/obx_eopt.c b/stack/obx/hdrs/obx_eopt.c new file mode 100644 index 0000000..e0b0487 --- /dev/null +++ b/stack/obx/hdrs/obx_eopt.c @@ -0,0 +1,51 @@ +/***************************************************************************** +** +** Name: obx_eopt.c +** +** File: OBEX Headers Encode Utility functions +** - optional functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> +#include "bt_target.h" +#include "obx_api.h" + + + +/******************************************************************************* +** +** Function OBX_AddTimeHdr +** +** Description This function is called to add an OBEX Time header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddTimeHdr(BT_HDR *p_pkt, char *p_time) +{ + return OBX_AddByteStrHdr(p_pkt, OBX_HI_TIME, (UINT8 *)p_time, (UINT16)strlen(p_time)); +} + + +/******************************************************************************* +** +** Function OBX_AddHttpHdr +** +** Description This function is called to add an OBEX HTTP header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddHttpHdr(BT_HDR *p_pkt, UINT8 *p_http, UINT16 len) +{ + return OBX_AddByteStrHdr(p_pkt, OBX_HI_HTTP, p_http, len); +} + + diff --git a/stack/obx/hdrs/obx_eunic.c b/stack/obx/hdrs/obx_eunic.c new file mode 100644 index 0000000..6b5cb29 --- /dev/null +++ b/stack/obx/hdrs/obx_eunic.c @@ -0,0 +1,64 @@ +/***************************************************************************** +** +** Name: obx_eunic.c +** +** File: OBEX Headers Encode Utility functions +** - Unicode functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "obx_api.h" + + +/******************************************************************************* +** +** Function OBX_AddNameHdr +** +** Description This function is called to add an OBEX Name header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddNameHdr(BT_HDR *p_pkt, UINT16 *p_name, UINT16 len) +{ + return OBX_AddUnicodeHdr(p_pkt, OBX_HI_NAME, p_name, len); +} + +/******************************************************************************* +** +** Function OBX_AddDescrHdr +** +** Description This function is called to add an OBEX Description header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddDescrHdr(BT_HDR *p_pkt, UINT16 *p_descr, UINT16 len) +{ + return OBX_AddUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_descr, len); +} + +/******************************************************************************* +** +** Function OBX_AddDestNameHdr +** +** Description This function is called to add an OBEX DestName header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddDestNameHdr(BT_HDR *p_pkt, UINT16 *p_dest, UINT16 len) +{ + return OBX_AddUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_dest, len); +} + + diff --git a/stack/obx/hdrs/obx_eutf.c b/stack/obx/hdrs/obx_eutf.c new file mode 100644 index 0000000..b298500 --- /dev/null +++ b/stack/obx/hdrs/obx_eutf.c @@ -0,0 +1,111 @@ +/***************************************************************************** +** +** Name: obx_eutf.c +** +** File: OBEX Headers Encode Utility functions +** - Unicode conversion functions +** +** Copyright (c) 2003-2005, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> +#include "bt_target.h" +#include "gki.h" +#include "obx_api.h" + + +/******************************************************************************* +** +** Function OBX_AddUtf8NameHdr +** +** Description This function is called to add an OBEX Name header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddUtf8NameHdr(BT_HDR *p_pkt, UINT8 *p_name) +{ + BOOLEAN status = FALSE; + UINT16 utf16_len = 0; + UINT16 *p_utf16 = NULL; + + if (p_name) + { + utf16_len = strlen((char *)p_name) * 2 + 2; + p_utf16 = (UINT16 *)GKI_getbuf(utf16_len); + } + + if (p_utf16) + utf16_len = utfc_8_to_16(p_utf16, utf16_len, p_name); + else + utf16_len = 0; + + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_NAME, p_utf16, utf16_len); + + if (p_utf16) + GKI_freebuf(p_utf16); + + return status; +} + +/******************************************************************************* +** +** Function OBX_AddUtf8DescrHdr +** +** Description This function is called to add an OBEX Description header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddUtf8DescrHdr(BT_HDR *p_pkt, UINT8 *p_descr) +{ + BOOLEAN status = FALSE; + UINT16 utf16_len; + UINT16 *p_utf16; + + utf16_len = strlen((char *)p_descr) * 2 + 2; + p_utf16 = (UINT16 *)GKI_getbuf(utf16_len); + if(p_utf16) + { + utf16_len = utfc_8_to_16(p_utf16, utf16_len, p_descr); + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_utf16, utf16_len); + GKI_freebuf(p_utf16); + } + return status; +} + +/******************************************************************************* +** +** Function OBX_AddUtf8DestNameHdr +** +** Description This function is called to add an OBEX DestName header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddUtf8DestNameHdr(BT_HDR *p_pkt, UINT8 *p_dest) +{ + BOOLEAN status = FALSE; + UINT16 utf16_len; + UINT16 *p_utf16; + + utf16_len = strlen((char *)p_dest) * 2 + 2; + p_utf16 = (UINT16 *)GKI_getbuf(utf16_len); + if(p_utf16) + { + utf16_len = utfc_8_to_16(p_utf16, utf16_len, p_dest); + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_utf16, utf16_len); + GKI_freebuf(p_utf16); + } + return status; +} + + + diff --git a/stack/obx/hdrs/obx_ewchar.c b/stack/obx/hdrs/obx_ewchar.c new file mode 100644 index 0000000..2025baa --- /dev/null +++ b/stack/obx/hdrs/obx_ewchar.c @@ -0,0 +1,100 @@ +/***************************************************************************** +** +** Name: obx_ewchar.c +** +** File: OBEX Headers Encode Utility functions +** - Unicode conversion functions +** +** Copyright (c) 2003-2005, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> +#include "bt_target.h" +#include "gki.h" +#include "obx_api.h" + +/******************************************************************************* +** +** Function OBX_AddAsciiNameHdr +** +** Description This function is called to add an OBEX Name header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddAsciiNameHdr(BT_HDR *p_pkt, char *p_name) +{ + BOOLEAN status; + UINT16 len = 0; + UINT16 *p_unicode = NULL; + + if(p_name) + { + len = strlen(p_name) + 1; + p_unicode = (UINT16 *)GKI_getbuf((UINT16)(len*2)); + } + + if(p_unicode) + len = OBX_CharToWchar(p_unicode, p_name, len); + else + len = 0; + + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_NAME, p_unicode, len); + + if(p_unicode) + GKI_freebuf(p_unicode); + return status; +} + + +/******************************************************************************* +** +** Function OBX_AddAsciiDescrHdr +** +** Description This function is called to add an OBEX Description header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddAsciiDescrHdr(BT_HDR *p_pkt, char *p_descr) +{ + BOOLEAN status; + UINT16 len = strlen(p_descr) + 1; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)(len*2)); + + len = OBX_CharToWchar(p_unicode, p_descr, len); + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_DESCRIPTION, p_unicode, len); + GKI_freebuf(p_unicode); + return status; +} + +/******************************************************************************* +** +** Function OBX_AddAsciiDestNameHdr +** +** Description This function is called to add an OBEX DestName header +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddAsciiDestNameHdr(BT_HDR *p_pkt, char *p_dest) +{ + BOOLEAN status; + UINT16 len = strlen(p_dest) + 1; + UINT16 *p_unicode = (UINT16 *)GKI_getbuf((UINT16)(len*2)); + + len = OBX_CharToWchar(p_unicode, p_dest, len); + status = OBX_AddUnicodeHdr(p_pkt, OBX_HI_DEST_NAME, p_unicode, len); + GKI_freebuf(p_unicode); + return status; +} + + + diff --git a/stack/obx/hdrs/obx_gen.c b/stack/obx/hdrs/obx_gen.c new file mode 100644 index 0000000..9b25e04 --- /dev/null +++ b/stack/obx/hdrs/obx_gen.c @@ -0,0 +1,896 @@ +/***************************************************************************** +** +** Name: obx_gen.c +** +** File: OBEX Headers Utility functions +** - common/generic functions +** +** Copyright (c) 2003-2011, Broadcom Corp., All Rights Reserved. +** Broadcom Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include <string.h> + +#include "bt_target.h" +#include "wcassert.h" +#include "obx_api.h" +#include "gki.h" +#include "obx_int.h" + +const UINT8 obx_hdr_start_offset[] = +{ + OBX_CONN_HDRS_OFFSET, /* OBX_CONNECT_REQ_EVT */ + OBX_SESS_HDRS_OFFSET, /* OBX_SESSION_REQ_EVT */ + OBX_DISCON_HDRS_OFFSET, /* OBX_DISCONNECT_REQ_EVT */ + OBX_PUT_HDRS_OFFSET, /* OBX_PUT_REQ_EVT */ + OBX_GET_HDRS_OFFSET, /* OBX_GET_REQ_EVT */ + OBX_SETPATH_REQ_HDRS_OFFSET,/* OBX_SETPATH_REQ_EVT */ + OBX_ABORT_HDRS_OFFSET, /* OBX_ABORT_REQ_EVT */ + OBX_ACTION_HDRS_OFFSET, /* OBX_ACTION_REQ_EVT */ + OBX_CONN_HDRS_OFFSET, /* OBX_CONNECT_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_SESSION_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_DISCONNECT_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_PUT_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_GET_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_SETPATH_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET, /* OBX_ABORT_RSP_EVT */ + OBX_RESPONSE_HDRS_OFFSET /* OBX_ACTION_RSP_EVT */ +}; + +/******************************************************************************* +** +** Function obx_access_rsp_code +** +** Description This function is used to read/change response code +** +** Returns void. +** +*******************************************************************************/ +void obx_access_rsp_code(BT_HDR *p_pkt, UINT8 *p_rsp_code) +{ + UINT8 *p = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + if(*p_rsp_code == OBX_RSP_DEFAULT) + *p_rsp_code = *p; + else + *p = *p_rsp_code; +} + +/******************************************************************************* +** +** Function obx_adjust_packet_len +** +** Description Adjust the packet length in the OBEX packet +** +** Returns void. +** +*******************************************************************************/ +void obx_adjust_packet_len(BT_HDR *p_pkt) +{ + UINT8 *p = (UINT8 *)(p_pkt + 1) + p_pkt->offset + 1; + UINT16_TO_BE_STREAM(p, p_pkt->len); +} + +/******************************************************************************* +** +** Function obx_read_header_len +** +** Description ph is the beginning of an OBEX header +** +** Returns total length of the header +** +*******************************************************************************/ +UINT16 obx_read_header_len(UINT8 *ph) +{ + UINT16 len = 0; + + /* + OBX_TRACE_DEBUG1( "obx_read_header_len: 0x%x", *ph); + */ + switch(*ph&OBX_HI_TYPE_MASK) + { + case OBX_HI_TYPE_BYTE: + len = 2; + break; + case OBX_HI_TYPE_INT: + len = 5; + break; + case OBX_HI_TYPE_ARRAY: + case OBX_HI_TYPE_UNIC: + ph++; + BE_STREAM_TO_UINT16(len, ph); + break; + } + /* + OBX_TRACE_DEBUG1( "len:%d", len); + */ + return len; +} + +/******************************************************************************* +** +** Function obx_dup_pkt +** +** Description This function duplicate the OBEX message +** +** Returns BT_HDR *. +** +*******************************************************************************/ +BT_HDR * obx_dup_pkt(BT_HDR *p_pkt) +{ + BT_HDR *p_new; + UINT16 size = p_pkt->len + p_pkt->offset + BT_HDR_SIZE; + + if (size < GKI_MAX_BUF_SIZE) + { + /* Use the largest general pool to allow challenge tags appendage */ + p_new = (BT_HDR *)GKI_getbuf(GKI_MAX_BUF_SIZE); + } + else + { + p_new = (BT_HDR *) GKI_getpoolbuf(OBX_LRG_DATA_POOL_ID); + } + + if (p_new) + memcpy(p_new, p_pkt, size ); + + return p_new; +} + + +/******************************************************************************* +** +** Function OBX_HdrInit +** +** Description This function is called to initialize an OBEX packet. This +** function takes a GKI buffer and sets the offset in BT_HDR as +** OBX_HDR_OFFSET, the len as 0. The layer_specific is set to the +** length still available. This function compares the given +** (pkt_size - BT_HDR_SIZE) with the peer MTU to get the lesser +** of the two and set the layer_specific to +** (lesser_size - OBX_HDR_OFFSET). +** If composing a header for the CONNECT request (there is no +** client handle yet), use OBX_HANDLE_NULL as the handle. +** +** If the pkt_size is larger than the largest public pool size, +** GKI_MAX_BUF_SIZE, then an attempt to grab a buffer from the reserved OBX +** data pool will be made. +** Returns BT_HDR *. +** +*******************************************************************************/ +BT_HDR *OBX_HdrInit(tOBX_HANDLE handle, UINT16 pkt_size) +{ + UINT16 mtu = OBX_HandleToMtu(handle); + BT_HDR *p_pkt = NULL; + UINT16 buf_size; +#if (BT_USE_TRACES == TRUE) + UINT16 req_size = pkt_size; +#endif + + WC_ASSERT(pkt_size > (BT_HDR_SIZE + OBX_HDR_OFFSET)); + + pkt_size -= BT_HDR_SIZE; + if(pkt_size > mtu ) + pkt_size = mtu; + pkt_size += (BT_HDR_SIZE + OBX_HDR_OFFSET); + + OBX_TRACE_DEBUG4( "OBX_HdrInit: checking req_size %d, pkt_size:%d, max:%d, offset:%d", + req_size, pkt_size, GKI_MAX_BUF_SIZE, OBX_HDR_OFFSET); + /* See if packet will fit in regular public pool */ + if ((pkt_size) < GKI_MAX_BUF_SIZE) + { + p_pkt = (BT_HDR *) GKI_getbuf(pkt_size); + } + else /* Must use the reserved OBX buffer pool */ + { + p_pkt = (BT_HDR *) GKI_getpoolbuf(OBX_LRG_DATA_POOL_ID); + if (!p_pkt) + { + OBX_TRACE_DEBUG1( "Out of Large buffers. Trying pkt_size:%d", GKI_MAX_BUF_SIZE); + p_pkt = (BT_HDR *) GKI_getbuf(GKI_MAX_BUF_SIZE); + } + } + + if(p_pkt) + { + buf_size = GKI_get_buf_size(p_pkt); + buf_size -= BT_HDR_SIZE; + if(buf_size > mtu) + buf_size = mtu; + + OBX_TRACE_DEBUG4( "OBX_HdrInit: req_size %d, pkt_size = %d, gki_size %d, buf_size %d", + req_size, pkt_size, GKI_get_buf_size(p_pkt), buf_size); + + p_pkt->offset = OBX_HDR_OFFSET; + p_pkt->len = 0; + p_pkt->event = 0; + + /* layer specific contains remaining space in packet */ + p_pkt->layer_specific = buf_size - OBX_HDR_OFFSET ; + p_pkt->layer_specific -= 2; + + OBX_TRACE_DEBUG2( "buf size: %d, ls:%d", buf_size, p_pkt->layer_specific); + } + else + { + OBX_TRACE_ERROR1("OBX_HdrInit: No buffers for size (%d)", pkt_size); + } + + return p_pkt; +} + + +/******************************************************************************* +** +** Function OBX_Add1ByteHdr +** +** Description This function is called to add a header with type as UINT8 +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_Add1ByteHdr(BT_HDR *p_pkt, UINT8 id, UINT8 data) +{ + UINT8 *p; + BOOLEAN status = FALSE; + UINT16 size = 2; /* total length added by this header - 1/hi & 1/hv */ + + if(p_pkt) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset+p_pkt->len; + /* verify that the HI is of correct type and the remaining length in the packet is good */ + if( ((id & OBX_HI_TYPE_MASK) == OBX_HI_TYPE_BYTE) && (p_pkt->layer_specific >= size) ) + { + *p++ = id; + *p++ = data; + + p_pkt->len += size; + p_pkt->layer_specific -= size; + status = TRUE; + } + } + + return status; +} + +/******************************************************************************* +** +** Function OBX_Add4ByteHdr +** +** Description This function is called to add a header with type as UINT32 +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_Add4ByteHdr(BT_HDR *p_pkt, UINT8 id, UINT32 data) +{ + UINT8 *p; + BOOLEAN status = FALSE; + UINT16 size = 5; /* total length added by this header - 1/hi & 4/hv */ + + if(p_pkt) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset+p_pkt->len; + /* verify that the HI is of correct type and the remaining length in the packet is good */ + if( ((id & OBX_HI_TYPE_MASK) == OBX_HI_TYPE_INT) && (p_pkt->layer_specific >= size) ) + { + *p++ = id; + UINT32_TO_BE_STREAM(p, data); + + p_pkt->len += size; + p_pkt->layer_specific -= size; + status = TRUE; + } + } + + return status; +} + +/******************************************************************************* +** +** Function OBX_AddByteStrStart +** +** Description This function is called to get the address to the beginning of +** the byte sequence for an OBEX header in an OBEX packet. +** +** Returns The address to add the byte sequence. +** +*******************************************************************************/ +UINT8 *OBX_AddByteStrStart(BT_HDR *p_pkt, UINT16 *p_len) +{ + UINT8 *p = (UINT8 *)(p_pkt + 1) + p_pkt->offset + p_pkt->len + 3; + + WC_ASSERT(p_len); + + if(*p_len > (p_pkt->layer_specific - 3) || *p_len == 0) + *p_len = p_pkt->layer_specific - 3; + return p; +} + +/******************************************************************************* +** +** Function OBX_AddByteStrHdr +** +** Description This function is called to add a header with type as byte sequence +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddByteStrHdr(BT_HDR *p_pkt, UINT8 id, UINT8 *p_data, UINT16 len) +{ + UINT8 *p; + BOOLEAN status = FALSE; + UINT16 size = (len+3); /* total length added by this header - 1/hi & len+2/hv */ + + if(p_pkt) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset+p_pkt->len; + /* verify that the HI is of correct type and the remaining length in the packet is good */ + if( ((id & OBX_HI_TYPE_MASK) == OBX_HI_TYPE_ARRAY) && (p_pkt->layer_specific >= size) ) + { + *p++ = id; + UINT16_TO_BE_STREAM(p, size); + if(p_data) + memcpy(p, p_data, len); + + p_pkt->len += size; + p_pkt->layer_specific -= size; + status = TRUE; + } + } + + return status; +} + +/******************************************************************************* +** +** Function OBX_AddUnicodeHdr +** +** Description This function is called to add a header with type as Unicode string +** to an OBEX packet. +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddUnicodeHdr(BT_HDR *p_pkt, UINT8 id, UINT16 *p_data, UINT16 len) +{ + UINT8 *p; + BOOLEAN status = FALSE; + UINT16 size, xx; + + if(p_pkt) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset+p_pkt->len; + size = (len*OBX_UNICODE_SIZE + 3); /* total length added by this header - 1/hi & len*OBX_UNICODE_SIZE+2/hv */ + OBX_TRACE_DEBUG4( "OBX_AddUnicodeHdr len: %d, size: %d, left: %d, id: 0x%x", + len, size, p_pkt->layer_specific, id ); + + /* verify that the HI is of correct type and the remaining length in the packet is good */ + if( ((id & OBX_HI_TYPE_MASK) == OBX_HI_TYPE_UNIC) && (p_pkt->layer_specific >= size) ) + { + *p++ = id; + UINT16_TO_BE_STREAM(p, size); + for(xx=0; xx<len; xx++) + { + UINT16_TO_BE_STREAM(p, *p_data); + p_data++; + } + + p_pkt->len += size; + p_pkt->layer_specific -= size; + status = TRUE; + } + } + + return status; +} + +/* Alternate Body header functions: for non-blocking scenario */ +/******************************************************************************* +** +** Function OBX_AddBodyStart +** +** Description This function is called to get the address to the beginning of +** the byte sequence for an OBEX body header in an OBEX packet. +** +** Returns The address to add body content. +** +*******************************************************************************/ +UINT8 *OBX_AddBodyStart(BT_HDR *p_pkt, UINT16 *p_len) +{ + UINT8 *p = (UINT8 *)(p_pkt + 1) + p_pkt->offset + p_pkt->len + 3; + + WC_ASSERT(p_len); + + if(*p_len > (p_pkt->layer_specific - 3) || *p_len == 0) + *p_len = p_pkt->layer_specific - 3; + return p; +} + +/******************************************************************************* +** +** Function OBX_AddBodyEnd +** +** Description This function is called to add the HI and the length of HV of an +** OBEX body header to an OBEX packet. If end is TRUE, HI is +** OBX_HI_BODY_END. If FALSE, HI is OBX_HI_BODY. It is assumed that +** the actual value of the body has been copied into the OBEX packet. +** +** Returns void +** +*******************************************************************************/ +void OBX_AddBodyEnd(BT_HDR *p_pkt, UINT8 *p, UINT16 len, BOOLEAN end) +{ + UINT8 id = (end)?OBX_HI_BODY_END:OBX_HI_BODY; + UINT8 *pb = (UINT8 *)(p_pkt + 1) + p_pkt->offset + p_pkt->len; + *pb++ = id; + len += 3; /* 1/hi, 2/hv_len */ + UINT16_TO_BE_STREAM(pb, len); + p_pkt->layer_specific -= len; + p_pkt->len += len; +} + +/******************************************************************************* +** +** Function OBX_AddTriplet +** +** Description This function is called to add a header with type as byte sequence +** to an OBEX packet. +** +** Note: The byte sequence uses a Tag-Length-Value encoding scheme +** These headers include: Application Parameters header +** Authenticate Challenge header +** Authenticate Response header +** +** Returns TRUE, if the header is added successfully. +** FALSE, if the operation failed. p_pkt is not altered. +** +*******************************************************************************/ +BOOLEAN OBX_AddTriplet(BT_HDR *p_pkt, UINT8 id, tOBX_TRIPLET *p_triplet, UINT8 num) +{ + UINT8 *p = (UINT8 *)(p_pkt+1)+p_pkt->offset+p_pkt->len; + BOOLEAN status = FALSE; + UINT16 size = 3;/* 1/hi & len+2/hv */ + UINT8 xx; + + /* calculate the total length added by this header */ + for(xx=0; xx< num; xx++) + size += (p_triplet[xx].len + 2); + + /* verify that the HI is of correct type and the remaining length in the packet is good */ + if( ((id & OBX_HI_TYPE_MASK) == OBX_HI_TYPE_ARRAY) && (p_pkt->layer_specific >= size) ) + { + *p++ = id; + UINT16_TO_BE_STREAM(p, size); + for(xx=0; xx< num; xx++) + { + *p++ = p_triplet[xx].tag; + *p++ = p_triplet[xx].len; + memcpy(p, p_triplet[xx].p_array, p_triplet[xx].len); + p += p_triplet[xx].len; + } + p_pkt->len += size; + p_pkt->layer_specific -= size; + status = TRUE; + } + + return status; +} + + +/******************************************************************************* +** +** Function OBX_CheckNext +** +** Description This function is called to check if the given OBEX packet +** contains the specified header. +** +** Returns NULL, if the header is not in the OBEX packet. +** The pointer to the specified header beginning from HI. +** +*******************************************************************************/ +UINT8 * OBX_CheckNext(BT_HDR *p_pkt, UINT8 *p_start, UINT8 id) +{ + UINT8 *p; + UINT8 *p_res = NULL; + UINT16 len, start, skip; + int remain; + + if(p_pkt != NULL && p_start != NULL) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset; + if(p_pkt->event <= OBX_MAX_OFFSET_IND) + { + start = obx_hdr_start_offset[p_pkt->event-1]; + p++; + BE_STREAM_TO_UINT16(len, p); + remain = len - start; + p = p - 3 + start; + + while(remain >0) + { + if(*p != id || p < p_start) + { + skip = obx_read_header_len(p); + p += skip; + /* Just in case this is a bad packet, make sure that remain is >= 0 */ + if(skip && (remain > skip)) + remain -= skip; + else + remain = 0; + } + else + { + p_res = p; + break; + } + } + } + } + + if (p_pkt) + { + OBX_TRACE_DEBUG2( "OBX_CheckNext: remain: %d len:%d", remain, p_pkt->len); + } + + return p_res; +} + + +/******************************************************************************* +** +** Function OBX_CheckHdr +** +** Description This function is called to check if the given OBEX packet +** contains the specified header. +** +** Returns NULL, if the header is not in the OBEX packet. +** The pointer to the specified header beginning from HI. +** +*******************************************************************************/ +UINT8 * OBX_CheckHdr(BT_HDR *p_pkt, UINT8 id) +{ + UINT8 *p; + UINT8 *p_res = NULL; + UINT16 len, start, skip; + int remain; + + if(p_pkt != NULL) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset; + if(p_pkt->event <= OBX_MAX_OFFSET_IND) + { + start = obx_hdr_start_offset[p_pkt->event-1]; + p++; + BE_STREAM_TO_UINT16(len, p); + remain = len - start; + p = p - 3 + start; + + while(remain >0) + { + if(*p != id) + { + skip = obx_read_header_len(p); + p += skip; + /* Just in case this is a bad packet, make sure that remain is >= 0 */ + if(skip && (remain > skip)) + remain -= skip; + else + remain = 0; + } + else + { + p_res = p; + break; + } + } + } + } + + return p_res; +} + +/******************************************************************************* +** +** Function OBX_ReadNumHdrs +** +** Description This function is called to check the number of headers in the +** given OBEX packet +** +** Returns number of headers. +** +*******************************************************************************/ +UINT8 OBX_ReadNumHdrs(BT_HDR *p_pkt, UINT8 *p_num_body) +{ + UINT8 num_hdrs = 0, num_body = 0; + UINT8 *p; + UINT16 len, start, skip; + int remain = 0; + + if(p_pkt != NULL) + { + p = (UINT8 *)(p_pkt+1)+p_pkt->offset; + if(p_pkt->event == 0) + { + /* GKI buffer just went through OBX_HdrInit; not processed by the state machine yet */ + remain = len = p_pkt->len; + } + else if(p_pkt->event <= OBX_MAX_OFFSET_IND) + { + start = obx_hdr_start_offset[p_pkt->event-1]; + p++; + BE_STREAM_TO_UINT16(len, p); + remain = len - start; + p = p - 3 + start; + } + + while(remain >0) + { + num_hdrs++; + if(*p == OBX_HI_BODY || *p == OBX_HI_BODY_END) + num_body++; + + skip = obx_read_header_len(p); + p += skip; + /* Just in case this is a bad packet, make sure that remain is >= 0 */ + if(skip && (remain > skip)) + remain -= skip; + else + remain = 0; + + } + } + if (p_num_body) + *p_num_body = num_body; + return num_hdrs; +} + +/******************************************************************************* +** +** Function OBX_ReadHdrLen +** +** Description This function is called to check the length of the specified +** header in the given OBEX packet. +** +** Returns OBX_INVALID_HDR_LEN, if the header is not in the OBEX packet. +** Otherwise the actual length of the header. +** +*******************************************************************************/ +UINT16 OBX_ReadHdrLen(BT_HDR *p_pkt, UINT8 id) +{ + UINT8 *p; + UINT16 len = OBX_INVALID_HDR_LEN; + + if( (p = OBX_CheckHdr(p_pkt, id)) != NULL) + len = obx_read_header_len(p); + + return len; +} + +/******************************************************************************* +** +** Function OBX_Read1ByteHdr +** +** Description This function is called to get the UINT8 HV of the given HI +** in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_Read1ByteHdr(BT_HDR *p_pkt, UINT8 id, UINT8 *p_data) +{ + BOOLEAN status = FALSE; + UINT8 *p_start = OBX_CheckHdr(p_pkt, id); + + if(p_start) + { + *p_data = *(++p_start); + status = TRUE; + } + return status; +} + +/******************************************************************************* +** +** Function OBX_Read4ByteHdr +** +** Description This function is called to get the UINT32 HV of the given HI +** in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_Read4ByteHdr(BT_HDR *p_pkt, UINT8 id, UINT32 *p_data) +{ + BOOLEAN status = FALSE; + UINT8 *p_start = OBX_CheckHdr(p_pkt, id); + + if(p_start) + { + p_start++; + BE_STREAM_TO_UINT32(*p_data, p_start); + status = TRUE; + } + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadByteStrHdr +** +** Description This function is called to get the byte sequence HV of the given +** HI in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadByteStrHdr(BT_HDR *p_pkt, UINT8 id, UINT8 **p_data, UINT16 *p_len, UINT8 next) +{ + BOOLEAN status = FALSE; + UINT8 *p_start = OBX_CheckHdr(p_pkt, id); + + if(p_start) + { + next += 1; + while(next && (id == *p_start++)) + { + next--; + BE_STREAM_TO_UINT16(*p_len, p_start); + if(next == 0) + { + status = TRUE; + *p_len -= 3; /* get rid of hi and hv_len */ + *p_data = p_start; + } + else + p_start = p_start + *p_len - 3; + } + } + else + { + *p_len = 0; + } + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadUnicodeHdr +** +** Description This function is called to get the Unicode HV of the given +** HI in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadUnicodeHdr(BT_HDR *p_pkt, UINT8 id, UINT16 *p_data, UINT16 *p_len) +{ + BOOLEAN status = FALSE; + UINT16 len, xx, max_len; + UINT8 *p_start = OBX_CheckHdr(p_pkt, id); + + if(p_start) + { + max_len = *p_len; + p_start++; /* 1/hi*/ + BE_STREAM_TO_UINT16(len, p_start); + len -= 3; /* 1/hi, 2/hv_len */ + len /= OBX_UNICODE_SIZE; /* size in UINT16 */ + /* only conver the provided size */ + if( len > max_len) + len = max_len; + for(xx=0; xx<len; xx++) + { + BE_STREAM_TO_UINT16(*p_data, p_start); + p_data++; + } + *p_len = len; + status = TRUE; + max_len -= len; + while ( (p_start = OBX_CheckNext(p_pkt, p_start, id)) != NULL && (max_len > 0)) + { + p_start++; /* 1/hi*/ + BE_STREAM_TO_UINT16(len, p_start); + len -= 3; /* 1/hi, 2/hv_len */ + len /= OBX_UNICODE_SIZE; /* size in UINT16 */ + /* only conver the provided size */ + if( len > max_len) + len = max_len; + for(xx=0; xx<len; xx++) + { + BE_STREAM_TO_UINT16(*p_data, p_start); + p_data++; + } + *p_len += len; + max_len -= len; + } + } + else + { + *p_len = 0; + } + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadTriplet +** +** Description This function is called to get the Triplet HV of the given +** HI in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadTriplet(BT_HDR *p_pkt, UINT8 id, tOBX_TRIPLET *p_triplet, UINT8 *p_num) +{ + BOOLEAN status = FALSE; + UINT8 *p_start = OBX_CheckHdr(p_pkt, id); + UINT16 len; + UINT8 count = 0; + + if(p_start) + { + p_start++; /* 1/hi*/ + BE_STREAM_TO_UINT16(len, p_start); + len -= 3; /* 1/hi, 2/hv_len */ + while(len && *p_num > count) + { + p_triplet[count].tag = *p_start++; + p_triplet[count].len = *p_start++; + OBX_TRACE_DEBUG3( "OBX_ReadTriplet: count: %d, tag: %x, len: %d", + count, p_triplet[count].tag, p_triplet[count].len); + p_triplet[count].p_array = p_start; + p_start += p_triplet[count].len; + if(len > (p_triplet[count].len + 2) ) + len -= (p_triplet[count].len + 2); + else + len = 0; + count++; + } + status = TRUE; + } + *p_num = count; + return status; +} + +/******************************************************************************* +** +** Function OBX_ReadActionIdHdr +** +** Description This function is called to get the HV of the Action ID header +** in the given OBEX packet. +** +** Returns TRUE, if the header is in the OBEX packet. +** FALSE, otherwise. +** +*******************************************************************************/ +BOOLEAN OBX_ReadActionIdHdr(BT_HDR *p_pkt, UINT8 *p_data) +{ + BOOLEAN status = FALSE; + UINT8 *p_start = OBX_CheckHdr(p_pkt, OBX_HI_ACTION_ID); + + if(p_start) + { + p_start++; + /* check for valid values: 0-2 */ + /* do not allow 0x80 - 0xFF (vendor extention) for now. */ + if (*p_start <= OBX_ACT_PERMISSION) + { + *p_data = *(p_start); + status = TRUE; + } + } + return status; +} diff --git a/stack/obx/hdrs/obx_wchar.c b/stack/obx/hdrs/obx_wchar.c new file mode 100644 index 0000000..5364210 --- /dev/null +++ b/stack/obx/hdrs/obx_wchar.c @@ -0,0 +1,84 @@ +/***************************************************************************** +** +** Name: obx_wchar.c +** +** File: OBEX Headers Encode conversion Utility functions +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** WIDCOMM Bluetooth Core. Proprietary and confidential. +** +*****************************************************************************/ +#include "bt_target.h" +#include "gki.h" +#include "obx_api.h" + +/******************************************************************************* +** +** Function OBX_CharToWchar +** +** Description This function is called to convert ASCII to Unicode (UINT16). +** +** Returns the length. +** +*******************************************************************************/ +UINT16 OBX_CharToWchar (UINT16 *w_str, char* a_str, UINT16 w_size) +{ + UINT16 result = 0; + int size = w_size; + + if (a_str == NULL || w_str == NULL) + return 0; + + while (size > 0 && *a_str != '\0') + { + w_str[result++] = (UINT16) *a_str; + a_str++; + size--; + } + + if (size > 0) + { + w_str[result] = 0; + } + + return (result+1); +} + +/******************************************************************************* +** +** Function OBX_WcharToChar +** +** Description This function is called to convert Unicode (UINT16) to ASCII. +** +** Returns void. +** +*******************************************************************************/ +void OBX_WcharToChar (char *a_str, UINT16* w_str, UINT16 a_size) +{ + UINT16 result = 0; + int size = a_size; + + if (w_str == NULL || a_str == NULL) + return; + + while (size > 0 && *w_str != 0) + { + if ((*w_str & ~0xff) != 0) + { + result = 0; + break; + } + + a_str[result++] = (char) *w_str; + ++(w_str); + --size; + } + + if(size) + a_str[result] = 0; + + return; + + +} + diff --git a/stack/obx/hdrs/utfc.c b/stack/obx/hdrs/utfc.c new file mode 100644 index 0000000..d59733d --- /dev/null +++ b/stack/obx/hdrs/utfc.c @@ -0,0 +1,245 @@ +/***************************************************************************** +** +** Name: utfc.c +** +** Description: UTF conversion utilities. +** +** Copyright (c) 2003-2004, WIDCOMM Inc., All Rights Reserved. +** +*****************************************************************************/ + +#include <string.h> +#include "bt_target.h" +#include "utfc.h" + +/* Based on code from Unicode, Inc: + * + * Copyright 2001-2003 Unicode, Inc. + * + * Limitations on Rights to Redistribute This Code + * + * Unicode, Inc. hereby grants the right to freely use the information + * supplied in this file in the creation of products supporting the + * Unicode Standard, and to make copies of this file in any form + * for internal or external distribution as long as this notice + * remains attached. + */ + +/******************************************************************************* +** Constants +*******************************************************************************/ + +#define UTFC_8_MASK 0xBF +#define UTFC_8_MARK 0x80 + +#define UTFC_SUR_HIGH_START 0xD800 +#define UTFC_SUR_HIGH_END 0xDBFF +#define UTFC_SUR_LOW_START 0xDC00 +#define UTFC_SUR_LOW_END 0xDFFF + +/* Lookup table for length of UTF-8 byte sequence based on upper four bits +** of first byte. Illegal values give length zero. +*/ +static const UINT8 utfc_8_seq_len[] = {1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 2, 2, 3, 4}; + +/* Magic values subtracted from a buffer value during UTF-8 conversion. +** This table contains as many values as there might be trailing bytes +** in a UTF-8 sequence. +**/ +static const UINT32 utfc_8_offset[] = {0x00000000, 0x00003080, + 0x000E2080, 0x03C82080}; + +static const UINT8 utfc_8_first_byte[] = {0x00, 0x00, 0xC0, 0xE0, 0xF0}; + +/******************************************************************************* +** +** Function utfc_16_to_8 +** +** Description Convert a UTF-16 array to a null-terminated UTF-8 string. +** Illegal characters are skipped. +** +** Returns Length of UTF-8 string in bytes. +** +*******************************************************************************/ +UINT16 utfc_16_to_8(UINT8 *p_utf8, UINT16 utf8_len, UINT16 *p_utf16, UINT16 utf16_len) +{ + UINT32 ch, ch2; + UINT16 len = 0; + UINT8 seq_len; + + /* sanity check destination buffer len */ + if (utf8_len == 0) + { + /* set null */ + *p_utf8 = 0; + return len; + } + + /* save space for null */ + utf8_len--; + + while (utf16_len-- > 0) + { + ch = (UINT32) *p_utf16++; + + /* if we have a surrogate pair, convert to UTF-32 first */ + if (ch >= UTFC_SUR_HIGH_START && ch <= UTFC_SUR_HIGH_END) + { + /* if not enough characters we're done */ + if (utf16_len == 0) + { + break; + } + + /* get next character */ + ch2 = *p_utf16++; + utf16_len--; + + /* if it's a low surrogate, convert to UTF-32 */ + if (ch2 >= UTFC_SUR_LOW_START && ch2 <= UTFC_SUR_LOW_END) + { + ch = ((ch - UTFC_SUR_HIGH_START) << 10) + + (ch2 - UTFC_SUR_LOW_START) + 0x00010000; + } + else + { + /* illegal UTF-16 sequence, skip it */ + continue; + } + } + + /* Figure out how many bytes the result will require */ + if (ch < 0x00000080) + seq_len = 1; + else if (ch < 0x00000800) + seq_len = 2; + else if (ch < 0x00010000) + seq_len = 3; + else + seq_len = 4; + + /* if sequence doesn't fit we're done */ + if (utf8_len < len + seq_len) + { + break; + } + + /* build UTF-8 sequence */ + switch (seq_len) + { /* note: everything falls through. */ + case 4: p_utf8[3] = (UINT8) ((ch | UTFC_8_MARK) & UTFC_8_MASK); ch >>= 6; + case 3: p_utf8[2] = (UINT8) ((ch | UTFC_8_MARK) & UTFC_8_MASK); ch >>= 6; + case 2: p_utf8[1] = (UINT8) ((ch | UTFC_8_MARK) & UTFC_8_MASK); ch >>= 6; + case 1: p_utf8[0] = (UINT8) (ch | utfc_8_first_byte[seq_len]); + } + + /* converted value is a null we're done */ + if (*p_utf8 == 0) + { + break; + } + + p_utf8 += seq_len; + len += seq_len; + } + + /* set null */ + *p_utf8 = 0; + + return len; +} + +/******************************************************************************* +** +** Function utfc_8_to_16 +** +** Description Convert a null-terminated UTF-8 string to a UTF-16 array. +** Illegal characters are skipped. The UTF-16 array is +** appended with a zero (null) character. +** +** Returns Length of UTF-16 array including null character. +** +*******************************************************************************/ +UINT16 utfc_8_to_16(UINT16 *p_utf16, UINT16 utf16_len, UINT8 *p_utf8) +{ + UINT32 ch; + UINT8 *p_end; + UINT16 *p; + UINT8 seq_len; + + /* sanity check destination buffer len */ + if (utf16_len == 0) + { + *p_utf16 = 0; + return 0; + } + + /* save space for null */ + utf16_len--; + + p = p_utf16; + p_end = (UINT8 *) p_utf8 + strlen((char *) p_utf8); + + while (*p_utf8) + { + /* get sequence length; skip if illegal */ + if ((seq_len = utfc_8_seq_len[*p_utf8 >> 4]) == 0) + { + p_utf8++; + continue; + } + + /* make sure sequence doesn't extend past end of UTF-8 buffer */ + if (p_utf8 + seq_len > p_end) + { + break; + } + + /* construct UTF-32 character from sequence */ + ch = 0; + switch (seq_len) + { /* note: everything falls through. */ + case 4: ch += *p_utf8++; ch <<= 6; + case 3: ch += *p_utf8++; ch <<= 6; + case 2: ch += *p_utf8++; ch <<= 6; + case 1: ch += *p_utf8++; + } + ch -= utfc_8_offset[seq_len - 1]; + + if (ch <= 0x0000FFFF) + { + /* UTF-16 surrogate values are illegal in UTF-32 */ + if (ch >= UTFC_SUR_HIGH_START && ch <= UTFC_SUR_LOW_END) + { + continue; + } + + /* make sure fits */ + if (p - p_utf16 == utf16_len) + { + break; + } + + *p++ = (UINT16) ch; + } + else if (ch < 0x0010FFFF) + { + /* make sure fits */ + if ((p - p_utf16) == (utf16_len - 1)) + { + break; + } + + ch -= 0x00010000; + *p++ = (UINT16) ((ch >> 10) + UTFC_SUR_HIGH_START); + *p++ = (UINT16) ((ch & 0x000003FF) + UTFC_SUR_LOW_START); + } + } + + /* set null */ + *p++ = 0; + + return (UINT16) (p - p_utf16); +} + |