10a7ce71fSopenharmony_ci/*
20a7ce71fSopenharmony_ci * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
30a7ce71fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
40a7ce71fSopenharmony_ci * you may not use this file except in compliance with the License.
50a7ce71fSopenharmony_ci * You may obtain a copy of the License at
60a7ce71fSopenharmony_ci *
70a7ce71fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
80a7ce71fSopenharmony_ci *
90a7ce71fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
100a7ce71fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
110a7ce71fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120a7ce71fSopenharmony_ci * See the License for the specific language governing permissions and
130a7ce71fSopenharmony_ci * limitations under the License.
140a7ce71fSopenharmony_ci */
150a7ce71fSopenharmony_ci
160a7ce71fSopenharmony_ci#include "coap.h"
170a7ce71fSopenharmony_ci#include "net.h"
180a7ce71fSopenharmony_ci#include "los_task.h"
190a7ce71fSopenharmony_ci#include "lwip/tcpip.h"
200a7ce71fSopenharmony_ci#include "lwip/udp.h"
210a7ce71fSopenharmony_ci#include "coap_session_internal.h"
220a7ce71fSopenharmony_ci#include "iot_config.h"
230a7ce71fSopenharmony_ci
240a7ce71fSopenharmony_ci#define TEST_IPV4 1
250a7ce71fSopenharmony_ci#define DHCP_COAP_TOKEN_LEN (4)
260a7ce71fSopenharmony_cistatic coap_context_t* g_cliCtx = NULL;
270a7ce71fSopenharmony_ci/* The response handler */
280a7ce71fSopenharmony_cistatic void MessageHandler(struct coap_context_t *ctx, coap_session_t *session, coap_pdu_t *sent,
290a7ce71fSopenharmony_ci    coap_pdu_t *received, coap_tid_t id)
300a7ce71fSopenharmony_ci{
310a7ce71fSopenharmony_ci    unsigned char* data;
320a7ce71fSopenharmony_ci    size_t dataLen;
330a7ce71fSopenharmony_ci    (void)ctx;
340a7ce71fSopenharmony_ci    (void)session;
350a7ce71fSopenharmony_ci    (void)sent;
360a7ce71fSopenharmony_ci    (void)received;
370a7ce71fSopenharmony_ci    (void)id;
380a7ce71fSopenharmony_ci    if (COAP_RESPONSE_CLASS(received->code) == 2) { /* 获取的数据2 */
390a7ce71fSopenharmony_ci        if (coap_get_data(received, &dataLen, &data)) {
400a7ce71fSopenharmony_ci            printf("Received data\n");
410a7ce71fSopenharmony_ci        }
420a7ce71fSopenharmony_ci    }
430a7ce71fSopenharmony_ci}
440a7ce71fSopenharmony_ci
450a7ce71fSopenharmony_ciint CoapClientStart(void)
460a7ce71fSopenharmony_ci{
470a7ce71fSopenharmony_ci    coap_address_t src_addr;
480a7ce71fSopenharmony_ci    if (g_cliCtx != NULL) {
490a7ce71fSopenharmony_ci        return 0;
500a7ce71fSopenharmony_ci    }
510a7ce71fSopenharmony_ci    /* Prepare coap socket */
520a7ce71fSopenharmony_ci    coap_address_init(&src_addr);
530a7ce71fSopenharmony_ci#if TEST_IPV4
540a7ce71fSopenharmony_ci    ip_addr_set_any(false, &(src_addr.addr));
550a7ce71fSopenharmony_ci#else
560a7ce71fSopenharmony_ci    ip_addr_set_any(true, &(src_addr.addr));
570a7ce71fSopenharmony_ci#endif
580a7ce71fSopenharmony_ci    src_addr.port = 23456; /* 主机端口号23456 */
590a7ce71fSopenharmony_ci    g_cliCtx = coap_new_context_lwip(&src_addr);
600a7ce71fSopenharmony_ci    if (!g_cliCtx) {
610a7ce71fSopenharmony_ci        return -1;
620a7ce71fSopenharmony_ci    }
630a7ce71fSopenharmony_ci    /* Set the response handler */
640a7ce71fSopenharmony_ci    coap_register_response_handler(g_cliCtx, MessageHandler);
650a7ce71fSopenharmony_ci    return 0;
660a7ce71fSopenharmony_ci}
670a7ce71fSopenharmony_civoid CoapClientStop(void)
680a7ce71fSopenharmony_ci{
690a7ce71fSopenharmony_ci    if (g_cliCtx != NULL) {
700a7ce71fSopenharmony_ci        coap_free_context_lwip(g_cliCtx);
710a7ce71fSopenharmony_ci        g_cliCtx = NULL;
720a7ce71fSopenharmony_ci    }
730a7ce71fSopenharmony_ci    printf("[%s][%d] stopped\n", __FUNCTION__, __LINE__);
740a7ce71fSopenharmony_ci    return;
750a7ce71fSopenharmony_ci}
760a7ce71fSopenharmony_ci/* to create a new token value depending on time */
770a7ce71fSopenharmony_cis32_t CoapNewToken(u16_t msg_id, u8_t *token, u8_t token_len)
780a7ce71fSopenharmony_ci{
790a7ce71fSopenharmony_ci    u32_t now_ms;
800a7ce71fSopenharmony_ci    if ((token == NULL) || (token_len < DHCP_COAP_TOKEN_LEN)) {
810a7ce71fSopenharmony_ci        return -1;
820a7ce71fSopenharmony_ci    }
830a7ce71fSopenharmony_ci    now_ms = sys_now();
840a7ce71fSopenharmony_ci    token[0] = (u8_t)(msg_id); /* 0数据 */
850a7ce71fSopenharmony_ci    token[1] = (u8_t)(msg_id >> 8); /* 1数据,8数据 */
860a7ce71fSopenharmony_ci    token[2] = (u8_t)(now_ms); /* 2数据 */
870a7ce71fSopenharmony_ci    token[3] = (u8_t)(now_ms >> 8); /* 3数据,8数据 */
880a7ce71fSopenharmony_ci    return 0;
890a7ce71fSopenharmony_ci}
900a7ce71fSopenharmony_ci#define STRING_LEN (7)
910a7ce71fSopenharmony_ciint CoapClientSendMsg(char* dst)
920a7ce71fSopenharmony_ci{
930a7ce71fSopenharmony_ci    coap_address_t dst_addr, listen_addr;
940a7ce71fSopenharmony_ci    static coap_uri_t uri;
950a7ce71fSopenharmony_ci    coap_pdu_t* request;
960a7ce71fSopenharmony_ci    coap_session_t *session = NULL;
970a7ce71fSopenharmony_ci    char serverUri[128] = {0};
980a7ce71fSopenharmony_ci    u8_t temp_token[DHCP_COAP_TOKEN_LEN] = {0};
990a7ce71fSopenharmony_ci    unsigned char getMethod = COAP_REQUEST_GET;
1000a7ce71fSopenharmony_ci    /* The destination endpoint */
1010a7ce71fSopenharmony_ci    coap_address_init(&dst_addr);
1020a7ce71fSopenharmony_ci    printf("[%s][%d] server : %s\n", __FUNCTION__, __LINE__, dst);
1030a7ce71fSopenharmony_ci
1040a7ce71fSopenharmony_ci    if (!ipaddr_aton(dst, &(dst_addr.addr))) {
1050a7ce71fSopenharmony_ci        return -1;
1060a7ce71fSopenharmony_ci    }
1070a7ce71fSopenharmony_ci    dst_addr.port = COAP_DEFAULT_PORT;
1080a7ce71fSopenharmony_ci    /* try to reuse existed session */
1090a7ce71fSopenharmony_ci    session = coap_session_get_by_peer(g_cliCtx, &dst_addr, 0);
1100a7ce71fSopenharmony_ci    if (session == NULL) {
1110a7ce71fSopenharmony_ci        coap_address_init(&listen_addr);
1120a7ce71fSopenharmony_ci        ip_addr_set_any(false, &(listen_addr.addr));
1130a7ce71fSopenharmony_ci        listen_addr.port = 23456; /* 监听端口号23456 */
1140a7ce71fSopenharmony_ci        session = coap_new_client_session(g_cliCtx, &listen_addr, &dst_addr, COAP_PROTO_UDP);
1150a7ce71fSopenharmony_ci        if (session == NULL) {
1160a7ce71fSopenharmony_ci            printf("[%s][%d] new client session failed\n", __FUNCTION__, __LINE__);
1170a7ce71fSopenharmony_ci            return -1;
1180a7ce71fSopenharmony_ci        }
1190a7ce71fSopenharmony_ci        session->sock.pcb = g_cliCtx->endpoint;
1200a7ce71fSopenharmony_ci        SESSIONS_ADD(g_cliCtx->endpoint->sessions, session);
1210a7ce71fSopenharmony_ci    }
1220a7ce71fSopenharmony_ci /* Prepare the request */
1230a7ce71fSopenharmony_ci    strcpy_s(serverUri, STRING_LEN, "/hello");
1240a7ce71fSopenharmony_ci    coap_split_uri((unsigned char *)serverUri, strlen(serverUri), &uri);
1250a7ce71fSopenharmony_ci    request = coap_new_pdu(session);
1260a7ce71fSopenharmony_ci    if (request == NULL) {
1270a7ce71fSopenharmony_ci        printf("[%s][%d] get pdu failed\n", __FUNCTION__, __LINE__);
1280a7ce71fSopenharmony_ci        return -1;
1290a7ce71fSopenharmony_ci    }
1300a7ce71fSopenharmony_ci    request->type = COAP_MESSAGE_CON;
1310a7ce71fSopenharmony_ci    request->tid = coap_new_message_id(session);
1320a7ce71fSopenharmony_ci    (void)CoapNewToken(request->tid, temp_token, DHCP_COAP_TOKEN_LEN);
1330a7ce71fSopenharmony_ci    if (coap_add_token(request, DHCP_COAP_TOKEN_LEN, temp_token) == 0) {
1340a7ce71fSopenharmony_ci        printf("[%s][%d] add token failed\n", __FUNCTION__, __LINE__);
1350a7ce71fSopenharmony_ci    }
1360a7ce71fSopenharmony_ci    request->code = getMethod;
1370a7ce71fSopenharmony_ci    coap_add_option(request, COAP_OPTION_URI_PATH, uri.path.length, uri.path.s);
1380a7ce71fSopenharmony_ci    char requestData[64] = {0};
1390a7ce71fSopenharmony_ci    (void)snprintf_s(requestData, sizeof(requestData), sizeof(requestData)-1, "%s", "Hello coap");
1400a7ce71fSopenharmony_ci    coap_add_data(request, 4 + strlen((const char *)(requestData + 4)), (unsigned char *)requestData);
1410a7ce71fSopenharmony_ci    coap_send_lwip(session, request);
1420a7ce71fSopenharmony_ci    return 0;
1430a7ce71fSopenharmony_ci}
1440a7ce71fSopenharmony_ci
1450a7ce71fSopenharmony_ciint CoapClientSend(void)
1460a7ce71fSopenharmony_ci{
1470a7ce71fSopenharmony_ci    if (g_cliCtx == NULL) {
1480a7ce71fSopenharmony_ci        return -1;
1490a7ce71fSopenharmony_ci    }
1500a7ce71fSopenharmony_ci    /* argv[0] is server_addr */
1510a7ce71fSopenharmony_ci    CoapClientSendMsg(PARAM_SERVER_ADDR); /* 主机IP地址 */
1520a7ce71fSopenharmony_ci    return 0;
1530a7ce71fSopenharmony_ci}
1540a7ce71fSopenharmony_ci
1550a7ce71fSopenharmony_civoid NetDemoTest(void)
1560a7ce71fSopenharmony_ci{
1570a7ce71fSopenharmony_ci    printf("coapclientTest start\r\n");
1580a7ce71fSopenharmony_ci    CoapClientStart();
1590a7ce71fSopenharmony_ci    CoapClientSend();
1600a7ce71fSopenharmony_ci}