/*************************************************************************
Copyright (c) 2011 - 2015 Qualcomm Technologies International, Ltd.
Part of ADK_QCC300x.WIN 1.0
FILE NAME
gatt_characteristic_write.c
DESCRIPTION
Functions to handle GATT Characteristic Write sub-procedures.
This module implements support for the following GATT sub-procedures:
- Write Without Response
NOTES
*/
#include "gatt_private.h"
#include <stdlib.h>
#include <string.h>
#include <vm.h>
#ifndef HYDRACORE
#include <memory.h>
#endif /* HYDRACORE */
static void handleInternalWriteReqLong(
cid_map_t *conn,
const GATT_INTERNAL_WRITE_REQ_T *m);
static void handleInternalWriteReqPrepare(
cid_map_t *conn,
const GATT_INTERNAL_WRITE_REQ_T *m);
#if (GATT_FEATURES & (GATT_WRITE_COMMAND | \
GATT_WRITE_SIGNED | \
GATT_WRITE | \
GATT_WRITE_LONG | \
GATT_WRITE_RELIABLE))
static void internalWriteReq(Task theAppTask,
uint16 id,
uint16 cid,
uint16 handle,
uint16 offs,
uint16 size_value,
const uint8 *value)
{
cid_map_t *conn = gattFindConn(cid);
if (conn && !conn->closing)
{
MAKE_GATT_MESSAGE_WITH_VALUE(GATT_INTERNAL_WRITE_REQ,
size_value, value);
message->common.task = theAppTask;
message->common.cid = cid;
message->handle = handle;
message->offs = offs;
message->id = id;
MessageSendConditionallyOnTask(
gattGetTask(),
GATT_INTERNAL_WRITE_REQ,
message,
&conn->data.app);
}
else
{
MAKE_GATT_MESSAGE(GATT_WRITE_CHARACTERISTIC_VALUE_CFM);
message->cid = cid;
message->handle = handle;
message->status = gatt_status_invalid_cid;
switch (id)
{
#if (GATT_FEATURES & GATT_WRITE_COMMAND)
case gatt_ms_write_without_response:
id = GATT_WRITE_WITHOUT_RESPONSE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_SIGNED)
case gatt_ms_signed_write_without_response:
id = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE)
case gatt_ms_write_characteristic_value:
id = GATT_WRITE_CHARACTERISTIC_VALUE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_LONG)
case gatt_ms_write_long_characteristic_value:
id = GATT_WRITE_LONG_CHARACTERISTIC_VALUE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_RELIABLE)
case gatt_ms_prepare_write:
id = GATT_RELIABLE_WRITE_PREPARE_CFM;
break;
#endif
default:
/* horror error which can't happen, ever. */
Panic();
}
MessageSend(theAppTask, id, message);
}
}
#endif /* WRITE_COMMAND | WRITE_SIGNED | WRITE | WRITE_LONG */
#if (GATT_FEATURES & GATT_WRITE_COMMAND)
void GattWriteWithoutResponseRequest(Task theAppTask,
uint16 cid,
uint16 handle,
uint16 size_value,
const uint8 *value)
{
internalWriteReq(theAppTask, gatt_ms_write_without_response, cid,
handle, 0 /* offs */, size_value, value);
}
#endif
#if (GATT_FEATURES & GATT_WRITE_SIGNED)
void GattSignedWriteWithoutResponseRequest(Task theAppTask,
uint16 cid,
uint16 handle,
uint16 size_value,
const uint8 *value)
{
internalWriteReq(theAppTask, gatt_ms_signed_write_without_response, cid,
handle, 0 /* offs */, size_value, value);
}
#endif
#if (GATT_FEATURES & GATT_WRITE)
void GattWriteCharacteristicValueRequest(Task theAppTask,
uint16 cid,
uint16 handle,
uint16 size_value,
const uint8 *value)
{
internalWriteReq(theAppTask, gatt_ms_write_characteristic_value, cid,
handle, 0 /* offs */, size_value, value);
}
#endif
#if (GATT_FEATURES & (GATT_WRITE_COMMAND | \
GATT_WRITE_SIGNED | \
GATT_WRITE | \
GATT_WRITE_LONG | \
GATT_WRITE_RELIABLE))
/*************************************************************************
NAME
gattHandleInternalWriteReq
DESCRIPTION
This function is handler for GATT_INTERNAL_WRITE_REQ internal message.
RETURNS
*/
void gattHandleInternalWriteReq(const GATT_INTERNAL_WRITE_REQ_T *m)
{
cid_map_t *conn = gattFindConnOrPanic(m->common.cid); /* never NULL */
STASH(conn, stash, WRITE_CHARACTERISTIC_VALUE);
uint16 flags;
switch (m->id)
{
#if (GATT_FEATURES & GATT_WRITE_COMMAND)
case gatt_ms_write_without_response:
flags = ATT_WRITE_COMMAND;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_SIGNED)
case gatt_ms_signed_write_without_response:
flags = ATT_WRITE_COMMAND | ATT_WRITE_SIGNED;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE)
case gatt_ms_write_characteristic_value:
flags = ATT_WRITE_REQUEST;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_LONG)
case gatt_ms_write_long_characteristic_value:
handleInternalWriteReqLong(conn, m);
return;
#endif
#if (GATT_FEATURES & GATT_WRITE_RELIABLE)
case gatt_ms_prepare_write:
handleInternalWriteReqPrepare(conn, m);
return;
#endif
default:
/* horror error which can't happen, ever. */
flags = 0;
Panic();
}
gattSetConnState(conn, m->common.task, (gatt_msg_scen_t)m->id);
gatt_write_req(m->common.cid, m->handle, flags, m->size_value, m->value);
/* Create the response message */
MAKE_STASH(conn, stash, WRITE_CHARACTERISTIC_VALUE);
stash->cid = m->common.cid;
stash->handle = m->handle;
}
/*************************************************************************
NAME
gattHandleAttWriteCfm
DESCRIPTION
This function handles Bluestack response for ATT_WRITE_REQ.
RETURNS
*/
void gattHandleAttWriteCfm(const ATT_WRITE_CFM_T *m)
{
cid_map_t *conn = gattFindConnOrPanic(m->cid); /* never NULL */
STASH(conn, stash, WRITE_CHARACTERISTIC_VALUE);
uint16 id;
stash->status = gatt_message_status(m->result);
switch (conn->data.scenario)
{
#if (GATT_FEATURES & GATT_WRITE_COMMAND)
case gatt_ms_write_without_response:
id = GATT_WRITE_WITHOUT_RESPONSE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE_SIGNED)
case gatt_ms_signed_write_without_response:
id = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CFM;
break;
#endif
#if (GATT_FEATURES & GATT_WRITE)
case gatt_ms_write_characteristic_value:
id = GATT_WRITE_CHARACTERISTIC_VALUE_CFM;
break;
#endif
default:
/* horror error which can't happen, ever. */
id = 0;
Panic();
}