コード例 #1
0
BtStatus SM_CalcPairConfirm(BtRemoteDevice *remDev, U8 *tk, U8 *rand, U8 *preq, U8 *pres, LeAddrType iat, LeAddrType rat, BD_ADDR ia, BD_ADDR ra)
{
    U8 p1[16] = {0};
    U8 iat1 = iat & 0x01;
    U8 rat1 = rat & 0x01;

    Assert (smpCntx.smConfirmOps.remDev == NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_CALCPAIRCONFIRM, iat, rat);
    bt_parm_trace(16, tk);
    bt_parm_trace(16, rand);
    bt_parm_trace(7, preq);
    bt_parm_trace(7, pres);
    BTBMDumpBdAddr(ia.addr);
    BTBMDumpBdAddr(ra.addr);

    smpCntx.smConfirmOps.remDev = remDev;
    smpCntx.smConfirmOps.encryptCount = 0;


    OS_MemCopy(smpCntx.smConfirmOps.k, tk, 16);
    /* p2 = (MSB)padding || ia || ra */
    OS_MemCopy((U8 *)&smpCntx.smConfirmOps.p2, ra.addr, 6);
    OS_MemCopy(&smpCntx.smConfirmOps.p2[6], ia.addr, 6);

    /* p1 = (MSB)pres || preq || rat1 || iat1 */
    p1[0] = iat1;
    p1[1] = rat1;
    OS_MemCopy(&p1[2], preq, 7);
    OS_MemCopy(&p1[9], pres, 7);

    /* r OXR p1 */
    SM_util_128bit_XOR(p1, p1, rand);
    return LeHciAES128Encrypt(SM_CalcPairConfirm_FSM, tk, p1);
}
コード例 #2
0
void tstmemcpy(const U8 *src, size_t length, kal_bool last)
{
    size_t  length2 = 0;
    bt_tst_log("tstmemcpy(%p, %d, %d) : %d, %d", src, length, last, tst_last_pos, tst_write_pos);
    if(length > (TST_RB_SIZE-tst_write_pos))
    {
        length2 = length - (TST_RB_SIZE-tst_write_pos);
        length -= length2;
        /* Copy second segment */
        OS_MemCopy(&tst_buffer[0], src+length, length2);
    }
    else
    {
        length2 = 0;
    }
    /* Copy first segment */
    OS_MemCopy(&tst_buffer[tst_write_pos], src, length);
    /* Update tst_write_pos */
    tst_write_pos = ((tst_write_pos+length)&TST_RB_SIZE_MASK)+length2;
    if(last)
    {
        if((tst_expand_bytes+(tst_write_pos+TST_RB_SIZE-tst_last_pos))&0x1)
        {
            tst_buffer[tst_write_pos] = 0;
            tst_write_pos = ((tst_write_pos+1)&TST_RB_SIZE_MASK);
        }
        tst_expand_bytes = 0;
        /* Update tst_last_pos */
        tst_last_pos = tst_write_pos;
        /* Wakeup tst thread */
        if(wakeup_fun)
            wakeup_fun();
    }
}
コード例 #3
0
U8 meUtilWriteEirName(U8 *buf, U8 bufLen, const U8 *name, U8 nameLen)
{
    int offset = 0;

    if(name && buf && bufLen > 2){
	nameLen = min(nameLen, OS_StrLen((const char*)name));
	if (nameLen)
	{
	    if (nameLen > bufLen - 2)
	    {
                buf[offset] = bufLen - 1;
		offset++;
		buf[offset++] = BT_EIR_NAME_SHORTENED;
		OS_MemCopy(buf + offset, name, bufLen - offset);
		offset = bufLen;
            }
	    else
	    {
                buf[offset++] = nameLen + 1;
                buf[offset++] = BT_EIR_NAME_COMPLETE;
                OS_MemCopy(buf + offset, name, nameLen);
                offset += nameLen;
            }
        }
    }
    Assert (offset <= bufLen);
    return offset;
}
コード例 #4
0
/*---------------------------------------------------------------------------
 *            OBEXH_ParseAuthChallenge
 *---------------------------------------------------------------------------
 *
 * Synopsis: Applications use this function to collect Authentication
 *           Challenge information as it is indicated in OBxx_HEADER_RX events.
 *           This function converts the raw header data into the provided
 *           structure. It must be called during every OBxx_HEADER_RX event
 *           when the header type is OBEX_AUTH_CHAL.
 *
 * Return:   TRUE when the entire header has been processed.
 */
BOOL OBEXH_ParseAuthChallenge(ObexAppHandle *AppHndl, ObexAuthChallengeInfo *Info)
{
#if OBEX_MAX_REALM_LEN > 0
    U16     toCopy;
#endif
    ObexTlv tlv;

#if XA_ERROR_CHECK == XA_ENABLED
    if (!AppHndl || !Info) {
        return FALSE;
    }
#endif /* XA_ERROR_CHECK == XA_ENABLED */
    ASSERT(AppHndl && Info && IsObexLocked());

    if ((AppHndl->parser).dataLen == 0) {
#if OBEX_MAX_REALM_LEN > 0
        /* Initialize the realm length */
        Info->realmLen = 0;
#endif
    }

    /* Parse Authentication Challenge tags */
    while (OBEXH_ParseTlv(AppHndl, &tlv))
    {
        switch(tlv.tag) {

        case 0: /* Nonce (fixed length, 16 bytes) */
            
            /* If the length is incorrect, clear the NONCE */
            if (tlv.length == AUTH_NONCE_LEN) {
                ASSERT(tlv.valueLen == tlv.length);
                OS_MemCopy(Info->nonce, tlv.value, tlv.valueLen);
            }
            break;

        case 1: /* Options (fixed length, 1 byte) */
            if (tlv.length == 1) {
                Info->options = *tlv.value;
            }
            break;

#if OBEX_MAX_REALM_LEN > 0
        case 2: /* Realm (variable length) */
            toCopy = min(tlv.valueLen, (OBEX_MAX_REALM_LEN - Info->realmLen));

            OS_MemCopy(Info->realm + Info->realmLen, tlv.value, toCopy);
            Info->realmLen += toCopy;
            break;
#endif
        default:
            continue;
        }
    }

    /* Indicate whether the entire header has been parsed. */
    return ((AppHndl->parser).headerLen == 0);
}
コード例 #5
0
/*---------------------------------------------------------------------------
 *            OBEXH_ParseAuthResponse
 *---------------------------------------------------------------------------
 *
 * Synopsis: Applications use this function to collect Authentication
 *           Response information as it is indicated in OBxx_HEADER_RX events.
 *           This function converts the raw header data into the provided
 *           structure. It must be called during every OBxx_HEADER_RX event
 *           when the header type is OBEX_AUTH_RESP.
 *
 * Return:   TRUE when the entire header has been processed.
 */
