forked from Rajaram-Regupathy/libtypec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libtypec.c
303 lines (267 loc) · 8.94 KB
/
libtypec.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*
MIT License
Copyright (c) 2022 Rajaram Regupathy <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// SPDX-License-Identifier: MIT
/**
* @file libtypec.c
* @author Rajaram Regupathy <[email protected]>
* @brief Core functions for libtypec
*/
#include <linux/magic.h>
#include <linux/types.h>
#include <sys/statfs.h>
#include "libtypec_ops.h"
#include <sys/utsname.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
static int sysfs_method = 0;
static char ver_buf[64];
static struct utsname ker_uname;
static const struct libtypec_os_backend *cur_libtypec_os_backend;
/**
* \mainpage libtypec 0.1 API Reference
*
* \section intro Introduction
*
* Existing USB-Type C and USB Power Delivery solutions, platform
* designs vary because of USB PD Specification versions, Vendor
* specific host interface and division in the protocol stack/policy
* management across the software layers. This necessitates tools and
* applications that enable efficient port management and allows end
* users to root cause/debug system issues.
*
* Existing TypeC class ABI is tied up between 1) Multiple Interface
* Protocols 2) Need for OS level PD policy for System level management
* against the static PD policy.
*
* Multiple Interface Protocols :
*
* Adding to this complexity is the multiple specification versions and
* platform designs there are different interface protocols ( PD Host
* Interface, UCSI, CrOS EC, TCPC) that provide inconsistent information
* to the TypeC Class ABI or hold additional design specific hooks. This
* necessitates an abstraction that provides a transparent interface to
* user space software.
*
* Static Capabilities:
*
* With policy management defined as implementation specific by USB-C and
* USB PD specifications, implementation of these policies are scattered
* in different platform drivers or firmware modules. This necessitates a
* common interface across all designs that allows management of port
* policy.
*
* “libtypec” is aimed to provide a generic interface abstracting all
* platform complexity for user space to develop tools for efficient USB-C
* port management and efficient diagnostic and debugging tools to debug of
* system issues around USB-C/USB PD topology.
*
* The data structures and interface APIs would match closer to USB Type-C®
* Connector System Software Interface (UCSI) Specification.
*
*/
char *get_kernel_verion(void)
{
if (uname(&ker_uname) != 0)
return 0;
else
return ker_uname.release;
}
char *get_os_name(void)
{
FILE *fp = fopen("/etc/os-release", "r");
static char buf[128];
char *p = NULL;
if (fp)
{
while (fgets(buf, sizeof(buf), fp))
{
char *ptr;
/* Ensure buffer always has eos marker at end */
buf[sizeof(buf) - 1] = '\0';
/* Remove \n */
for (ptr = buf; *ptr && *ptr != '\n'; ptr++)
;
*ptr = '\0';
if (strncmp(buf, "ID=", 3) == 0) {
p = buf + 3;
break;
}
}
fclose(fp);
}
return p;
}
/**
* This function initializes libtypec and must be called before
* calling any other libtypec function.
*
* The function is responsible for setting up the backend interface and
* also provides necessary platform session information
*
* \param Array of platform session strings
*
* \returns 0 on success
*/
int libtypec_init(char **session_info)
{
int ret;
struct statfs sb;
sprintf(ver_buf, "libtypec %d.%d", LIBTYPEC_MAJOR_VERSION, LIBTYPEC_MINOR_VERSION);
session_info[LIBTYPEC_VERSION_INDEX] = ver_buf;
session_info[LIBTYPEC_KERNEL_INDEX] = get_kernel_verion();
session_info[LIBTYPEC_OS_INDEX] = get_os_name();
ret = statfs(SYSFS_TYPEC_PATH, &sb);
if (ret == 0 && sb.f_type == SYSFS_MAGIC)
{
sysfs_method = 1;
cur_libtypec_os_backend = &libtypec_lnx_sysfs_backend;
ret = cur_libtypec_os_backend->init(session_info);
}
return ret;
}
/**
* This function must be called before exiting libtypec session to perform
* cleanup.
*
* \param
*
* \returns 0 on success
*/
int libtypec_exit(void)
{
/* clear session info */
return cur_libtypec_os_backend->exit();
}
/**
* This function shall be used to get the platform policy capabilities
*
* \param cap_data Data structure to hold platform capability
*
* \returns 0 on success
*/
int libtypec_get_capability(struct libtypec_capabiliy_data *cap_data)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_capability_ops(cap_data);
}
/**
* This function shall be used to get the capabilities of a connector
*
* \param conn_num Indicates which connector's capability needs to be retrieved
*
* \param conn_cap_data Data structure to hold connector capability
*
* \returns 0 on success
*/
int libtypec_get_conn_capability(int conn_num, struct libtypec_connector_cap_data *conn_cap_data)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_conn_capability_ops(conn_num, conn_cap_data);
}
/**
* This function shall be used to get the Alternate Modes that the Connector/
* Cable/Attached Device is capable of supporting.
*
* \param recipient Represents alternate mode to be retrieved from local
* or SOP or SOP' or SOP"
*
* \param conn_num Indicates which connector's capability needs to be retrivied
*
* \returns number of alternate modes on success
*/
int libtypec_get_alternate_modes(int recipient, int conn_num, struct altmode_data *alt_mode_data)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_alternate_modes(recipient, conn_num, alt_mode_data);
}
/**
* This function shall be used to get the Cable Property of a connector
*
* \param conn_num Indicates which connector's status needs to be retrieved
*
* \returns 0 on success
*/
int libtypec_get_cable_properties(int conn_num, struct libtypec_cable_property *cbl_prop_data)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_cable_properties_ops(conn_num, cbl_prop_data);
}
/**
* This function shall be used to get the Connector status
*
* \param conn_num Indicates which connector's status needs to be retrieved
*
* \returns 0 on success
*/
int libtypec_get_connector_status(int conn_num, struct libtypec_connector_status *conn_sts)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_connector_status_ops(conn_num, conn_sts);
}
/**
* This function shall be used to get the USB PD response messages from
*
* \param recipient Represents PD response message to be retrieved from local
* or SOP or SOP' or SOP"
*
* \param conn_num Indicates which connector's PD message needs to be retrieved
*
* \param pd_msg_resp
* \returns 0 on success
*/
int libtypec_get_pd_message(int recipient, int conn_num, int num_bytes, int resp_type, char *pd_msg_resp)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_pd_message_ops(recipient, conn_num, num_bytes, resp_type, pd_msg_resp);
}
/**
* This function shall be used to get PDOs from local and partner Policy Managers
*
* \param conn_num Represents connector to be queried
*
* \param partner Set to TRUE to retrieve partner PDOs
*
* \param offset Index from which PDO needs to be retrieved
*
* \param num_pdo Represents number of PDOs to be retrieved
*
* \param src_snk Set to TRUE to retrieve Source PDOs
*
* \param type Represents type of Source PDOs requested
*
* \param pdo_data Holds PDO data retrieved
*
* \returns PDO retrieved on success
*/
int libtypec_get_pdos (int conn_num, int partner, int offset, int *num_pdo, int src_snk, int type, unsigned int *pdo_data)
{
if (!cur_libtypec_os_backend)
return -EIO;
return cur_libtypec_os_backend->get_pdos_ops(conn_num, partner, offset, num_pdo, src_snk, type, pdo_data);
}