Ejemplo n.º 1
0
BtStatus FMP_Close(FmpChannel *channel)
{
    BtStatus status = BT_STATUS_FAILED;

    /* Validate parameters */
    CheckUnlockedParm(BT_STATUS_INVALID_PARM, channel != 0);

    OS_LockStack();

    CheckLockedParm(BT_STATUS_NOT_FOUND, 
                    IsNodeOnList(&FMP(dev_list), &(channel->node)));

    // check state
    if (channel->state == FMP_STATE_OPEN)
    {
        status = GattDisconnect(channel->link);
    }

    if (status == BT_STATUS_SUCCESS)
    {
        FmpClearConnection(channel, status);
    }


    OS_UnlockStack();
    return status;
}
Ejemplo n.º 2
0
BtStatus FMP_Open(FmpChannel **channel, BD_ADDR *addr)
{
    BtStatus status = BT_STATUS_FAILED;
    FmpChannel *ch; 

    CheckUnlockedParm(BT_STATUS_INVALID_PARM, addr != 0);

    OS_LockStack();

    kal_trace(BT_TRACE_BLE_PROFILES, FMP_OPENCONNECTION);
    if ((*channel != NULL) && IsNodeOnList(&FMP(dev_list), &((*channel)->node)))
    {
        ch = *channel;
    }
    else
    {
        ch = FmpNewChannel();
        if (ch == NULL)
        {
            return BT_STATUS_NO_RESOURCES;
        }
    }

    if (ch->state == FMP_STATE_CLOSED)
    {
        status = CMGR_CreateDataLink(&ch->cmgr_handler, addr);
        kal_trace(BT_TRACE_BLE_PROFILES, FMP_CREATEDATALINK_STATUS, status);
        if (status == BT_STATUS_SUCCESS)
        {
            status = GattClientConnect(ch->cmgr_handler.remDev);
        }

        if (status != BT_STATUS_SUCCESS && status != BT_STATUS_PENDING)
        {
            FmpFreeChannel(ch);
            return status;          
        }

        ch->state = FMP_STATE_OPENING;
        *channel = ch;      
    }

    OS_UnlockStack();
    return status;
}
Ejemplo n.º 3
0
/*--------------------------------------------------------------------------- 
 * ME_Decode
 * 
 *     This function decodes AT commands received by a gateway (ME).
 */ 