BOOL OBEXH_ParseAuthResponse(ObexAppHandle *AppHndl, ObexAuthResponseInfo *Info)
{
#if OBEX_MAX_USERID_LEN > 0
    U16     toCopy;
#endif
    ObexTlv tlv;

#if XA_ERROR_CHECK == XA_ENABLED
    if (!AppHndl || !Info) {
        return FALSE;
    }
#endif /* XA_ERROR_CHECK == XA_ENABLED */
    ASSERT(AppHndl && Info && IsObexLocked());

    if ((AppHndl->parser).dataLen == 0) {
        /* Initialize the User ID length */
#if OBEX_MAX_USERID_LEN > 0
        Info->userIdLen = 0;
#endif
    }

    /* Parse Authentication Response tags */
    while (OBEXH_ParseTlv(AppHndl, &tlv))
    {
        switch(tlv.tag)
        {
        case 0: /* Request-Digest (fixed length, 16 bytes) */
            if (tlv.length == AUTH_NONCE_LEN) {
                OS_MemCopy(Info->digest, tlv.value, tlv.valueLen); 
            }
            break;

#if OBEX_MAX_USERID_LEN > 0
        case 1: /* User Id (variable length) */
            toCopy = min(tlv.valueLen, (OBEX_MAX_USERID_LEN - Info->userIdLen));

            OS_MemCopy(Info->userId + Info->userIdLen, tlv.value, toCopy);
            Info->userIdLen += toCopy;
            break;
#endif /* OBEX_MAX_USERID_LEN > 0 */

        case 2: /* Nonce (fixed length, 16 bytes) */
            if (tlv.length == AUTH_NONCE_LEN) {
                OS_MemCopy(Info->nonce,  tlv.value, tlv.valueLen);
            }
            break;
        }
    }

    /* Indicate whether the entire header has been parsed. */
    return ((AppHndl->parser).headerLen == 0);
}
コード例 #6
0
INT8U OSTaskQuery (INT8U prio, OS_TCB *p_task_data)
{
	OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
	OS_CPU_SR cpu_sr;

	cpu_sr = 0; /* Prevent compiler warning                           */
#endif    
#if OS_ARG_CHK_EN > 0
	if (prio > OS_LOWEST_PRIO) { /* Task priority valid ?    	                       */
		if (prio != OS_PRIO_SELF) {
			return (OS_PRIO_INVALID);
		}
	}
#endif
	OS_ENTER_CRITICAL();
	if (prio == OS_PRIO_SELF) { /* See if suspend SELF                                */
		prio = OSTCBCur->OSTCBPrio;
	}
	ptcb = OSTCBPrioTbl[prio];
	if (ptcb == (OS_TCB *)0) { /* Task to query must exist                           */
		OS_EXIT_CRITICAL();
		return (OS_PRIO_ERR);
	}
	if (ptcb == (OS_TCB *)1) { /* Task to query must not be assigned to a Mutex      */
		OS_EXIT_CRITICAL();
		return (OS_TASK_NOT_EXIST);
	}
	/* Copy TCB into user storage area                    */
	OS_MemCopy((INT8U *)p_task_data, (INT8U *)ptcb, sizeof(OS_TCB));
	OS_EXIT_CRITICAL();
	return (OS_NO_ERR);
}
コード例 #7
0
/*****************************************************************************
 * FUNCTION
 *  SM_SendPairRsp
 * DESCRIPTION
 *  Send SMP pairing response
 * PARAMETERS
 *  remDev         [IN]
 *  presData       [OUT]
 *  ioCapability   [IN]
 *  oobFlag        [IN]
 *  bondFlag       [IN]
 *  MITMProtect    [IN]
 *  maxKeySize     [IN]
 *  iKeyDist       [IN]
 *  rKeyDist       [IN]
 * RETURNS
 *  BtStatus
 *****************************************************************************/
BtStatus SM_SendPairRsp(BtRemoteDevice *remDev,
                        U8 *presData,
                        SmIOCapability ioCapability, 
                        SmOOBFlag oobFlag, 
                        SmBondingFlag bondFlag, 
                        BOOL MITMProtect, 
                        U8 maxKeySize,
                        SmKeyDistribute iKeyDist,
                        SmKeyDistribute rKeyDist)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();
    
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDPAIRRSP, ioCapability, oobFlag, bondFlag, MITMProtect, maxKeySize, iKeyDist, rKeyDist);
    Assert(remDev != NULL);
    Assert(presData != NULL);
    packet->data[i++] = SMC_PAIR_RSP;
    packet->data[i++] = ioCapability;
    packet->data[i++] = oobFlag;
    packet->data[i++] = (MITMProtect == TRUE) ? ((1 << 2) | bondFlag) : bondFlag;
    packet->data[i++] = maxKeySize;
    packet->data[i++] = iKeyDist;
    packet->data[i++] = rKeyDist;
    packet->dataLen = i;
    if (presData)
    {
        OS_MemCopy(presData, packet->data, 7);
        bt_parm_trace(7, presData);
    }

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #8
0
/*---------------------------------------------------------------------------
 *            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;
}
コード例 #9
0
/*--------------------------------------------------------------------------- 
 * AT_Encode_Common
 * 
 *     Encodes TE originated AT commands. 
 */ 
