16ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/******************************************************************************
26ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
36ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Copyright (C) 2004-2012 Broadcom Corporation
46ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
56ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Licensed under the Apache License, Version 2.0 (the "License");
66ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  you may not use this file except in compliance with the License.
76ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  You may obtain a copy of the License at:
86ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
96ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  http://www.apache.org/licenses/LICENSE-2.0
106ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  Unless required by applicable law or agreed to in writing, software
126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  distributed under the License is distributed on an "AS IS" BASIS,
136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  See the License for the specific language governing permissions and
156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  limitations under the License.
166ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/
186ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach
196ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/******************************************************************************
206ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
216ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *  BTA AG AT command interpreter.
226ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach *
236ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/
24e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
25e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include <string.h>
26e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "gki.h"
27e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "bta_ag_at.h"
28e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach#include "utl.h"
29e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
30e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/*****************************************************************************
31e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**  Constants
32e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach*****************************************************************************/
33e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
34e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************
35e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
36e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function         bta_ag_at_init
37e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
38e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description      Initialize the AT command parser control block.
396ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach**
40e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
41e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns          void
42e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
43e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach******************************************************************************/
44e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid bta_ag_at_init(tBTA_AG_AT_CB *p_cb)
45e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{
46e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    p_cb->p_cmd_buf = NULL;
47e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    p_cb->cmd_pos = 0;
48e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach}
49e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
50e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************
51e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
52e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function         bta_ag_at_reinit
53e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
54e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description      Re-initialize the AT command parser control block.  This
55e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  function resets the AT command parser state and frees
56e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  any GKI buffer.
576ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach**
58e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
59e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns          void
60e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
61e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach******************************************************************************/
62e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid bta_ag_at_reinit(tBTA_AG_AT_CB *p_cb)
63e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{
64e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    if (p_cb->p_cmd_buf != NULL)
65e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
66e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        GKI_freebuf(p_cb->p_cmd_buf);
67e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        p_cb->p_cmd_buf = NULL;
68e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
69e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    p_cb->cmd_pos = 0;
70e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach}
71e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************
72e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
73e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function         bta_ag_process_at
74e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
75e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description      Parse AT commands.  This function will take the input
76e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  character string and parse it for AT commands according to
77e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  the AT command table passed in the control block.
786ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach**
79e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
80e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns          void
81e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
82e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach******************************************************************************/
83e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid bta_ag_process_at(tBTA_AG_AT_CB *p_cb)
84e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{
85e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    UINT16      idx;
86e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    UINT8       arg_type;
87e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    char        *p_arg;
88e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    INT16       int_arg = 0;
89e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    /* loop through at command table looking for match */
90e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    for (idx = 0; p_cb->p_at_tbl[idx].p_cmd[0] != 0; idx++)
91e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
92e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        if (!utl_strucmp(p_cb->p_at_tbl[idx].p_cmd, p_cb->p_cmd_buf))
93e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
94e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            break;
95e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
96e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
97e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
98e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    /* if there is a match; verify argument type */
99e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    if (p_cb->p_at_tbl[idx].p_cmd[0] != 0)
100e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
101e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* start of argument is p + strlen matching command */
102e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        p_arg = p_cb->p_cmd_buf + strlen(p_cb->p_at_tbl[idx].p_cmd);
103e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
104e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* if no argument */
105e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        if (p_arg[0] == 0)
106e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
107e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            arg_type = BTA_AG_AT_NONE;
108e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
109e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* else if arg is '?' and it is last character */
110e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        else if (p_arg[0] == '?' && p_arg[1] == 0)
111e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
112e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            /* we have a read */
113e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            arg_type = BTA_AG_AT_READ;
114e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
115e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* else if arg is '=' */
116e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        else if (p_arg[0] == '=' && p_arg[1] != 0)
117e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
118e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            if (p_arg[1] == '?' && p_arg[2] == 0)
119e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
120e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                /* we have a test */
121e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                arg_type = BTA_AG_AT_TEST;
122e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
123e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            else
124e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
125e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                /* we have a set */
126e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                arg_type = BTA_AG_AT_SET;
127e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
128e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                /* skip past '=' */
129e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_arg++;
130e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
131e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
132e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        else
133e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* else it is freeform argument */
134e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
135e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            arg_type = BTA_AG_AT_FREE;
136e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
137e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
138e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* if arguments match command capabilities */
139e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        if ((arg_type & p_cb->p_at_tbl[idx].arg_type) != 0)
140e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
141e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            /* if it's a set integer check max, min range */
142e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            if (arg_type == BTA_AG_AT_SET &&
143e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_cb->p_at_tbl[idx].fmt == BTA_AG_AT_INT)
144e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
145e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                int_arg = utl_str2int(p_arg);
146e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                if (int_arg < (INT16) p_cb->p_at_tbl[idx].min ||
147e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    int_arg > (INT16) p_cb->p_at_tbl[idx].max)
148e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                {
149e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    /* arg out of range; error */
150e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    (*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
151e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                }
152e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                else
153e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                {
1546ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach
155e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    (*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
156e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                }
157e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
158e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            else
159e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
160e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                (*p_cb->p_cmd_cback)(p_cb->p_user, idx, arg_type, p_arg, int_arg);
161e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
162e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
163e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        /* else error */
164e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        else
165e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
166e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            (*p_cb->p_err_cback)(p_cb->p_user, FALSE, NULL);
167e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
168e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
169e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    /* else no match call error callback */
170e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    else
171e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
172e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        (*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
173e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
174e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach}
175e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
176e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach/******************************************************************************
177e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
178e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Function         bta_ag_at_parse
179e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
180e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Description      Parse AT commands.  This function will take the input
181e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  character string and parse it for AT commands according to
182e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**                  the AT command table passed in the control block.
1836ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach**
184e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
185e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach** Returns          void
186e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach**
187e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach******************************************************************************/
188e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbachvoid bta_ag_at_parse(tBTA_AG_AT_CB *p_cb, char *p_buf, UINT16 len)
189e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach{
190e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    int i = 0;
191e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    char* p_save;
192e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
193e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    if (p_cb->p_cmd_buf == NULL)
194e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
195e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        p_cb->p_cmd_buf = (char *) GKI_getbuf(p_cb->cmd_max_len);
196e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        p_cb->cmd_pos = 0;
197e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
198e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
199e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    for (i = 0; i < len;)
200e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    {
201e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        while (p_cb->cmd_pos < p_cb->cmd_max_len-1 && i < len)
202e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        {
203e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            /* Skip null characters between AT commands. */
204e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            if ((p_cb->cmd_pos == 0) && (p_buf[i] == 0))
205e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
206e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                i++;
207e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                continue;
208e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
2096ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach
210e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            p_cb->p_cmd_buf[p_cb->cmd_pos] = p_buf[i++];
211e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            if ( p_cb->p_cmd_buf[p_cb->cmd_pos] == '\r' || p_cb->p_cmd_buf[p_cb->cmd_pos] == '\n')
212e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
213e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_cb->p_cmd_buf[p_cb->cmd_pos] = 0;
214e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                if ((p_cb->cmd_pos > 2)                                      &&
215e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    (p_cb->p_cmd_buf[0] == 'A' || p_cb->p_cmd_buf[0] == 'a') &&
216e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    (p_cb->p_cmd_buf[1] == 'T' || p_cb->p_cmd_buf[1] == 't'))
217e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                {
218e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    p_save = p_cb->p_cmd_buf;
219e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    p_cb->p_cmd_buf += 2;
220e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    bta_ag_process_at(p_cb);
221e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                    p_cb->p_cmd_buf = p_save;
222e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                }
223e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
224e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_cb->cmd_pos = 0;
2256ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach
2266ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach            }
227e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            else if( p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1A || p_cb->p_cmd_buf[p_cb->cmd_pos] == 0x1B )
228e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
229e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_cb->p_cmd_buf[++p_cb->cmd_pos] = 0;
230e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                (*p_cb->p_err_cback)(p_cb->p_user, TRUE, p_cb->p_cmd_buf);
231e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                p_cb->cmd_pos = 0;
232e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
233e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            else
234e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            {
235e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach                ++p_cb->cmd_pos;
236e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            }
237e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        }
238e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
239e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach        if (i < len)
240e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach            p_cb->cmd_pos = 0;
241e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach    }
242e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach}
243e448862a47c08eb23185aaed574b39264f5005fcAndre Eisenbach
244