Heh, I don't know what the GATTC_DISCOVERY_COMPLETE event is, but here's the general sequence I use:
Handle the CYBLE_EVT_GATTC_FIND_BY_TYPE_VALUE_RSP event for each service that matches the UUID.
Handle the CYBLE_EVT_GATTC_READ_BY_TYPE_RSP event for each characteristic.
//You now have the handles for the service you are looking for, and the characteristics within the service.
//Note: there will be an event to signal the completion of the discover commands I believe, but you can also end them early (before completion) with the command CyBle_GattcStopCmd();
Now, you merely call the function CyBle_GattcWriteCharacteristicValue(cyBle_connHandle, &CYBLE_GATTC_WRITE_REQ_T); replacing the WRITE_REQ_T with a structure containing the data and metadata for writing your data to the specified characteristic.
Thank you for your response, but I am still a little confused. I'm not sure exactly what you mean when you say: "Handle the .. event for..."
Currently I am calling the GattcWriteCharacteristicValue() with the handle returned by the CYBLE_EVT_GATT_CONNECT_IND event. Is this incorrect?
UPDATE: I did finally get the Write function working based on the example shown in the 100 Days: UART_to_BLE example.
Sorry, the wording was as little poor. The handles for the services/characteristics you are using perfectly. I was referring to having a case to grab the handle values for the service/characteristics when those events occurred (hence, handling a generation of the event, not the handle value :))
Glad to hear that you got it working :)