AtStatus TE_Encode_Common(AtContext *Atc, U16 Type, const AtCommands *Command, XaBufferDesc *Output)
{
    U16     avail = (Output->buffSize - Output->writeOffset) -1;
    U16     len;

    switch (Type) {
    case AT_SET_ERROR_MODE:
        /* Syntax: AT+CMEE=[<n>] */
        if (avail < 1) {
            return AT_STATUS_NO_RESOURCES;
        }
        Output->buff[Output->writeOffset++] = Command->p.error.mode + '0';
        break;

#if (AT_HANDSFREE == XA_ENABLED) || (AT_PHONEBOOK == XA_ENABLED) || (AT_SMS == XA_ENABLED)
    case AT_SELECT_CHARACTER_SET:
        /* Syntax: AT+CSCS=[<chset>] */
        len = OS_StrLen(Command->p.charSet.type);
        if (avail < len) {
            return AT_STATUS_NO_RESOURCES;
        }
        OS_MemCopy(Output->buff + Output->writeOffset, (const U8*)Command->p.charSet.type, len);
        Output->writeOffset += len;
        break;
#endif /* (AT_HANDSFREE == XA_ENABLED) || (AT_PHONEBOOK == XA_ENABLED) */

    default:
        return AT_STATUS_NOT_SUPPORTED;
    }
    return AT_STATUS_OK;
}
コード例 #10
0
static void SM_CalcPairConfirm_FSM(const BtEvent *event)
{
    BtEvent newEvent;
    bt_trace(TRACE_FUNC, BT_SMP_SM_CALCPAIRCONFIRMFSM, smpCntx.smConfirmOps.encryptCount, event->errCode);
    switch (smpCntx.smConfirmOps.encryptCount)
    {
    case 0:
        if (event->errCode == HC_STATUS_SUCCESS)
        {
            smpCntx.smConfirmOps.encryptCount++;
            SM_util_128bit_XOR(smpCntx.smConfirmOps.p2, smpCntx.smConfirmOps.p2, (U8 *)event->p.smEncryptResponse.EncryptData);
            LeHciAES128Encrypt(SM_CalcPairConfirm_FSM, smpCntx.smConfirmOps.k, smpCntx.smConfirmOps.p2);
            break;
        }
        /* fall-through */
    case 1:
        newEvent.errCode = event->errCode;
        newEvent.eType = BTEVENT_LE_SM_RESULT;
        newEvent.p.smConfirmResponse.remDev = smpCntx.smConfirmOps.remDev;
        OS_MemCopy(newEvent.p.smConfirmResponse.ConfirmValue, event->p.smEncryptResponse.EncryptData, SM_CONFIRM_VALUE_LENGTH);
        SM_LinkCallback(smpCntx.smConfirmOps.remDev, &newEvent);
        OS_MemSet((U8 *)&smpCntx.smConfirmOps, 0x00, sizeof(sm_confirm_op));
        break;
    }
}
コード例 #11
0
BtStatus SM_CalcSTK(BtRemoteDevice *remDev, U8 *tk, U8 *srand, U8 *mrand)
{
    U8 r[16] = {0};

    Assert (smpCntx.smCalcSTKOps == NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_CALCSTK);
    bt_parm_trace(16, tk);
    bt_parm_trace(8, srand);  /* r1 */
    bt_parm_trace(8, mrand);  /* r2 */

    smpCntx.smCalcSTKOps = remDev;

    /* r = (MSB)r1 || r2 */
    OS_MemCopy(r, mrand, 8);
    OS_MemCopy(&r[8], srand, 8);
    
    return LeHciAES128Encrypt(SM_CalcSTK_FSM, tk, r);
}
コード例 #12
0
static void SM_CalcSTK_FSM(const BtEvent *event)
{
    BtEvent newEvent;
    newEvent.errCode = event->errCode;
    newEvent.eType = BTEVENT_LE_SM_RESULT;
    newEvent.p.smEncryptResponse.remDev = smpCntx.smCalcSTKOps;
    OS_MemCopy(newEvent.p.smEncryptResponse.EncryptData, event->p.smEncryptResponse.EncryptData, 16);
    SM_LinkCallback(smpCntx.smCalcSTKOps, &newEvent);
    smpCntx.smCalcSTKOps = NULL;
}
コード例 #13
0
/*****************************************************************************
 * FUNCTION
 *  BTAppSdpCreateSortingAttributes
 * DESCRIPTION
 *  
 * PARAMETERS
 *  ptr                 [IN]        
 *  attribute_no        [IN]        
 * RETURNS
 *  void
 *****************************************************************************/
