1 /*
2  * Copyright (c) 2020 Manivannan Sadhasivam <mani@kernel.org>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <zephyr.h>
9 
10 #include "lw_priv.h"
11 
12 #include <LoRaMac.h>
13 
14 static const char *const status2str[] = {
15 	[LORAMAC_STATUS_OK] = "OK",
16 	[LORAMAC_STATUS_BUSY] = "Busy",
17 	[LORAMAC_STATUS_SERVICE_UNKNOWN] = "Service unknown",
18 	[LORAMAC_STATUS_PARAMETER_INVALID] = "Parameter invalid",
19 	[LORAMAC_STATUS_FREQUENCY_INVALID] = "Frequency invalid",
20 	[LORAMAC_STATUS_DATARATE_INVALID] = "Datarate invalid",
21 	[LORAMAC_STATUS_FREQ_AND_DR_INVALID] = "Frequency or datarate invalid",
22 	[LORAMAC_STATUS_NO_NETWORK_JOINED] = "No network joined",
23 	[LORAMAC_STATUS_LENGTH_ERROR] = "Length error",
24 	[LORAMAC_STATUS_REGION_NOT_SUPPORTED] = "Region not supported",
25 	[LORAMAC_STATUS_SKIPPED_APP_DATA] = "Skipped APP data",
26 	[LORAMAC_STATUS_DUTYCYCLE_RESTRICTED] = "Duty-cycle restricted",
27 	[LORAMAC_STATUS_NO_CHANNEL_FOUND] = "No channel found",
28 	[LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND] = "No free channel found",
29 	[LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME] =
30 		"Busy beacon reserved time",
31 	[LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME] =
32 		"Busy ping-slot window time",
33 	[LORAMAC_STATUS_BUSY_UPLINK_COLLISION] = "Busy uplink collision",
34 	[LORAMAC_STATUS_CRYPTO_ERROR] = "Crypto error",
35 	[LORAMAC_STATUS_FCNT_HANDLER_ERROR] = "FCnt handler error",
36 	[LORAMAC_STATUS_MAC_COMMAD_ERROR] = "MAC command error",
37 	[LORAMAC_STATUS_CLASS_B_ERROR] = "ClassB error",
38 	[LORAMAC_STATUS_CONFIRM_QUEUE_ERROR] = "Confirm queue error",
39 	[LORAMAC_STATUS_MC_GROUP_UNDEFINED] = "Multicast group undefined",
40 	[LORAMAC_STATUS_ERROR] = "Unknown error",
41 };
42 
lorawan_status2str(unsigned int status)43 const char *lorawan_status2str(unsigned int status)
44 {
45 	if (status < ARRAY_SIZE(status2str)) {
46 		return status2str[status];
47 	} else {
48 		return "Unknown status!";
49 	}
50 }
51 
52 static const char *const eventinfo2str[] = {
53 	[LORAMAC_EVENT_INFO_STATUS_OK] = "OK",
54 	[LORAMAC_EVENT_INFO_STATUS_ERROR] = "Error",
55 	[LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT] = "Tx timeout",
56 	[LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT] = "Rx 1 timeout",
57 	[LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT] = "Rx 2 timeout",
58 	[LORAMAC_EVENT_INFO_STATUS_RX1_ERROR] = "Rx1 error",
59 	[LORAMAC_EVENT_INFO_STATUS_RX2_ERROR] = "Rx2 error",
60 	[LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL] = "Join failed",
61 	[LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED] = "Downlink repeated",
62 	[LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR] =
63 		"Tx DR payload size error",
64 	[LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL] = "Address fail",
65 	[LORAMAC_EVENT_INFO_STATUS_MIC_FAIL] = "MIC fail",
66 	[LORAMAC_EVENT_INFO_STATUS_MULTICAST_FAIL] = "Multicast fail",
67 	[LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED] = "Beacon locked",
68 	[LORAMAC_EVENT_INFO_STATUS_BEACON_LOST] = "Beacon lost",
69 	[LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND] = "Beacon not found",
70 };
71 
lorawan_eventinfo2str(unsigned int status)72 const char *lorawan_eventinfo2str(unsigned int status)
73 {
74 	if (status < ARRAY_SIZE(eventinfo2str)) {
75 		return eventinfo2str[status];
76 	} else {
77 		return "Unknown event!";
78 	}
79 }
80 
81 /*
82  * MAC status and Event status to Zephyr error code conversion.
83  * Direct mapping is not possible as statuses often indicate the domain from
84  * which the error originated rather than its cause or meaning. -EINVAL has been
85  * used as a general error code because those usually result from incorrect
86  * configuration.
87  */
88 static const int status2errno[] = {
89 	[LORAMAC_STATUS_BUSY] = -EBUSY,
90 	[LORAMAC_STATUS_SERVICE_UNKNOWN] = -ENOPROTOOPT,
91 	[LORAMAC_STATUS_PARAMETER_INVALID] = -EINVAL,
92 	[LORAMAC_STATUS_FREQUENCY_INVALID] = -EINVAL,
93 	[LORAMAC_STATUS_DATARATE_INVALID] = -EINVAL,
94 	[LORAMAC_STATUS_FREQ_AND_DR_INVALID] = -EINVAL,
95 	[LORAMAC_STATUS_NO_NETWORK_JOINED] = -ENOTCONN,
96 	[LORAMAC_STATUS_LENGTH_ERROR] = -EMSGSIZE,
97 	[LORAMAC_STATUS_REGION_NOT_SUPPORTED] = -EPFNOSUPPORT,
98 	[LORAMAC_STATUS_SKIPPED_APP_DATA] = -EMSGSIZE,
99 	[LORAMAC_STATUS_DUTYCYCLE_RESTRICTED] = -ECONNREFUSED,
100 	[LORAMAC_STATUS_NO_CHANNEL_FOUND] = -ENOTCONN,
101 	[LORAMAC_STATUS_NO_FREE_CHANNEL_FOUND] = -ENOTCONN,
102 	[LORAMAC_STATUS_BUSY_BEACON_RESERVED_TIME] = -EBUSY,
103 	[LORAMAC_STATUS_BUSY_PING_SLOT_WINDOW_TIME] = -EBUSY,
104 	[LORAMAC_STATUS_BUSY_UPLINK_COLLISION] = -EBUSY,
105 	[LORAMAC_STATUS_CRYPTO_ERROR] = -EINVAL,
106 	[LORAMAC_STATUS_FCNT_HANDLER_ERROR] = -EINVAL,
107 	[LORAMAC_STATUS_MAC_COMMAD_ERROR] = -EINVAL,
108 	[LORAMAC_STATUS_CLASS_B_ERROR] = -EINVAL,
109 	[LORAMAC_STATUS_CONFIRM_QUEUE_ERROR] = -EINVAL,
110 	[LORAMAC_STATUS_MC_GROUP_UNDEFINED] = -EINVAL,
111 };
112 
lorawan_status2errno(unsigned int status)113 const int lorawan_status2errno(unsigned int status)
114 {
115 	if (status < ARRAY_SIZE(status2errno) && status2errno[status] != 0) {
116 		return status2errno[status];
117 	} else {
118 		return status == LORAMAC_STATUS_OK ? 0 : -EINVAL;
119 	}
120 }
121 
122 static const int eventinfo2errno[] = {
123 	[LORAMAC_EVENT_INFO_STATUS_ERROR] = -EINVAL,
124 	[LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT] = -ETIMEDOUT,
125 	[LORAMAC_EVENT_INFO_STATUS_RX1_TIMEOUT] = -ETIMEDOUT,
126 	[LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT] = -ETIMEDOUT,
127 	[LORAMAC_EVENT_INFO_STATUS_RX1_ERROR] = -EINVAL,
128 	[LORAMAC_EVENT_INFO_STATUS_RX2_ERROR] = -EINVAL,
129 	[LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL] = -EINVAL,
130 	[LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED] = -ECONNRESET,
131 	[LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR] = -EMSGSIZE,
132 	[LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL] = -EACCES,
133 	[LORAMAC_EVENT_INFO_STATUS_MIC_FAIL] = -EACCES,
134 	[LORAMAC_EVENT_INFO_STATUS_MULTICAST_FAIL] = -EINVAL,
135 	[LORAMAC_EVENT_INFO_STATUS_BEACON_LOCKED] = -EINVAL,
136 	[LORAMAC_EVENT_INFO_STATUS_BEACON_LOST] = -EINVAL,
137 	[LORAMAC_EVENT_INFO_STATUS_BEACON_NOT_FOUND] = -EINVAL,
138 };
139 
lorawan_eventinfo2errno(unsigned int status)140 const int lorawan_eventinfo2errno(unsigned int status)
141 {
142 	if (status < ARRAY_SIZE(eventinfo2errno) &&
143 	    eventinfo2errno[status] != 0) {
144 		return eventinfo2errno[status];
145 	} else {
146 		return status == LORAMAC_EVENT_INFO_STATUS_OK ? 0 : -EINVAL;
147 	}
148 }
149