*/
static const gchar *at_final_responses_success[] = {
"OK",
- "CONNECT"
+ "CONNECT",
+ "ABORTED"
};
/**
return *cur == '\0' ? NULL : cur;
}
-static TcoreAtResponse *__response_new()
+static TcoreAtResponse *__at_response_new()
{
TcoreAtResponse *at_resp;
return at_resp;
}
-static void __response_free(TcoreAtResponse *at_resp)
+static void __at_response_free(TcoreAtResponse *at_resp)
{
if (at_resp == NULL) {
err("Response is NULL");
tcore_free(at_resp);
}
+static gboolean __at_is_abort(TcoreAtResponse *at_resp)
+{
+ gboolean aborted = FALSE;
+ if (at_resp == NULL) {
+ err("at_resp is NULL");
+ return FALSE;
+ }
+
+ /* Request is ABORTED */
+ if (g_strcmp0(at_resp->final_response, "ABORTED") == 0)
+ aborted = TRUE;
+ dbg("Aborted: [%s]", (aborted ? "YES" : "NO"));
-static void __response_add(TcoreAtResponse *at_resp, const gchar *line)
+ return aborted;
+}
+
+static void __at_response_add(TcoreAtResponse *at_resp, const gchar *line)
{
if ((at_resp == NULL) || (line == NULL)) {
err("at_resp: [%p] line: [%p]", at_resp, line);
at_resp->lines = g_slist_append(at_resp->lines, tcore_strdup(line));
}
-static void __emit_pending_response(TcoreAT *at)
+static void __at_emit_pending_response(TcoreAT *at, gboolean abort)
{
TcorePending *p;
+ TcoreQueue *at_queue;
if (at == NULL) {
err("at is NULL");
tcore_at_request_free(at->req);
at->req = NULL;
- p = tcore_queue_pop(tcore_hal_ref_queue(at->hal));
- if (p == NULL) {
- warn("NO pending request!!!");
- return;
+ at_queue = tcore_hal_ref_queue(at->hal);
+
+ /*
+ * If 'abort' is TRUE,
+ * then Pop the first Abortable Request from Queue
+ */
+ if (abort) {
+ p = tcore_queue_pop_abortable_pending(at_queue);
+ if (p == NULL) {
+ warn("No Abortable requests!!!");
+ goto out;
+ }
+ }
+ else {
+ p = tcore_queue_pop(at_queue);
+ if (p == NULL) {
+ warn("NO pending request!!!");
+ goto out;
+ }
}
tcore_pending_emit_response_callback(p, sizeof(TcoreAtResponse), at->resp);
tcore_pending_free(p);
- __response_free(at->resp);
+out:
+ __at_response_free(at->resp);
at->resp = NULL;
}
-static void __emit_unsolicited_message(TcoreAT *at, const gchar *line)
+static void __at_emit_unsolicited_message(TcoreAT *at, const gchar *line)
{
struct _notification *noti = NULL;
struct _notification_callback *item = NULL;
}
if (data_len_final == actual_buffer_size) {
- __emit_unsolicited_message(at, position);
+ __at_emit_unsolicited_message(at, position);
at->data_mode = MODE_HEX;
at->buf_read_pos = at->buf_read_pos + (actual_buffer_size + 1);
data_len_final = ZERO;
/* Check request */
if (at->req == NULL) {
- dbg(" Not AT request " );
- __emit_unsolicited_message(at, pos);
+ dbg("Not AT request" );
+ __at_emit_unsolicited_message(at, pos);
}
else {
- dbg(" AT request " );
+ dbg("AT request" );
if (g_strcmp0(pos, "> ") == 0) {
if (at->req->next_send_pos) {
dbg("send next: [%s]", at->req->next_send_pos);
}
if (at->resp == NULL)
- at->resp = __response_new();
+ at->resp = __at_response_new();
ret = __check_final_response(pos);
switch (ret) {
at->resp->final_response = tcore_strdup(pos);
- __emit_pending_response(at);
+ __at_emit_pending_response(at, __at_is_abort(at->resp));
at->buf_read_pos = next_pos + 1;
return TRUE;
case TCORE_AT_RECV_MSG_TYPE_NOTI: {
switch (at->req->type) {
case TCORE_AT_COMMAND_TYPE_NO_RESULT:
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
break;
case TCORE_AT_COMMAND_TYPE_NUMERIC:
if (at->resp->lines == NULL && isdigit(pos[0]))
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
break;
case TCORE_AT_COMMAND_TYPE_SINGLELINE:
if (at->resp->lines == NULL)
if (at->req->prefix)
if (g_str_has_prefix(pos, at->req->prefix))
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
else
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
break;
case TCORE_AT_COMMAND_TYPE_MULTILINE:
dbg("MULTILINE");
if (at->req->prefix)
if (g_str_has_prefix(pos, at->req->prefix))
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
else
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
break;
case TCORE_AT_COMMAND_TYPE_PDU:
dbg("PDU");
if (at->req->prefix)
if (g_str_has_prefix(pos, at->req->prefix))
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
if (at->resp->lines != NULL)
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
else
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
else
- __response_add(at->resp, pos);
+ __at_response_add(at->resp, pos);
break;
default:
warn("UNKNOWN");
- __emit_unsolicited_message(at, pos);
+ __at_emit_unsolicited_message(at, pos);
break;
} /* switch (at->req->type) */
} break;
return ret;
}
+
+TelReturn tcore_at_prepare_and_send_request_ex(CoreObject *co,
+ const gchar *cmd, const gchar *prefix, TcoreAtCommandType type,
+ TcorePendingPriority priority, void *request,
+ TcorePendingResponseCallback resp_cb, void *resp_cb_data,
+ TcorePendingSendCallback send_cb, void *send_cb_data,
+ guint timeout, TcorePendingTimeoutCallback timeout_cb, void *timeout_cb_data,
+ gboolean auto_free, gboolean abortable)
+{
+ TcorePending *pending;
+ TcoreAtRequest *at_req;
+ TcoreHal *hal;
+ TelReturn ret = TEL_RETURN_FAILURE;
+
+ hal = tcore_object_get_hal(co);
+ if (hal == NULL) {
+ err("HAL is NULL");
+ return ret;
+ }
+ dbg("hal: [%p]", hal);
+
+ /* Create Pending Request */
+ pending = tcore_pending_new(co, 0);
+ if (pending == NULL) {
+ err("Pending is NULL");
+ return ret;
+ }
+
+ /* Create AT-Command Request */
+ at_req = tcore_at_request_new(cmd, prefix, type);
+ if (at_req == NULL) {
+ err("Request is NULL");
+
+ tcore_pending_free(pending);
+ return ret;
+ }
+
+ tcore_pending_set_request_data(pending, 0, at_req);
+ tcore_pending_link_request(pending, request);
+
+ tcore_pending_set_priority(pending, priority);
+
+ tcore_pending_set_response_callback(pending, resp_cb, resp_cb_data);
+ tcore_pending_set_send_callback(pending, send_cb, send_cb_data);
+
+ if (timeout > 0)
+ tcore_pending_set_timeout(pending, timeout);
+ tcore_pending_set_timeout_callback(pending, timeout_cb, timeout_cb_data);
+
+ if (auto_free)
+ tcore_pending_set_auto_free_status_after_sent(pending, auto_free);
+
+ if (abortable)
+ tcore_pending_set_abortable(pending, abortable);
+
+ ret = tcore_hal_send_request(hal, pending);
+ dbg("ret: [0x%x]", ret);
+
+ return ret;
+}
+
gboolean flag_received_response; /**< Received response: Response received from modem */
gboolean flag_auto_free_after_sent; /**< Auto free: Not expecting Response */
+ /**< Abortable Request */
+ gboolean abortable;
+
/**< Essential references */
void *request;
TcorePlugin *plugin;
return pending->flag_auto_free_after_sent;
}
+TelReturn tcore_pending_set_abortable(TcorePending *pending,
+ gboolean abortable)
+{
+ if (pending == NULL) {
+ err("pending is NULL");
+ return TEL_RETURN_INVALID_PARAMETER;
+ }
+
+ pending->abortable = abortable;
+
+ return TEL_RETURN_SUCCESS;
+}
+
+gboolean tcore_pending_get_abortable(TcorePending *pending)
+{
+ if (pending == NULL) {
+ err("pending is NULL");
+ return FALSE;
+ }
+
+ return pending->abortable;
+}
+
TelReturn tcore_pending_set_request_data(TcorePending *pending,
guint data_len, void *data)
{
return NULL;
}
+TcorePending *tcore_queue_pop_abortable_pending(TcoreQueue *queue)
+{
+ TcorePending *pending = NULL;
+ gint i = 0;
+
+ if (queue == NULL) {
+ err("queue is NULL");
+ return NULL;
+ }
+
+ /*
+ * Scan through the list of 'pending' Requests and
+ * get the first Abortable Request
+ */
+ do {
+ pending = g_queue_peek_nth(queue->gq, i);
+ if (pending == NULL) {
+ err("pending is NULL");
+ return NULL;
+ }
+ else if (tcore_pending_get_abortable(pending) == TRUE) {
+ dbg("Found Abrotable 'pending' request: [%p]", pending);
+
+ /* Pop the Abortable 'pending' Request */
+ g_queue_pop_nth(queue->gq, i);
+ break;
+ }
+
+ i++;
+ } while (pending != NULL);
+
+ return pending;
+}
TcorePending *tcore_queue_pop_timeout_pending(TcoreQueue *queue)
{
guint i = 0;
return __queue_search_full(queue, id, 0, SEARCH_FIELD_ID_ALL, TRUE);
}
-TcorePending *tcore_queue_ref_pending_by_id(TcoreQueue *queue, guint id)
-{
- if (queue == NULL) {
- err("queue is NULL");
- return NULL;
- }
-
- return __queue_search_full(queue, id, 0, SEARCH_FIELD_ID_ALL, FALSE);
-}
-
TcorePending *tcore_queue_ref_next_pending(TcoreQueue *queue)
{
TcorePending *pending = NULL;
return pending;
}
+TcorePending *tcore_queue_ref_pending_by_id(TcoreQueue *queue, guint id)
+{
+ if (queue == NULL) {
+ err("queue is NULL");
+ return NULL;
+ }
+
+ return __queue_search_full(queue, id, 0, SEARCH_FIELD_ID_ALL, FALSE);
+}
+
guint tcore_queue_get_length(TcoreQueue *queue)
{
if (queue == NULL) {