void BTAppSdpCreateSortingAttributes(U8 *ptr, U8 attribute_no)
{
    U8 i = 0;
    U8 j = 0;
    BT_APP_ATTRIBUTE_struct_t temp_buffer;
    BT_APP_ATTRIBUTE_struct_t *item1;
    BT_APP_ATTRIBUTE_struct_t *item2;

    for (i = 0; i < attribute_no; i++)
    {
        item1 = (BT_APP_ATTRIBUTE_struct_t*) (ptr + sizeof(BT_APP_ATTRIBUTE_struct_t) * i);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_INDEXxD, i);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_ATTRIBUTE_IDxD, item1->attribute_id);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_ATTRIBUTE_SIZExD, item1->attribute_size);
    }
    for (i = 0; i < attribute_no; i++)
    {
        for (j = i; j < attribute_no; j++)
        {
            item1 = (BT_APP_ATTRIBUTE_struct_t*) (ptr + sizeof(BT_APP_ATTRIBUTE_struct_t) * i);
            item2 = (BT_APP_ATTRIBUTE_struct_t*) (ptr + sizeof(BT_APP_ATTRIBUTE_struct_t) * j);
            if (item1->attribute_id > item2->attribute_id)
            {
                OS_MemSet((U8*) & temp_buffer, 0, sizeof(temp_buffer));
                OS_MemCopy((U8*) & temp_buffer, (U8*) item1, sizeof(BT_APP_ATTRIBUTE_struct_t));
                OS_MemCopy((U8*) item1, (U8*) item2, sizeof(BT_APP_ATTRIBUTE_struct_t));
                OS_MemCopy((U8*) item2, (U8*) & temp_buffer, sizeof(BT_APP_ATTRIBUTE_struct_t));
            }
        }
    }
    kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_AFTER_SORTING);
    for (i = 0; i < attribute_no; i++)
    {
        item1 = (BT_APP_ATTRIBUTE_struct_t*) (ptr + sizeof(BT_APP_ATTRIBUTE_struct_t) * i);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_INDEXxD, i);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_ATTRIBUTE_IDxD, item1->attribute_id);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_SORT_ATTIBS_ATTRIBUTE_SIZExD, item1->attribute_size);
    }

}
コード例 #14
0
static void SM_Rand_FSM(const BtEvent *event)
{
    BtEvent newEvent;
    bt_trace(TRACE_FUNC, BT_SMP_SM_RANDFSM, smpCntx.smRandOps.randLen, smpCntx.smRandOps.randCount);
    bt_parm_trace(8, (U8 *)event->p.smRand64Response.randValue64);
    if(smpCntx.smRandOps.randLen == 16)
    {
        switch (smpCntx.smRandOps.randCount)
        {
        case 0:
            if (event->errCode == HC_STATUS_SUCCESS)
            {
                smpCntx.smRandOps.randCount++;
                OS_MemCopy((U8 *)smpCntx.smRandOps.tmpRandValue, (U8 *)event->p.smRand64Response.randValue64, SM_RAND_VALUE_LENGTH);
                LeHciRand(SM_Rand_FSM);
                return;
            }
        case 1:
            if (event->errCode == HC_STATUS_SUCCESS)
            {
                U8 tmp[SM_RAND_VALUE_LENGTH];
                OS_MemCopy(tmp, event->p.smRand64Response.randValue64, SM_RAND_VALUE_LENGTH);
                OS_MemCopy(newEvent.p.smRand128Response.randValue128, smpCntx.smRandOps.tmpRandValue, SM_RAND_VALUE_LENGTH);
                OS_MemCopy(newEvent.p.smRand128Response.randValue128 + SM_RAND_VALUE_LENGTH, tmp, SM_RAND_VALUE_LENGTH);
                break;
            }
        }
        newEvent.p.smRand128Response.remDev = smpCntx.smRandOps.remDev;
    }
    else
    {
        newEvent.p.smRand64Response.remDev = smpCntx.smRandOps.remDev;
    }
    newEvent.eType = BTEVENT_LE_SM_RESULT;
    newEvent.errCode = event->errCode;
    SM_LinkCallback(smpCntx.smRandOps.remDev, &newEvent);
    OS_MemSet((U8 *)&smpCntx.smRandOps, 0x00, sizeof(sm_rand_op));
 }
コード例 #15
0
void bt_a2dp_fake_get_payload_data(U32 prefer_size, U8 *data)
{
    if(sbc_size != 0)
    {
        OS_MemCopy(data, sbc_buffer + sbc_sent_offset ,prefer_size);
        sbc_sent_offset += prefer_size;
        if(sbc_sent_offset >= sbc_size)
            sbc_sent_offset = 0;
    }
    else
    {
        data[0] = 0x00;
    }
}
コード例 #16
0
static void bpp_adp_auth_ind(bt_bpp_obex_auth_chal_info * chal_info)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    bt_bpp_auth_ind_struct *auth_ind =
        (bt_bpp_auth_ind_struct*) construct_local_para(sizeof(bt_bpp_auth_ind_struct), TD_CTRL);
	
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    auth_ind->hprinter = g_bpp_adp_cntx.printer_handle;
	OS_MemCopy((U8*)&(auth_ind->chal_info), (U8*)chal_info, sizeof(auth_ind->chal_info));

    bpp_adp_send_msg2app(MSG_ID_BT_BPP_AUTH_IND, (local_para_struct*) auth_ind);
}
コード例 #17
0
/*****************************************************************************
 * FUNCTION
 *  SM_SendPairRandom
 * DESCRIPTION
 *  Send SMP pairing random value
 * PARAMETERS
 *  remDev         [IN]
 *  random         [IN]
 * RETURNS
 *  BtStatus
 *****************************************************************************/
