bool tpsocket_event_storage_stream_to_cloud(struct tpsocket_handler *handler, struct list_head *buf, int event)
{
//debug_show_tpbuf_list(buf, "TEST", 3);
struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler);
STORAGE_SESSION *storage_session = handler->priv;
int err_code = 0;
if (event != TPSOCKET_EVENT_WRITABLE) {
MYDEBUG("storage stream to cloud event = %s, sock = %p, session = %p\n", tpsocket_event_name(event), sock, storage_session);
if (storage_session) {
DBG_DBG("Device Id = %s, session sock = %p\n", storage_session->dev_id, storage_session->sock);
}
}
switch(event) {
case TPSOCKET_EVENT_LISTEN:
break;
case TPSOCKET_EVENT_SHUTDOWN:
break;
case TPSOCKET_EVENT_ACCEPT:
break;
case TPSOCKET_EVENT_CONNECTED:
MYDEBUG("STORAGESTREAM2CLOUD: %s:%s Connected\n", sock->addr, sock->port);
if (false == storage_stream_consumer_post(storage_session))
return false;
if (false == storage_start_read(storage_session)) {
DBG_ERR("read stream file failed\n");
return false;
}
break;
case TPSOCKET_EVENT_REQ_HEAD:
break;
case TPSOCKET_EVENT_RSP_HEAD:
break;
case TPSOCKET_EVENT_SUB_HEAD:
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_WRITABLE:
if (storage_session->file && !list_empty(&(storage_session->file->parser.buf))) {
if (storage_session->chunked && !tpsocket_chunk_encode(&(storage_session->file->parser.buf))) {
tpsocket_free_buf(&(storage_session->file->parser.buf), tpsocket_event_name(event), 0);
break;
}
storage_session_write_list_force(storage_session, &(storage_session->file->parser.buf), true);
storage_session->file->read_buf_length = 0;
}
break;
case TPSOCKET_EVENT_STREAM:
return true;
case TPSOCKET_EVENT_MESSAGE:
err_code = common_check_error_code(buf);
if (!err_code) {
DBG_DBG("storage stream push success\n");
storage_session->post_success = 1;
#ifndef TAPO_CAMERA
} else if (err_code == -98400) {
//If the recording/relay server finds out that the device is not eligible for cloud storage,
// it returns an error code of -98400 upon which the firmware updates the cloud storage feature of that device.
DEV_INFO *dev_info = get_dev_info(storage_session->storage_server->worker_ctx->top_ctx, storage_session->dev_id, NULL);
if (dev_info) {
dev_info->cloud_storage = false;
}
// mark as success here to avoid retrying.
storage_session->post_success = 1;
#endif
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
common_tpsocket_close_immediately(sock);
break;
case TPSOCKET_EVENT_RESET:
break;
case TPSOCKET_EVENT_KEEPALIVE:
common_tpsocket_close_immediately(sock);
break;
case TPSOCKET_EVENT_CLOSED:
if (storage_session) {
tpsocket_unbind(sock, &storage_session->sock);
uloop_timeout_cancel(&storage_session->reupload_tmo);
tpsocket_free2(&storage_session->file, storage_session);
if (storage_session->post_success) {
storage_session->stream_send_to_cloud_flag = 0;
}
storage_session->uploading_flag = 0;
storage_session_set_push_status(storage_session, 0);
/* handle timeout immediately */
storage_server_timeout_handle_immediately(storage_session->storage_server);
}
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
return true;
}bool storage_stream_upload(STORAGE_SESSION *storage_session)
{
DEV_INFO *dev_info = NULL;
STORAGE_SERVER *storage_server;
if (!storage_session) {
DBG_ERR("arg NULL\n");
return false;
}
if (storage_session->sock) {
DBG_DBG("sock exist\n");
return true;
}
storage_server = storage_session->storage_server;
uloop_timeout_set(&storage_session->reupload_tmo, storage_session->reupload_idle_time);
dev_info = get_dev_info(storage_server->worker_ctx->top_ctx, storage_session->dev_id, NULL);
if (!dev_info) {
DBG_ERR("Not find device\n");
return false;
}
/* create socket */
struct tpsocket_handler storage_stream_to_cloud = {
.cb = tpsocket_event_storage_stream_to_cloud,
.cer = MEDIACENTER_CERTFILE,
.write_buf_max = STORAGE_MEMORY_CACHE_LIMIT,
};
storage_session->retry_count++;
if ((storage_session->sock = tpsocket_from_url(dev_info->relay_storage_url, &storage_stream_to_cloud))) {
//if (storage_session->sock = tpsocket_from_url("http://192.168.137.103:8010", &storage_stream_to_cloud)) {
DBG_DBG("Create session sock = %p, session = %p\n", storage_session->sock, storage_session);
storage_session->sock->handler.priv = storage_session;
storage_session->uploading_flag = 1;
storage_session_set_push_status(storage_session, 1);
}
return true;
}
bool storage_start_read(STORAGE_SESSION *storage_session)
{
if (!storage_session) {
DBG_ERR("arg NULL\n");
return false;
}
struct tpsocket_handler client = {
.cb = storage_read_file,
.flowcontrol = 10*1024,
.priv = storage_session,
.read_buf_max = STORAGE_MEMORY_CACHE_LIMIT,
};
if (STORAGE_STREAMING == storage_session->storage_type) {
storage_session->file = tpsocket_new(NULL, "stream", NULL, storage_session->stream_path, TPSOCKET_TYPE_FILE, &client);
if (!storage_session->file) {
DBG_ERR("open %s failed\n", storage_session->stream_path);
return false;
}
}
else {
storage_session->file = tpsocket_new(NULL, "read", NULL, storage_session->snapshot_path, TPSOCKET_TYPE_FILE, &client);
if (!storage_session->file) {
DBG_ERR("open %s failed\n", storage_session->snapshot_path);
return false;
}
}
DBG_DBG("session = %p, sock = %p, open file = %p\n", storage_session, storage_session->sock, storage_session->file);
return true;
}bool storage_read_file(struct tpsocket_handler*handler, struct list_head*buf, int event)
{
STORAGE_SESSION *storage_session = handler->priv;
//MYDEBUG("storage read file event = %s, sock = %p, consumer = %p\n", tpsocket_event_name(event), sock, storage_session);
switch(event) {
case TPSOCKET_EVENT_CONNECTED:
break;
case TPSOCKET_EVENT_REQ_HEAD:
break;
case TPSOCKET_EVENT_RSP_HEAD:
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_SUB_HEAD:
case TPSOCKET_EVENT_STREAM:
case TPSOCKET_EVENT_MESSAGE:
if (false == storage_file_produce(storage_session, buf)) {
return false;
}
goto out;
//break;
case TPSOCKET_EVENT_RESET:
break;
case TPSOCKET_EVENT_CLOSED:
if (storage_session) {
storage_session->file = NULL;
if (storage_session->sock) {
if (!list_empty(buf)) {
if (storage_session->chunked) {
tpsocket_chunk_encode(buf);
tpsocket_write_list_force(storage_session->sock, buf, true);
}
}
if (STORAGE_STREAMING == storage_session->storage_type) {
storage_session_stream_add_tail(storage_session);
}
else {
storage_session_snapshot_add_tail(storage_session);
}
}
}
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
out:
return true;
}bool storage_file_produce(STORAGE_SESSION *storage_session, struct list_head *buf)
{
if (!storage_session) {
DBG_ERR("arg NULL\n");
return false;
}
if (!storage_session->sock) {
DBG_ERR("%p arg NULL, file = %p\n", storage_session, storage_session->file);
return false;
}
if (tpsocket_writable(storage_session->sock)) {
if (!list_empty(buf) && storage_session->chunked && !tpsocket_chunk_encode(buf)) {
tpsocket_free_buf(buf, "PRODUCE", 0);
return false;
}
storage_session_write_list_force(storage_session, buf, true);
}
return true;
}typedef struct _STORAGE_SESSION_ {
struct list_head list;
struct list_head headers;
struct tpsocket_fd *sock;
struct tpsocket_fd *file;
int store;
int chunked;
int ts_encoded;
int stream;
bool storage_success;
char dev_id[LEN_MAX_ID];
char dev_ip[LEN_MAX_ID];
char host[LEN_MAX_HOST];
char cookie[LEN_MAX_COOKIE];
char xtoken[LEN_MAX_TOKEN];
char event_id[LEN_MAX_EVENT_ID];
time_t event_timestamp;
enum EVENT_TYPE event_type;
int count_id;
int region_buf_len;
char region_buf[LEN_MAX_128*4];
int storage_type;
int content_len;
char snapshot_path[LEN_MAX_PATH];
char stream_path[LEN_MAX_PATH];
bool stream_send_to_cloud_flag;
bool snapshot_send_to_cloud_flag;
bool uploading_flag;
bool delete_flag;
int retry_count;
int post_success;
//
unsigned long long reupload_total_load;
unsigned long long reupload_last_load;
unsigned long long reupload_last_sent;
int reupload_idle_time;
struct uloop_timeout reupload_tmo;
void *producer;
void *iot_consumer;
STORAGE_SERVER *storage_server;
} STORAGE_SESSION; 参考这个代码重新帮我实现日志的读写功能。