/*--------------------------------------------------------------------------- * OBEXH_BuildByteSeq() *--------------------------------------------------------------------------- * * Synopsis: Builds Byte Sequence and UNICODE style OBEX headers. Used by * both client and server functions. * * Return: TRUE if headers could be added. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_BuildByteSeq(ObexAppHandle *AppHndl, ObexHeaderType Type, const U8 *Value, U16 Len) { OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !ObIsHeaderSpaceAvail(AppHndl, (U16)(Len+3)) || ((Type & 0xC0) != 0x40 && (Type & 0xC0) != 0)) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && AppHndl->buffer != 0); ASSERT(ObIsHeaderSpaceAvail(AppHndl, (U16)(Len+3)) && ((Type & 0xC0) == 0x40 || (Type & 0xC0) == 0)); if (Type == OBEXH_END_BODY) { AppHndl->appHeaderIsEndBody = TRUE; } AppHndl->buffer[AppHndl->txLength++] = Type; AppHndl->buffer[AppHndl->txLength++] = (U8)((Len+3) >> 8); AppHndl->buffer[AppHndl->txLength++] = (U8) (Len+3); if (Len > 0) { ASSERT( Value != 0 ); OS_MemCopy(AppHndl->buffer+AppHndl->txLength, Value, Len); AppHndl->txLength += Len; } OS_UnlockObex(); return TRUE; }
/*--------------------------------------------------------------------------- * OBEXH_Build1Byte() *--------------------------------------------------------------------------- * * Synopsis: Builds 1-byte style OBEX headers. Used by both client and * server functions. * * Return: TRUE if headers could be added. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_Build1Byte(ObexAppHandle *AppHndl, ObexHeaderType Type, U8 Value) { OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !ObIsHeaderSpaceAvail(AppHndl, 2) || (Type & 0xC0) != 0x80) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && AppHndl->buffer != 0); ASSERT(ObIsHeaderSpaceAvail(AppHndl, 2) && (Type & 0xC0) == 0x80); AppHndl->buffer[AppHndl->txLength++] = Type; AppHndl->buffer[AppHndl->txLength++] = Value; OS_UnlockObex(); return TRUE; }
/*--------------------------------------------------------------------------- * OBEXH_BuildEmptyEndBody() *--------------------------------------------------------------------------- * * Synopsis: Builds empty OBEX headers. Used by both client and * server functions. * * Return: TRUE if headers could be added. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_BuildEmptyEndBody(ObexAppHandle *AppHndl) { OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !ObIsHeaderSpaceAvail(AppHndl, 1)) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && AppHndl->buffer != 0); ASSERT(ObIsHeaderSpaceAvail(AppHndl, 1)); AppHndl->buffer[AppHndl->txLength++] = OBEXH_END_BODY; AppHndl->buffer[AppHndl->txLength++] = 0x00; AppHndl->buffer[AppHndl->txLength++] = 0x03; OS_UnlockObex(); return TRUE; }
/*--------------------------------------------------------------------------- * OBEXH_Build4Byte() *--------------------------------------------------------------------------- * * Synopsis: Builds 4-byte style OBEX headers. Used by both client and * server functions. * * Return: TRUE if headers could be added. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_Build4Byte(ObexAppHandle *AppHndl, ObexHeaderType Type, U32 Value) { OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !ObIsHeaderSpaceAvail(AppHndl, 5) || ((Type & 0xC0) != 0xC0)) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && AppHndl->buffer != 0); ASSERT(ObIsHeaderSpaceAvail(AppHndl, 5) && (Type & 0xC0) == 0xC0); AppHndl->buffer[AppHndl->txLength++] = Type; StoreBE32( AppHndl->buffer+AppHndl->txLength, Value); AppHndl->txLength += 4; OS_UnlockObex(); return TRUE; }
/*--------------------------------------------------------------------------- * OBEXH_BuildAuthResponse *--------------------------------------------------------------------------- * * Synopsis: This function is used by applications to build an Authentication * response to a received Challenge. The header is constructed from * the fields in the ObexAuthResponse structure. * * Return: TRUE if header was successfully built. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_BuildAuthResponse(ObexAppHandle *AppHndl, ObexAuthResponse *Response, U8 *Nonce) { U8 len; xMD5Context context; //#if XA_DEBUG == XA_ENABLED U8 *orig; //#endif /* XA_DEBUG == XA_ENABLED */ OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !Response || !Nonce) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && Response && Nonce); len = CALC_RESPONSE_LEN(Response); //#if XA_DEBUG == XA_ENABLED orig = AppHndl->buffer + AppHndl->txLength; //#endif /* XA_DEBUG == XA_ENABLED */ #if XA_ERROR_CHECK == XA_ENABLED if (!ObIsHeaderSpaceAvail(AppHndl, (U16)(len+3))) { OS_UnlockObex(); return FALSE; } #endif ASSERT(ObIsHeaderSpaceAvail(AppHndl, (U16)(len+3))); /* Build the OBEX Response Header Identifier */ AppHndl->buffer[AppHndl->txLength++] = OBEXH_AUTH_RESP; AppHndl->buffer[AppHndl->txLength++] = (U8)((len+3) >> 8); AppHndl->buffer[AppHndl->txLength++] = (U8) (len+3); /* Build digest from nonce and password */ AppHndl->buffer[AppHndl->txLength++] = 0; /* Request Digest Code */ AppHndl->buffer[AppHndl->txLength++] = AUTH_NONCE_LEN; /* Digest Length (16 bytes) */ xMD5Init(&context); xMD5Update(&context, Nonce, AUTH_NONCE_LEN); xMD5Update(&context, (U8 *)":", 1); xMD5Update(&context, Response->password, Response->passwordLen); xMD5Final(AppHndl->buffer+AppHndl->txLength, &context); AppHndl->txLength += AUTH_NONCE_LEN; /* Add UserId */ if (Response->userIdLen) { AppHndl->buffer[AppHndl->txLength++] = 1; /* UserId */ AppHndl->buffer[AppHndl->txLength++] = Response->userIdLen; /* Realm Len */ OS_MemCopy(AppHndl->buffer+AppHndl->txLength, Response->userId, Response->userIdLen); AppHndl->txLength += Response->userIdLen; } /* Add Nonce */ AppHndl->buffer[AppHndl->txLength++] = 2; /* Nonce */ AppHndl->buffer[AppHndl->txLength++] = AUTH_NONCE_LEN; /* (16 bytes) */ OS_MemCopy(AppHndl->buffer+AppHndl->txLength, Nonce, AUTH_NONCE_LEN); AppHndl->txLength += AUTH_NONCE_LEN; //#if XA_DEBUG == XA_ENABLED ASSERT((orig + len + 3) == (AppHndl->buffer + AppHndl->txLength)); //#endif OS_UnlockObex(); return TRUE; }
/*--------------------------------------------------------------------------- * OBEXH_BuildAuthChallenge *--------------------------------------------------------------------------- * * Synopsis: OBEX applications use this function to build an Authentication * Challenge header. The header is constructed from the field * values in the ObexAuthChallenge structure. * * Return: TRUE if header was successfully built. * FALSE if headers would exceed limits on buffer or transmit space. */ BOOL OBEXH_BuildAuthChallenge(ObexAppHandle *AppHndl, ObexAuthChallenge *Challenge, U8 *NonceOut) { U8 len; //#if XA_DEBUG == XA_ENABLED U8 *orig; //#endif /* XA_DEBUG == XA_ENABLED */ OS_LockObex(); #if XA_ERROR_CHECK == XA_ENABLED if (!AppHndl || !Challenge ) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(AppHndl && Challenge); len = CALC_CHALLENGE_LEN(Challenge); //#if XA_DEBUG == XA_ENABLED orig = AppHndl->buffer + AppHndl->txLength; //#endif /* XA_DEBUG == XA_ENABLED */ #if XA_ERROR_CHECK == XA_ENABLED if (!ObIsHeaderSpaceAvail(AppHndl, (U16)(len+3))) { OS_UnlockObex(); return FALSE; } #endif /* XA_ERROR_CHECK == XA_ENABLED */ ASSERT(ObIsHeaderSpaceAvail(AppHndl, (U16)(len+3))); /* Build the OBEX Challenge Header Identifier */ AppHndl->buffer[AppHndl->txLength++] = OBEXH_AUTH_CHAL; AppHndl->buffer[AppHndl->txLength++] = (U8)((len+3) >> 8); AppHndl->buffer[AppHndl->txLength++] = (U8) (len+3); /* Build nonce from challenge string */ AppHndl->buffer[AppHndl->txLength++] = 0; /* Nonce Code */ AppHndl->buffer[AppHndl->txLength++] = AUTH_NONCE_LEN; /* (16 bytes) */ MD5(AppHndl->buffer+AppHndl->txLength, Challenge->challenge, Challenge->challengeLen); if (NonceOut) OS_MemCopy(NonceOut, AppHndl->buffer+AppHndl->txLength, AUTH_NONCE_LEN); AppHndl->txLength += AUTH_NONCE_LEN; /* Add Options */ if (Challenge->options) { AppHndl->buffer[AppHndl->txLength++] = 1; /* Options Code */ AppHndl->buffer[AppHndl->txLength++] = 1; /* Options Len */ AppHndl->buffer[AppHndl->txLength++] = Challenge->options; /* Options */ } /* Add Realm */ if (Challenge->realmLen) { AppHndl->buffer[AppHndl->txLength++] = 2; /* Realm Code */ AppHndl->buffer[AppHndl->txLength++] = Challenge->realmLen; /* Realm Len */ OS_MemCopy(AppHndl->buffer+AppHndl->txLength, Challenge->realm, Challenge->realmLen); AppHndl->txLength += Challenge->realmLen; } //#if XA_DEBUG == XA_ENABLED ASSERT((orig + len + 3) == (AppHndl->buffer + AppHndl->txLength)); //#endif OS_UnlockObex(); return TRUE; }