BtStatus SM_SendPairRandom(BtRemoteDevice *remDev, U8 *random)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();

    Assert(remDev != NULL);
    Assert(random != NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDPAIRRANDOM);
    bt_parm_trace(SM_RANDOM_VALUE_LENGTH, random);

    packet->data[i++] = SMC_PAIR_RANDOM;
    OS_MemCopy(packet->data + 1, random, SM_RANDOM_VALUE_LENGTH);
    packet->dataLen = 1 + SM_RANDOM_VALUE_LENGTH;

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #18
0
BtStatus SM_SendIdentityInfo(BtRemoteDevice *remDev, U8 *irk)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();

    Assert(remDev != NULL);
    Assert(irk != NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDIDENTITYINFO);
    bt_parm_trace(SM_IRK_VALUE_LENGTH, irk);

    packet->data[i++] = SMC_IDEN_INFO;
    OS_MemCopy(packet->data + 1, irk, SM_IRK_VALUE_LENGTH);
    packet->dataLen = i + SM_IRK_VALUE_LENGTH;

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #19
0
BtStatus SM_SendSigningInfo(BtRemoteDevice *remDev, U8 *csrk)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();

    Assert(remDev != NULL);
    Assert(csrk != NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDSIGNINGINFO);
    bt_parm_trace(SM_CSRK_VALUE_LENGTH, csrk);

    packet->data[i++] = SMC_SIGN_INFO;
    OS_MemCopy(packet->data + 1, csrk, SM_CSRK_VALUE_LENGTH);
    packet->dataLen = i + SM_CSRK_VALUE_LENGTH;

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #20
0
BtStatus SM_SendIdentityAddrInfo(BtRemoteDevice *remDev, LeAddrType addrType, BD_ADDR bdAddr)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();

    Assert(remDev != NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDIDENTITYADDRINFO, 
             addrType, bdAddr.addr[0], bdAddr.addr[1], bdAddr.addr[2], bdAddr.addr[3], bdAddr.addr[4], bdAddr.addr[5]);

    packet->data[i++] = SMC_IDEN_ADDR_INFO;
    packet->data[i++] = addrType;
    OS_MemCopy(packet->data + i, bdAddr.addr, BD_ADDR_SIZE);
    packet->dataLen = i + BD_ADDR_SIZE;

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #21
0
U8 meUtilWriteEirBLEServiceList(U8 *buf, U8 bufLen)
{
    U8 offset = 0, recNum = 0, index;
    U8 uuid_list[MAX_EIR_SDP_SIZE * 2], len = 0;
        
    if (bufLen >= 4)
    {
        for (index = 0; index < MAX_EIR_SDP_SIZE; index++)
        {
            if (MEC(eirSdpCtx)[index].used != 0)
            {
                OS_Report("UUID=0x%x",MEC(eirSdpCtx)[index].service_class);
                if(SdpIsBLEService(MEC(eirSdpCtx)[index].service_class))
                {
                    recNum++;
                    StoreLE16(&uuid_list[len], MEC(eirSdpCtx)[index].service_class);
                    len += 2;
                }
            }
        }

        if (recNum)
        {
            if (len + 2 > bufLen)
            {
                /* EIR UUID is not completed */
                len = bufLen - 2;
                recNum = len / 2;
                buf[1] = BT_EIR_SERVICE_CLASS_16UUID_MORE;
            }
            else
            {
                /* EIR UUID is completed */
                buf[1] = BT_EIR_SERVICE_CLASS_16UUID_COMPLETE;
            }
            bt_trace(TRACE_GROUP_1, BTLOG_EIRRECORDNUMxD, recNum);
            buf[0] = len + 1;
            offset += 2;
            OS_MemCopy(buf + offset, uuid_list, len);
            offset += len;
        }
    }
    Assert (offset <= bufLen);
    return offset;
}
コード例 #22
0
//HdpChannel *hdp_create_channel(MdepId id, BD_ADDR *bdaddr, HdpChannelType type, HdpRole role)
HdpChannel *hdp_create_channel(HdpInstance *instance, BD_ADDR *bdaddr, HdpChannelType type)
{
	HdpChannel *channel = NULL;
	L2capLinkMode mode;
	U16 rmUuid = 0;
	OS_Report("[HDP]hdp_create_channel");

//	instance = hdp_find_instance(id);		
	if (NULL == instance)
	{
		OS_Report("[HDP]instance is NULL");
		goto error;
	}
	channel = (HdpChannel *)hdp_util_malloc(sizeof(HdpChannel));
	Assert(channel != NULL);

	OS_MemSet(channel, 0x0, sizeof(HdpChannel));

	OS_MemCopy(&channel->bdAddr, bdaddr, sizeof(BD_ADDR));

	channel->instance = instance;
	channel->type = type;

	mode = hdp_util_convert_type2mode(instance->channelType);
	if (HDP_INVALID_L2CAP_MODE == mode)
	{
		OS_Report("[HDP] invalid l2cap mode");
		goto error;
	}
	channel->config.inLinkMode = mode;
	rmUuid = hdp_get_target_uuid(instance->feature.role);
	if (0 == rmUuid)
	{
		OS_Report("[HDP] invalid remote device uuid");
		goto error;
	}
	channel->rmUuid = rmUuid;

	InsertTailList(&hdp_cntx.channel, &(channel->node));
	return channel;
error:
	hdp_util_free(channel);
	return NULL;
}
コード例 #23
0
ファイル: os_task.c プロジェクト: Bechance/H3A_v6.1
// CODE_SECTION(OSTaskQuery,".UserProgramCode")
INT8U  OSTaskQuery( INT8U prio, OS_TCB *p_task_data )
{
	OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
	OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
	if ( prio > OS_LOWEST_PRIO )                 /* Task priority valid ?                              */
	{
		if ( prio != OS_PRIO_SELF )
		{
			return ( OS_ERR_PRIO_INVALID );
		}
	}
	if ( p_task_data == ( OS_TCB * )0 )          /* Validate 'p_task_data'                             */
	{
		return ( OS_ERR_PDATA_NULL );
	}
#endif
	OS_ENTER_CRITICAL();
	if ( prio == OS_PRIO_SELF )                  /* See if suspend SELF                                */
	{
		prio = OSTCBCur->OSTCBPrio;
	}
	ptcb = OSTCBPrioTbl[prio];
	if ( ptcb == ( OS_TCB * )0 )                 /* Task to query must exist                           */
	{
		OS_EXIT_CRITICAL();
		return ( OS_ERR_PRIO );
	}
	if ( ptcb == OS_TCB_RESERVED )               /* Task to query must not be assigned to a Mutex      */
	{
		OS_EXIT_CRITICAL();
		return ( OS_ERR_TASK_NOT_EXIST );
	}
	/* Copy TCB into user storage area                    */
	OS_MemCopy(( INT8U * )p_task_data, ( INT8U * )ptcb, sizeof( OS_TCB ) );
	OS_EXIT_CRITICAL();
	return ( OS_ERR_NONE );
}
コード例 #24
0
static void sendContextInd(context_info *pCtx){
    ilm_struct *ilm = NULL;
    U16 *field;
    local_para_struct *ind;

    ilm = (ilm_struct*)bt_win_malloc(sizeof(ilm_struct)-MAX_ILM_BUFFER_SIZE+pCtx->size);
    ind = (local_para_struct*)ilm->ilm_data;
    ind->ref_count = 1;
    ind->msg_len = pCtx->size;

    OS_MemCopy(((U8*)ind)+sizeof(local_para_struct),
                            (const U8*)pCtx->ctx,
                            pCtx->size-sizeof(local_para_struct));
    /* Init  */
    ilm->msg_id = pCtx->msg;
    ilm->src_mod_id = MOD_BT;
    ilm->dest_mod_id = MOD_BT;
    ilm->sap_id = INVALID_SAP;
    bt_log_primitive(ilm);
    bt_win_free(ilm);
}
コード例 #25
0
/*****************************************************************************
 * FUNCTION
 *  SM_SendEncryptInfo
 * DESCRIPTION
 *  Send SMP pairing encryption long term key information
 * PARAMETERS
 *  remDev         [IN]
 *  ltk            [IN]
 * RETURNS
 *  BtStatus
 *****************************************************************************/
