1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "openthread-posix-config.h"
30 #include "platform-posix.h"
31 
32 #include <assert.h>
33 #include <fcntl.h>
34 #include <setjmp.h>
35 #include <sys/socket.h>
36 #include <unistd.h>
37 
38 #include <openthread/logging.h>
39 #include <openthread/platform/misc.h>
40 
41 #include "common/code_utils.hpp"
42 
43 otPlatResetReason          gPlatResetReason   = OT_PLAT_RESET_REASON_POWER_ON;
44 static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
45 
otPlatGetResetReason(otInstance * aInstance)46 otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
47 {
48     OT_UNUSED_VARIABLE(aInstance);
49 
50     return gPlatResetReason;
51 }
52 
otPlatWakeHost(void)53 void otPlatWakeHost(void)
54 {
55     // TODO: implement an operation to wake the host from sleep state.
56 }
57 
otPlatSetMcuPowerState(otInstance * aInstance,otPlatMcuPowerState aState)58 otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
59 {
60     OT_UNUSED_VARIABLE(aInstance);
61 
62     otError error = OT_ERROR_NONE;
63 
64     switch (aState)
65     {
66     case OT_PLAT_MCU_POWER_STATE_ON:
67     case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
68         gPlatMcuPowerState = aState;
69         break;
70 
71     default:
72         error = OT_ERROR_FAILED;
73         break;
74     }
75 
76     return error;
77 }
78 
otPlatAssertFail(const char * aFilename,int aLineNumber)79 void otPlatAssertFail(const char *aFilename, int aLineNumber)
80 {
81 #if OPENTHREAD_CONFIG_LOG_PLATFORM && OPENTHREAD_CONFIG_LOG_LEVEL < OT_LOG_LEVEL_CRIT
82     OT_UNUSED_VARIABLE(aFilename);
83     OT_UNUSED_VARIABLE(aLineNumber);
84 #else
85     otLogCritPlat("assert failed at %s:%d", aFilename, aLineNumber);
86 #endif
87     // For debug build, use assert to generate a core dump
88     assert(false);
89     exit(1);
90 }
91 
otPlatGetMcuPowerState(otInstance * aInstance)92 otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
93 {
94     OT_UNUSED_VARIABLE(aInstance);
95 
96     return gPlatMcuPowerState;
97 }
98 
SocketWithCloseExec(int aDomain,int aType,int aProtocol,SocketBlockOption aBlockOption)99 int SocketWithCloseExec(int aDomain, int aType, int aProtocol, SocketBlockOption aBlockOption)
100 {
101     int rval = 0;
102     int fd   = -1;
103 
104 #ifdef __APPLE__
105     VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
106 
107     VerifyOrExit((rval = fcntl(fd, F_GETFD, 0)) != -1, perror("fcntl(F_GETFD)"));
108     rval |= aBlockOption == kSocketNonBlock ? O_NONBLOCK | FD_CLOEXEC : FD_CLOEXEC;
109     VerifyOrExit((rval = fcntl(fd, F_SETFD, rval)) != -1, perror("fcntl(F_SETFD)"));
110 #else
111     aType |= aBlockOption == kSocketNonBlock ? SOCK_CLOEXEC | SOCK_NONBLOCK : SOCK_CLOEXEC;
112     VerifyOrExit((fd = socket(aDomain, aType, aProtocol)) != -1, perror("socket(SOCK_CLOEXEC)"));
113 #endif
114 
115 exit:
116     if (rval == -1)
117     {
118         VerifyOrDie(close(fd) == 0, OT_EXIT_ERROR_ERRNO);
119         fd = -1;
120     }
121 
122     return fd;
123 }
124