This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

libMiMic(MiMic library for mbed)は、WebService機能を提供するSDKです。 mbedでWebAPIに対応したネットワークデバイスを簡単に作ることが出来ます。

libMiMicはMiMic projectで開発しています。MiMic projectについてはこちらをご覧ください。 http://nyatla.jp/mimic/wp/

構成

libMiMicはmbedRTOS上で動作し、ユーザアプリケーションにAPIを提供します。コアAPIはC言語で記述されていますが、使用頻度の高いものについてはmbed向けのC++APIが準備されています。

/media/uploads/nyatla/libmimic-sdk.png

※libMiMicはmbedの標準イーサネットドライバをしようしていません。

標準イーサネットドライバと同時に使用することはできません。

  • MiMicIP - IPv4スタックです。レテンシとメモリ消費量を抑えたuipベースのライブラリです。
  • ARP/ICMP/UDP/TCP - 基礎的なソケットAPIを提供します。APIは独自です。
  • HTTP/1.1 Server - HTTP/1.1に対応したサーバです。マルチセッション・Chunked・持続性接続に対応しています。
  • HTTP Modules - HTTP/1.1の機能モジュールです。以下のモジュールがあります。
    • ROM file provider - ROMに格納したファイルイメージを公開します。
    • File system provider - mbedファイルシステムを公開します。
    • Onchip configuration - プログラムフラッシュを利用して設定を保存します。
    • MiMicVM processor - RPCリクエスト(MiMicVM)を処理します。
    • FileUpload - ファイルアップロードを受け取ります。
    • URL decoder - HTTPリクエストを解析します。
    • UPnP handler -UPnPメッセージを処理します。
    • WebSocket - Websocketサーバです。
  • mDNS - マルチキャストDNSサービスです。
  • UPnP - UPnP/1.0の機能を提供します。UPnP handlerと協調して動作します。(現在はデバイス探索(SSDP)・デスクリプション(Description)のみ実装してあります。)
  • DHCP/APIPA - ゼロコンフィギュレーション用のモジュールです。
  • HTTP/1.1 Client
  • mbed C++ class library - mbed向けのC++CPIです。C言語のものより簡単です。

対応機種

  • mbed(mbed LPC1768)
  • LPCXpresso1769

プログラム

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

サンプル

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

チュートリアル

English

libMiMic(MiMic library for mbed) is SDK which provides Webservice functions. It can be created networking device easily using mbed.

See more MiMic information, See MiMic project website. http://nyatla.jp/mimic/wp/

Structure

libMiMic run on mbed RTOS and provides networking API to user application. This library has C++ class API for the mbed, and low-level C language API.

/media/uploads/nyatla/libmimic-sdk.png

For WebService general, it can be written in a simple C + + API.

libMiMic does not have the standard Ethernet driver of mbed. It is not possible that will be used with the standard Ethernet driver.

  • MiMicIP - IPv4 protocol stack. This is based uip which is reduced memory and latency.
  • ARP / ICMP / UDP / TCP - Those are provide basic IP protocols.
  • HTTP/1.1 Server - The Http server compatible HTTP/1.1. It supports multi-session, chunked transport, persistent connection.
  • HTTP Modules - There are addon-module for HTTP server. The following modules.
    • ROM file module - Publish the file images in ROM.
    • File system module - Publish thefiles in mbed file system.
    • Onchip configuration module - To save the network settings to the program flash via REST.
    • MiMicVM module - To handle the (MiMicVM) RPC request.
    • FileUpload module - Accept a file via HTTP POST.
    • URL dedoce module - A versatility URL decoder.
    • UPnP handle module - To handle UPnP messages.
    • UPnP - This provides UPnP/1.0 device functions. It works together with UPnP handler.
    • Websocket - websocket (version13) server
  • mDNS Service - DNS-SD protocol server.
  • UPnP - This provides UPnP/1.0 device functions which works with UPnP handler. (You have been implemented (SSDP) ? description only (Description) device search now.) It is a module zero configuration for - DHCP / APIPA. mbed C + + class library - C of mbed for + + is the CPI. It is simple than that of the C language.
  • DHCP/APIPA - It support zero-cpnfigulation.
  • mbed C++ class library. Almost APIs for Web applications are available.
  • HTTP/1.1 Client

Supported target

  • mbed(mbed LPC1768)
  • LPCXpresso1769

Application

Import programMiMicRemoteMCU-for-Mbed

MiMic RemoteMCU for mbed. This program provides MCU control API over REST API. It can control MCU from Javascript,PHP or any HTTP rest client directly. And, The application has self development environment.

Import programMbedFileServer

The program publishes files at local directory and SD filesystem. It is a full-fledged webServer somewhat.

Sample

Import programMiMicSimpleHttpd

This is a simplest HTTP server made ​​of libMiMic. It will echo back a request path.

Import programUPnPBasicDevice

Simplest UPnP basic device example. This program to run UPnP basic device on the mbed.

Import programWebSocketSample

MiMicSDK Websocket module sample program.

Import programHttpClientSamlpe

A http client sample program.

Import programTcpSocketClientSamlpe

MiMicSDK Tcp client socket sample program.

Import programUdpSocketSamlpe

Udp socket sample program. This program will send back the received packet.

Tutorial

