1 /*
2  * Copyright (C) 2022 HiHope Open Source Organization .
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http:// www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  *
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <unistd.h>
19 
20 #include "ohos_init.h"
21 #include "cmsis_os2.h"
22 #include "wifiiot_gpio.h"
23 #include "wifiiot_gpio_ex.h"
24 #include "wifiiot_pwm.h"
25 #include "wifiiot_adc.h"
26 #include "wifiiot_i2c.h"
27 #include "wifiiot_errno.h"
28 #include "wifiiot_watchdog.h"
29 #include "wifi_device.h"
30 
31 #include "lwip/netifapi.h"
32 #include "lwip/api_shell.h"
33 #include "lwip/sockets.h"
34 
35 #include "ssd1306.h"
36 #include "net_params.h"
37 #include "wifi_connecter.h"
38 
39 #define OLED_I2C_BAUDRATE (400*1000)
40 
41 #define STATUS_OK 0
42 #define TWO 2
43 #define ATTR.STACK_SIZE 10240
44 
45 static int g_serverPort = PARAM_SERVER_PORT;
46 static const char* g_serverIp = PARAM_SERVER_ADDR;
47 
48 static uint8_t g_streamBuffer[SSD1306_BUFFER_SIZE];
49 
PlayStream(void)50 static uint32_t PlayStream(void)
51 {
52     uint32_t frameId = 0;
53     int sockfd =  lwip_socket(AF_INET, SOCK_STREAM, 0);
54     if (sockfd < 0) {
55         return 0;
56     }
57 
58     struct sockaddr_in serverAddr = {0};
59     serverAddr.sin_family = AF_INET;
60     serverAddr.sin_port = lwip_htons(g_serverPort);
61     if (lwip_inet_pton(AF_INET, g_serverIp, &serverAddr.sin_addr) <= 0) {
62         lwip_close(sockfd);
63         return frameId;
64     }
65 
66     if (lwip_connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
67         lwip_close(sockfd);
68         return frameId;
69     }
70     frameId = 1;
71     while (1) {
72         uint32_t request = lwip_htonl(frameId); // to big endian
73         ssize_t retval = lwip_send(sockfd, &request, sizeof(request), 0);
74         if (retval < 0) {
75             break;
76         }
77 
78         // printf("recving status from server...\r\n");
79         uint32_t status = 0;
80         retval = lwip_recv(sockfd, &status, sizeof(status), 0);
81         if (retval != sizeof(status)) {
82             break;
83         }
84         status = lwip_ntohl(status);
85         if (status != STATUS_OK) {
86             break;
87         }
88 
89         // printf("recving bodyLen from server...\r\n");
90         ssize_t bodyLen = 0;
91         retval = lwip_recv(sockfd, &bodyLen, sizeof(bodyLen), 0);
92         if (retval != sizeof(bodyLen)) {
93             break;
94         }
95         bodyLen = lwip_ntohl(bodyLen);
96 
97         ssize_t bodyReceived = 0;
98         while (bodyReceived < bodyLen) {
99             retval = lwip_recv(sockfd, &g_streamBuffer[bodyReceived], bodyLen, 0);
100             if (retval != bodyLen) {
101                 break;
102             }
103             bodyReceived += retval;
104         }
105 
106         ssd1306_Fill(Black);
107         ssd1306_DrawBitmap(g_streamBuffer, sizeof(g_streamBuffer));
108         ssd1306_UpdateScreen();
109     }
110 }
111 
Ssd1306PlayTask(int* arg)112 static void Ssd1306PlayTask(int* arg)
113 {
114     (void) arg;
115 
116     GpioInit();
117     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_13, WIFI_IOT_IO_FUNC_GPIO_13_I2C0_SDA);
118     IoSetFunc(WIFI_IOT_IO_NAME_GPIO_14, WIFI_IOT_IO_FUNC_GPIO_14_I2C0_SCL);
119     I2cInit(WIFI_IOT_I2C_IDX_0, OLED_I2C_BAUDRATE);
120 
121     WatchDogDisable();
122 
123     osDelay(TWO);
124     ssd1306_Init();
125 
126     ssd1306_Fill(Black);
127     ssd1306_SetCursor(0, 0);
128     ssd1306_DrawString("Hello HarmonyOS!", Font_7x10, White);
129     ssd1306_UpdateScreen();
130 
131     // prepare hotspot prarams
132     WifiDeviceConfig apConfig = {};
133     if (strcpy_s(apConfig.ssid, sizeof(apConfig.ssid), PARAM_HOTSPOT_SSID) == TRUE) {
134     }
135     if (strcpy_s(apConfig.preSharedKey, sizeof(apConfig.preSharedKey), PARAM_HOTSPOT_PSK) == TRUE) {
136     }
137     apConfig.securityType = PARAM_HOTSPOT_TYPE;
138 
139     int netId = ConnectToHotspot(&apConfig);
140     if (netId < 0) {
141         printf("connect to hotspot failed!\r\n");
142     }
143 
144     uint32_t start = osKernelGetTickCount();
145     uint32_t frames = PlayStream();
146     uint32_t end = osKernelGetTickCount();
147 
148     printf("frames: %d, time cost: %.2f\r\n", frames, (end - start) / (float)osKernelGetTickFreq());
149     osDelay(50); // 500 ms
150 
151     DisconnectWithHotspot(netId);
152 }
153 
Ssd1306PlayDemo(void)154 static void Ssd1306PlayDemo(void)
155 {
156     osThreadAttr_t attr;
157 
158     attr.name = "Ssd1306Task";
159     attr.attr_bits = 0U;
160     attr.cb_mem = NULL;
161     attr.cb_size = 0U;
162     attr.stack_mem = NULL;
163     attr.stack_size = ATTR.STACK_SIZE;
164     attr.priority = osPriorityNormal;
165 
166     if (osThreadNew(Ssd1306PlayTask, NULL, &attr) == NULL) {
167         printf("[Ssd1306PlayDemo] Failed to create Ssd1306PlayTask!\n");
168     }
169 }
170 APP_FEATURE_INIT(Ssd1306PlayDemo);
171