├── Samples
└── CurlEasyHttps
│ ├── CurlEasyHttps
│ ├── applibs_versions.h
│ ├── app_manifest.json
│ ├── certs
│ │ └── DigiCertHighAssuranceEVRootCA.pem
│ ├── CurlEasyHttps.vcxproj.filters
│ ├── epoll_timerfd_utilities.h
│ ├── CurlEasyHttps.vcxproj
│ ├── epoll_timerfd_utilities.c
│ ├── mt3620_rdb.h
│ └── main.c
│ └── CurlEasyHttps.sln
├── LICENSE
├── README.md
└── .gitignore
/Samples/CurlEasyHttps/CurlEasyHttps/applibs_versions.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | // This header defines which struct versions will be used for applibs APIs.
3 | #define WIFICONFIG_STRUCTS_VERSION 1
4 | #define UART_STRUCTS_VERSION 1
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/app_manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "SchemaVersion": 1,
3 | "Name" : "CurlEasyHttps",
4 | "ComponentId" : "011b3254-6b4e-4af1-bc81-22e7f677f4bf",
5 | "EntryPoint": "/bin/app",
6 | "CmdArgs": [],
7 | "TargetApplicationRuntimeVersion": 1,
8 | "Capabilities": {
9 | "AllowedConnections": [ "example.com" ],
10 | "Gpio": [ 8 ],
11 | "Uart": [],
12 | "WifiConfig": false
13 | }
14 | }
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28105.52
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CurlEasyHttps", "CurlEasyHttps\CurlEasyHttps.vcxproj", "{74BC727B-6B7D-48E1-B600-6296320BC17E}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM = Debug|ARM
11 | Release|ARM = Release|ARM
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {74BC727B-6B7D-48E1-B600-6296320BC17E}.Debug|ARM.ActiveCfg = Debug|ARM
15 | {74BC727B-6B7D-48E1-B600-6296320BC17E}.Debug|ARM.Build.0 = Debug|ARM
16 | {74BC727B-6B7D-48E1-B600-6296320BC17E}.Release|ARM.ActiveCfg = Release|ARM
17 | {74BC727B-6B7D-48E1-B600-6296320BC17E}.Release|ARM.Build.0 = Release|ARM
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {E48DFA9C-552D-4B6A-B07B-F10609A588E3}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/certs/DigiCertHighAssuranceEVRootCA.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
3 | MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
4 | d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
5 | ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
6 | MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
7 | LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
8 | RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
9 | +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
10 | PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
11 | xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
12 | Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
13 | hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
14 | EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
15 | MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
16 | FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
17 | nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
18 | eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
19 | hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
20 | Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
21 | vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
22 | +OkuE6N36B9K
23 | -----END CERTIFICATE-----
24 |
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/CurlEasyHttps.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Header Files
23 |
24 |
25 |
26 | Source Files
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Header Files
35 |
36 |
37 | Header Files
38 |
39 |
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Azure Sphere Samples
3 | This repository contains samples for the [Azure Sphere platform](https://www.microsoft.com/azure-sphere/).
4 |
5 | ## Using the samples
6 | See the [Azure Sphere Getting Started](https://www.microsoft.com/en-us/azure-sphere/get-started/) page for details on getting an [Azure Sphere Development kit](https://aka.ms/AzureSpheredevkits) and setting up your PC for development. You should complete the Azure Sphere [Installation](https://docs.microsoft.com/azure-sphere/install/overview) and [Quickstarts](https://docs.microsoft.com/azure-sphere/quickstarts/qs-overview) to validate that your environment is configured properly before using the samples here.
7 |
8 | Clone this repository locally. Each folder within the samples subdirectory is a self-contained sample. To use a sample open the Visual Studio solution in its folder. You can then build and deploy the sample to your Azure Sphere development kit to learn about the APIs and capabilities it is demonstrating.
9 |
10 | ## Contributing
11 | This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
12 |
13 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
14 |
15 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
16 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
17 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
18 |
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/epoll_timerfd_utilities.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | typedef void (*event_handler_t)(void);
7 |
8 | ///
9 | /// Creates an epoll instance.
10 | ///
11 | /// A valid epoll file descriptor on success, or -1 on failure
12 | int CreateEpollFd(void);
13 |
14 | ///
15 | /// Registers an event handler to an epoll instance.
16 | ///
17 | /// Epoll file descriptor
18 | /// File descriptor generating events for the epoll
19 | /// Event handler
20 | /// Bit mask for the epoll event type
21 | /// 0 on success, or -1 on failure
22 | int AddEventHandlerToEpoll(int epollFd, int eventFd, event_handler_t eventHandler,
23 | const uint32_t epollEventMask);
24 |
25 | ///
26 | /// Changes the period of a timerfd.
27 | ///
28 | /// Timer file descriptor
29 | /// The new period
30 | /// 0 on success, or -1 on failure
31 | int SetTimerFdInterval(int timerFd, const struct timespec *period);
32 |
33 | ///
34 | /// Consumes an event by reading from the timer file descriptor.
35 | /// If the event is not consumed, then it will immediately recur.
36 | ///
37 | /// Timer file descriptor
38 | /// 0 on success, or -1 on failure
39 | int ConsumeTimerFdEvent(int timerFd);
40 |
41 | ///
42 | /// Creates a timerfd and adds it to an epoll instance.
43 | ///
44 | /// Epoll file descriptor
45 | /// The timer period
46 | /// Event handler
47 | /// Bit mask for the epoll event type
48 | /// A valid timerfd file descriptor on success, or -1 on failure
49 | int CreateTimerFdAndAddToEpoll(int epollFd, const struct timespec *period,
50 | event_handler_t eventHandler, const uint32_t epollEventMask);
51 |
52 | ///
53 | /// Waits for an event on an epoll instance and triggers the handler.
54 | ///
55 | /// Epoll file descriptor
56 | /// 0 on success, or -1 on failure
57 | int WaitForEventAndCallHandler(int epollFd);
58 |
59 | ///
60 | /// Closes a file descriptor and prints an error on failure.
61 | ///
62 | /// File descriptor to close
63 | /// File descriptor name to use in error message
64 | void CloseFdAndPrintError(int fd, const char *name);
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/CurlEasyHttps.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | ARM
7 |
8 |
9 | Release
10 | ARM
11 |
12 |
13 |
14 | {74bc727b-6b7d-48e1-b600-6296320bc17e}
15 | AzureSphere
16 | CurlEasyHttps
17 | 15.0
18 | Linux
19 | 1.0
20 | Generic
21 | {D51BCBC9-82E9-4017-911E-C93873C4EA2B}
22 | Device
23 | GCC_AzureSphere_1_0
24 |
25 |
26 |
27 | true
28 |
29 |
30 | false
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | $(IncludePath);$(ISenseIncludePath);
39 |
40 |
41 | $(IncludePath);$(ISenseIncludePath);
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | true
54 |
55 |
56 |
57 |
58 |
59 |
60 | -Werror=implicit-function-declaration %(AdditionalOptions)
61 |
62 |
63 | applibs;pthread;gcc_s;c;curl
64 | -Wl,--no-undefined -nodefaultlibs %(AdditionalOptions)
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/epoll_timerfd_utilities.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "epoll_timerfd_utilities.h"
7 |
8 | int CreateEpollFd(void)
9 | {
10 | int epollFd = -1;
11 |
12 | epollFd = epoll_create1(0);
13 | if (epollFd == -1) {
14 | Log_Debug("ERROR: Could not create epoll instance: %d (%s)\n", errno, strerror(errno));
15 | return -1;
16 | }
17 |
18 | return epollFd;
19 | }
20 |
21 | int AddEventHandlerToEpoll(int epollFd, int eventFd, event_handler_t eventHandler,
22 | const uint32_t epollEventMask)
23 | {
24 | struct epoll_event eventToAdd;
25 | eventToAdd.data.ptr = eventHandler;
26 | eventToAdd.events = epollEventMask;
27 |
28 | // Register the eventFd on the epoll instance referred by epollFd
29 | // and register the eventHandler handler for events in epollEventMask
30 | if (epoll_ctl(epollFd, EPOLL_CTL_ADD, eventFd, &eventToAdd) == -1) {
31 | Log_Debug("ERROR: Could not add event to epoll instance %s (%d)\n", strerror(errno), errno);
32 | return -1;
33 | }
34 |
35 | return 0;
36 | }
37 |
38 | int SetTimerFdInterval(int timerFd, const struct timespec *period)
39 | {
40 | struct itimerspec newValue = {};
41 | newValue.it_value = *period;
42 | newValue.it_interval = *period;
43 |
44 | if (timerfd_settime(timerFd, 0, &newValue, NULL) < 0) {
45 | Log_Debug("ERROR: Could not set timerfd interval %s (%d)\n", strerror(errno), errno);
46 | return -1;
47 | }
48 |
49 | return 0;
50 | }
51 |
52 | int ConsumeTimerFdEvent(int timerFd)
53 | {
54 | uint64_t timerData = 0;
55 |
56 | if (read(timerFd, &timerData, sizeof(timerData)) == -1) {
57 | Log_Debug("ERROR: Could not read timerfd %s (%d)\n", strerror(errno), errno);
58 | return -1;
59 | }
60 |
61 | return 0;
62 | }
63 |
64 | int CreateTimerFdAndAddToEpoll(int epollFd, const struct timespec *period,
65 | event_handler_t eventHandler, const uint32_t epollEventMask)
66 | {
67 | // Create the timerfd and arm it by setting the interval to period
68 | int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
69 | if (timerFd < 0) {
70 | Log_Debug("ERROR: Could not create timerfd %s (%d)\n", strerror(errno), errno);
71 | return -1;
72 | }
73 | if (SetTimerFdInterval(timerFd, period) != 0) {
74 | int result = close(timerFd);
75 | if (result != 0) {
76 | Log_Debug("ERROR: Could not close timerfd %s (%d)\n", strerror(errno), errno);
77 | }
78 | return -1;
79 | }
80 |
81 | if (AddEventHandlerToEpoll(epollFd, timerFd, eventHandler, epollEventMask) != 0) {
82 | return -1;
83 | }
84 |
85 | return timerFd;
86 | }
87 |
88 | int WaitForEventAndCallHandler(int epollFd)
89 | {
90 | struct epoll_event event;
91 | int numEventsOccurred = epoll_wait(epollFd, &event, 1, -1);
92 |
93 | if (numEventsOccurred == -1) {
94 | if (errno == EINTR) {
95 | // interrupted by signal, e.g. due to breakpoint being set; ignore
96 | return 0;
97 | }
98 | Log_Debug("ERROR: Failed waiting on events: %s (%d)\n", strerror(errno), errno);
99 | return -1;
100 | }
101 |
102 | if (numEventsOccurred == 1 && event.data.ptr != NULL) {
103 | event_handler_t eventHandler = (event_handler_t)(event.data.ptr);
104 | eventHandler();
105 | }
106 |
107 | return 0;
108 | }
109 |
110 | void CloseFdAndPrintError(int fd, const char *fdName)
111 | {
112 | if (fd >= 0) {
113 | int result = close(fd);
114 | if (result != 0) {
115 | Log_Debug("WARNING: Could not close fd %s: %s (%d).\n", fdName, strerror(errno), errno);
116 | }
117 | }
118 | }
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/mt3620_rdb.h:
--------------------------------------------------------------------------------
1 | /// This header contains the peripheral pinout definitions for the
2 | /// MT3620 Reference Development Board (RDB)
3 | #pragma once
4 |
5 | #include
6 | #include
7 |
8 | /// LED 1 Red channel is GPIO8.
9 | #define MT3620_RDB_LED1_RED MT3620_GPIO8
10 |
11 | /// LED 1 Green channel is GPIO9.
12 | #define MT3620_RDB_LED1_GREEN MT3620_GPIO9
13 |
14 | /// LED 1 Blue channel is GPIO10.
15 | #define MT3620_RDB_LED1_BLUE MT3620_GPIO10
16 |
17 | /// LED 2 Red channel is GPIO15.
18 | #define MT3620_RDB_LED2_RED MT3620_GPIO15
19 |
20 | /// LED 2 Green channel is GPIO16.
21 | #define MT3620_RDB_LED2_GREEN MT3620_GPIO16
22 |
23 | /// LED 2 Blue channel is GPIO17.
24 | #define MT3620_RDB_LED2_BLUE MT3620_GPIO17
25 |
26 | /// LED 3 Red channel is GPIO18.
27 | #define MT3620_RDB_LED3_RED MT3620_GPIO18
28 |
29 | /// LED 3 Green channel is GPIO19.
30 | #define MT3620_RDB_LED3_GREEN MT3620_GPIO19
31 |
32 | /// LED 3 Blue channel is GPIO20.
33 | #define MT3620_RDB_LED3_BLUE MT3620_GPIO20
34 |
35 | /// LED 4 Red channel is GPIO21.
36 | #define MT3620_RDB_LED4_RED MT3620_GPIO21
37 |
38 | /// LED 4 Green channel is GPIO22.
39 | #define MT3620_RDB_LED4_GREEN MT3620_GPIO22
40 |
41 | /// LED 4 Blue channel is GPIO23.
42 | #define MT3620_RDB_LED4_BLUE MT3620_GPIO23
43 |
44 | /// Status LED Red channel is GPIO45.
45 | #define MT3620_RDB_STATUS_LED_RED MT3620_GPIO45
46 |
47 | /// Status LED Green channel is GPIO46.
48 | #define MT3620_RDB_STATUS_LED_GREEN MT3620_GPIO46
49 |
50 | /// Status LED Blue channel is GPIO47.
51 | #define MT3620_RDB_STATUS_LED_BLUE MT3620_GPIO47
52 |
53 | /// Networking LED Red channel is GPIO48.
54 | #define MT3620_RDB_NETWORKING_LED_RED MT3620_GPIO48
55 |
56 | /// Networking LED Green channel is GPIO14.
57 | #define MT3620_RDB_NETWORKING_LED_GREEN MT3620_GPIO14
58 |
59 | /// Networking LED Blue channel is GPIO11.
60 | #define MT3620_RDB_NETWORKING_LED_BLUE MT3620_GPIO11
61 |
62 | /// Button A is GPIO12.
63 | #define MT3620_RDB_BUTTON_A MT3620_GPIO12
64 |
65 | /// Button B is GPIO13.
66 | #define MT3620_RDB_BUTTON_B MT3620_GPIO13
67 |
68 | // Header 1, pin 1 is SYS_RST
69 | // Header 1, pin 2 is GND
70 |
71 | /// GPIO59 is exposed on header 1, pin 3
72 | #define MT3620_RDB_HEADER1_PIN3_GPIO MT3620_GPIO59
73 |
74 | /// GPIO0 is exposed on header 1, pin 4
75 | #define MT3620_RDB_HEADER1_PIN4_GPIO MT3620_GPIO0
76 |
77 | /// GPIO56 is exposed on header 1, pin 5
78 | #define MT3620_RDB_HEADER1_PIN5_GPIO MT3620_GPIO56
79 |
80 | /// GPIO1 is exposed on header 1, pin 6
81 | #define MT3620_RDB_HEADER1_PIN6_GPIO MT3620_GPIO1
82 |
83 | /// GPIO58 is exposed on header 1, pin 7
84 | #define MT3620_RDB_HEADER1_PIN7_GPIO MT3620_GPIO58
85 |
86 | /// GPIO2 is exposed on header 1, pin 8
87 | #define MT3620_RDB_HEADER1_PIN8_GPIO MT3620_GPIO2
88 |
89 | /// GPIO57 is exposed on header 1, pin 9
90 | #define MT3620_RDB_HEADER1_PIN9_GPIO MT3620_GPIO57
91 |
92 | /// GPIO3 is exposed on header 1, pin 10
93 | #define MT3620_RDB_HEADER1_PIN10_GPIO MT3620_GPIO3
94 |
95 | /// GPIO60 is exposed on header 1, pin 11
96 | #define MT3620_RDB_HEADER1_PIN11_GPIO MT3620_GPIO60
97 |
98 | /// GPIO4 is exposed on header 1, pin 12
99 | #define MT3620_RDB_HEADER1_PIN12_GPIO MT3620_GPIO4
100 |
101 | // Header 2, pins 1, 3, 5, 7 are only supported as the ISU0 UART
102 | #define MT3620_RDB_HEADER2_ISU0_UART MT3620_UART_ISU0
103 |
104 | // Header 2, pin 2 is GND
105 |
106 | /// GPIO5 is exposed on header 2, pin 4
107 | #define MT3620_RDB_HEADER2_PIN4_GPIO MT3620_GPIO5
108 |
109 | /// GPIO6 is exposed on header 2, pin 6
110 | #define MT3620_RDB_HEADER2_PIN6_GPIO MT3620_GPIO6
111 |
112 | /// GPIO7 is exposed on header 2, pin 8
113 | #define MT3620_RDB_HEADER2_PIN8_GPIO MT3620_GPIO7
114 |
115 | /// GPIO30 is exposed on header 2, pin 9
116 | #define MT3620_RDB_HEADER2_PIN9_GPIO MT3620_GPIO30
117 |
118 | // Header 2, pin 10 is ADC VREF
119 |
120 | /// GPIO41 is exposed on header 2, pin 11
121 | #define MT3620_RDB_HEADER2_PIN11_GPIO MT3620_GPIO41
122 |
123 | /// GPIO43 is exposed on header 2, pin 12
124 | #define MT3620_RDB_HEADER2_PIN12_GPIO MT3620_GPIO43
125 |
126 | /// GPIO42 is exposed on header 2, pin 13
127 | #define MT3620_RDB_HEADER2_PIN13_GPIO MT3620_GPIO42
128 |
129 | /// GPIO44 is exposed on header 2, pin 14
130 | #define MT3620_RDB_HEADER2_PIN14_GPIO MT3620_GPIO44
131 |
132 | // Header 3, pin 1 is 5V
133 | // Header 3, pin 2 is GND
134 | // Header 3, pin 3 is 3V3
135 | // Header 3, pin 4 is RTC_WAKEUP
136 |
137 | // Header 3, pin 6 is IO0 UART TX
138 | // Header 3, pin 8 is IO1 UART TX
139 | // Header 3, pin 10 is PMU EN
140 |
141 | // Header 3, pins 5, 7, 9, 11 are only supported as the ISU3 UART
142 | #define MT3620_RDB_HEADER3_ISU3_UART MT3620_UART_ISU3
143 |
144 | /// GPIO70 is exposed on header 3, pin 12
145 | #define MT3620_RDB_HEADER3_PIN12_GPIO MT3620_GPIO70
146 |
147 | // Header 4, pin 1 is SWDIO
148 | // Header 4, pin 2 is GND
149 | // Header 4, pin 3 is SWCLK
150 | // Header 4, pin 4 is SWO
151 |
152 | // Header 4, pins 5, 7, 9, 11 are only supported as the ISU1 UART
153 | #define MT3620_RDB_HEADER4_ISU1_UART MT3620_UART_ISU1
154 |
155 | // Header 4, pins 6, 8, 10, 12 are only supported as the ISU2 UART
156 | #define MT3620_RDB_HEADER4_ISU2_UART MT3620_UART_ISU2
157 |
158 | /// GPIO35 is exposed on header 4, pin 13
159 | #define MT3620_RDB_HEADER4_PIN13_GPIO MT3620_GPIO35
160 |
161 | /// GPIO40 is exposed on header 4, pin 14
162 | #define MT3620_RDB_HEADER4_PIN14_GPIO MT3620_GPIO40
163 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
--------------------------------------------------------------------------------
/Samples/CurlEasyHttps/CurlEasyHttps/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | // applibs_versions.h defines the API struct versions to use for applibs APIs.
9 | #include "applibs_versions.h"
10 | #include
11 | #include
12 | #include
13 |
14 | #include "epoll_timerfd_utilities.h"
15 |
16 | // This sample C application for Azure Sphere periodically downloads and outputs the index web page
17 | // at example.com, by using cURL over a secure HTTPS connection.
18 | //
19 | // It uses the API for the following Azure Sphere application libraries:
20 | // - log (messages shown in Visual Studio's Device Output window during debugging);
21 | // - storage (device storage interaction);
22 | // - curl (web client library).
23 |
24 | static volatile sig_atomic_t terminationRequested = false;
25 |
26 | ///
27 | /// Signal handler for termination requests. This handler must be async-signal-safe.
28 | ///
29 | static void TerminationHandler(int signalNumber)
30 | {
31 | // Don't use Log_Debug here, as it is not guaranteed to be async signal safe
32 | terminationRequested = true;
33 | }
34 |
35 | // Epoll and event handler file descriptors.
36 | static int webpageDownloadTimerFd = -1;
37 | static int epollFd = -1;
38 |
39 | ///
40 | /// Data pointer and size of a block of memory allocated on the heap.
41 | ///
42 | typedef struct {
43 | char *data;
44 | size_t size;
45 | } memory_block_t;
46 |
47 | ///
48 | /// Callback for curl_easy_perform() that copies all the downloaded chunks in a single memory
49 | /// block.
50 | /// The pointer to the chunks array
51 | /// The size of each chunk
52 | /// The count of the chunks
53 | /// The pointer where all the downloaded chunks are aggregated
54 | ///
55 | static size_t StoreDownloadedDataCallback(void *chunks, size_t chunkSize, size_t chunksCount,
56 | void *memoryBlock)
57 | {
58 | memory_block_t *block = (memory_block_t *)memoryBlock;
59 |
60 | size_t additionalDataSize = chunkSize * chunksCount;
61 | block->data = realloc(block->data, block->size + additionalDataSize + 1);
62 | if (block->data == NULL) {
63 | Log_Debug("Out of memory, realloc returned NULL: errno=%d (%s)'n", errno, strerror(errno));
64 | abort();
65 | }
66 |
67 | memcpy(block->data + block->size, chunks, additionalDataSize);
68 | block->size += additionalDataSize;
69 | block->data[block->size] = 0; // Ensure the block of memory is null terminated.
70 |
71 | return additionalDataSize;
72 | }
73 |
74 | ///
75 | /// Outputs the reason a cURL function failed using the curl_easy_strerror() utility function.
76 | ///
77 | #define CURL_LOG_STRERROR(message) \
78 | do { \
79 | Log_Debug(#message " failed at line %d: %d (%s)\n", __LINE__, res, \
80 | curl_easy_strerror(res)); \
81 | } while (false)
82 |
83 | ///
84 | /// Download a web page over HTTPS protocol using cURL.
85 | ///
86 | static void PerformWebPageDownload(void)
87 | {
88 | CURL *curlHandle = NULL;
89 | CURLcode res = 0;
90 | memory_block_t block = {NULL, 0};
91 | char *certificatePath = NULL;
92 |
93 | bool isNetworkingReady = false;
94 | if ((Networking_IsNetworkingReady(&isNetworkingReady) < 0) || !isNetworkingReady) {
95 | Log_Debug("\n\nNot doing download because network is not up.\n\n");
96 | goto exitLabel;
97 | }
98 |
99 | Log_Debug("\n\n -===- Starting downloading -===-\n\n");
100 |
101 | // Init the cURL library.
102 | if ((res = curl_global_init(CURL_GLOBAL_ALL)) != CURLE_OK) {
103 | CURL_LOG_STRERROR(curl_global_init);
104 | goto exitLabel;
105 | }
106 |
107 | if ((curlHandle = curl_easy_init()) == NULL) {
108 | Log_Debug("curl_easy_init() failed\n");
109 | goto cleanupLabel;
110 | }
111 |
112 | // Specify URL to download.
113 | // Important: any change in the domain name must be reflected in the AllowedConnections
114 | // capability in app_manifest.json.
115 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_URL, "https://example.com")) != CURLE_OK) {
116 | CURL_LOG_STRERROR(curl_reasy_setopt);
117 | goto cleanupLabel;
118 | }
119 |
120 | // Set output level to verbose.
121 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_VERBOSE, 1L)) != CURLE_OK) {
122 | CURL_LOG_STRERROR(curl_easy_setopt);
123 | goto cleanupLabel;
124 | }
125 |
126 | // Get the full path to the certificate file used to authenticate the HTTPS server identity.
127 | // The DigiCertHighAssuranceEVRootCA.pem file is the certificate that is used to verify the
128 | // server identity.
129 | certificatePath =
130 | Storage_GetAbsolutePathInImagePackage("certs/DigiCertHighAssuranceEVRootCA.pem");
131 | if (certificatePath == NULL) {
132 | Log_Debug("The certificate path could not be resolved: errno=%d (%s)\n", errno,
133 | strerror(errno));
134 | goto cleanupLabel;
135 | }
136 |
137 | // Set the path for the certificate file that cURL uses to validate the server certificate.
138 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_CAINFO, certificatePath)) != CURLE_OK) {
139 | CURL_LOG_STRERROR(curl_easy_setopt);
140 | goto cleanupLabel;
141 | }
142 |
143 | // Let cURL follow any HTTP 3xx redirects.
144 | // Important: any redirection to different domain names requires that domain name to be added to
145 | // app_manifest.json.
146 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_FOLLOWLOCATION, 1L)) != CURLE_OK) {
147 | CURL_LOG_STRERROR(curl_easy_setopt);
148 | goto cleanupLabel;
149 | }
150 |
151 | // Set up callback for cURL to use when downloading data.
152 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, StoreDownloadedDataCallback)) !=
153 | CURLE_OK) {
154 | CURL_LOG_STRERROR(curl_easy_setopt);
155 | goto cleanupLabel;
156 | }
157 |
158 | // Set the custom parameter of the callback to the memory block.
159 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, (void *)&block)) != CURLE_OK) {
160 | CURL_LOG_STRERROR(curl_easy_setopt);
161 | goto cleanupLabel;
162 | }
163 |
164 | // Specify a user agent.
165 | if ((res = curl_easy_setopt(curlHandle, CURLOPT_USERAGENT, "libcurl-agent/1.0")) != CURLE_OK) {
166 | CURL_LOG_STRERROR(curl_easy_setopt);
167 | goto cleanupLabel;
168 | }
169 |
170 | // Perform the download of the web page.
171 | if ((res = curl_easy_perform(curlHandle)) != CURLE_OK) {
172 | CURL_LOG_STRERROR(curl_easy_perform);
173 | } else {
174 | Log_Debug("\n\n -===- Downloaded content (%lu bytes): -===-\n\n", block.size);
175 | Log_Debug("%s\n", block.data);
176 | }
177 |
178 | cleanupLabel:
179 | // Clean up allocated memory.
180 | free(block.data);
181 | free(certificatePath);
182 | // Clean up sample's cURL resources.
183 | curl_easy_cleanup(curlHandle);
184 | // Clean up cURL library's resources.
185 | curl_global_cleanup();
186 |
187 | exitLabel:
188 | return;
189 | }
190 |
191 | ///
192 | /// The timer event handler.
193 | ///
194 | static void TimerEventHandler(void)
195 | {
196 | if (ConsumeTimerFdEvent(webpageDownloadTimerFd) != 0) {
197 | terminationRequested = true;
198 | return;
199 | }
200 |
201 | PerformWebPageDownload();
202 | }
203 |
204 | ///
205 | /// Initialization of the sample includes the following:
206 | /// - set up a SIGTERM termination handler;
207 | /// - set up an epoll instance;
208 | /// - set up a timer event.
209 | ///
210 | /// 0 on success, or -1 on failure
211 | static int Init(void)
212 | {
213 | struct sigaction action;
214 | memset(&action, 0, sizeof(struct sigaction));
215 | action.sa_handler = TerminationHandler;
216 | sigaction(SIGTERM, &action, NULL);
217 |
218 | epollFd = CreateEpollFd();
219 | if (epollFd < 0) {
220 | return -1;
221 | }
222 |
223 | // Issue an HTTPS request at the specified period.
224 | struct timespec tenSeconds = {10, 0};
225 | webpageDownloadTimerFd =
226 | CreateTimerFdAndAddToEpoll(epollFd, &tenSeconds, &TimerEventHandler, EPOLLIN);
227 | if (webpageDownloadTimerFd < 0) {
228 | return -1;
229 | }
230 |
231 | return 0;
232 | }
233 |
234 | ///
235 | /// Clean up the resources previously allocated.
236 | ///
237 | static void Cleanup(void)
238 | {
239 | Log_Debug("Closing file descriptors\n");
240 |
241 | // Close the timer and epoll file descriptors.
242 | CloseFdAndPrintError(webpageDownloadTimerFd, "WebpageDownloadTimer");
243 | CloseFdAndPrintError(epollFd, "Epoll");
244 | }
245 |
246 | //
247 | /// Main entry point for this sample.
248 | ///
249 | int main(int argc, char *argv[])
250 | {
251 | Log_Debug("cURL HTTPS application starting\n");
252 |
253 | if (Init() != 0) {
254 | terminationRequested = true;
255 | }
256 |
257 | // Download the web page immediately.
258 | PerformWebPageDownload();
259 |
260 | // Use epoll to wait for events and trigger handlers, until an error or SIGTERM happens
261 | // Periodically downloads the web page.
262 | while (!terminationRequested) {
263 | if (WaitForEventAndCallHandler(epollFd) != 0) {
264 | terminationRequested = true;
265 | }
266 | }
267 |
268 | Cleanup();
269 | Log_Debug("Application exiting\n");
270 | return 0;
271 | }
--------------------------------------------------------------------------------