Committer:
nyatla
Date:
Wed Nov 19 14:45:17 2014 +0000
Revision:
109:18f12ac01097
Parent:
100:8d45dab6dcf6
Child:
110:257739f9b31e
new MiMicIP API;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nyatla 48:00d211aac2ec 1 /*********************************************************************************
nyatla 48:00d211aac2ec 2 * PROJECT: MiMic
nyatla 48:00d211aac2ec 3 * --------------------------------------------------------------------------------
nyatla 48:00d211aac2ec 4 *
nyatla 48:00d211aac2ec 5 * This file is part of MiMic
nyatla 48:00d211aac2ec 6 * Copyright (C)2011 Ryo Iizuka
nyatla 48:00d211aac2ec 7 *
nyatla 48:00d211aac2ec 8 * MiMic is free software: you can redistribute it and/or modify
nyatla 48:00d211aac2ec 9 * it under the terms of the GNU Lesser General Public License as published
nyatla 48:00d211aac2ec 10 * by the Free Software Foundation, either version 3 of the License, or
nyatla 48:00d211aac2ec 11 * (at your option) any later version.
nyatla 48:00d211aac2ec 12 *
nyatla 48:00d211aac2ec 13 * This program is distributed in the hope that it will be useful,
nyatla 48:00d211aac2ec 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nyatla 48:00d211aac2ec 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nyatla 48:00d211aac2ec 16 * GNU General Public License for more details.
nyatla 48:00d211aac2ec 17 *
nyatla 48:00d211aac2ec 18 * You should have received a copy of the GNU Lesser General Public License
nyatla 48:00d211aac2ec 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
nyatla 48:00d211aac2ec 20 *
nyatla 48:00d211aac2ec 21 * For further information please contact.
nyatla 48:00d211aac2ec 22 * http://nyatla.jp/
nyatla 48:00d211aac2ec 23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
nyatla 48:00d211aac2ec 24 *
nyatla 48:00d211aac2ec 25 *********************************************************************************/
nyatla 48:00d211aac2ec 26 #include "NyLPC_cSsdpSocket.h"
nyatla 48:00d211aac2ec 27 #include "NyLPC_http.h"
nyatla 109:18f12ac01097 28 #include "NyLPC_netif.h"
nyatla 109:18f12ac01097 29
nyatla 48:00d211aac2ec 30
nyatla 48:00d211aac2ec 31 #include <stdio.h>
nyatla 48:00d211aac2ec 32 #include <string.h>
nyatla 48:00d211aac2ec 33
nyatla 48:00d211aac2ec 34
nyatla 48:00d211aac2ec 35
nyatla 48:00d211aac2ec 36
nyatla 48:00d211aac2ec 37
nyatla 48:00d211aac2ec 38 #define HTTP_SP 0x20
nyatla 48:00d211aac2ec 39
nyatla 48:00d211aac2ec 40 #define PARSE_NULL 0
nyatla 48:00d211aac2ec 41 #define PARSE_ST 0x01
nyatla 48:00d211aac2ec 42 #define PARSE_MAN 0x11
nyatla 48:00d211aac2ec 43 #define PARSE_UNKNOWN 0xff
nyatla 48:00d211aac2ec 44
nyatla 48:00d211aac2ec 45 static const struct NyLPC_TIPv4Addr SSDP_MCAST_IPADDR=NyLPC_TIPv4Addr_pack(239,255,255,250);
nyatla 48:00d211aac2ec 46 static const char* STR_UPNP_ROOT_DEVICE="upnp:rootdevice";
nyatla 48:00d211aac2ec 47
nyatla 48:00d211aac2ec 48 struct TMSearchHeader
nyatla 48:00d211aac2ec 49 {
nyatla 48:00d211aac2ec 50 struct NyLPC_THttpBasicHeader super;
nyatla 48:00d211aac2ec 51
nyatla 48:00d211aac2ec 52 const struct NyLPC_TUPnPDeviceRecord* _ref_devices;
nyatla 48:00d211aac2ec 53 /**
nyatla 48:00d211aac2ec 54 * パーサのステータス
nyatla 48:00d211aac2ec 55 */
nyatla 48:00d211aac2ec 56 NyLPC_TUInt8 st;
nyatla 48:00d211aac2ec 57 /**
nyatla 48:00d211aac2ec 58 * メモリ位置
nyatla 48:00d211aac2ec 59 */
nyatla 48:00d211aac2ec 60 const NyLPC_TChar* _rpos;
nyatla 48:00d211aac2ec 61 struct{
nyatla 48:00d211aac2ec 62 const NyLPC_TChar* st_str;
nyatla 48:00d211aac2ec 63 const NyLPC_TChar* man_str;
nyatla 48:00d211aac2ec 64 NyLPC_TUInt16 st_len;
nyatla 48:00d211aac2ec 65 NyLPC_TUInt16 man_len;
nyatla 48:00d211aac2ec 66 }result;
nyatla 48:00d211aac2ec 67 };
nyatla 48:00d211aac2ec 68
nyatla 48:00d211aac2ec 69 //とりあえずprivate
nyatla 48:00d211aac2ec 70 void NyLPC_cSsdpSocket_notify(NyLPC_TcSsdpSocket_t* i_inst);
nyatla 48:00d211aac2ec 71
nyatla 48:00d211aac2ec 72
nyatla 48:00d211aac2ec 73 static NyLPC_TBool urlHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
nyatla 48:00d211aac2ec 74 {
nyatla 48:00d211aac2ec 75 // *であるかを確認 未実装
nyatla 48:00d211aac2ec 76 return NyLPC_TBool_TRUE;
nyatla 48:00d211aac2ec 77 }
nyatla 57:bc4330dfa62f 78
nyatla 48:00d211aac2ec 79 #define TIMEOUT_IN_MS 100
nyatla 48:00d211aac2ec 80
nyatla 48:00d211aac2ec 81 /**
nyatla 48:00d211aac2ec 82 * SERVER MessageHeaderの値
nyatla 48:00d211aac2ec 83 * 40文字以内であること。
nyatla 48:00d211aac2ec 84 */
nyatla 100:8d45dab6dcf6 85 #define SERVER_MESSAGE_HEADER "MiMic/1.4 UPnP/1.0 MiMicUPnP/0.2"
nyatla 48:00d211aac2ec 86
nyatla 48:00d211aac2ec 87
nyatla 48:00d211aac2ec 88 /**
nyatla 48:00d211aac2ec 89 * MsearchResponseを格納したTxパケットをAllocする。
nyatla 48:00d211aac2ec 90 * @param i_st
nyatla 48:00d211aac2ec 91 * ST値
nyatla 48:00d211aac2ec 92 * @param i_udn
nyatla 48:00d211aac2ec 93 * DDESCのUDNの値
nyatla 48:00d211aac2ec 94 * @param i_usn
nyatla 48:00d211aac2ec 95 * USNのサフィックスパラメータ
nyatla 48:00d211aac2ec 96 * @return
nyatla 48:00d211aac2ec 97 * MsearchResponseを格納したTXメモリ
nyatla 48:00d211aac2ec 98 */
nyatla 48:00d211aac2ec 99 static void* allocMsearchResponeTx(
nyatla 48:00d211aac2ec 100 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 101 const NyLPC_TChar* i_st,
nyatla 48:00d211aac2ec 102 const NyLPC_TChar* i_udn,
nyatla 48:00d211aac2ec 103 const NyLPC_TChar* i_usn,
nyatla 48:00d211aac2ec 104 NyLPC_TUInt16 i_st_len,
nyatla 48:00d211aac2ec 105 NyLPC_TInt16* o_len)
nyatla 48:00d211aac2ec 106 {
nyatla 48:00d211aac2ec 107 NyLPC_TChar* obuf;
nyatla 48:00d211aac2ec 108 NyLPC_TUInt16 l;
nyatla 57:bc4330dfa62f 109 NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)((i_usn!=NULL)?strlen(i_usn):0);
nyatla 48:00d211aac2ec 110 NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
nyatla 48:00d211aac2ec 111 NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
nyatla 48:00d211aac2ec 112
nyatla 48:00d211aac2ec 113 // //161Byte
nyatla 48:00d211aac2ec 114 // "HTTP/1.1 200 OK\r\n" //15+2=17
nyatla 48:00d211aac2ec 115 // "CACHE-CONTROL: max-age = nnnn\r\n" //29+2=31
nyatla 48:00d211aac2ec 116 // "SERVER: [:40byte:]\r\n" //8+40+2=50
nyatla 48:00d211aac2ec 117 // "EXT: \r\n" //5+2 = 7
nyatla 48:00d211aac2ec 118 // "LOCATION: http://xxx.xxx.xxx.xxx:nnnnn/%s/d.xml\r\n" //34+2=46
nyatla 48:00d211aac2ec 119 // "USN: %s%s\r\n" //5+2=7
nyatla 48:00d211aac2ec 120 // "ST: %s\r\n\r\n" //4+4=8
nyatla 48:00d211aac2ec 121 l=166+len_location+len_usn+len_udn+i_st_len;
nyatla 109:18f12ac01097 122 obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,l,&l,TIMEOUT_IN_MS);
nyatla 48:00d211aac2ec 123
nyatla 48:00d211aac2ec 124 if(obuf==NULL){
nyatla 48:00d211aac2ec 125 return NULL;
nyatla 48:00d211aac2ec 126 }
nyatla 48:00d211aac2ec 127 //必要なメモリサイズを確保できた?
nyatla 48:00d211aac2ec 128 if(l<161+len_location+len_usn+len_udn+i_st_len)
nyatla 48:00d211aac2ec 129 {
nyatla 109:18f12ac01097 130 NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf);
nyatla 48:00d211aac2ec 131 return NULL;
nyatla 48:00d211aac2ec 132 }
nyatla 48:00d211aac2ec 133 //ワーク変数lの再初期化
nyatla 48:00d211aac2ec 134 l=0;
nyatla 48:00d211aac2ec 135 strcpy(obuf,
nyatla 48:00d211aac2ec 136 "HTTP/1.1 200 OK\r\n"
nyatla 48:00d211aac2ec 137 "CACHE-CONTROL: max-age = 300\r\n"
nyatla 48:00d211aac2ec 138 "SERVER: "SERVER_MESSAGE_HEADER"\r\n"
nyatla 48:00d211aac2ec 139 "EXT: \r\n"
nyatla 48:00d211aac2ec 140 "LOCATION: http://");
nyatla 48:00d211aac2ec 141 l+=strlen(obuf);
nyatla 48:00d211aac2ec 142 //IP addr:port\r\n
nyatla 109:18f12ac01097 143 l+=NyLPC_TIPv4Addr_toString(NyLPC_iUdpSocket_getSockIP(i_inst->_socket),obuf+l);
nyatla 48:00d211aac2ec 144 *(obuf+l)=':';
nyatla 48:00d211aac2ec 145 l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
nyatla 48:00d211aac2ec 146 *(obuf+l)='/';l++;
nyatla 48:00d211aac2ec 147 memcpy(obuf+l,i_inst->location_path,len_location);l+=len_location;
nyatla 48:00d211aac2ec 148 memcpy(obuf+l,"/d.xml",6);l+=6;
nyatla 48:00d211aac2ec 149 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 150 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 151 l+=2;
nyatla 48:00d211aac2ec 152 //USN: uuid:xxx
nyatla 48:00d211aac2ec 153 memcpy(obuf+l,"USN: ",5); l+=5;
nyatla 48:00d211aac2ec 154 memcpy(obuf+l,i_udn,len_udn); l+=len_udn; //uuid:xxx
nyatla 48:00d211aac2ec 155 if(i_usn!=NULL){
nyatla 48:00d211aac2ec 156 *(obuf+l+0)=':';
nyatla 48:00d211aac2ec 157 *(obuf+l+1)=':';
nyatla 48:00d211aac2ec 158 l+=2;
nyatla 48:00d211aac2ec 159 memcpy(obuf+l,i_usn,len_usn);l+=len_usn; //usn:xxx
nyatla 48:00d211aac2ec 160 }
nyatla 48:00d211aac2ec 161 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 162 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 163 l+=2;
nyatla 48:00d211aac2ec 164 //ST
nyatla 48:00d211aac2ec 165 memcpy(obuf+l,"ST: ",4); l+=4;
nyatla 48:00d211aac2ec 166 memcpy(obuf+l,i_st,i_st_len);l+=i_st_len;
nyatla 48:00d211aac2ec 167 memcpy(obuf+l,"\r\n\r\n",4); l+=4;
nyatla 48:00d211aac2ec 168 *o_len=l;
nyatla 48:00d211aac2ec 169 return obuf;
nyatla 48:00d211aac2ec 170 }
nyatla 48:00d211aac2ec 171
nyatla 48:00d211aac2ec 172
nyatla 48:00d211aac2ec 173 /**
nyatla 48:00d211aac2ec 174 * MsearchResponseを格納したTxパケットをAllocする。
nyatla 48:00d211aac2ec 175 * @param i_udn
nyatla 48:00d211aac2ec 176 * udn
nyatla 48:00d211aac2ec 177 * @param i_udn
nyatla 48:00d211aac2ec 178 * DDESCのUDNの値
nyatla 48:00d211aac2ec 179 * @param i_usn
nyatla 48:00d211aac2ec 180 * USNのサフィックスパラメータ
nyatla 48:00d211aac2ec 181 * @return
nyatla 48:00d211aac2ec 182 * MsearchResponseを格納したTXメモリ
nyatla 48:00d211aac2ec 183 */
nyatla 48:00d211aac2ec 184 static void* allocNotifyTx(
nyatla 48:00d211aac2ec 185 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 186 const NyLPC_TChar* i_udn,
nyatla 48:00d211aac2ec 187 const NyLPC_TChar* i_usn,
nyatla 48:00d211aac2ec 188 NyLPC_TInt16* o_len)
nyatla 48:00d211aac2ec 189 {
nyatla 48:00d211aac2ec 190 NyLPC_TChar* obuf;
nyatla 48:00d211aac2ec 191 NyLPC_TUInt16 l,l2;
nyatla 57:bc4330dfa62f 192 NyLPC_TUInt16 len_usn=(NyLPC_TUInt16)((i_usn!=NULL)?strlen(i_usn):0);
nyatla 48:00d211aac2ec 193 NyLPC_TUInt16 len_udn=(NyLPC_TUInt16)strlen(i_udn);
nyatla 48:00d211aac2ec 194 NyLPC_TUInt16 len_location=(NyLPC_TUInt16)strlen(i_inst->location_path);
nyatla 50:35e765380772 195
nyatla 48:00d211aac2ec 196 // //193Byte
nyatla 48:00d211aac2ec 197 // "NOTIFY * HTTP/1.1\r\n" //15+2=17
nyatla 48:00d211aac2ec 198 // "HOST: 239.255.255.250:1900\r\n" //26+2=28
nyatla 48:00d211aac2ec 199 // "CACHE-CONTROL: max-age = 1800\r\n" //29+2=31
nyatla 48:00d211aac2ec 200 // "SERVER: [:40byte:]\r\n" //8+40+2=50
nyatla 48:00d211aac2ec 201 // "NTS: ssdp:alive\r\n" //14+2 =17
nyatla 48:00d211aac2ec 202 // "LOCATION: http://xxx.xxx.xxx.xxx:nnnnn/%s/d.xml\r\n"//44+2=46
nyatla 48:00d211aac2ec 203 // "USN: %s%s\r\n" //5+2=7
nyatla 48:00d211aac2ec 204 // "NT: %s\r\n\r\n" //4+4=8
nyatla 57:bc4330dfa62f 205 l2=204+len_location+len_usn+len_udn+((len_usn>0)?len_usn:len_udn);
nyatla 109:18f12ac01097 206 obuf=NyLPC_iUdpSocket_allocSendBuf(i_inst->_socket,l2,&l,TIMEOUT_IN_MS);
nyatla 48:00d211aac2ec 207 if(obuf==NULL){
nyatla 48:00d211aac2ec 208 return NULL;
nyatla 48:00d211aac2ec 209 }
nyatla 48:00d211aac2ec 210 //必要なメモリサイズを確保できた?
nyatla 48:00d211aac2ec 211 if(l<l2)
nyatla 48:00d211aac2ec 212 {
nyatla 109:18f12ac01097 213 NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,obuf);
nyatla 48:00d211aac2ec 214 return NULL;
nyatla 48:00d211aac2ec 215 }
nyatla 48:00d211aac2ec 216 //ワーク変数lの再初期化
nyatla 48:00d211aac2ec 217 l=0;
nyatla 48:00d211aac2ec 218 strcpy(obuf,
nyatla 48:00d211aac2ec 219 "NOTIFY * HTTP/1.1\r\n"
nyatla 48:00d211aac2ec 220 "HOST: 239.255.255.250:1900\r\n"
nyatla 48:00d211aac2ec 221 "CACHE-CONTROL: max-age = 300\r\n"
nyatla 48:00d211aac2ec 222 "SERVER: "SERVER_MESSAGE_HEADER"\r\n"
nyatla 48:00d211aac2ec 223 "NTS: ssdp:alive\r\n"
nyatla 48:00d211aac2ec 224 "LOCATION: http://");
nyatla 48:00d211aac2ec 225 l+=strlen(obuf);
nyatla 48:00d211aac2ec 226 //IP addr:port\r\n
nyatla 109:18f12ac01097 227 l+=NyLPC_TIPv4Addr_toString(NyLPC_iUdpSocket_getSockIP(i_inst->_socket),obuf+l);
nyatla 48:00d211aac2ec 228 *(obuf+l)=':';
nyatla 48:00d211aac2ec 229 l+=1+NyLPC_itoa(i_inst->location_port,obuf+l+1,10);
nyatla 48:00d211aac2ec 230 *(obuf+l)='/';l++;
nyatla 48:00d211aac2ec 231 memcpy(obuf+l,i_inst->location_path,len_location);l+=len_location;
nyatla 48:00d211aac2ec 232 memcpy(obuf+l,"/d.xml",6);l+=6;
nyatla 48:00d211aac2ec 233 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 234 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 235 l+=2;
nyatla 48:00d211aac2ec 236 //USN: uuid:xxx
nyatla 48:00d211aac2ec 237 memcpy(obuf+l,"USN: ",5); l+=5;
nyatla 48:00d211aac2ec 238 memcpy(obuf+l,i_udn,len_udn); l+=len_udn; //uuid:xxx
nyatla 48:00d211aac2ec 239 if(i_usn!=NULL){
nyatla 48:00d211aac2ec 240 *(obuf+l+0)=':';
nyatla 48:00d211aac2ec 241 *(obuf+l+1)=':';
nyatla 48:00d211aac2ec 242 l+=2;
nyatla 48:00d211aac2ec 243 memcpy(obuf+l,i_usn,len_usn);l+=len_usn; //usn:xxx
nyatla 48:00d211aac2ec 244 }
nyatla 48:00d211aac2ec 245 *(obuf+l+0)='\r';
nyatla 48:00d211aac2ec 246 *(obuf+l+1)='\n';
nyatla 48:00d211aac2ec 247 l+=2;
nyatla 48:00d211aac2ec 248 //NT
nyatla 48:00d211aac2ec 249 memcpy(obuf+l,"NT: ",4); l+=4;
nyatla 48:00d211aac2ec 250 if(len_usn>0){
nyatla 48:00d211aac2ec 251 memcpy(obuf+l,i_usn,len_usn);l+=len_usn;
nyatla 48:00d211aac2ec 252 }else{
nyatla 48:00d211aac2ec 253 memcpy(obuf+l,i_udn,len_udn);l+=len_udn;
nyatla 48:00d211aac2ec 254 }
nyatla 48:00d211aac2ec 255 memcpy(obuf+l,"\r\n\r\n",4); l+=4;
nyatla 48:00d211aac2ec 256 *o_len=l;
nyatla 48:00d211aac2ec 257 return obuf;
nyatla 48:00d211aac2ec 258 }
nyatla 48:00d211aac2ec 259
nyatla 48:00d211aac2ec 260
nyatla 48:00d211aac2ec 261 static NyLPC_TBool messageHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_name,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
nyatla 48:00d211aac2ec 262 {
nyatla 48:00d211aac2ec 263 struct TMSearchHeader* header=(struct TMSearchHeader*)o_out;
nyatla 48:00d211aac2ec 264 switch(header->st)
nyatla 48:00d211aac2ec 265 {
nyatla 48:00d211aac2ec 266 case PARSE_NULL:
nyatla 48:00d211aac2ec 267 if(NyLPC_stricmp(i_name,"ST")==0){
nyatla 48:00d211aac2ec 268 //mode==ST
nyatla 48:00d211aac2ec 269 header->st=PARSE_ST;
nyatla 48:00d211aac2ec 270 header->result.st_str=NULL;
nyatla 48:00d211aac2ec 271 }else if(NyLPC_stricmp(i_name,"MAN")==0){
nyatla 48:00d211aac2ec 272 //mode=MAN
nyatla 48:00d211aac2ec 273 header->st=PARSE_MAN;
nyatla 48:00d211aac2ec 274 header->result.man_str=NULL;
nyatla 48:00d211aac2ec 275 }else{
nyatla 48:00d211aac2ec 276 header->st=PARSE_UNKNOWN;
nyatla 48:00d211aac2ec 277 //無視
nyatla 48:00d211aac2ec 278 }
nyatla 48:00d211aac2ec 279 break;
nyatla 48:00d211aac2ec 280 case PARSE_ST:
nyatla 48:00d211aac2ec 281 if((header->result.st_str==NULL) && (i_c!=HTTP_SP)){
nyatla 48:00d211aac2ec 282 header->result.st_str=header->_rpos;
nyatla 48:00d211aac2ec 283 }
nyatla 48:00d211aac2ec 284 if(i_c=='\0')
nyatla 48:00d211aac2ec 285 {
nyatla 48:00d211aac2ec 286 header->result.st_len=header->_rpos-header->result.st_str-1;
nyatla 48:00d211aac2ec 287 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 288 }
nyatla 48:00d211aac2ec 289 break;
nyatla 48:00d211aac2ec 290 case PARSE_MAN:
nyatla 48:00d211aac2ec 291 if((header->result.man_str==NULL) && (i_c!=HTTP_SP)){
nyatla 48:00d211aac2ec 292 header->result.man_str=header->_rpos;
nyatla 48:00d211aac2ec 293 }
nyatla 48:00d211aac2ec 294 if(i_c=='\0'){
nyatla 48:00d211aac2ec 295 header->result.man_len=header->_rpos-header->result.man_str-1;
nyatla 48:00d211aac2ec 296 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 297 }
nyatla 48:00d211aac2ec 298 break;
nyatla 48:00d211aac2ec 299 case PARSE_UNKNOWN:
nyatla 48:00d211aac2ec 300 default:
nyatla 48:00d211aac2ec 301 if(i_c=='\0'){
nyatla 48:00d211aac2ec 302 header->st=PARSE_NULL;
nyatla 48:00d211aac2ec 303 }
nyatla 48:00d211aac2ec 304 break;
nyatla 48:00d211aac2ec 305 }
nyatla 48:00d211aac2ec 306 return NyLPC_TBool_TRUE;
nyatla 48:00d211aac2ec 307 }
nyatla 48:00d211aac2ec 308
nyatla 48:00d211aac2ec 309 /**
nyatla 48:00d211aac2ec 310 * デフォルトハンドラ
nyatla 48:00d211aac2ec 311 */
nyatla 48:00d211aac2ec 312 static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler=
nyatla 48:00d211aac2ec 313 {
nyatla 48:00d211aac2ec 314 messageHandler,
nyatla 48:00d211aac2ec 315 urlHandler
nyatla 48:00d211aac2ec 316 };
nyatla 48:00d211aac2ec 317
nyatla 48:00d211aac2ec 318 static NyLPC_TBool parseHeader(struct TMSearchHeader* i_out,const void* i_rx,NyLPC_TInt16 i_rx_size)
nyatla 48:00d211aac2ec 319 {
nyatla 48:00d211aac2ec 320 NyLPC_TInt16 i;
nyatla 48:00d211aac2ec 321 NyLPC_TcHttpBasicHeaderParser_t parser;
nyatla 48:00d211aac2ec 322 //headerの初期化
nyatla 48:00d211aac2ec 323 i_out->st=PARSE_NULL;
nyatla 48:00d211aac2ec 324 i_out->result.st_str=NULL;
nyatla 48:00d211aac2ec 325 i_out->result.man_str=NULL;
nyatla 48:00d211aac2ec 326 NyLPC_cHttpBasicHeaderParser_initialize(&parser,&handler);
nyatla 48:00d211aac2ec 327 NyLPC_cHttpBasicHeaderParser_parseInit(&parser,&(i_out->super));
nyatla 48:00d211aac2ec 328 for(i=0;i<i_rx_size;i++){
nyatla 48:00d211aac2ec 329 i_out->_rpos=((const char*)(i_rx))+i;
nyatla 48:00d211aac2ec 330 if(NyLPC_cHttpBasicHeaderParser_parseChar(&parser,i_out->_rpos,1,&(i_out->super))<0){
nyatla 48:00d211aac2ec 331 NyLPC_cHttpBasicHeaderParser_finalize(&parser);
nyatla 48:00d211aac2ec 332 return NyLPC_TBool_FALSE;//ERROR
nyatla 48:00d211aac2ec 333 }
nyatla 48:00d211aac2ec 334 }
nyatla 48:00d211aac2ec 335 NyLPC_cHttpBasicHeaderParser_parseFinish(&parser,&(i_out->super));
nyatla 48:00d211aac2ec 336 NyLPC_cHttpBasicHeaderParser_finalize(&parser);
nyatla 48:00d211aac2ec 337 return NyLPC_TBool_TRUE;//OK
nyatla 48:00d211aac2ec 338 }
nyatla 48:00d211aac2ec 339
nyatla 109:18f12ac01097 340 static NyLPC_TBool onPacket(NyLPC_TiUdpSocket_t* i_sock,const void* i_buf,const struct NyLPC_TIPv4RxInfo* i_info)
nyatla 48:00d211aac2ec 341 {
nyatla 48:00d211aac2ec 342 //パケット解析
nyatla 48:00d211aac2ec 343 void* tx;
nyatla 48:00d211aac2ec 344 struct TMSearchHeader header;
nyatla 48:00d211aac2ec 345 NyLPC_TInt16 tx_len;
nyatla 48:00d211aac2ec 346 NyLPC_TInt8 i,i2;
nyatla 109:18f12ac01097 347 NyLPC_TcSsdpSocket_t* inst=((NyLPC_TcSsdpSocket_t*)i_sock->_tag);
nyatla 48:00d211aac2ec 348 if(!parseHeader(&header,i_buf,i_info->size)){
nyatla 48:00d211aac2ec 349 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 350 }
nyatla 48:00d211aac2ec 351 //resultチェック
nyatla 48:00d211aac2ec 352 if(header.result.man_str==NULL || header.result.st_str==NULL){
nyatla 48:00d211aac2ec 353 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 354 }
nyatla 48:00d211aac2ec 355 //Methodチェック
nyatla 48:00d211aac2ec 356 if(header.super.startline.req.method!=NyLPC_THttpMethodType_M_SEARCH){
nyatla 48:00d211aac2ec 357 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 358 }
nyatla 48:00d211aac2ec 359
nyatla 48:00d211aac2ec 360 //MANチェック
nyatla 48:00d211aac2ec 361 if(strncmp("\"ssdp:discover\"",header.result.man_str,15)!=0){
nyatla 48:00d211aac2ec 362 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 363 }
nyatla 48:00d211aac2ec 364 //STによる処理分岐
nyatla 48:00d211aac2ec 365 if(strncmp("ssdp:all",header.result.st_str,8)==0){
nyatla 48:00d211aac2ec 366 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 367 inst,header.result.st_str,
nyatla 109:18f12ac01097 368 inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE,
nyatla 48:00d211aac2ec 369 header.result.st_len,
nyatla 48:00d211aac2ec 370 &tx_len);
nyatla 48:00d211aac2ec 371 if(tx==NULL){
nyatla 48:00d211aac2ec 372 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 373 }
nyatla 109:18f12ac01097 374 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 375 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 376 }
nyatla 48:00d211aac2ec 377 //全デバイスの送信
nyatla 109:18f12ac01097 378 for(i=0;i<inst->number_of_device;i++){
nyatla 48:00d211aac2ec 379 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 380 inst,header.result.st_str,
nyatla 109:18f12ac01097 381 inst->ref_device_record[i]->udn,inst->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 382 header.result.st_len,
nyatla 48:00d211aac2ec 383 &tx_len);
nyatla 48:00d211aac2ec 384 if(tx==NULL){
nyatla 48:00d211aac2ec 385 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 386 }
nyatla 109:18f12ac01097 387 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 388 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 389 }
nyatla 109:18f12ac01097 390 for(i2=0;i2<inst->ref_device_record[i]->number_of_service;i2++){
nyatla 48:00d211aac2ec 391 //serviceに一致
nyatla 48:00d211aac2ec 392 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 393 inst,header.result.st_str,
nyatla 109:18f12ac01097 394 inst->ref_device_record[i]->udn,inst->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 395 header.result.st_len,
nyatla 48:00d211aac2ec 396 &tx_len);
nyatla 48:00d211aac2ec 397 if(tx==NULL){
nyatla 48:00d211aac2ec 398 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 399 }
nyatla 109:18f12ac01097 400 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 401 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 402 }
nyatla 48:00d211aac2ec 403 }
nyatla 48:00d211aac2ec 404 }
nyatla 48:00d211aac2ec 405 }else if(strncmp("uuid:",header.result.st_str,5)==0){
nyatla 48:00d211aac2ec 406 //UDNの一致するデバイスの送信
nyatla 48:00d211aac2ec 407 NyLPC_TInt16 i;
nyatla 109:18f12ac01097 408 for(i=inst->number_of_device-1;i>=0;i--){
nyatla 109:18f12ac01097 409 if(strncmp(header.result.st_str,inst->ref_device_record[i]->udn,header.result.st_len)==0){
nyatla 48:00d211aac2ec 410 //UDN一致
nyatla 48:00d211aac2ec 411 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 412 inst,header.result.st_str,
nyatla 109:18f12ac01097 413 inst->ref_device_record[i]->udn,NULL,
nyatla 48:00d211aac2ec 414 header.result.st_len,
nyatla 48:00d211aac2ec 415 &tx_len);
nyatla 48:00d211aac2ec 416 if(tx==NULL){
nyatla 48:00d211aac2ec 417 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 418 }
nyatla 109:18f12ac01097 419 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 420 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 421 }
nyatla 48:00d211aac2ec 422 break;//送信処理終了
nyatla 48:00d211aac2ec 423 }
nyatla 48:00d211aac2ec 424 }
nyatla 48:00d211aac2ec 425 }else if(strncmp(STR_UPNP_ROOT_DEVICE,header.result.st_str,15)==0){
nyatla 100:8d45dab6dcf6 426 //rootDeviceはSTR_UPNP_ROOT_DEVICE
nyatla 48:00d211aac2ec 427 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 428 inst,header.result.st_str,
nyatla 109:18f12ac01097 429 inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE,
nyatla 48:00d211aac2ec 430 header.result.st_len,
nyatla 48:00d211aac2ec 431 &tx_len);
nyatla 48:00d211aac2ec 432 if(tx==NULL){
nyatla 48:00d211aac2ec 433 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 434 }
nyatla 109:18f12ac01097 435 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 436 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 437 }
nyatla 48:00d211aac2ec 438 }else if(strncmp("urn:",header.result.st_str,4)==0){
nyatla 109:18f12ac01097 439 for(i=0;i<inst->number_of_device;i++){
nyatla 48:00d211aac2ec 440 //urn一致チェック
nyatla 109:18f12ac01097 441 if(strncmp(inst->ref_device_record[i]->device_type,header.result.st_str,header.result.st_len)==0){
nyatla 48:00d211aac2ec 442 //deviceに一致
nyatla 48:00d211aac2ec 443 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 444 inst,header.result.st_str,
nyatla 109:18f12ac01097 445 inst->ref_device_record[i]->udn,inst->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 446 header.result.st_len,
nyatla 48:00d211aac2ec 447 &tx_len);
nyatla 48:00d211aac2ec 448 if(tx==NULL){
nyatla 48:00d211aac2ec 449 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 450 }
nyatla 109:18f12ac01097 451 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 452 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 453 }
nyatla 48:00d211aac2ec 454 continue;
nyatla 48:00d211aac2ec 455 }
nyatla 109:18f12ac01097 456 for(i2=0;i2<inst->ref_device_record[i]->number_of_service;i2++){
nyatla 109:18f12ac01097 457 if(strncmp(inst->ref_device_record[i]->services[i2].service_type,header.result.st_str,header.result.st_len)==0){
nyatla 48:00d211aac2ec 458 //serviceに一致
nyatla 48:00d211aac2ec 459 tx=allocMsearchResponeTx(
nyatla 109:18f12ac01097 460 inst,header.result.st_str,
nyatla 109:18f12ac01097 461 inst->ref_device_record[i]->udn,inst->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 462 header.result.st_len,
nyatla 48:00d211aac2ec 463 &tx_len);
nyatla 48:00d211aac2ec 464 if(tx==NULL){
nyatla 48:00d211aac2ec 465 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 466 }
nyatla 109:18f12ac01097 467 if(!NyLPC_iUdpSocket_psend(i_sock,&i_info->peer_ip,i_info->peer_port,tx,tx_len)){
nyatla 48:00d211aac2ec 468 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 469 }
nyatla 48:00d211aac2ec 470 }
nyatla 48:00d211aac2ec 471 }
nyatla 48:00d211aac2ec 472 }
nyatla 48:00d211aac2ec 473 }
nyatla 48:00d211aac2ec 474 //正常終了
nyatla 48:00d211aac2ec 475 return NyLPC_TBool_FALSE;
nyatla 48:00d211aac2ec 476 ERROR2:
nyatla 109:18f12ac01097 477 NyLPC_iUdpSocket_releaseSendBuf(i_sock,tx);
nyatla 48:00d211aac2ec 478 ERROR1:
nyatla 48:00d211aac2ec 479 return NyLPC_TBool_FALSE;
nyatla 48:00d211aac2ec 480 }
nyatla 48:00d211aac2ec 481
nyatla 100:8d45dab6dcf6 482 #define SSDP_NOTIFY_INTERVAL 150*1000 //300*0.5*1000
nyatla 48:00d211aac2ec 483 #define FLAG_ORDER_START_SERVICE 0
nyatla 48:00d211aac2ec 484 #define FLAG_ORDER_STOP_SERVICE 1
nyatla 48:00d211aac2ec 485 #define FLAG_IS_SERVICE_RUNNING 2
nyatla 48:00d211aac2ec 486
nyatla 109:18f12ac01097 487 static void onPeriodic(NyLPC_TiUdpSocket_t* i_sock)
nyatla 48:00d211aac2ec 488 {
nyatla 109:18f12ac01097 489 NyLPC_TcSsdpSocket_t* inst=(NyLPC_TcSsdpSocket_t*)i_sock->_tag;
nyatla 109:18f12ac01097 490 if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_IS_SERVICE_RUNNING)){
nyatla 48:00d211aac2ec 491 //実行中
nyatla 48:00d211aac2ec 492 //停止要求着てる?
nyatla 109:18f12ac01097 493 if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_ORDER_STOP_SERVICE))
nyatla 48:00d211aac2ec 494 {
nyatla 48:00d211aac2ec 495 //状態変更
nyatla 109:18f12ac01097 496 NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_IS_SERVICE_RUNNING);
nyatla 48:00d211aac2ec 497 //要求フラグクリア
nyatla 109:18f12ac01097 498 NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_ORDER_STOP_SERVICE);
nyatla 48:00d211aac2ec 499 //@bug ByeBye送信しろ
nyatla 109:18f12ac01097 500 }else if(NyLPC_cStopwatch_isExpired(&inst->_periodic_sw)){
nyatla 48:00d211aac2ec 501 //Notify送信
nyatla 109:18f12ac01097 502 NyLPC_cSsdpSocket_notify(inst);
nyatla 48:00d211aac2ec 503 //タイマ再始動
nyatla 109:18f12ac01097 504 NyLPC_cStopwatch_startExpire(&inst->_periodic_sw,SSDP_NOTIFY_INTERVAL);
nyatla 48:00d211aac2ec 505 }
nyatla 48:00d211aac2ec 506 }else{
nyatla 48:00d211aac2ec 507 //停止中
nyatla 48:00d211aac2ec 508 //開始要求着てる?
nyatla 109:18f12ac01097 509 if(NyLPC_TUInt8_isBitOn(inst->_flags,FLAG_ORDER_START_SERVICE))
nyatla 48:00d211aac2ec 510 {
nyatla 48:00d211aac2ec 511 //状態変更
nyatla 109:18f12ac01097 512 NyLPC_TUInt8_setBit(inst->_flags,FLAG_IS_SERVICE_RUNNING);
nyatla 48:00d211aac2ec 513 //要求フラグクリア
nyatla 109:18f12ac01097 514 NyLPC_TUInt8_unsetBit(inst->_flags,FLAG_ORDER_START_SERVICE);
nyatla 48:00d211aac2ec 515 //次回expireするように
nyatla 109:18f12ac01097 516 NyLPC_cStopwatch_startExpire(&inst->_periodic_sw,SSDP_NOTIFY_INTERVAL);
nyatla 48:00d211aac2ec 517 }
nyatla 48:00d211aac2ec 518 }
nyatla 48:00d211aac2ec 519 }
nyatla 48:00d211aac2ec 520
nyatla 48:00d211aac2ec 521 /**
nyatla 48:00d211aac2ec 522 * デバイスツリーを展開する。
nyatla 48:00d211aac2ec 523 */
nyatla 48:00d211aac2ec 524 static void expandDeviceTree(NyLPC_TcSsdpSocket_t* i_inst,const struct NyLPC_TUPnPDevDescDevice* i_dev)
nyatla 48:00d211aac2ec 525 {
nyatla 48:00d211aac2ec 526 NyLPC_TUInt16 i;
nyatla 48:00d211aac2ec 527 if(i_inst->number_of_device>=NyLPC_TcSsdpSocket_MAX_DEVICES){
nyatla 48:00d211aac2ec 528 NyLPC_Warning();//
nyatla 48:00d211aac2ec 529 }
nyatla 48:00d211aac2ec 530 i_inst->ref_device_record[i_inst->number_of_device]=i_dev;
nyatla 48:00d211aac2ec 531 i_inst->number_of_device++;
nyatla 48:00d211aac2ec 532 for(i=0;i<i_dev->number_of_devices;i++){
nyatla 48:00d211aac2ec 533 expandDeviceTree(i_inst,i_dev->devices[i]);
nyatla 48:00d211aac2ec 534 }
nyatla 48:00d211aac2ec 535 return;
nyatla 48:00d211aac2ec 536 }
nyatla 48:00d211aac2ec 537
nyatla 48:00d211aac2ec 538 void NyLPC_cSsdpSocket_initialize(
nyatla 48:00d211aac2ec 539 NyLPC_TcSsdpSocket_t* i_inst,
nyatla 48:00d211aac2ec 540 const struct NyLPC_TUPnPDevDescDevice* i_ref_dev_record,
nyatla 48:00d211aac2ec 541 NyLPC_TUInt16 i_server_port,const NyLPC_TChar* i_ref_location_path)
nyatla 48:00d211aac2ec 542 {
nyatla 109:18f12ac01097 543 i_inst->_socket=NyLPC_cNetIf_createUdpSocketEx(1900,NyLPC_TSocketType_UDP_NOBUF);
nyatla 109:18f12ac01097 544 i_inst->_socket->_tag=i_inst;
nyatla 48:00d211aac2ec 545
nyatla 109:18f12ac01097 546 NyLPC_iUdpSocket_setOnRxHandler(i_inst->_socket,onPacket);
nyatla 109:18f12ac01097 547 NyLPC_iUdpSocket_setOnPeriodicHandler(i_inst->_socket,onPeriodic);
nyatla 109:18f12ac01097 548
nyatla 109:18f12ac01097 549 NyLPC_iUdpSocket_joinMulticast(i_inst->_socket,&SSDP_MCAST_IPADDR);
nyatla 48:00d211aac2ec 550 i_inst->_flags=0;
nyatla 48:00d211aac2ec 551 NyLPC_cStopwatch_initialize(&(i_inst->_periodic_sw));
nyatla 50:35e765380772 552 i_inst->number_of_device=0;
nyatla 48:00d211aac2ec 553 expandDeviceTree(i_inst,i_ref_dev_record);
nyatla 48:00d211aac2ec 554 i_inst->location_port=i_server_port;
nyatla 48:00d211aac2ec 555 i_inst->location_path=i_ref_location_path;
nyatla 48:00d211aac2ec 556 }
nyatla 48:00d211aac2ec 557 void NyLPC_cSsdpSocket_finalize(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 558 {
nyatla 48:00d211aac2ec 559 NyLPC_cStopwatch_finalize(&(i_inst->_periodic_sw));
nyatla 109:18f12ac01097 560 NyLPC_iUdpSocket_finalize(i_inst->_socket);
nyatla 48:00d211aac2ec 561 }
nyatla 48:00d211aac2ec 562
nyatla 48:00d211aac2ec 563 void NyLPC_cSsdpSocket_start(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 564 {
nyatla 48:00d211aac2ec 565 //Notifyを3回送信
nyatla 48:00d211aac2ec 566 NyLPC_TInt16 i;
nyatla 53:9fdba33969fe 567 NyLPC_cSsdpSocket_notify(i_inst);
nyatla 53:9fdba33969fe 568 for(i=0;i<2;i++){
nyatla 53:9fdba33969fe 569 NyLPC_cThread_sleep(800);
nyatla 48:00d211aac2ec 570 NyLPC_cSsdpSocket_notify(i_inst);
nyatla 48:00d211aac2ec 571 }
nyatla 48:00d211aac2ec 572
nyatla 48:00d211aac2ec 573 //ストップウォッチの開始要求
nyatla 48:00d211aac2ec 574 NyLPC_TUInt8_setBit(i_inst->_flags,FLAG_ORDER_START_SERVICE);
nyatla 48:00d211aac2ec 575 do{
nyatla 48:00d211aac2ec 576 NyLPC_cThread_sleep(10);
nyatla 48:00d211aac2ec 577 //開始フラグがクリアされるまでループ
nyatla 48:00d211aac2ec 578 }while(NyLPC_TUInt8_isBitOn(i_inst->_flags,FLAG_ORDER_START_SERVICE));
nyatla 48:00d211aac2ec 579 }
nyatla 48:00d211aac2ec 580 void NyLPC_cSsdpSocket_stop(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 581 {
nyatla 48:00d211aac2ec 582 //今は使えない。
nyatla 48:00d211aac2ec 583 NyLPC_Abort();
nyatla 48:00d211aac2ec 584 NyLPC_TUInt8_setBit(i_inst->_flags,FLAG_ORDER_STOP_SERVICE);
nyatla 48:00d211aac2ec 585 do{
nyatla 48:00d211aac2ec 586 NyLPC_cThread_sleep(10);
nyatla 48:00d211aac2ec 587 //開始フラグがクリアされるまでループ
nyatla 48:00d211aac2ec 588 }while(NyLPC_TUInt8_isBitOn(i_inst->_flags,FLAG_ORDER_STOP_SERVICE));
nyatla 48:00d211aac2ec 589 }
nyatla 48:00d211aac2ec 590 void NyLPC_cSsdpSocket_notify(NyLPC_TcSsdpSocket_t* i_inst)
nyatla 48:00d211aac2ec 591 {
nyatla 48:00d211aac2ec 592 void* tx;
nyatla 48:00d211aac2ec 593 NyLPC_TInt16 tx_len;
nyatla 48:00d211aac2ec 594 NyLPC_TUInt8 i,i2;
nyatla 48:00d211aac2ec 595 //rootdevice
nyatla 48:00d211aac2ec 596 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 597 i_inst,
nyatla 48:00d211aac2ec 598 i_inst->ref_device_record[0]->udn,STR_UPNP_ROOT_DEVICE,
nyatla 48:00d211aac2ec 599 &tx_len);
nyatla 48:00d211aac2ec 600 if(tx==NULL){
nyatla 48:00d211aac2ec 601 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 602 }
nyatla 109:18f12ac01097 603 if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 604 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 605 }
nyatla 48:00d211aac2ec 606 //all device
nyatla 48:00d211aac2ec 607 for(i=0;i<i_inst->number_of_device;i++){
nyatla 48:00d211aac2ec 608 //uuid
nyatla 48:00d211aac2ec 609 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 610 i_inst,
nyatla 48:00d211aac2ec 611 i_inst->ref_device_record[i]->udn,NULL,
nyatla 48:00d211aac2ec 612 &tx_len);
nyatla 48:00d211aac2ec 613 if(tx==NULL){
nyatla 48:00d211aac2ec 614 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 615 }
nyatla 109:18f12ac01097 616 if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 617 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 618 }
nyatla 48:00d211aac2ec 619 //devicatype
nyatla 48:00d211aac2ec 620 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 621 i_inst,
nyatla 48:00d211aac2ec 622 i_inst->ref_device_record[i]->udn,i_inst->ref_device_record[i]->device_type,
nyatla 48:00d211aac2ec 623 &tx_len);
nyatla 48:00d211aac2ec 624 if(tx==NULL){
nyatla 48:00d211aac2ec 625 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 626 }
nyatla 109:18f12ac01097 627 if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 628 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 629 }
nyatla 48:00d211aac2ec 630 for(i2=0;i2<i_inst->ref_device_record[i]->number_of_service;i2++){
nyatla 48:00d211aac2ec 631 tx=allocNotifyTx(
nyatla 48:00d211aac2ec 632 i_inst,
nyatla 48:00d211aac2ec 633 i_inst->ref_device_record[i]->udn,i_inst->ref_device_record[i]->services[i2].service_type,
nyatla 48:00d211aac2ec 634 &tx_len);
nyatla 48:00d211aac2ec 635 if(tx==NULL){
nyatla 48:00d211aac2ec 636 NyLPC_OnErrorGoto(ERROR1);
nyatla 48:00d211aac2ec 637 }
nyatla 109:18f12ac01097 638 if(!NyLPC_iUdpSocket_psend(i_inst->_socket,&SSDP_MCAST_IPADDR,1900,tx,tx_len)){
nyatla 48:00d211aac2ec 639 NyLPC_OnErrorGoto(ERROR2);
nyatla 48:00d211aac2ec 640 }
nyatla 48:00d211aac2ec 641 }
nyatla 48:00d211aac2ec 642 }
nyatla 48:00d211aac2ec 643 return;
nyatla 48:00d211aac2ec 644 ERROR2:
nyatla 109:18f12ac01097 645 NyLPC_iUdpSocket_releaseSendBuf(i_inst->_socket,tx);
nyatla 48:00d211aac2ec 646 ERROR1:
nyatla 48:00d211aac2ec 647 return;
nyatla 48:00d211aac2ec 648 }
nyatla 48:00d211aac2ec 649