BtStatus SM_SendEncryptInfo(BtRemoteDevice *remDev, U8 *ltk)
{
    int i = 0;
    BtPacket *packet = SM_AllocCmdPkt();

    Assert(remDev != NULL);
    Assert(ltk != NULL);
    bt_trace(TRACE_FUNC, BT_SMP_SM_SENDENCRYPTINFO);
    bt_parm_trace(SM_LTK_VALUE_LENGTH, ltk);
    Report(("UPF Debug LTK Send to Remote Side"));
    Report(("UPF Debug LTK LSB->MSB:%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
        ltk[0],ltk[1],ltk[2],ltk[3],ltk[4],ltk[5],ltk[6],ltk[7]));
    Report(("UPF Debug LTK LSB->MSB:%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x",
        ltk[8],ltk[9],ltk[10],ltk[11],ltk[12],ltk[13],ltk[14],ltk[15]));

    packet->data[i++] = SMC_ENCRYPT_INFO;
    OS_MemCopy(packet->data + 1, ltk, SM_LTK_VALUE_LENGTH);
    packet->dataLen = 1 + SM_LTK_VALUE_LENGTH;

    SM_ResetTimer(remDev);
    return SM_SendL2capData(remDev, packet);
}
コード例 #26
0
/*****************************************************************************
 * FUNCTION
 *  bpp_adp_get_attr_confirm
 * DESCRIPTION
 *  This function send get attr confirm to bpp app (mmi)
 * PARAMETERS
 *  printer         [?]         [?]
 *  err_code        [IN]        
 * RETURNS
 *  void
 *****************************************************************************/
static void bpp_adp_get_attr_confirm(BPP_ERROR_CODE err_code, bt_bpp_printer_attributes *attr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    bt_bpp_get_printer_attr_cnf_struct *get_attr_cnf = NULL;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    BT_BPP_TRACE_INFO_ARG1(BPP_ADP_GET_ATTR_CONFIRM,err_code);

    get_attr_cnf =
        (bt_bpp_get_printer_attr_cnf_struct*) construct_local_para(sizeof(bt_bpp_get_printer_attr_cnf_struct), TD_CTRL);

    OS_MemSet((U8*)&get_attr_cnf->printer_attributes, 0, sizeof(get_attr_cnf->printer_attributes));
    get_attr_cnf->hprinter = g_bpp_adp_cntx.printer_handle;
    get_attr_cnf->cnf_code = err_code;
	
	if (attr != NULL)
	{
		get_attr_cnf->printer_attributes.printer_state = attr->printer_state;
		get_attr_cnf->printer_attributes.state_reason = attr->state_reason;
	}
	
	if (err_code == BPP_SUCCESS)
	{		
		OS_MemCopy((U8*)&get_attr_cnf->printer_attributes.capability, (U8*)&attr->capability, sizeof(bt_bpp_printer_capability));
	}

	if (g_bpp_adp_cntx.cur_req == BPP_REQ_GETPRINTERATTR)
    {
		g_bpp_adp_cntx.cur_req = BPP_REQ_NONE;
    }

    bpp_adp_send_msg2app(MSG_ID_BT_BPP_GET_PRINTER_ATTR_CNF, (local_para_struct*) get_attr_cnf);
	
}
コード例 #27
0
/*---------------------------------------------------------------------------
 *            TCPSTACK_GetTpConnInfo()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Retrieves OBEX transport layer connection information. This
 *            function can be called when a transport connection is active
 *            to retrieve connection specific information. It should be used
 *            in conjunction with the receive flow control API to retrieve 
 *            the minimum amount of application storage space (low water mark)
 *            used when deciding to pause and resume data flow.
 *
 * Return:    TRUE  - The structure was successfully completed.
 *            FALSE - The transport is not connected.
 */
