1 /*
2  * Copyright (C) 2021-2023 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 #include "ulog/ulog.h"
8 #include "aos/kernel.h"
9 #include "ucamera_service.h"
10 #include <httpclient.h>
11 #include "wifi_camera.h"
12 // #include <aiconfig.h>
13 
14 /*Tested this program with esp32 eye*/
15 
16 #define TAG "WIFI_CAMERA"
17 
18 #define HEAD_SIZE 2048
19 #define BODY_SZIE (1024 * 128 + 1)
20 
21 static httpclient_t wifi_camera_client = { 0 };
22 static httpclient_data_t wifi_camera_client_data = {0};
23 
wifi_camera_delete(ucamera_device_t * dev)24 static void wifi_camera_delete(ucamera_device_t *dev)
25 {
26     free(dev);
27 }
28 
wifi_camera_device_available(void)29 static bool wifi_camera_device_available(void)
30 {
31     return true;
32 }
33 
wifi_camera_init(ucamera_device_t * dev)34 int32_t wifi_camera_init(ucamera_device_t *dev)
35 {
36     int32_t ret;
37     char *customer_header = "Accept: */*\r\n";
38 
39     ret = httpclient_prepare(&wifi_camera_client_data, HEAD_SIZE, BODY_SZIE);
40     if (ret != HTTP_SUCCESS)
41         return -1;
42 
43     wifi_camera_client.is_http = true;
44     httpclient_set_custom_header(&wifi_camera_client, customer_header);
45 
46     LOG("wifi camera init done\n");
47     return ret;
48 }
49 
wifi_camera_uninit(ucamera_device_t * dev)50 int32_t wifi_camera_uninit(ucamera_device_t *dev)
51 {
52     int32_t ret;
53 
54     ret = httpclient_unprepare(&wifi_camera_client_data);
55     return ret;
56 }
57 
wifi_camera_connect(ucamera_device_t * dev)58 int32_t wifi_camera_connect(ucamera_device_t *dev)
59 {
60     int32_t ret;
61 
62     ret = httpclient_conn(&wifi_camera_client, (const char *)WIFICAMERA_URL);
63     if (HTTP_SUCCESS != ret) {
64         LOGE(TAG, "http connect failed");
65         return -1;
66     }
67 
68     LOG("connect to wifi camera successfully\n");
69     return ret;
70 }
71 
wifi_camera_disconnect(ucamera_device_t * dev)72 void wifi_camera_disconnect(ucamera_device_t *dev)
73 {
74     if (!dev)
75         return;
76 
77     httpclient_clse(&wifi_camera_client);
78     LOG("disconnect to wifi camera successfully\n");
79 }
80 
wifi_camera_get_frame(ucamera_device_t * dev)81 frame_buffer_t *wifi_camera_get_frame(ucamera_device_t *dev)
82 {
83     int ret;
84 
85     if (!dev)
86         return NULL;
87 
88     httpclient_reset(&wifi_camera_client_data);
89     ret = httpclient_send(&wifi_camera_client, (const char *)WIFICAMERA_URL, HTTP_GET, &wifi_camera_client_data);
90     if (HTTP_SUCCESS != ret) {
91         LOGE(TAG, "http send request failed");
92         return NULL;
93     }
94 
95     do {
96         ret = httpclient_recv(&wifi_camera_client, &wifi_camera_client_data);
97         if (ret < 0) {
98             dev->stream_buf = NULL;
99             dev->stream_len = 0;
100             break;
101         }
102         dev->stream_buf = wifi_camera_client_data.response_buf;
103         dev->stream_len = wifi_camera_client_data.response_content_len;
104     } while (ret == HTTP_EAGAIN);
105 
106     /*malloc frame*/
107     dev->frame.buf = dev->stream_buf;
108     dev->frame.len = dev->stream_len;
109     dev->frame.width = WIFI_CAMERA_FRAME_WIDTH;
110     dev->frame.height = WIFI_CAMERA_FRAME_HEIGHT;
111     dev->frame.format = FRAME_FORMAT_RGB565;
112 
113     return &dev->frame;
114 }
115 
wifi_camera_device_create(int devindex)116 static ucamera_device_t *wifi_camera_device_create(int devindex)
117 {
118     ucamera_device_t *device = NULL;
119 
120     /* Initialize all variables that we clean on shutdown */
121     device = (ucamera_device_t *) malloc(sizeof(ucamera_device_t));
122     if (!device) {
123         LOGE(TAG, "malloc camera device fail\n");
124         return 0;
125     }
126     device->is_dummy = false;
127     device->width = WIFI_CAMERA_FRAME_WIDTH;
128     device->height = WIFI_CAMERA_FRAME_HEIGHT;
129 
130     /* Set the function pointers */
131     device->camera_init = wifi_camera_init;
132     device->camera_uninit = wifi_camera_uninit;
133     device->camera_connect = wifi_camera_connect;
134     device->camera_disconnect = wifi_camera_disconnect;
135     device->camera_get_frame = wifi_camera_get_frame;
136     device->camera_free = wifi_camera_delete;
137 
138     LOG("create camera device successfully\n");
139     return device;
140 }
141 
142 ucamera_context_t wifi_camera = {
143     WIFI_CAMERA_NAME, "http camera stream over wifi",
144     wifi_camera_device_available, wifi_camera_device_create
145 };
146