forked from SiliconLabs/cpc-daemon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
167 lines (131 loc) · 4.89 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/***************************************************************************//**
* @file
* @brief Co-Processor Communication Protocol(CPC) - Main
*******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#define _GNU_SOURCE
#include <pthread.h>
#include <stdbool.h>
#include <stddef.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/time.h>
#include "cpcd/exit.h"
#include "cpcd/config.h"
#include "cpcd/logging.h"
#include "cpcd/modes.h"
#include "cpcd/security.h"
#include "cpcd/server_core.h"
#include "version.h"
#include "driver/driver_kill.h"
#include "server_core/epoll/epoll.h"
pthread_t main_thread; // Current thread
/* Global copy of argv to be able to restart the daemon with the same arguments. */
char **argv_g = 0;
int argc_g = 0;
int main(int argc, char *argv[])
{
argc_g = argc;
argv_g = argv;
bool secondary_already_running_bootloader = false;
main_thread = pthread_self();
pthread_setname_np(main_thread, "cpcd");
/* Setup crash and graceful exit signaling */
exit_init(main_thread);
epoll_init();
logging_init();
PRINT_INFO("[CPCd v%s] [Library API v%d] [RCP Protocol v%d]", PROJECT_VER, LIBRARY_API_VERSION, PROTOCOL_VERSION);
PRINT_INFO("Git commit: %s / branch: %s", GIT_SHA1, GIT_REFSPEC);
PRINT_INFO("Sources hash: %s", SOURCES_HASH);
if (geteuid() == 0) {
WARN("Running CPCd as 'root' is not recommended. Proceed at your own risk.");
}
config_init(argc, argv);
#if !defined(ENABLE_ENCRYPTION)
PRINT_INFO("\033[31;1mENCRYPTION IS DISABLED \033[0m");
#else
if (config.use_encryption == false) {
PRINT_INFO("\033[31;1mENCRYPTION IS DISABLED \033[0m");
}
#endif
if (config.reset_sequence) {
secondary_already_running_bootloader = is_bootloader_running();
}
if (secondary_already_running_bootloader) {
PRINT_INFO("The bootloader has been detected to be currently running on the secondary. This can be caused by :");
PRINT_INFO("- A secondary which only has the bootloader flashed and no CPC application.");
PRINT_INFO("- A previously failed firmware upgrade.");
PRINT_INFO("- A previous daemon invocation with -e parameter (to put the secondary in bootloader mode and exit).");
}
switch (config.operation_mode) {
case MODE_NORMAL:
PRINT_INFO("Starting daemon in normal mode");
if (secondary_already_running_bootloader) {
FATAL("Cannot run CPCd in normal mode because the bootloader is currently running on the secondary.");
}
run_normal_mode();
break;
case MODE_BINDING_PLAIN_TEXT:
#if defined(ENABLE_ENCRYPTION)
PRINT_INFO("Starting daemon in plain text binding mode");
if (secondary_already_running_bootloader) {
FATAL("Cannot run CPCd in binding plain-text mode because the bootloader is currently running on the secondary.");
}
run_binding_mode();
#else
FATAL("Tried to initiate binding mode with encryption disabled");
#endif
break;
case MODE_BINDING_ECDH:
#if defined(ENABLE_ENCRYPTION)
PRINT_INFO("Starting daemon in ECDH binding mode");
if (secondary_already_running_bootloader) {
FATAL("Cannot run CPCd in binding ECDH mode because the bootloader is currently running on the secondary.");
}
run_binding_mode();
#else
FATAL("Tried to initiate binding mode with encryption disabled");
#endif
break;
case MODE_BINDING_UNBIND:
#if defined(ENABLE_ENCRYPTION)
PRINT_INFO("Starting daemon in unbind mode");
if (secondary_already_running_bootloader) {
FATAL("Cannot run CPCd in unbind mode because the bootloader is currently running on the secondary.");
}
run_binding_mode();
#else
FATAL("Tried to unbind with encryption disabled");
#endif
break;
case MODE_FIRMWARE_UPDATE:
PRINT_INFO("Starting daemon in firmware update mode");
run_firmware_update();
break;
case MODE_UART_VALIDATION:
PRINT_INFO("Starting daemon in UART validation mode");
if (secondary_already_running_bootloader) {
FATAL("Cannot run CPCd in UART validation mode because the bootloader is currently running on the secondary.");
}
run_uart_validation();
break;
default:
BUG();
break;
}
return 0;
}