static BOOL TCPSTACK_GetTpConnInfo(ObexTransportContext  con,
                                   ObexTpConnInfo   *tpConnInfo)
{
    SOCKADDR             name;
    U32                  len;
    ObTcpCommonTransport *txp;

    tpConnInfo->tpType = OBEX_TP_TCP;
    tpConnInfo->minRxBuffs = 1;
    tpConnInfo->maxPduSize = 1450;

    /* Get the local device address for the transport being used */
    txp = ContainingRecord((SOCKET *)con, ObTcpCommonTransport, conn);
    /* We do not have a transport connection */
    if (txp->state != OCS_CONNECTED) return FALSE;
    len = sizeof(SOCKADDR);
    if (getsockname(txp->conn, &name, &len) != 0) return FALSE;
    ASSERT(len == 16);
    /* Get the server IP address and store it Big Endian */
    OS_MemCopy(txp->devAddr, name.sa_data+2, 4);
    tpConnInfo->devAddr = txp->devAddr;
    return TRUE;
}
コード例 #28
0
/*--------------------------------------------------------------------------- 
 * TE_Encode
 * 
 *     This function encodes an AT command for transmission to the gateway (ME).
 */ 
AtStatus TE_Encode(AtContext *Atc, const AtCommands *Command, XaBufferDesc *Out)
{
    AtStatus    status;
    const char *cmdStr = 0;
    U8          idx, grp;
    U16         len;

    CheckUnlockedParm(AT_STATUS_INVALID_PARM, Atc && Command && Out);
    
    idx = (Command->type & 0x00ff);
    grp = (Command->type & 0x0f00) >> 8;

    if (idx > Atc->lastCmd[grp]) {
        return AT_STATUS_NOT_FOUND;
    }

    cmdStr = AT_CommandTable[grp][(idx)];
    len = OS_StrLen(cmdStr);

    /* Check space for "AT"<base command>"="<cr> */
    CheckUnlockedParm(AT_STATUS_NO_RESOURCES, (Out->buffSize - Out->writeOffset) > (len + 4));

    Out->buff[Out->writeOffset++] = 'A';
    Out->buff[Out->writeOffset++] = 'T';
    OS_MemCopy(Out->buff + Out->writeOffset, (const U8*)cmdStr, len);
    Out->writeOffset += len;
    Out->buff[Out->writeOffset++] = '=';

    switch (Command->type & 0xff00) {
    case AT_GROUP_COMMON:
        status = TE_Encode_Common(Atc, Command->type, Command, Out);
        break;

#if AT_HEADSET == XA_ENABLED
    case AT_GROUP_HEADSET:
        status = TE_Encode_Headset(Atc, Command->type, &Command->p.hs, Out);
        break;
#endif /* AT_HEADSET == XA_ENABLED */

#if AT_HANDSFREE == XA_ENABLED
    case AT_GROUP_HANDSFREE:
        status = TE_Encode_Handsfree(Atc, Command->type, &Command->p.hf, Out);
        break;
#endif /* AT_HANDSFREE == XA_ENABLED */

#if AT_PHONEBOOK == XA_ENABLED
    case AT_GROUP_PHONEBOOK:
        status = TE_Encode_Phonebook(Atc, Command->type, &Command->p.pb, Out);
        break;
#endif /* AT_HANDSFREE == XA_ENABLED */

    default:
        if (Command->type & AT_TEST) {
            if ((Out->buffSize - Out->writeOffset) < 1) {
                return AT_STATUS_NO_RESOURCES;
            }
        }
        else if (Command->type & AT_READ) {
            Out->writeOffset--;      /* remove the '=' */
        } 
        else {
            Assert(0);
            return AT_STATUS_NOT_SUPPORTED;
        }
        
        Out->buff[Out->writeOffset++] = '?';
        status = AT_STATUS_OK;
        break;
    }
    
    if (status == AT_STATUS_OK)
        Out->buff[Out->writeOffset++] = '\r';

    return status;
}
コード例 #29
0
/*--------------------------------------------------------------------------- 
 * AT_Encode_Common
 * 
 *     Encodes Audio Gateway (ME) originated AT results.
 */ 