AtStatus ME_Decode(AtContext *Atc, AtCommands *Command, XaBufferDesc *In)
{
    I8           i, t;
    U16          len, offset=0;
    BOOL         match = FALSE;
    const char **table;
    char         cmdStr[COMMAND_STAGE_LEN];
    AtStatus     status = AT_STATUS_INVALID_PARM;

    CheckUnlockedParm(AT_STATUS_INVALID_PARM, (Atc && Command && In));

	// Handle message data of SMS for send and write
	if(Command->bContinue)
	{
		if(Command->bContinue)
		{
			switch(Command->type)
			{
			#if AT_SMS == XA_ENABLED
			case AT_SEND_MESSAGE:
				Command->p.sms.sendMsg.msg = AtMakeString(&In->buff[In->readOffset], (U16)(In->writeOffset - In->readOffset));
				break;
			case AT_STORE_MESSAGE:
				Command->p.sms.writeMsg.msg = AtMakeString(&In->buff[In->readOffset], (U16)(In->writeOffset - In->readOffset));
				break;
                                          #endif
			default:
				break;
			}
			Command->bContinue = FALSE;
		}
		return AT_STATUS_OK;
	}

    OS_MemSet((U8 *)Command, 0, sizeof(AtCommands));

    AtRemoveWhiteSpace(In);

    AtDebugOut(In);
    
    /* Commands we process must start with "AT" and end with <cr> */
    if (((In->buff[In->readOffset] != 'A') && (In->buff[In->readOffset] != 'a')) || 
        ((In->buff[In->readOffset + 1] != 'T') && (In->buff[In->readOffset + 1] != 't')))  {
        return AT_STATUS_NOT_FOUND;
    }

    len = (In->writeOffset - In->readOffset) - 1;

	if(len <= 1)
	{
		/* It is check alive CMD */
		Command->type = AT_CHECK_ALIVE;
		status = AT_STATUS_OK;
	       goto exit;
	}


    /* For efficiency, convert the first 6 characters to uppercase
     * for case-insensitive comparison with command string table.
     */
    i = min (COMMAND_STAGE_LEN, len);

    OS_MemSet((U8*)cmdStr, 0, COMMAND_STAGE_LEN);

    while (i-- > 0)
        cmdStr[i] = ToUpper(In->buff[In->readOffset + 2 + i]);

    for (t = 0; (table = AT_CommandTable[t]) != 0; t++) 
    {
        for (i = 0; table[i]; i++) 
        {
            if(table[i][0] == 0) continue;
            for (offset = 0; offset < len; offset++) 
            {
                if (table[i][offset] == 0) 
                {
                    match = TRUE;
                    break;
                }
                if (cmdStr[offset] != table[i][offset]) 
                {
                    break;
                }
            }
            Assert (offset < COMMAND_STAGE_LEN);

            if (match) 
            {
                break;
            }
        }
        if (match) 
        {
            break;
        }
    }

    if (!match) 
    {
        return AT_STATUS_NOT_FOUND;
    }

    In->readOffset += offset + 2;   /* Skip over 'AT'<command type> */

    Command->type = (AtCommand)(i | (0x0100 * t));

    /* Check for Test and Read commands. */
    len = In->writeOffset - In->readOffset;

    if (((len == 1) || (len == 2)) && (In->buff[In->writeOffset - 1] == '?')) {
        if (In->buff[In->readOffset] == '=')
            Command->type |= AT_TEST;
        else Command->type |= AT_READ;

        In->readOffset += len;

        status = AT_STATUS_OK;
        goto exit;
    }
    else if (len && (In->buff[In->readOffset] == '=')) {
        /* Strip off equals sign between command and value */
        In->readOffset++;
    }

    Assert(In->readOffset <= In->writeOffset);

    switch (t) {
    case 0:
        status = ME_Decode_Common(Atc, &Command->type, Command, In);
        break;

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

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

#if AT_PHONEBOOK == XA_ENABLED
    case 3:
        status = ME_Decode_Phonebook(Atc, &Command->type, &Command->p.pb, In);
        break;
#endif /* AT_PHONEBOOK == XA_ENABLED */

#if AT_SMS == XA_ENABLED
	case 4:
		status = ME_Decode_Sms(Atc, &Command->type, &Command->p.sms, In);
		break;
#endif /* AT_SMS == XA_ENABLED */


    default:
        Assert(0);
        break;
    }

exit:
	if(status != AT_STATUS_CONTINUE)
    In->readOffset = In->writeOffset = 0;
	else
		Command->bContinue = TRUE;
    return status;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/*--------------------------------------------------------------------------- 
 * TE_Decode
 * 
 *     This function decodes an AT result received by the device (TE).
 */ 
AtStatus TE_Decode(AtContext *Atc, AtResults *Result, XaBufferDesc *In)
{
    I8           i, t, skip;
    U16          len, offset;
    BOOL         match = FALSE;
    const char **table;
    char         resultStr[RESULT_STAGE_LEN];
    AtStatus     status = AT_STATUS_INVALID_PARM;

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

    OS_MemSet((U8 *)Result, 0, sizeof(AtResults));

    AtRemoveWhiteSpace(In);

    AtDebugOut(In);

    len = In->writeOffset - In->readOffset;

    /* For efficiency, convert the first 15 characters to uppercase
     * for case-insensitive comparison with command string table.
     */
    i = min (RESULT_STAGE_LEN, len);

    OS_MemSet((U8*)resultStr, 0, RESULT_STAGE_LEN);

    while (i-- > 0)
        resultStr[i] = ToUpper(In->buff[In->readOffset + i]);

    for (t = 0; (table = AT_CommandTable[t]) != 0; t++) {

        for (skip = 0, i = 0; table[i]; i++) {

            for (offset = 0; (offset < len) || table[i][offset + skip] == 0; offset++) {
                if (table[i][offset + skip] == 0) {
                    match = TRUE;
                    break;
                }

                if (resultStr[offset] != table[i][offset + skip]) {
                    /* We've hit a mismatch. If the StrTable entry has a space,
                     * then it's been compressed out of the input buffer so skip it.
                     */
                    if ((table[i][offset] != ' ') ||
                        (resultStr[offset] != table[i][offset + skip + 1])) {
                        break;
                    }
                    skip += 1;
                }
            }
            Assert (offset < RESULT_STAGE_LEN);

            if (match) break;
        }
        if (match) break;
    }

    if (!match) {
        return AT_STATUS_NOT_FOUND;
    }

    In->readOffset += offset;   /* Skip over <command type> */

    Result->type = (AtCommand)(i | (0x0100 * t));

    /* Strip the ':' between the command and the parameters. */
    if ((In->writeOffset > In->readOffset) && (In->buff[In->readOffset] == ':'))
        In->readOffset++;

    Assert(In->readOffset <= In->writeOffset);

    switch (t) {
    case 0:
        status = TE_Decode_Common(Atc, &Result->type, Result, In);
        break;

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

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

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

    default:
        Assert(0);
        break;
    }

    In->readOffset = In->writeOffset = 0;
    return status;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------
 *            OBEXH_ParseTlv
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Sniffs out a TLV from the current header
 *
 * Return:    TRUE  if parsing was successful.
 *            FALSE if an error occurred or no more TLVs are present.
 */
BOOL OBEXH_ParseTlv(ObexAppHandle *AppHndl, ObexTlv *tlv)
{
    U8          *buffer;
    U16          len;
    U8           toUse;
    BOOL success = FALSE;

    CheckUnlockedParm(FALSE, AppHndl && tlv);

    OS_LockObex();

    /* On the first OBxx_HEADER_RX indication there is no data available.
     * Use this event to initialize the parser.
     */
    if (AppHndl->parser.dataLen == 0) {
        /* ASSERT that we are in the correct internal state to parse
         * this header, and that it is a byte sequence header
         */
        ASSERT((AppHndl->parser).rxState == OBSC_RX_PUT_HEAD2);
        ASSERT(((AppHndl->parser).header & 0xC0) == 0x40);

        /* Initialize key fields */
        AppHndl->tlv.state = 0; 
        buffer = 0;
        len = 0;
        goto Done;
    }

    /* Use these locals as aliases for the AppHndl fields */
    buffer = AppHndl->tlv.headerBuff;
    len = AppHndl->tlv.headerLen;

    if (buffer == 0) {
        buffer = AppHndl->parser.rxBuff;
        len = AppHndl->parser.dataLen;
    }

    while (len)
    {
        switch (AppHndl->tlv.state) {
        case 0: /* Buff points to option type */
            AppHndl->tlv.tag = *buffer++;
            AppHndl->tlv.state = 1;
            len--;
            break;

        case 1: /* Buff points to option length */
            AppHndl->tlv.length = *buffer++;
            AppHndl->tlv.state = 2;
            AppHndl->tlv.valuePos = 0;
            len--;

            /* No break; fall through to handle option data */
        case 2:
            /* Update length of option data we currently need. */
            toUse = min(AppHndl->tlv.length - AppHndl->tlv.valuePos, len);

            /* Fill in tlv values in case they are necessary */
            tlv->tag = AppHndl->tlv.tag;
            tlv->length = AppHndl->tlv.length;

            /* Is reassembly both necessary and possible for this TLV? */
#if OBEX_TLV_BUFF_SIZE > 0
            if ((toUse < AppHndl->tlv.length) &&
                (AppHndl->tlv.length < OBEX_TLV_BUFF_SIZE)) {

                /* Append recevied data into our staging buffer */
                OS_MemCopy(AppHndl->tlv.value + AppHndl->tlv.valuePos,
                    buffer, toUse);
                AppHndl->tlv.valuePos += toUse;
                tlv->value = AppHndl->tlv.value;
                tlv->valueLen = AppHndl->tlv.length;
                len -= toUse;
                buffer += toUse;
            
                /* Indicate success ONLY if we have completed staging */
                tlv->remainLen = (tlv->length - AppHndl->tlv.valuePos);
                success = (tlv->remainLen == 0);
            } else {
#endif /* OBEX_TLV_BUFF_SIZE > 0 */
            
                /* If reassembly is impossible or unnecessary, simply copy
                 * tag information */
                tlv->value = buffer;
                tlv->valueLen = toUse;
                AppHndl->tlv.valuePos += toUse;
                len -= toUse;
                buffer += toUse;

                /* Indicate "last" if we are indicating the last chunk of bytes
                 * as counted by valuePos
                 */
                tlv->remainLen = (tlv->length - AppHndl->tlv.valuePos);
                /* Indicate success because staging isn't going to happen */
                success = TRUE;

#if OBEX_TLV_BUFF_SIZE > 0
            }
#endif  /* OBEX_TLV_BUFF_SIZE > 0 */

            if (success)
            {
                /* If we have reached the end of the tlv then reset state for
                 * next time */
                if (tlv->remainLen == 0) {
                    AppHndl->tlv.state = 0;
                }
                goto Done;
            }
            break;
        }
    }

    /* If control gets here we have exhausted the buffer */
    buffer = 0;

Done:
    /* Reset buffer/length from locals and return success */
    AppHndl->tlv.headerBuff = buffer;
    AppHndl->tlv.headerLen = len;

    OS_UnlockObex();
    return success;
}