1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
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 * limitations under the License.
14 */
15
16 #include "hisysevent_easy.h"
17
18 #include <stddef.h>
19 #include <string.h>
20 #include <time.h>
21 #include <unistd.h>
22
23 #include "easy_def.h"
24 #include "easy_event_builder.h"
25 #include "easy_socket_writer.h"
26 #include "easy_util.h"
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 static const char CUSTOMIZED_PARAM_KEY[] = "DATA";
33 static const int SEC_2_MILLIS = 1000;
34 static const int MILLS_2_NANOS = 1000000;
35
GetTimestampnull36 static int64_t GetTimestamp()
37 {
38 struct timespec tp;
39 clock_gettime(CLOCK_REALTIME, &tp);
40 int64_t time = tp.tv_sec * SEC_2_MILLIS;
41 time += tp.tv_nsec / MILLS_2_NANOS;
42 return time;
43 }
44
ParseTimeZone(long tz)45 static uint8_t ParseTimeZone(long tz)
46 {
47 static long allTimeZones[] = {
48 3600, 7200, 10800, 11880, 14400, 18000, 21600,
49 25200, 28800, 32400, 33480, 36000, 39600, 43200,
50 0, -3600, -7200, -10800, -11880, -14400, 15480,
51 -18000, -19080, -19620, -21600, -22680, -25200, -28800,
52 -30420, -32400, -33480, -36000, -37080, -39600, -43200,
53 -44820, -46800, -50400
54 };
55 uint8_t ret = 14; // 14 is the index of "+0000" in array
56 for (uint8_t index = 0; index < (sizeof(allTimeZones) / sizeof(long)); ++index) {
57 if (allTimeZones[index] == tz) {
58 ret = index;
59 break;
60 }
61 }
62 return ret;
63 }
64
CheckEventType(uint8_t eventType)65 static int CheckEventType(uint8_t eventType)
66 {
67 if ((eventType < EASY_EVENT_TYPE_FAULT) || (eventType > EASY_EVENT_TYPE_BEHAVIOR)) {
68 return ERR_TYPE_INVALID;
69 }
70 return SUCCESS;
71 }
72
InitEventHeader(struct HiSysEventEasyHeader* header, const char* domain, const char* name, const uint8_t eventType)73 static int InitEventHeader(struct HiSysEventEasyHeader* header, const char* domain, const char* name,
74 const uint8_t eventType)
75 {
76 if ((MemoryCopy((uint8_t*)(header->domain), DOMAIN_ARRAY_LEN, (uint8_t*)domain, strlen(domain)) != SUCCESS) ||
77 (MemoryCopy((uint8_t*)(header->name), NAME_ARRAY_LEN, (uint8_t*)name, strlen(name)) != SUCCESS)) {
78 return ERR_MEM_OPT_FAILED;
79 }
80 header->type = eventType - 1; // only 2 bits to store event type
81 header->timestamp = GetTimestamp();
82 tzset();
83 header->timeZone = ParseTimeZone(timezone);
84 header->pid = (uint32_t)getpid();
85 header->tid = (uint32_t)gettid();
86 header->uid = (uint32_t)getuid();
87 header->isTraceOpened = 0; // no need to allocate memory for trace info.
88 return SUCCESS;
89 }
90
HiSysEventEasyWrite(const char* domain, const char* name, enum HiSysEventEasyType eventType, const char* data)91 int HiSysEventEasyWrite(const char* domain, const char* name, enum HiSysEventEasyType eventType, const char* data)
92 {
93 if ((domain == NULL) || (strlen(domain) > MAX_DOMAIN_LENGTH)) {
94 return ERR_DOMAIN_INVALID;
95 }
96 if ((name == NULL) || (strlen(name) > MAX_EVENT_NAME_LENGTH)) {
97 return ERR_NAME_INVALID;
98 }
99 int ret = CheckEventType(eventType);
100 if (ret != SUCCESS) {
101 return ret;
102 }
103 uint8_t eventBuffer[EVENT_BUFF_LEN] = { 0 };
104 size_t offset = 0;
105 // applend block size
106 *((int32_t*)eventBuffer) = EVENT_BUFF_LEN;
107 offset += sizeof(int32_t);
108 // append header, only two bits to store event type in memory
109 struct HiSysEventEasyHeader header;
110 ret = MemoryInit((uint8_t*)(&header), sizeof(struct HiSysEventEasyHeader));
111 if (ret != SUCCESS) {
112 return ret;
113 }
114 ret = InitEventHeader(&header, domain, name, eventType);
115 if (ret != SUCCESS) {
116 return ret;
117 }
118 ret = AppendHeader(eventBuffer, EVENT_BUFF_LEN, &offset, &header);
119 if (ret != SUCCESS) {
120 return ret;
121 }
122 // append param count, only one cutomized parameter
123 if (offset + sizeof(int32_t) > EVENT_BUFF_LEN) {
124 return ERR_EVENT_BUF_INVALID;
125 }
126 *((int32_t*)(eventBuffer + offset)) = 1;
127 offset += sizeof(int32_t);
128 ret = AppendStringParam(eventBuffer, EVENT_BUFF_LEN, &offset, CUSTOMIZED_PARAM_KEY, data);
129 if (ret != SUCCESS) {
130 return ret;
131 }
132 // write event to socket
133 ret = Write(eventBuffer, EVENT_BUFF_LEN);
134 if (ret != SUCCESS) {
135 return ret;
136 }
137 return SUCCESS;
138 }
139
140 #ifdef __cplusplus
141 }
142 #endif