AtStatus ME_Encode_Common(AtContext *Atc, U16 Type, const AtResults *Result, XaBufferDesc *Output)
{
    U16 	 len;
    U16     avail = (Output->buffSize - Output->writeOffset) - 2;

    switch (Type) {
    case AT_OK:         /* Syntax: OK */
    case AT_ERROR:      /* Syntax: ERROR */
    case AT_RING:       /* Syntax: RING */
    case AT_NO_CARRIER: /* Syntax: NO CARRIER */
    case AT_BUSY:       /* Syntax: BUSY */
    case AT_NO_ANSWER:  /* Syntax: NO ANSWER */
    case AT_DELAYED:    /* Syntax: DELAYED */
    case AT_BLACKLISTED:/* Syntax: BLACKLISTED */
        /* No parameters, yank the ':' & ' ' */
        Output->writeOffset -= 2;
        break;

    case AT_EXTENDED_ERROR:
        /* Syntax: +CME ERROR: <err> */
        if (avail < 3) {
            return AT_STATUS_NO_RESOURCES;
        }

        Output->writeOffset += AtItoA(Output->buff + Output->writeOffset, 
                                      Result->p.error.type);
        break;

    case AT_MANUFACTURE_ID:
		/* Subtract "<Cr><Lf>+CGMI: " */
		/* Output->writeOffset -= 7; */ /* For WISE requirement */
		Output->buff[Output->writeOffset++] = '\"';
		OS_MemCopy(Output->buff + Output->writeOffset, (const U8*)Result->p.manufactureID, OS_StrLen((const char *)Result->p.manufactureID));
		Output->writeOffset += OS_StrLen((const char *)Result->p.manufactureID);
		Output->buff[Output->writeOffset++] = '\"';
		break;
    case AT_MODEL_ID:
		/* Subtract "<Cr><Lf>+CGMM: " */
		/* Output->writeOffset -= 7; */ /* For WISE requirement */
		Output->buff[Output->writeOffset++] = '\"';		
		OS_MemCopy(Output->buff + Output->writeOffset, (const U8*)Result->p.modelID, OS_StrLen((const char *)Result->p.modelID));
		Output->writeOffset += OS_StrLen((const char *)Result->p.modelID);		
		Output->buff[Output->writeOffset++] = '\"';
		break;

    case (AT_SELECT_CHARACTER_SET|AT_TEST):
		#if 1
		len = OS_StrLen(Result->p.charset_test);
		if(len == 0)
		{
			return AT_STATUS_INVALID_PARM;
		}
		else if(avail < len+2)
		{
			return AT_STATUS_NO_RESOURCES;
		}
		else
		{
			OS_MemCopy(Output->buff + Output->writeOffset, (const U8*)Result->p.charset_test, len);
			Output->writeOffset += len;
		}
		#else
		if(Result->p.charset_test > 0)
		{
			U8 i, offset = Output->writeOffset;

			if(avail < 2)
				return AT_STATUS_NO_RESOURCES;
			else
				avail -= 2;
			
			Output->buff[Output->writeOffset++] = '(';
			for(i = 0;i < Result->p.charset_test.num; i++)
			{
				if( i != 0 )
				{
					if(avail == 0)
						return AT_STATUS_NO_RESOURCES;
					Output->buff[Output->writeOffset++] = ',';
				}
				
				len = OS_StrLen(Result->p.charset_test.charset[i]);
				if( avail < len+2 )
				{
					return AT_STATUS_NO_RESOURCES;
				}
				else
				{
					Output->buff[Output->writeOffset++] = '\"';
					OS_MemCopy(Output->buff + Output->writeOffset,Result->p.charset_test.charset[i], len);
					Output->writeOffset += len;					
					Output->buff[Output->writeOffset++] = '\"';
					avail -= (len+2);
				}				
		   	}
			Output->buff[Output->writeOffset++] = ')';
	   	}
		else
		{
			return AT_STATUS_INVALID_PARM;
		}
		#endif
		break;

    case AT_SELECT_CHARACTER_SET|AT_READ:
		len = OS_StrLen(Result->p.charset);
		if(len == 0)
		{
			return AT_STATUS_INVALID_PARM;
		}
		else if(avail < len+2)
		{
			return AT_STATUS_NO_RESOURCES;
		}
		else
		{
			Output->buff[Output->writeOffset++] = '\"';
			OS_MemCopy(Output->buff + Output->writeOffset, (const U8*)Result->p.charset, len);
			Output->writeOffset += len;
			Output->buff[Output->writeOffset++] = '\"';
		}
		break;
		
    case AT_RAW:
        Output->writeOffset -= 7; /* Subtract "Cr Lf RAW: " */
        OS_MemCopy(Output->buff + Output->writeOffset, 
                   Result->p.data, OS_StrLen((const char *)Result->p.data));
        Output->writeOffset += OS_StrLen((const char *)Result->p.data);
        break;

    default:
        return AT_STATUS_NOT_SUPPORTED;
    }

    return AT_STATUS_OK;
}
コード例 #30
0
/*--------------------------------------------------------------------------- 
 * ME_Encode
 * 
 *     This function encodes an AT result for transmission to the device (TE).
 */ 
AtStatus ME_Encode(AtContext *Atc, const AtResults *Result, XaBufferDesc *Out)
{
    const char *cmdStr = 0;
    AtCommand   idx, grp;
    U16         len;
    AtStatus    status = AT_STATUS_INVALID_PARM;

    CheckUnlockedParm(AT_STATUS_INVALID_PARM, (Atc && Result && Out));

    idx = (Result->type & 0x00ff);
    grp = (Result->type & 0x0f00) >> 8;

    if (idx > Atc->lastCmd[grp] || grp >= AT_NUM_GROUPS) {
        return AT_STATUS_NOT_FOUND;
    }

    cmdStr = AT_CommandTable[grp][(idx)];
    len = OS_StrLen(cmdStr);

    /* Check space for "AT"<base command>"="<cr> */
    /* Check space for <cr><lf><base command>":"<cr><lf> */
    CheckUnlockedParm(AT_STATUS_NO_RESOURCES, (Out->buffSize - Out->writeOffset) > (len + 6));

    Out->buff[Out->writeOffset++] = '\r';
    Out->buff[Out->writeOffset++] = '\n';
    OS_MemCopy(Out->buff + Out->writeOffset, (const U8 *)cmdStr, len);
    Out->writeOffset += len;
    Out->buff[Out->writeOffset++] = ':';
    Out->buff[Out->writeOffset++] = ' ';  /* Required by some Ericsson handsets */

    switch (Result->type & 0x0f00) {
    case AT_GROUP_COMMON:
        status = ME_Encode_Common(Atc, Result->type, Result, Out);
        break;

#if AT_HEADSET == XA_ENABLED
    case AT_GROUP_HEADSET:
        status = ME_Encode_Headset(Atc, Result->type, &Result->p.hs, Out);
        break;
#endif /* AT_HEADSET == XA_ENABLED */

#if AT_HANDSFREE == XA_ENABLED
    case AT_GROUP_HANDSFREE:
        status = ME_Encode_Handsfree(Atc, Result->type, &Result->p.hf, Out);
        break;
#endif /* AT_HANDSFREE == XA_ENABLED */

#if AT_PHONEBOOK == XA_ENABLED
    case AT_GROUP_PHONEBOOK:
        status = ME_Encode_Phonebook(Atc, Result->type, &Result->p.pb, Out);
        break;
#endif /* AT_PHONEBOOK == XA_ENABLED */

#if AT_SMS == XA_ENABLED
	case AT_GROUP_SMS:
		status = ME_Encode_Sms(Atc, Result->type, &Result->p.sms, Out);
		break;
#endif

    default:
        Assert(0);
        break;
    }

    if ((status == AT_STATUS_OK) && (Result->type != AT_RAW)) {
        Out->buff[Out->writeOffset++] = '\r';
        Out->buff[Out->writeOffset++] = '\n';
    }

    return status;
}