├── .gitignore ├── LICENSE ├── PZ8583.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── markzheng.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── markzheng.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── PZ8583.xcscheme │ └── xcschememanagement.plist ├── PZ8583 ├── 8583 │ ├── 8583warp │ │ ├── NSString+ThreeDes.h │ │ ├── NSString+ThreeDes.m │ │ ├── PZBaseMessage.h │ │ ├── PZBaseMessage.m │ │ ├── PZMessageRequest.h │ │ ├── PZMessageRequest.m │ │ ├── PZMessageResponse.h │ │ ├── PZMessageResponse.m │ │ ├── PZMessageUtils.h │ │ ├── PZMessageUtils.m │ │ ├── PZMiddleMessage.h │ │ ├── PZMiddleMessage.m │ │ ├── PZPosField.h │ │ ├── PZPosField.m │ │ ├── PZPrivateField60.h │ │ ├── PZPrivateField60.m │ │ ├── PZPrivateField62.h │ │ └── PZPrivateField62.m │ ├── BerTlv │ │ ├── BerTag.h │ │ ├── BerTag.m │ │ ├── BerTlv.h │ │ ├── BerTlv.m │ │ ├── BerTlvBuilder.h │ │ ├── BerTlvBuilder.m │ │ ├── BerTlvComm.h │ │ ├── BerTlvParser.h │ │ ├── BerTlvParser.m │ │ ├── BerTlvs.h │ │ ├── BerTlvs.m │ │ ├── HexUtil.h │ │ └── HexUtil.m │ ├── Utils.zip │ ├── Utils │ │ ├── BerTlv │ │ │ ├── BerTag.h │ │ │ ├── BerTag.m │ │ │ ├── BerTlv.h │ │ │ ├── BerTlv.m │ │ │ ├── BerTlvBuilder.h │ │ │ ├── BerTlvBuilder.m │ │ │ ├── BerTlvComm.h │ │ │ ├── BerTlvParser.h │ │ │ ├── BerTlvParser.m │ │ │ ├── BerTlvs.h │ │ │ ├── BerTlvs.m │ │ │ ├── HexUtil.h │ │ │ └── HexUtil.m │ │ ├── NSString+ThreeDes.h │ │ ├── NSString+ThreeDes.m │ │ ├── PZCRSA.h │ │ ├── PZCRSA.m │ │ ├── PZMessageUtils.h │ │ └── PZMessageUtils.m │ ├── handler │ │ ├── PZCustomConstant.h │ │ ├── PZCustomConstant.m │ │ ├── PZPosParamRequest.h │ │ ├── PZPosParamRequest.m │ │ ├── PZPosParamResponse.h │ │ ├── PZPosParamResponse.m │ │ ├── PZPosStateRequest.h │ │ ├── PZPosStateRequest.m │ │ ├── PZPosStateResponse.h │ │ ├── PZPosStateResponse.m │ │ ├── PZPublicKeyObject.h │ │ ├── PZPublicKeyObject.m │ │ ├── PZPurchaseRequest.h │ │ ├── PZPurchaseRequest.m │ │ ├── PZPurchaseResponse.h │ │ ├── PZPurchaseResponse.m │ │ ├── PZReverseRequest.h │ │ ├── PZReverseRequest.m │ │ ├── PZReverseResponse.h │ │ ├── PZReverseResponse.m │ │ ├── PZSignInRequest.h │ │ ├── PZSignInRequest.m │ │ ├── PZSignInResponse.h │ │ ├── PZSignInResponse.m │ │ ├── TlvTagValue.h │ │ └── TlvTagValue.m │ └── iso8583 │ │ ├── dl_base.h │ │ ├── dl_err.h │ │ ├── dl_iso8583.c │ │ ├── dl_iso8583.h │ │ ├── dl_iso8583_common.c │ │ ├── dl_iso8583_common.h │ │ ├── dl_iso8583_defs_pos.c │ │ ├── dl_iso8583_defs_pos.h │ │ ├── dl_iso8583_fields.c │ │ ├── dl_iso8583_fields.h │ │ ├── dl_mem.c │ │ ├── dl_mem.h │ │ ├── dl_output.c │ │ ├── dl_output.h │ │ ├── dl_str.c │ │ ├── dl_str.h │ │ ├── dl_time.c │ │ ├── dl_time.h │ │ ├── dl_timer.c │ │ └── dl_timer.h ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── CocoaAsyncSocket │ ├── GCD │ │ ├── GCDAsyncSocket.h │ │ ├── GCDAsyncSocket.m │ │ ├── GCDAsyncUdpSocket.h │ │ └── GCDAsyncUdpSocket.m │ ├── README.markdown │ └── RunLoop │ │ ├── AsyncSocket.h │ │ ├── AsyncSocket.m │ │ ├── AsyncUdpSocket.h │ │ └── AsyncUdpSocket.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── PLSocketCenter.h ├── PLSocketCenter.m ├── PZTransService.h ├── PZTransService.m ├── UIViewExt.h ├── UIViewExt.m ├── ViewController.h ├── ViewController.m └── main.m ├── PZ8583Tests ├── Info.plist └── PZ8583Tests.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Peter.Zheng 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 | 23 | -------------------------------------------------------------------------------- /PZ8583.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PZ8583.xcodeproj/project.xcworkspace/xcuserdata/markzheng.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefunny/ObjC-PZ8583/246371d08e45541beaf7aaa643b3fe02c6668390/PZ8583.xcodeproj/project.xcworkspace/xcuserdata/markzheng.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PZ8583.xcodeproj/xcuserdata/markzheng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PZ8583.xcodeproj/xcuserdata/markzheng.xcuserdatad/xcschemes/PZ8583.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /PZ8583.xcodeproj/xcuserdata/markzheng.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PZ8583.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | BD554D121B58B51D005AF2EF 16 | 17 | primary 18 | 19 | 20 | BD554D2B1B58B51E005AF2EF 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/NSString+ThreeDes.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ThreeDes.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (ThreeDes) 12 | 13 | //Des 14 | + (NSString*)encryptDes:(NSString*)plainText withKey:(NSString*)key; 15 | + (NSString*)decryptDes:(NSString*)plainText withKey:(NSString*)key ; 16 | 17 | //3Des 18 | + (NSString *)decrypt3Des:(NSString *)plainText withKey:(NSString *)key ; 19 | + (NSString *)encrypt3Des:(NSString *)plainText withKey:(NSString *)key ; 20 | 21 | //数据异或 22 | + (NSString *)dataXor:(NSString *)data1 withData:(NSString *)data2 ; 23 | 24 | //sha-1 25 | - (NSString*) sha1; 26 | 27 | //md5 28 | -(NSString *) md5; 29 | 30 | //base64运算 31 | + (NSString *)base64StringFromText:(NSData *)data; 32 | + (NSData *)textFromBase64String:(NSString *)string; 33 | 34 | //mac计算 35 | + (NSString *)macBlock:(NSString *)pack withMacKey:(NSString *)macKey; 36 | + (NSString *)genMacWithMacBlock:(NSString *)block withMacKey:(NSString *)macKey; 37 | 38 | //52#加密 39 | + (NSString *)pinBlock:(NSString *)password withCard:(NSString *)panNum withPinKey:(NSString *)pinkey; 40 | 41 | //磁道加密 42 | + (NSString *)trkStr:(NSString *)trkStr withTrkKey:(NSString *)trkKey; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZBaseMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZBaseMessage.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/30. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PZPosField.h" 11 | #import "PZMessageUtils.h" 12 | 13 | @interface PZBaseMessage : NSObject 14 | 15 | /*报文头,TPDU、Head*/ 16 | @property (nonatomic,strong) NSString *messageTpdu; 17 | @property (nonatomic,strong) NSString *messageHead; 18 | 19 | /*基本公共参数*/ 20 | @property (nonatomic,strong) NSString *merchantId; 21 | @property (nonatomic,strong) NSString *terminalId; 22 | @property (nonatomic,strong) NSString *mposNumber; 23 | @property (nonatomic,strong) NSString *merchantName; 24 | @property (nonatomic,strong) NSString *batchNumber; 25 | @property (nonatomic,strong) NSString *tranTtc; 26 | 27 | /*消息类型*/ 28 | @property (nonatomic,strong) NSString *messageType; 29 | 30 | @property (nonatomic,strong) PZPosField *posFields; 31 | 32 | /** 33 | * @brief 解包 34 | * @param bytes 字节数组形态的8583报文,从消息类型开始,包括mac字段。 35 | */ 36 | - (BOOL)decode:(NSData *)mes ; 37 | 38 | /** 39 | * @brief 打包成8583格式报文 40 | * @return 转换网络传输的字节 41 | */ 42 | - (NSData *)encode; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZBaseMessage.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZBaseMessage.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/30. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZBaseMessage.h" 10 | #import "PZMiddleMessage.h" 11 | 12 | NSString *const tpdu = @"6000000000"; 13 | NSString *const head = @"603100000000"; 14 | 15 | @implementation PZBaseMessage 16 | 17 | - (id)init { 18 | if (self = [super init]) { 19 | _terminalId = nil; 20 | _merchantId = nil; 21 | _posFields = [PZPosField new]; 22 | _messageTpdu = tpdu; 23 | _messageHead = head; 24 | } 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)decode:(NSData *)data { 30 | PZMiddleMessage *m8583 = [PZMiddleMessage new]; 31 | m8583.hasTpdu = YES; 32 | m8583.hasHead = YES; 33 | [m8583 decode:data]; 34 | 35 | self.posFields = m8583.posFields; 36 | 37 | self.terminalId = m8583.posFields.terminalId; 38 | self.merchantId = m8583.posFields.merchantId; 39 | self.tranTtc = m8583.posFields.tranTtc; 40 | 41 | self.messageTpdu = m8583.msgTpdu; 42 | self.messageHead = m8583.msgHead; 43 | #ifdef DEBUG 44 | [m8583 showMessageDump]; 45 | #endif 46 | return YES; 47 | } 48 | 49 | /** 50 | * @brief 打包成8583格式报文 51 | * @return 转换网络传输的字节 52 | */ 53 | - (NSData *)encode { 54 | PZMiddleMessage *mes = [PZMiddleMessage new]; 55 | 56 | mes.posFields = self.posFields; 57 | 58 | if (self.messageTpdu) { 59 | [mes setMsgTpdu:self.messageTpdu]; 60 | mes.hasTpdu = YES; 61 | } 62 | 63 | if (self.messageHead) { 64 | [mes setMsgHead:self.messageHead]; 65 | mes.hasHead = YES; 66 | } 67 | 68 | NSData *sendData = [mes encode]; 69 | #ifdef DEBUG 70 | [mes showMessageDump]; 71 | #endif 72 | 73 | return sendData; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZRequest.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZBaseMessage.h" 10 | 11 | @interface PZMessageRequest : PZBaseMessage 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZRequest.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageRequest.h" 10 | 11 | @implementation PZMessageRequest 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZResponse.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZBaseMessage.h" 10 | 11 | @interface PZMessageResponse : PZBaseMessage 12 | 13 | @property (nonatomic,strong) NSString *respCode; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZResponse.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageResponse.h" 10 | 11 | @implementation PZMessageResponse 12 | 13 | - (BOOL)decode:(NSData *)mes { 14 | [super decode:mes]; 15 | 16 | self.respCode = self.posFields.responseCode; 17 | 18 | return YES; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZMessageUtils.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PZMessageUtils : NSObject 12 | 13 | + (NSString *)hexToAscii:(NSString *)str; 14 | 15 | + (NSString *)asciiToHex:(NSString *)str; 16 | 17 | + (NSData*) hexToBytes:(NSString *)str; 18 | 19 | + (NSString *)hexStringFromData:(NSData *)data; 20 | 21 | //+ (void)showMessageHexWithData:(NSData *)data ; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMessageUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZMessageUtils.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageUtils.h" 10 | //#import "dl_output.h" 11 | 12 | @implementation PZMessageUtils 13 | 14 | + (NSString *)hexToAscii:(NSString *)str { 15 | NSData *hexData = [self hexToBytes:str]; 16 | NSString *asciiStr = [[NSString alloc] initWithData:hexData encoding:NSASCIIStringEncoding]; 17 | 18 | return asciiStr; 19 | } 20 | 21 | + (NSString *)asciiToHex:(NSString *)str { 22 | NSData *hexData = [str dataUsingEncoding:NSASCIIStringEncoding]; 23 | NSString *hexStr = [self hexStringFromData:hexData]; 24 | 25 | return hexStr; 26 | } 27 | 28 | + (NSData*) hexToBytes:(NSString *)str 29 | { 30 | NSMutableData* data = [NSMutableData data]; 31 | 32 | int idx; 33 | for (idx = 0; idx+2 <= str.length; idx+=2) { 34 | 35 | NSRange range = NSMakeRange(idx, 2); 36 | 37 | NSString* hexStr = [str substringWithRange:range]; 38 | 39 | NSScanner* scanner = [NSScanner scannerWithString:hexStr]; 40 | 41 | unsigned int intValue; 42 | 43 | [scanner scanHexInt:&intValue]; 44 | 45 | [data appendBytes:&intValue length:1]; 46 | 47 | } 48 | 49 | return data; 50 | } 51 | 52 | + (NSString *)hexStringFromData:(NSData *)data 53 | { 54 | NSMutableString *str = [NSMutableString string]; 55 | 56 | Byte *byte = (Byte *)[data bytes]; 57 | 58 | for (int i = 0; i<[data length]; i++) { 59 | // byte+i为指针 60 | [str appendString:[self stringFromByte:*(byte+i)]]; 61 | } 62 | 63 | return str; 64 | } 65 | 66 | + (NSString *)stringFromByte:(Byte)byteVal 67 | { 68 | NSMutableString *str = [NSMutableString string]; 69 | 70 | //取高四位 71 | Byte byte1 = byteVal>>4; 72 | 73 | //取低四位 74 | Byte byte2 = byteVal & 0xf; 75 | 76 | //拼接16进制字符串 77 | [str appendFormat:@"%x",byte1]; 78 | [str appendFormat:@"%x",byte2]; 79 | 80 | return str; 81 | } 82 | 83 | //+ (void)showMessageHexWithData:(NSData *)data { 84 | // DL_UINT8 *bytes = (DL_UINT8 *)[data bytes]; 85 | // DL_OUTPUT_Hex(stdout, NULL, bytes, (DL_UINT32)data.length); 86 | //} 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMiddleMessage.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZMiddleMessage.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PZPosField.h" 11 | 12 | /******************************************************************************/ 13 | @interface PZMiddleMessage : NSObject 14 | 15 | /** 16 | * 打包之后,这里存放打包文件 17 | */ 18 | @property (nonatomic,readonly) NSData *msgData; 19 | /** 20 | * 打包文件长度 21 | */ 22 | @property (nonatomic,readonly) NSInteger dataSize; 23 | 24 | @property (nonatomic,assign) BOOL hasTpdu; 25 | @property (nonatomic,readwrite,copy) NSString *msgTpdu; 26 | @property (nonatomic,assign) BOOL hasHead; 27 | @property (nonatomic,readwrite,copy) NSString *msgHead; 28 | 29 | @property (nonatomic,readwrite,strong) PZPosField *posFields; 30 | 31 | /** 32 | * @brief 解包 33 | * @param bytes 字节数组形态的8583报文,从消息类型开始,包括mac字段。 34 | */ 35 | - (BOOL)decode:(NSData *)bytes ; 36 | 37 | /** 38 | * @brief 打包成8583格式报文 39 | * @return 转换网络传输的字节 40 | */ 41 | - (NSData *)encode; 42 | 43 | /** 44 | * @brief 填充报文域内容 45 | * @param content 域内容 46 | * @param index 域位置 47 | * @param 成功与否 48 | */ 49 | - (BOOL)setFieldValueWithString:(NSString *)content atIndex:(NSInteger)index; 50 | - (BOOL)setFieldValueWithData:(NSData *)content atIndex:(NSInteger)index; 51 | 52 | - (NSString *)getFieldValueStringAtIndex:(NSInteger)index; 53 | - (NSData *)getFieldValueDataAtIndex:(NSInteger)index; 54 | 55 | @end 56 | 57 | /******************************************************************************/ 58 | 59 | @interface PZMiddleMessage (Utils) 60 | 61 | /** 62 | * 打印报文结构及内容 63 | */ 64 | - (void)showMessageDump ; 65 | 66 | /** 67 | *打印报文16进制格式 68 | */ 69 | - (void)showMessageHex; 70 | 71 | @end 72 | 73 | /******************************************************************************/ 74 | 75 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZMiddleMessage.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZMiddleMessage.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMiddleMessage.h" 10 | #import "PZMessageUtils.h" 11 | #include "dl_iso8583.h" 12 | #include "dl_iso8583_defs_pos.h" 13 | #include "dl_output.h" 14 | 15 | // indicates the buffer size (in bytes) 16 | #define kBUFFER_SIZE 1000 17 | #define kBUFFER_TPDU 5 18 | #define kBUFFER_HEAD 6 19 | 20 | @interface PZMiddleMessage () 21 | { 22 | DL_ISO8583_HANDLER isoHandler; 23 | DL_ISO8583_MSG isoMsg; 24 | DL_UINT8 buf[kBUFFER_SIZE]; 25 | DL_UINT16 bufSize; 26 | 27 | DL_UINT8 isotpdu[kBUFFER_TPDU]; 28 | DL_UINT8 isohead[kBUFFER_HEAD]; 29 | } 30 | 31 | @end 32 | 33 | @implementation PZMiddleMessage 34 | 35 | - (id)init { 36 | if (self = [super init]) { 37 | DL_ISO8583_DEFS_POS_GetHandler(&isoHandler); 38 | /* initialise ISO message */ 39 | // DL_ISO8583_MSG_Init(sBuf,kBUFFER_SIZE,&isoMsg); 40 | DL_ISO8583_MSG_Init(NULL,0,&isoMsg); 41 | _msgHead = nil; 42 | _msgTpdu = nil; 43 | bufSize = 0; 44 | //默认是不包含tpdu和head的 45 | _hasHead = NO; 46 | _hasTpdu = NO; 47 | 48 | _posFields = [PZPosField new]; 49 | } 50 | 51 | return self; 52 | } 53 | 54 | - (void)dealloc { 55 | /* destroy ISO Msg */ 56 | DL_ISO8583_MSG_Free(&isoMsg); 57 | } 58 | 59 | /** 60 | * @brief 解包 61 | * @param bytes 字节数组形态的8583报文,从消息类型开始,包括mac字段。 62 | * @param dataSize 字节长度 63 | */ 64 | - (BOOL)decode:(NSData *)bytes { 65 | 66 | bufSize = [bytes length]; 67 | const char *deBytes = [bytes bytes]; 68 | NSInteger index = 0; 69 | 70 | if (self.hasTpdu) { 71 | memcpy(isotpdu, deBytes, kBUFFER_TPDU); 72 | NSData *tmpData = [NSData dataWithBytes:isotpdu length:kBUFFER_TPDU]; 73 | self.msgTpdu = [PZMessageUtils hexStringFromData:tmpData]; 74 | index += kBUFFER_TPDU; 75 | } 76 | 77 | if (self.hasHead) { 78 | memcpy(isohead, deBytes + index, kBUFFER_HEAD); 79 | NSData *tmpData = [NSData dataWithBytes:isohead length:kBUFFER_HEAD]; 80 | self.msgHead = [PZMessageUtils hexStringFromData:tmpData]; 81 | index += kBUFFER_HEAD; 82 | } 83 | 84 | bufSize -= index; 85 | memcpy(buf, deBytes+index, bufSize); 86 | DL_ERR result = DL_ISO8583_MSG_Unpack(&isoHandler,buf,bufSize,&isoMsg); 87 | if (result == kDL_ERR_NONE) { 88 | [self decodeToPosFields]; 89 | return YES; 90 | } 91 | 92 | return NO; 93 | } 94 | 95 | /** 96 | * @brief 打包成8583格式报文 97 | * @return 转换网络传输的字节 98 | */ 99 | - (NSData *)encode { 100 | 101 | [self encodeFromPosFields]; 102 | 103 | DL_ERR result = DL_ISO8583_MSG_Pack(&isoHandler,&isoMsg,buf,&bufSize); 104 | if (result != kDL_ERR_NONE) { 105 | return nil; 106 | } 107 | NSMutableData *msgBuf = [NSMutableData dataWithCapacity:0]; 108 | if (self.hasTpdu) { 109 | [msgBuf appendData:[PZMessageUtils hexToBytes:self.msgTpdu]]; 110 | } 111 | 112 | if (self.hasHead) { 113 | [msgBuf appendData:[PZMessageUtils hexToBytes:self.msgHead]]; 114 | } 115 | 116 | [msgBuf appendData:self.msgData]; 117 | 118 | return msgBuf; 119 | } 120 | 121 | #pragma mark - util 122 | - (BOOL)setFieldValueWithString:(NSString *)content atIndex:(NSInteger)index { 123 | NSData *valueData = [content dataUsingEncoding:NSUTF8StringEncoding]; 124 | return [self setFieldValueWithData:valueData atIndex:index]; 125 | } 126 | 127 | - (BOOL)setFieldValueWithData:(NSData *)content atIndex:(NSInteger)index { 128 | 129 | DL_UINT16 fieldIndex = (DL_UINT16)index; 130 | const DL_UINT8 *fieldValue = [content bytes]; 131 | DL_UINT16 iValueLength = [content length]; 132 | DL_ERR result = DL_ISO8583_MSG_SetField_Bin(fieldIndex,fieldValue,iValueLength,&isoMsg); 133 | if (result == kDL_ERR_NONE) { 134 | return YES; 135 | } 136 | 137 | return NO; 138 | } 139 | 140 | - (NSString *)getFieldValueStringAtIndex:(NSInteger)index { 141 | NSData *dataValue = [self getFieldValueDataAtIndex:index]; 142 | if (!dataValue) { 143 | return nil; 144 | } 145 | 146 | NSString *strValue = [[NSString alloc] initWithData:dataValue encoding:NSUTF8StringEncoding]; 147 | if (!strValue) { 148 | strValue = [PZMessageUtils hexStringFromData:dataValue]; 149 | } 150 | 151 | return strValue; 152 | } 153 | 154 | - (NSData *)getFieldValueDataAtIndex:(NSInteger)index { 155 | 156 | DL_UINT16 fieldIndex = (DL_UINT16)index; 157 | int result = DL_ISO8583_MSG_HaveField(fieldIndex,&isoMsg); 158 | if (result == 0) { 159 | return nil; 160 | } 161 | DL_UINT8 *data; 162 | DL_UINT16 iDataLength = 0; 163 | DL_ISO8583_MSG_GetField_Bin(fieldIndex,&isoMsg,&data,&iDataLength); 164 | 165 | return [NSData dataWithBytes:data length:iDataLength]; 166 | } 167 | 168 | - (NSData *)msgData { 169 | return [NSData dataWithBytes:buf length:bufSize]; 170 | } 171 | 172 | - (NSInteger)dataSize { 173 | return bufSize; 174 | } 175 | 176 | - (void)decodeToPosFields { 177 | NSInteger index = 0; 178 | for (; index < kDL_ISO8583_MAX_FIELD_IDX + 1; index++) { 179 | NSString *value = nil; 180 | if (index == 1 || index == 64) { 181 | NSData *data = [self getFieldValueDataAtIndex:index]; 182 | value = [PZMessageUtils hexStringFromData:data]; 183 | } else { 184 | value = [self getFieldValueStringAtIndex:index]; 185 | } 186 | 187 | if (value) { 188 | NSString *dictKey = [NSString stringWithFormat:@"%lu",(long)index]; 189 | NSString *key = self.posFields.mapDict[dictKey]; 190 | [self.posFields setValue:value forKey:key]; 191 | } 192 | } 193 | 194 | #ifdef DEBUG 195 | NSLog(@"-----------------------"); 196 | [self.posFields description]; 197 | #endif 198 | } 199 | 200 | - (void)encodeFromPosFields { 201 | 202 | NSDictionary *dict = self.posFields.mapDict; 203 | [dict enumerateKeysAndObjectsUsingBlock:^(id key,id obj,BOOL *stop){ 204 | NSInteger index = [key integerValue]; 205 | id value = [self.posFields valueForKey:obj]; 206 | if (value) { 207 | if ([value isKindOfClass:[NSString class]]) { 208 | [self setFieldValueWithString:value atIndex:index]; 209 | } else { 210 | [self setFieldValueWithData:value atIndex:index]; 211 | } 212 | 213 | #ifdef DEBUG 214 | NSLog(@"%@:%@:%@",obj,key,value); 215 | #endif 216 | } 217 | }]; 218 | } 219 | 220 | #pragma mark - Utils 221 | - (void)showMessageDump { 222 | /* output ISO message content */ 223 | DL_ISO8583_MSG_Dump(stdout,NULL,&isoHandler,&isoMsg); 224 | } 225 | 226 | - (void)showMessageHex { 227 | DL_OUTPUT_Hex(stdout,NULL,buf,bufSize); 228 | } 229 | 230 | @end 231 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPosField.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZField.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /******************************************************************************/ 12 | @interface PZPosField : NSObject 13 | 14 | @property (nonatomic, strong) NSString *messageType; //0 15 | @property (nonatomic, strong) NSString *bitmap; //1 16 | @property (nonatomic, strong) NSString *cardPan; //2 17 | @property (nonatomic, strong) NSString *processCode; //3 18 | @property (nonatomic, strong) NSString *tranAmount; //4 19 | @property (nonatomic, strong) NSString *tranTtc; // 11 20 | @property (nonatomic, strong) NSString *tranTime; //12 21 | @property (nonatomic, strong) NSString *tranDate; //13 22 | @property (nonatomic, strong) NSString *expireDate; //14 23 | @property (nonatomic, strong) NSString *settDate; //15 24 | @property (nonatomic, strong) NSString *serverMode; //22 25 | @property (nonatomic, strong) NSString *conditionMode; //25 26 | @property (nonatomic, strong) NSString *pinCode; //26 27 | @property (nonatomic, strong) NSString *acqCode; //32 28 | @property (nonatomic, strong) id track2Data; //35 29 | @property (nonatomic, strong) id track3Data; //36 30 | @property (nonatomic, strong) NSString *referenceNum; //37 31 | @property (nonatomic, strong) NSString *authCode; //38 32 | @property (nonatomic, strong) NSString *responseCode; //39 33 | @property (nonatomic, strong) NSString *terminalId; //41 34 | @property (nonatomic, strong) NSString *merchantId; //42 35 | @property (nonatomic, strong) NSString *aditionRespData; //44 36 | @property (nonatomic, strong) NSString *private48; //48 37 | @property (nonatomic, strong) NSString *currentCode; //49 38 | @property (nonatomic, strong) id pinData; //52 39 | @property (nonatomic, strong) NSString *securityCode; //53 40 | @property (nonatomic, strong) NSString *balanceAmount; //54 41 | @property (nonatomic, strong) id icCardData; //55 42 | @property (nonatomic, strong) NSString *private60; //60 43 | @property (nonatomic, strong) NSString *originMessage; //61 44 | @property (nonatomic, strong) id private62; //62 45 | @property (nonatomic, strong) NSString *private63; //63 46 | @property (nonatomic, strong) NSString *messageMac; //64 47 | 48 | @property (nonatomic,readonly,strong) NSDictionary *mapDict; //dictionary 49 | 50 | @end 51 | /******************************************************************************/ 52 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPosField.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZField.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/11. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPosField.h" 10 | 11 | @implementation PZPosField 12 | 13 | - (NSDictionary*)mapDict { 14 | return @{@"0":@"messageType", 15 | @"1":@"bitmap", 16 | @"2":@"cardPan", 17 | @"3":@"processCode", 18 | @"4":@"tranAmount", 19 | @"11":@"tranTtc", 20 | @"12":@"tranTime", 21 | @"13":@"tranDate", 22 | @"14":@"expireDate", 23 | @"15":@"settDate", 24 | @"22":@"serverMode", 25 | @"25":@"conditionMode", 26 | @"26":@"pinCode", 27 | @"32":@"acqCode", 28 | @"35":@"track2Data", 29 | @"36":@"track3Data", 30 | @"37":@"referenceNum", 31 | @"38":@"authCode", 32 | @"39":@"responseCode", 33 | @"41":@"terminalId", 34 | @"42":@"merchantId", 35 | @"44":@"aditionRespData", 36 | @"48":@"private48", 37 | @"49":@"currentCode", 38 | @"52":@"pinData", 39 | @"53":@"securityCode", 40 | @"54":@"balanceAmount", 41 | @"55":@"icCardData", 42 | @"60":@"private60", 43 | @"61":@"originMessage", 44 | @"62":@"private62", 45 | @"63":@"private63", 46 | @"64":@"messageMac"}; 47 | } 48 | 49 | - (id)copyWithZone:(NSZone *)zone { 50 | PZPosField *fields = [[PZPosField allocWithZone:zone] init]; 51 | fields.messageType = self.messageType; 52 | fields.bitmap = self.bitmap; 53 | fields.cardPan = self.cardPan; 54 | fields.processCode = self.processCode; 55 | fields.tranAmount = self.tranAmount; 56 | fields.tranTtc = self.tranTtc; 57 | fields.tranTime = self.tranTime; 58 | fields.tranDate = self.tranDate; 59 | fields.expireDate = self.expireDate; 60 | fields.settDate = self.settDate; 61 | fields.serverMode = self.serverMode; 62 | fields.conditionMode = self.conditionMode; 63 | fields.pinCode = self.pinCode; 64 | fields.acqCode = self.acqCode; 65 | fields.track2Data = self.track2Data; 66 | fields.track3Data = self.track3Data; 67 | fields.referenceNum = self.referenceNum; 68 | fields.authCode = self.authCode; 69 | fields.responseCode = self.responseCode; 70 | fields.terminalId = self.terminalId; 71 | fields.merchantId = self.merchantId; 72 | fields.aditionRespData = self.aditionRespData; 73 | fields.private48 = self.private48; 74 | fields.currentCode = self.currentCode; 75 | fields.pinData = self.pinData; 76 | fields.securityCode = self.securityCode; 77 | fields.balanceAmount = self.balanceAmount; 78 | fields.icCardData = self.icCardData; 79 | fields.private60 = self.private60; 80 | fields.originMessage = self.originMessage; 81 | fields.private62 = self.private62; 82 | fields.private63 = self.private63; 83 | fields.messageMac = self.messageMac; 84 | 85 | return fields; 86 | } 87 | 88 | - (NSString *)description { 89 | NSDictionary *dict = self.mapDict; 90 | NSArray *keySort = [[dict allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2){ 91 | NSInteger key1 = [(NSString *)obj1 integerValue]; 92 | NSInteger key2 = [(NSString *)obj2 integerValue]; 93 | 94 | return key1 <= key2 ? NSOrderedAscending : NSOrderedDescending; 95 | }]; 96 | 97 | NSMutableString *mutablesStr = [NSMutableString new]; 98 | for (NSString *key in keySort) { 99 | NSString *obj = dict[key]; 100 | if ([self valueForKey:obj]) { 101 | NSLog(@"%@:%@:%@",obj,key,[self valueForKey:obj]); 102 | [mutablesStr appendFormat:@"%@:%@:%@\n",obj,key,[self valueForKey:obj]]; 103 | } 104 | } 105 | 106 | return mutablesStr; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPrivateField60.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPrivateField60.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/12. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PZPrivateField60 : NSObject 12 | 13 | @property (nonatomic,strong) NSString *msgType; 14 | @property (nonatomic,strong) NSString *batchNumber; 15 | @property (nonatomic,strong) NSString *networkCode; 16 | 17 | - (BOOL)decode:(NSString *)field60; 18 | 19 | - (NSString *)encode; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPrivateField60.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPrivateField60.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/12. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPrivateField60.h" 10 | 11 | static NSInteger kField60Len = 11; 12 | static NSInteger kMsgTypeLen = 2; 13 | static NSInteger kBatchNumberLen = 6; 14 | static NSInteger kNetworkCodeLen = 3; 15 | 16 | @implementation PZPrivateField60 17 | 18 | - (BOOL)decode:(NSString *)field60 { 19 | if (field60 == nil) { 20 | return NO; 21 | } 22 | 23 | if (field60.length < kMsgTypeLen + kBatchNumberLen) { 24 | return NO; 25 | } 26 | 27 | NSRange range = NSMakeRange(0, kMsgTypeLen); 28 | self.msgType = [field60 substringWithRange:range]; 29 | 30 | range = NSMakeRange(range.location + range.length, kBatchNumberLen); 31 | self.batchNumber = [field60 substringWithRange:range]; 32 | 33 | if (field60.length >= kField60Len) { 34 | range = NSMakeRange(range.location+range.length, kNetworkCodeLen); 35 | self.networkCode = [field60 substringWithRange:range]; 36 | } 37 | 38 | return YES; 39 | } 40 | 41 | - (NSString *)encode { 42 | if (self.msgType == nil || self.msgType.length != kMsgTypeLen) { 43 | return nil; 44 | } 45 | 46 | if (self.batchNumber == nil || self.batchNumber.length != kBatchNumberLen) { 47 | return nil; 48 | } 49 | 50 | return [self description]; 51 | } 52 | 53 | - (BOOL)isEqual:(id)object { 54 | if (object == self) { 55 | return YES; 56 | } 57 | 58 | if (![object isKindOfClass:[PZPrivateField60 class]]) { 59 | return NO; 60 | } 61 | 62 | PZPrivateField60 *field = (PZPrivateField60 *)object; 63 | if ([[field description] isEqualToString:[self description]] ) { 64 | return YES; 65 | } else { 66 | return NO; 67 | } 68 | } 69 | 70 | - (NSUInteger)hash { 71 | NSString *hashStr = [self description]; 72 | return [hashStr hash]; 73 | } 74 | 75 | - (NSString *)description { 76 | NSString *netCode = self.networkCode ? self.networkCode : @""; 77 | return [NSString stringWithFormat:@"%@%@%@",self.msgType,self.batchNumber,netCode]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPrivateField62.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPrivateField62.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/18. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PZPrivateField62 : NSObject 12 | 13 | @property (nonatomic,strong) NSString *keyIndex; 14 | @property (nonatomic,strong) NSString *pinKey; 15 | @property (nonatomic,strong) NSString *pinKeyValue; 16 | @property (nonatomic,strong) NSString *macKey; 17 | @property (nonatomic,strong) NSString *macKeyValue; 18 | @property (nonatomic,strong) NSString *trkKey; 19 | @property (nonatomic,strong) NSString *trkKeyValue; 20 | 21 | - (id)initWithData:(NSString *)prvData; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PZ8583/8583/8583warp/PZPrivateField62.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPrivateField62.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/18. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPrivateField62.h" 10 | 11 | const NSInteger kKeyIndexLen = 2; 12 | const NSInteger kPinKeyLen = 32; 13 | const NSInteger kPinKeyValueLen = 8; 14 | const NSInteger kMacKeyLen = 32; 15 | const NSInteger kMacKeyValueLen = 8; 16 | const NSInteger kTrkKeyLen = 32; 17 | const NSInteger kTrkKeyValueLen = 8; 18 | 19 | @implementation PZPrivateField62 20 | 21 | - (id)initWithData:(NSString *)prvData { 22 | if (self = [super init]) { 23 | NSRange range = NSMakeRange(0, kKeyIndexLen); 24 | _keyIndex = [prvData substringWithRange:range]; 25 | range = NSMakeRange(range.location+range.length, kPinKeyLen); 26 | _pinKey = [prvData substringWithRange:range]; 27 | range = NSMakeRange(range.location+range.length, kPinKeyValueLen); 28 | _pinKeyValue = [prvData substringWithRange:range]; 29 | 30 | range = NSMakeRange(range.location+range.length, kMacKeyLen); 31 | _macKey = [prvData substringWithRange:range]; 32 | range = NSMakeRange(range.location+range.length, kMacKeyValueLen); 33 | _macKeyValue = [prvData substringWithRange:range]; 34 | 35 | range = NSMakeRange(range.location+range.length, kTrkKeyLen); 36 | _trkKey = [prvData substringWithRange:range]; 37 | range = NSMakeRange(range.location+range.length, kTrkKeyValueLen); 38 | _trkKeyValue = [prvData substringWithRange:range]; 39 | } 40 | 41 | return self; 42 | } 43 | 44 | - (NSString *)description { 45 | NSString *desc = [NSString stringWithFormat:@"",self.pinKey,self.pinKeyValue, 46 | self.macKey,self.macKeyValue,self.trkKey,self.trkKeyValue]; 47 | return desc; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTag.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @interface BerTag : NSObject 9 | 10 | @property(nonatomic, copy) NSData *data;; 11 | 12 | - (id) init:(NSData *)aData 13 | offset:(uint)aOffset 14 | length:(uint)aLength; 15 | 16 | - (id) init:(uint8_t)aFirstByte; 17 | - (id) init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte; 18 | - (id) init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte thirdByte:(uint8_t)aThirdByte; 19 | 20 | - (BOOL)isConstructed; 21 | 22 | - (BOOL)isEqual:(id)other; 23 | - (BOOL)isEqualToTag:(BerTag *)tag; 24 | - (NSUInteger)hash; 25 | - (NSString *)description; 26 | 27 | - (NSString *)hex; 28 | 29 | + (BerTag *)parse:(NSString *)aHexString; 30 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTag.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTag.h" 7 | #import "HexUtil.h" 8 | 9 | 10 | @implementation BerTag { 11 | } 12 | 13 | @synthesize data; 14 | 15 | - (id)init:(NSData *)aData offset:(uint)aOffset length:(uint)aLength { 16 | self = [super init]; 17 | if(self) { 18 | NSRange range = {aOffset, aLength}; 19 | data = [aData subdataWithRange:range]; 20 | } 21 | return self; 22 | } 23 | 24 | - (id)init:(uint8_t)aFirstByte { 25 | self = [super init]; 26 | if(self) { 27 | data = [NSData dataWithBytes:&aFirstByte length:1]; 28 | } 29 | return self; 30 | } 31 | 32 | - (id)init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte { 33 | self = [super init]; 34 | if(self) { 35 | uint8_t bytes[2]; 36 | bytes[0] = aFirstByte; 37 | bytes[1] = aSecondByte; 38 | data = [NSData dataWithBytes:bytes length:2]; 39 | } 40 | return self; 41 | } 42 | 43 | - (id)init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte thirdByte:(uint8_t)aThirdByte { 44 | self = [super init]; 45 | if(self) { 46 | uint8_t bytes[3]; 47 | bytes[0] = aFirstByte; 48 | bytes[1] = aSecondByte; 49 | bytes[2] = aThirdByte; 50 | data = [NSData dataWithBytes:bytes length:3]; 51 | } 52 | return self; 53 | } 54 | 55 | - (BOOL)isConstructed { 56 | //by peter 20150714 57 | // uint8_t *bytes = (uint8_t *) data.bytes; 58 | // 0x20 59 | // return (bytes[0] & 0b00100000) != 0; 60 | 61 | return NO; 62 | } 63 | 64 | - (BOOL)isEqual:(id)other { 65 | if (other == self) { 66 | return YES; 67 | } 68 | 69 | if (!other || ![[other class] isEqual:[self class]]) { 70 | return NO; 71 | } 72 | 73 | return [self isEqualToTag:other]; 74 | } 75 | 76 | - (BOOL)isEqualToTag:(BerTag *)tag { 77 | if (self == tag) { 78 | return YES; 79 | } 80 | 81 | if (tag == nil) { 82 | return NO; 83 | } 84 | 85 | return !(data != tag->data && ![data isEqualToData:tag->data]); 86 | } 87 | 88 | - (NSUInteger)hash { 89 | return [data hash]; 90 | } 91 | 92 | - (NSString *)description { 93 | NSMutableString *description = [NSMutableString stringWithCapacity:data.length+2]; 94 | if(self.isConstructed) { 95 | [description appendFormat:@"+ "]; 96 | } else { 97 | [description appendFormat:@"- "]; 98 | } 99 | [description appendFormat:@"%@", [HexUtil format:data]]; 100 | return description; 101 | } 102 | 103 | + (BerTag *)parse:(NSString *)aHexString { 104 | NSData *data = [HexUtil parse:aHexString]; 105 | return [[BerTag alloc] init:data offset:0 length:(uint)data.length]; 106 | } 107 | 108 | - (NSString *)hex { 109 | return [HexUtil format:data]; 110 | } 111 | 112 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlv.h: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlv.h 3 | // BerTlv 4 | // 5 | // Created by Evgeniy Sinev on 04/08/14. 6 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class BerTag; 12 | 13 | @interface BerTlv : NSObject 14 | 15 | @property(copy, nonatomic, readonly) BerTag * tag ; 16 | @property(copy, nonatomic, readonly) NSData * value ; 17 | @property(copy, nonatomic, readonly) NSArray * list ; 18 | @property(nonatomic, readonly) BOOL primitive ; 19 | @property(nonatomic, readonly) BOOL constructed ; 20 | 21 | - (id)init:(BerTag *)aTag value:(NSData *)aValue; 22 | - (id)init:(BerTag *)aTag array:(NSArray *)aArray; 23 | 24 | - (BOOL) hasTag:(BerTag *)aTag; 25 | - (BerTlv *) find:(BerTag *)aTag; 26 | - (NSArray *) findAll:(BerTag *)aTag; 27 | 28 | - (NSString *) hexValue; 29 | - (NSString *) textValue; 30 | 31 | - (NSString *) dump:(NSString *)aPadding; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlv.m: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlv.m 3 | // BerTlv 4 | // 5 | // Created by Evgeniy Sinev on 04/08/14. 6 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 7 | // 8 | 9 | #import "BerTlv.h" 10 | #import "BerTag.h" 11 | #import "HexUtil.h" 12 | 13 | @implementation BerTlv 14 | 15 | @synthesize tag, value, list, constructed, primitive; 16 | 17 | - (id)init:(BerTag *)aTag array:(NSArray *)aArray { 18 | self = [super init]; 19 | if(self) { 20 | tag = aTag; 21 | list = aArray; 22 | constructed = aTag.isConstructed; 23 | primitive = !constructed; 24 | } 25 | return self; 26 | } 27 | 28 | - (id)init:(BerTag *)aTag value:(NSData *)aValue { 29 | self = [super init]; 30 | if(self) { 31 | tag = aTag; 32 | value = aValue; 33 | constructed = aTag.isConstructed; 34 | primitive = !constructed; 35 | } 36 | return self; 37 | } 38 | 39 | - (BOOL)hasTag:(BerTag *)aTag { 40 | return [self find:aTag] != nil; 41 | } 42 | 43 | - (BerTlv *)find:(BerTag *)aTag { 44 | if([aTag isEqualToTag:tag]) { 45 | return self; 46 | } 47 | 48 | if(primitive) { 49 | return nil; 50 | } 51 | 52 | for( BerTlv * tlv in list) { 53 | BerTlv *found = [tlv find:aTag]; 54 | if(found!=nil) { 55 | return found; 56 | } 57 | } 58 | 59 | return nil; 60 | } 61 | 62 | - (NSArray *)findAll:(BerTag *)aTag { 63 | NSMutableArray *array = [[NSMutableArray alloc] init]; 64 | if([aTag isEqualToTag:tag]) { 65 | [array addObject:self]; 66 | } 67 | 68 | if(constructed) { 69 | for( BerTlv * tlv in list) { 70 | NSArray *found = [tlv findAll:aTag]; 71 | [array addObjectsFromArray:found]; 72 | } 73 | } 74 | 75 | return array; 76 | } 77 | 78 | - (NSString *)hexValue { 79 | [self checkPrimitive]; 80 | return [HexUtil format:value]; 81 | } 82 | 83 | - (NSString *)textValue { 84 | return [[NSString alloc] initWithData:self.value encoding:NSASCIIStringEncoding]; 85 | } 86 | 87 | - (void)checkPrimitive { 88 | if(constructed) { 89 | @throw([NSException exceptionWithName:@"NotPrimitiveTagException" 90 | reason:[NSString stringWithFormat:@"Tag %@ is constructed", tag] 91 | userInfo:nil]); 92 | } 93 | } 94 | 95 | 96 | - (NSString *)dump:(NSString *)aPadding { 97 | NSMutableString *sb = [[NSMutableString alloc] init]; 98 | 99 | if(primitive) { 100 | [sb appendFormat:@"%@ - [%@] %@\n", aPadding, tag.hex, [self hexValue]]; 101 | } else { 102 | [sb appendFormat:@"%@ + [%@]\n", aPadding, tag.hex]; 103 | NSMutableString *childPadding = [[NSMutableString alloc] init]; 104 | [childPadding appendString:aPadding]; 105 | [childPadding appendString:aPadding]; 106 | for (BerTlv *tlv in list) { 107 | [sb appendString:[tlv dump:childPadding]]; 108 | } 109 | } 110 | return sb; 111 | } 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class BerTlv; 9 | @class BerTlvs; 10 | @class BerTag; 11 | 12 | 13 | @interface BerTlvBuilder : NSObject 14 | 15 | // initialize 16 | - (id)init; 17 | - (id)initWithTlv :(BerTlv * ) aTlv ; 18 | - (id)initWithTlvs :(BerTlvs * ) aTlvs ; 19 | - (id)initWithTemplate :(BerTag * ) aTag ; 20 | 21 | // build 22 | - (NSData *) buildData ; 23 | - (BerTlvs *) buildTlvs ; 24 | - (BerTlv *) buildTlv ; 25 | 26 | // add values 27 | - (void) addBerTlv :(BerTlv *) aTlv ; 28 | - (void) addBerTlvs :(BerTlvs *) aTlvs; 29 | - (void) addAmount :(NSDecimalNumber *) aAmount tag:(BerTag *)aTag; 30 | - (void) addDate :(NSDate *) aDate tag:(BerTag *)aTag; 31 | - (void) addTime :(NSDate *) aTime tag:(BerTag *)aTag; 32 | - (void) addText :(NSString *) aText tag:(BerTag *)aTag; 33 | - (void) addBcd :(NSUInteger ) aValue tag:(BerTag *)aTag length:(NSUInteger )aLength; 34 | - (void) addBytes :(NSData *) aBuf tag:(BerTag *)aTag; 35 | - (void) addHex :(NSString *) aHex tag:(BerTag *)aTag; 36 | 37 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvBuilder.h" 7 | #import "BerTlv.h" 8 | #import "BerTlvs.h" 9 | #import "BerTag.h" 10 | #import "HexUtil.h" 11 | #import "BerTlvParser.h" 12 | 13 | 14 | @implementation BerTlvBuilder { 15 | NSMutableData *data; 16 | BerTag *templateTag; 17 | } 18 | 19 | - (id)init { 20 | self = [super init]; 21 | if (self) { 22 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (id)initWithTemplate:(BerTag *)aTag { 29 | self = [super init]; 30 | if (self) { 31 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 32 | templateTag = aTag; 33 | } 34 | return self; 35 | } 36 | 37 | - (id)initWithTlv:(BerTlv *)aTlv { 38 | self = [super init]; 39 | if (self) { 40 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 41 | if(aTlv.primitive) { 42 | [self addBytes:aTlv.value tag:aTlv.tag]; 43 | } else { 44 | templateTag = aTlv.tag; 45 | for (BerTlv *tlv in aTlv.list) { 46 | [self addBerTlv:tlv]; 47 | } 48 | } 49 | } 50 | return self; 51 | } 52 | 53 | - (id)initWithTlvs:(BerTlvs *)aTlvs { 54 | self = [super init]; 55 | if (self) { 56 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 57 | [self addBerTlvs:aTlvs]; 58 | } 59 | return self; 60 | } 61 | 62 | - (void)addBcd:(NSUInteger )aValue tag:(BerTag *)aTag length:(NSUInteger )aLength { 63 | NSMutableString *hex = [NSMutableString stringWithFormat:@"%@", @(aValue)]; 64 | for(int i=0; hex.length < aLength*2 && i<100; i++) { 65 | [hex insertString:@"0" atIndex:0]; 66 | } 67 | [self addHex:hex tag:aTag]; 68 | } 69 | 70 | - (void)addAmount:(NSDecimalNumber *)aAmount tag:(BerTag *)aTag { 71 | NSUInteger cents = [aAmount decimalNumberByMultiplyingBy:[[NSDecimalNumber alloc] initWithInt:100]].unsignedIntegerValue; 72 | [self addBcd:cents tag:aTag length:6]; 73 | } 74 | 75 | - (void)addDate:(NSDate *)aDate tag:(BerTag *)aTag { 76 | NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init]; 77 | [dateFormat setDateFormat: @"yyMMdd"]; 78 | NSString *hex = [dateFormat stringFromDate:aDate]; 79 | [self addHex:hex tag:aTag]; 80 | } 81 | 82 | - (void)addTime:(NSDate *)aTime tag:(BerTag *)aTag { 83 | NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init]; 84 | [dateFormat setDateFormat: @"HHmmss"]; 85 | NSString *hex = [dateFormat stringFromDate:aTime]; 86 | [self addHex:hex tag:aTag]; 87 | } 88 | 89 | - (void)addBytes:(NSData *)aBuf tag:(BerTag *)aTag { 90 | // TYPE 91 | [data appendData:aTag.data]; 92 | 93 | // LEN 94 | NSData * lenData = [self createLengthData:aBuf.length]; 95 | [data appendData:lenData]; 96 | 97 | // VALUE 98 | [data appendData:aBuf]; 99 | } 100 | 101 | - (void)addText:(NSString *)aText tag:(BerTag *)aTag { 102 | NSData *buf = [aText dataUsingEncoding:NSASCIIStringEncoding]; 103 | [self addBytes:buf tag:aTag]; 104 | } 105 | 106 | - (void)addHex:(NSString *)aHex tag:(BerTag *)aTag { 107 | NSData *buf = [HexUtil parse:aHex]; 108 | [self addBytes:buf tag:aTag]; 109 | } 110 | 111 | - (NSData *)buildData { 112 | // no template tag so can simply return data buffer 113 | if (templateTag == nil) { 114 | return data; 115 | } 116 | 117 | // calculates bytes count for TYPE and LENGTH 118 | NSUInteger typeBytesCount = templateTag.data.length; 119 | NSUInteger lengthBytesCount = [self calcBytesCountForLength:data.length]; 120 | 121 | NSMutableData *ret = [[NSMutableData alloc] initWithCapacity: 122 | + typeBytesCount 123 | + lengthBytesCount 124 | + data.length 125 | ]; 126 | 127 | // TYPE 128 | [ret appendData:templateTag.data]; 129 | 130 | // LENGTH 131 | NSData *lengthData = [self createLengthData:data.length]; 132 | [ret appendData:lengthData]; 133 | 134 | // VALUE 135 | [ret appendData:data]; 136 | 137 | return ret; 138 | 139 | } 140 | 141 | - (NSData *)createLengthData:(NSUInteger)aLength { 142 | if(aLength < 0x80) { 143 | uint8_t buf[1]; 144 | buf[0] = (uint8_t) aLength; 145 | return [NSData dataWithBytes:buf length:1]; 146 | 147 | } else if (aLength <0x100) { 148 | uint8_t buf[2]; 149 | buf[0] = 0x81; 150 | buf[1] = (uint8_t) aLength; 151 | return [NSData dataWithBytes:buf length:2]; 152 | 153 | } else if( aLength < 0x10000) { 154 | uint8_t buf[3]; 155 | buf[0] = 0x82; 156 | buf[1] = (uint8_t) (aLength / 0x100); 157 | buf[2] = (uint8_t) (aLength % 0x100); 158 | return [NSData dataWithBytes:buf length:3]; 159 | 160 | } else if( aLength < 0x1000000 ) { 161 | uint8_t buf[4]; 162 | buf[0] = 0x83; 163 | buf[1] = (uint8_t) (aLength / 0x10000); 164 | buf[2] = (uint8_t) (aLength / 0x100); 165 | buf[3] = (uint8_t) (aLength % 0x100); 166 | return [NSData dataWithBytes:buf length:4]; 167 | 168 | } else { 169 | @throw([NSException exceptionWithName:@"LengthOutOfRangeException" 170 | reason:[NSString stringWithFormat:@"Length [%lu] is out of range ( > 0x1000000)", (unsigned long) aLength] 171 | userInfo:nil]); 172 | } 173 | 174 | } 175 | 176 | - (BerTlv *)buildTlv { 177 | BerTlvParser * parser = [[BerTlvParser alloc] init]; 178 | return [parser parseConstructed:[self buildData]]; 179 | } 180 | 181 | - (BerTlvs *)buildTlvs { 182 | BerTlvParser * parser = [[BerTlvParser alloc] init]; 183 | return [parser parseTlvs:[self buildData]]; 184 | } 185 | 186 | - (NSUInteger) calcBytesCountForLength:(NSUInteger)aLength { 187 | NSUInteger ret; 188 | if(aLength < 0x80) { 189 | ret = 1; 190 | } else if (aLength <0x100) { 191 | ret = 2; 192 | } else if( aLength < 0x10000) { 193 | ret = 3; 194 | } else if( aLength < 0x1000000 ) { 195 | ret = 4; 196 | } else { 197 | @throw([NSException exceptionWithName:@"LengthOutOfRangeException" 198 | reason:[NSString stringWithFormat:@"Length [%lu] is out of range ( > 0x1000000)", (unsigned long) aLength] 199 | userInfo:nil]); 200 | } 201 | return ret; 202 | } 203 | 204 | 205 | - (void)addBerTlv:(BerTlv *)aTlv { 206 | // primitive 207 | if(aTlv.primitive) { 208 | [self addBytes:aTlv.value tag:aTlv.tag]; 209 | 210 | // constructed 211 | } else { 212 | BerTlvBuilder *builder = [[BerTlvBuilder alloc] initWithTemplate:aTlv.tag]; 213 | for (BerTlv *tlv in aTlv.list) { 214 | [builder addBerTlv:tlv]; 215 | } 216 | [data appendData:builder.buildData]; 217 | } 218 | } 219 | 220 | - (void)addBerTlvs:(BerTlvs *)aTlvs { 221 | for (BerTlv *tlv in aTlvs.list) { 222 | [self addBerTlv:tlv]; 223 | } 224 | } 225 | 226 | 227 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvComm.h: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlvComm.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/14. 6 | // Copyright (c) 2015年 paylab. All rights reserved. 7 | // 8 | 9 | 10 | #import "BerTlvParser.h" 11 | #import "BerTlvBuilder.h" 12 | #import "HexUtil.h" 13 | #import "BerTlvs.h" 14 | #import "BerTlv.h" 15 | #import "BerTag.h" 16 | 17 | -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 05/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class BerTlv; 9 | @class BerTlvs; 10 | 11 | 12 | @interface BerTlvParser : NSObject 13 | 14 | - (BerTlv *)parseConstructed:(NSData *)aData; 15 | - (BerTlvs *)parseTlvs:(NSData *)aData; 16 | 17 | 18 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 05/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvParser.h" 7 | #import "BerTlv.h" 8 | #import "HexUtil.h" 9 | #import "BerTag.h" 10 | #import "BerTlvs.h" 11 | 12 | 13 | static int IS_DEBUG_ENABLED = 0; 14 | 15 | @implementation BerTlvParser { 16 | 17 | 18 | 19 | } 20 | - (BerTlv *)parseConstructed:(NSData *)aData { 21 | uint result=0; 22 | BerTlv * ret = [self parseWithResult:&result data:aData offset:0 len:(uint)aData.length level:0]; 23 | return ret; 24 | } 25 | 26 | - (BerTlvs *)parseTlvs:(NSData *)aData { 27 | if(aData.length==0) { 28 | return [[BerTlvs alloc] init:[[NSArray alloc] init]]; 29 | } 30 | 31 | NSMutableArray *list = [[NSMutableArray alloc] init]; 32 | int offset = 0; 33 | for(uint i=0; i<100; i++) { 34 | uint result=0; 35 | BerTlv * ret = [self parseWithResult:&result data:aData offset:offset len:(uint)aData.length-offset level:0]; 36 | [list addObject:ret]; 37 | 38 | if (result >= aData.length) { 39 | break; 40 | } 41 | 42 | offset = result; 43 | } 44 | 45 | return [[BerTlvs alloc] init:list]; 46 | } 47 | 48 | - (BerTlv *)parseWithResult:(uint*)aOutResult 49 | data:(NSData *)aBuf 50 | offset:(uint)aOffset 51 | len:(uint)aLen 52 | level:(uint)aLevel 53 | { 54 | if(aOffset+aLen > aBuf.length) { 55 | @throw([NSException exceptionWithName:@"OutOfRangeException" 56 | reason:[NSString stringWithFormat:@"Length is out of the range [offset=%d, len=%d, array.length=%lu, level=%d]" 57 | , aOffset, aLen, (unsigned long) aBuf.length, aLevel] 58 | userInfo:nil]); 59 | } 60 | 61 | NSString *levelPadding = IS_DEBUG_ENABLED ? [self createLevelPadding:aLevel] : @""; 62 | if(IS_DEBUG_ENABLED) { 63 | NSLog(@"%@parseWithResult( level=%d, offset=%d, len=%d, buf=%@)" 64 | , levelPadding, aLevel, aOffset, aLen, [HexUtil format:aBuf] 65 | ); 66 | } 67 | 68 | // TAG 69 | uint tagBytesCount = [self calcTagBytesCount:aBuf offset:aOffset]; 70 | BerTag *tag = [self createTag:aBuf offset:aOffset len:tagBytesCount pad:levelPadding]; 71 | 72 | // LENGTH 73 | uint lengthBytesCount = [self calcLengthBytesCount:aBuf offset:aOffset + tagBytesCount]; 74 | uint valueLength = [self calcDataLength:aBuf offset:aOffset + tagBytesCount]; 75 | 76 | if(IS_DEBUG_ENABLED) { 77 | NSLog(@"%@lenBytesCount = %d, len = %d, lenBuf = %@" 78 | , levelPadding, lengthBytesCount, valueLength, [HexUtil format:aBuf offset:aOffset + tagBytesCount len:lengthBytesCount]); 79 | } 80 | 81 | // VALUE 82 | if(tag.isConstructed) { 83 | NSMutableArray *array = [[NSMutableArray alloc] init]; 84 | [self addChildren:aBuf 85 | offset:aOffset 86 | level:aLevel 87 | levelPadding:levelPadding 88 | tagBytesCount:tagBytesCount 89 | dataBytesCount:lengthBytesCount 90 | valueLength:valueLength 91 | array:array 92 | ]; 93 | uint resultOffset = aOffset + tagBytesCount + lengthBytesCount + valueLength; 94 | if(IS_DEBUG_ENABLED) { 95 | NSLog(@"%@Returning constructed offset = %d", levelPadding, resultOffset ); 96 | } 97 | *aOutResult = resultOffset; 98 | return [[BerTlv alloc] init:tag array:array]; 99 | 100 | } else { 101 | NSRange range = {aOffset+tagBytesCount+lengthBytesCount, valueLength}; 102 | NSData *value = [aBuf subdataWithRange:range]; 103 | uint resultOffset = aOffset + tagBytesCount + lengthBytesCount + valueLength; 104 | 105 | if(IS_DEBUG_ENABLED) { 106 | NSLog(@"%@Primitive value = %@", levelPadding, [HexUtil format:value]); 107 | NSLog(@"%@Returning primitive offset = %d", levelPadding, resultOffset ); 108 | } 109 | *aOutResult = resultOffset; 110 | return [[BerTlv alloc] init:tag value:value]; 111 | } 112 | } 113 | 114 | - (uint)calcTagBytesCount:(NSData *)aBuf offset:(uint)aOffset { 115 | uint8_t const *bytes = aBuf.bytes; 116 | if((bytes[aOffset] & 0x1F) == 0x1F) { // see subsequent bytes 117 | uint len = 2; 118 | //update by peter 119 | // for(int i=aOffset+1; i3) { 164 | @throw([NSException exceptionWithName:@"BadLengthException" 165 | reason:[NSString stringWithFormat:@"At position %d the len is more then 3 [%d]" 166 | , aOffset, numberOfBytes] 167 | userInfo:nil]); 168 | } 169 | 170 | length = 0; 171 | for(int i=aOffset+1; i 7 | 8 | @class BerTag; 9 | @class BerTlv; 10 | 11 | 12 | @interface BerTlvs : NSObject 13 | 14 | @property(copy, nonatomic, readonly) NSArray * list ; 15 | 16 | - (id)init:(NSArray *)aList; 17 | 18 | - (BerTlv *) find :(BerTag *)aTag; 19 | - (NSArray *) findAll:(BerTag *)aTag; 20 | 21 | - (NSString *) dump:(NSString *)aPadding; 22 | 23 | 24 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/BerTlvs.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvs.h" 7 | #import "BerTag.h" 8 | #import "BerTlv.h" 9 | 10 | 11 | @implementation BerTlvs { 12 | 13 | 14 | } 15 | 16 | @synthesize list; 17 | 18 | - (id)init:(NSArray *)aList { 19 | self = [super init]; 20 | if (self) { 21 | list = aList; 22 | } 23 | return self; 24 | } 25 | 26 | - (BerTlv *)find:(BerTag *)aTag { 27 | for (BerTlv *tlv in list) { 28 | BerTlv *found = [tlv find:aTag]; 29 | if(found!=nil) { 30 | return found; 31 | } 32 | } 33 | return nil; 34 | } 35 | 36 | - (NSArray *)findAll:(BerTag *)aTag { 37 | NSMutableArray *ret = [[NSMutableArray alloc] init]; 38 | for (BerTlv *tlv in list) { 39 | [ret addObjectsFromArray:[tlv findAll:aTag]]; 40 | } 41 | return ret; 42 | } 43 | 44 | - (NSString *) dump:(NSString *)aPadding { 45 | NSMutableString *sb = [[NSMutableString alloc] init]; 46 | for (BerTlv *tlv in list) { 47 | [sb appendString:[tlv dump:aPadding]]; 48 | } 49 | 50 | return sb; 51 | } 52 | 53 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/HexUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface HexUtil : NSObject 10 | 11 | + (NSString *) format:(NSData *)aData; 12 | + (NSString *) prettyFormat:(NSData *)aData; 13 | 14 | + (NSData *) parse:(NSString *)aHex; 15 | 16 | + (NSString *)format:(NSData *)data offset:(uint)offset len:(NSUInteger)len; 17 | @end -------------------------------------------------------------------------------- /PZ8583/8583/BerTlv/HexUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "HexUtil.h" 7 | 8 | static uint8_t HEX_BYTES[] = { 9 | // 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 11 | /* 0 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 12 | /* 1 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 13 | /* 2 */, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 99, 99, 99, 99, 99, 99 14 | /* 3 */, 99, 10, 11, 12, 13, 14, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99 15 | /* 4 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 16 | /* 5 */, 99, 10, 11, 12, 13, 14, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99 17 | /* 6 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 18 | }; 19 | 20 | static uint8_t HEX_BYTES_LEN = 128; 21 | static uint8_t HEX_BYTE_SKIP = 99; 22 | 23 | 24 | @implementation HexUtil { 25 | 26 | 27 | } 28 | 29 | + (NSString *)prettyFormat:(NSData *)aData { 30 | NSMutableString *sb = [[NSMutableString alloc] initWithCapacity:aData.length*2]; 31 | uint8_t const *bytes = aData.bytes; 32 | [sb appendFormat:@"[%@]", @(aData.length)]; 33 | for(NSUInteger i=0; i < aData.length; i++) { 34 | uint8_t b = bytes[i]; 35 | [sb appendFormat:@" %02X", b]; 36 | } 37 | return sb; 38 | } 39 | 40 | + (NSString *)format:(NSData *)aData { 41 | return [HexUtil format:aData offset:0 len:aData.length]; 42 | } 43 | 44 | + (NSData *)parse:(NSString *)aHex { 45 | char const *text = [aHex cStringUsingEncoding:NSASCIIStringEncoding]; 46 | size_t len = strnlen(text, aHex.length); 47 | 48 | uint8_t high = 0; 49 | BOOL highPassed = NO; 50 | 51 | NSMutableData *data = [[NSMutableData alloc] initWithCapacity:len/2]; 52 | 53 | for(int i=0; i< len; i++) { 54 | char index = text[i]; 55 | 56 | // checks if value out of 127 (ASCII must contains from 0 to 127) 57 | if(index >= HEX_BYTES_LEN ) { 58 | continue; 59 | } 60 | 61 | uint8_t nibble = HEX_BYTES[index]; 62 | 63 | // checks if not HEX chars 64 | if(nibble == HEX_BYTE_SKIP) { 65 | continue; 66 | } 67 | 68 | if(highPassed) { 69 | // fills right nibble, creates byte and adds it 70 | uint8_t low = (uint8_t) (nibble & 0x7f); 71 | highPassed = NO; 72 | uint8_t currentByte = ((high << 4) + low); 73 | [data appendBytes:¤tByte length:1]; 74 | 75 | } else { 76 | // fills left nibble 77 | high = (uint8_t) (nibble & 0x7f); 78 | highPassed = YES; 79 | } 80 | } 81 | 82 | if(highPassed) { 83 | @throw([NSException exceptionWithName:@"EvenException" 84 | reason:[NSString stringWithFormat:@"Even count of HEX chars. Hex string is %@" 85 | , aHex] 86 | userInfo:nil]); 87 | } 88 | // returns immutable 89 | return [NSData dataWithData:data]; 90 | } 91 | 92 | 93 | + (NSString *)format:(NSData *)aData offset:(uint)aOffset len:(NSUInteger)aLen { 94 | NSMutableString *sb = [[NSMutableString alloc] initWithCapacity:aData.length*2]; 95 | uint8_t const *bytes = aData.bytes; 96 | NSUInteger max = aOffset+aLen; 97 | for(NSUInteger i=aOffset; i < max; i++) { 98 | uint8_t b = bytes[i]; 99 | [sb appendFormat:@"%02X", b]; 100 | } 101 | return sb; 102 | } 103 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codefunny/ObjC-PZ8583/246371d08e45541beaf7aaa643b3fe02c6668390/PZ8583/8583/Utils.zip -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTag.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @interface BerTag : NSObject 9 | 10 | @property(nonatomic, copy) NSData *data;; 11 | 12 | - (id) init:(NSData *)aData 13 | offset:(uint)aOffset 14 | length:(uint)aLength; 15 | 16 | - (id) init:(uint8_t)aFirstByte; 17 | - (id) init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte; 18 | - (id) init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte thirdByte:(uint8_t)aThirdByte; 19 | 20 | - (BOOL)isConstructed; 21 | 22 | - (BOOL)isEqual:(id)other; 23 | - (BOOL)isEqualToTag:(BerTag *)tag; 24 | - (NSUInteger)hash; 25 | - (NSString *)description; 26 | 27 | - (NSString *)hex; 28 | 29 | + (BerTag *)parse:(NSString *)aHexString; 30 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTag.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTag.h" 7 | #import "HexUtil.h" 8 | 9 | 10 | @implementation BerTag { 11 | } 12 | 13 | @synthesize data; 14 | 15 | - (id)init:(NSData *)aData offset:(uint)aOffset length:(uint)aLength { 16 | self = [super init]; 17 | if(self) { 18 | NSRange range = {aOffset, aLength}; 19 | data = [aData subdataWithRange:range]; 20 | } 21 | return self; 22 | } 23 | 24 | - (id)init:(uint8_t)aFirstByte { 25 | self = [super init]; 26 | if(self) { 27 | data = [NSData dataWithBytes:&aFirstByte length:1]; 28 | } 29 | return self; 30 | } 31 | 32 | - (id)init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte { 33 | self = [super init]; 34 | if(self) { 35 | uint8_t bytes[2]; 36 | bytes[0] = aFirstByte; 37 | bytes[1] = aSecondByte; 38 | data = [NSData dataWithBytes:bytes length:2]; 39 | } 40 | return self; 41 | } 42 | 43 | - (id)init:(uint8_t)aFirstByte secondByte:(uint8_t)aSecondByte thirdByte:(uint8_t)aThirdByte { 44 | self = [super init]; 45 | if(self) { 46 | uint8_t bytes[3]; 47 | bytes[0] = aFirstByte; 48 | bytes[1] = aSecondByte; 49 | bytes[2] = aThirdByte; 50 | data = [NSData dataWithBytes:bytes length:3]; 51 | } 52 | return self; 53 | } 54 | 55 | - (BOOL)isConstructed { 56 | //by peter 20150714 57 | // uint8_t *bytes = (uint8_t *) data.bytes; 58 | // 0x20 59 | // return (bytes[0] & 0b00100000) != 0; 60 | 61 | return NO; 62 | } 63 | 64 | - (BOOL)isEqual:(id)other { 65 | if (other == self) { 66 | return YES; 67 | } 68 | 69 | if (!other || ![[other class] isEqual:[self class]]) { 70 | return NO; 71 | } 72 | 73 | return [self isEqualToTag:other]; 74 | } 75 | 76 | - (BOOL)isEqualToTag:(BerTag *)tag { 77 | if (self == tag) { 78 | return YES; 79 | } 80 | 81 | if (tag == nil) { 82 | return NO; 83 | } 84 | 85 | return !(data != tag->data && ![data isEqualToData:tag->data]); 86 | } 87 | 88 | - (NSUInteger)hash { 89 | return [data hash]; 90 | } 91 | 92 | - (NSString *)description { 93 | NSMutableString *description = [NSMutableString stringWithCapacity:data.length+2]; 94 | if(self.isConstructed) { 95 | [description appendFormat:@"+ "]; 96 | } else { 97 | [description appendFormat:@"- "]; 98 | } 99 | [description appendFormat:@"%@", [HexUtil format:data]]; 100 | return description; 101 | } 102 | 103 | + (BerTag *)parse:(NSString *)aHexString { 104 | NSData *data = [HexUtil parse:aHexString]; 105 | return [[BerTag alloc] init:data offset:0 length:(uint)data.length]; 106 | } 107 | 108 | - (NSString *)hex { 109 | return [HexUtil format:data]; 110 | } 111 | 112 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlv.h: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlv.h 3 | // BerTlv 4 | // 5 | // Created by Evgeniy Sinev on 04/08/14. 6 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class BerTag; 12 | 13 | @interface BerTlv : NSObject 14 | 15 | @property(copy, nonatomic, readonly) BerTag * tag ; 16 | @property(copy, nonatomic, readonly) NSData * value ; 17 | @property(copy, nonatomic, readonly) NSArray * list ; 18 | @property(nonatomic, readonly) BOOL primitive ; 19 | @property(nonatomic, readonly) BOOL constructed ; 20 | 21 | - (id)init:(BerTag *)aTag value:(NSData *)aValue; 22 | - (id)init:(BerTag *)aTag array:(NSArray *)aArray; 23 | 24 | - (BOOL) hasTag:(BerTag *)aTag; 25 | - (BerTlv *) find:(BerTag *)aTag; 26 | - (NSArray *) findAll:(BerTag *)aTag; 27 | 28 | - (NSString *) hexValue; 29 | - (NSString *) textValue; 30 | 31 | - (NSString *) dump:(NSString *)aPadding; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlv.m: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlv.m 3 | // BerTlv 4 | // 5 | // Created by Evgeniy Sinev on 04/08/14. 6 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 7 | // 8 | 9 | #import "BerTlv.h" 10 | #import "BerTag.h" 11 | #import "HexUtil.h" 12 | 13 | @implementation BerTlv 14 | 15 | @synthesize tag, value, list, constructed, primitive; 16 | 17 | - (id)init:(BerTag *)aTag array:(NSArray *)aArray { 18 | self = [super init]; 19 | if(self) { 20 | tag = aTag; 21 | list = aArray; 22 | constructed = aTag.isConstructed; 23 | primitive = !constructed; 24 | } 25 | return self; 26 | } 27 | 28 | - (id)init:(BerTag *)aTag value:(NSData *)aValue { 29 | self = [super init]; 30 | if(self) { 31 | tag = aTag; 32 | value = aValue; 33 | constructed = aTag.isConstructed; 34 | primitive = !constructed; 35 | } 36 | return self; 37 | } 38 | 39 | - (BOOL)hasTag:(BerTag *)aTag { 40 | return [self find:aTag] != nil; 41 | } 42 | 43 | - (BerTlv *)find:(BerTag *)aTag { 44 | if([aTag isEqualToTag:tag]) { 45 | return self; 46 | } 47 | 48 | if(primitive) { 49 | return nil; 50 | } 51 | 52 | for( BerTlv * tlv in list) { 53 | BerTlv *found = [tlv find:aTag]; 54 | if(found!=nil) { 55 | return found; 56 | } 57 | } 58 | 59 | return nil; 60 | } 61 | 62 | - (NSArray *)findAll:(BerTag *)aTag { 63 | NSMutableArray *array = [[NSMutableArray alloc] init]; 64 | if([aTag isEqualToTag:tag]) { 65 | [array addObject:self]; 66 | } 67 | 68 | if(constructed) { 69 | for( BerTlv * tlv in list) { 70 | NSArray *found = [tlv findAll:aTag]; 71 | [array addObjectsFromArray:found]; 72 | } 73 | } 74 | 75 | return array; 76 | } 77 | 78 | - (NSString *)hexValue { 79 | [self checkPrimitive]; 80 | return [HexUtil format:value]; 81 | } 82 | 83 | - (NSString *)textValue { 84 | return [[NSString alloc] initWithData:self.value encoding:NSASCIIStringEncoding]; 85 | } 86 | 87 | - (void)checkPrimitive { 88 | if(constructed) { 89 | @throw([NSException exceptionWithName:@"NotPrimitiveTagException" 90 | reason:[NSString stringWithFormat:@"Tag %@ is constructed", tag] 91 | userInfo:nil]); 92 | } 93 | } 94 | 95 | 96 | - (NSString *)dump:(NSString *)aPadding { 97 | NSMutableString *sb = [[NSMutableString alloc] init]; 98 | 99 | if(primitive) { 100 | [sb appendFormat:@"%@ - [%@] %@\n", aPadding, tag.hex, [self hexValue]]; 101 | } else { 102 | [sb appendFormat:@"%@ + [%@]\n", aPadding, tag.hex]; 103 | NSMutableString *childPadding = [[NSMutableString alloc] init]; 104 | [childPadding appendString:aPadding]; 105 | [childPadding appendString:aPadding]; 106 | for (BerTlv *tlv in list) { 107 | [sb appendString:[tlv dump:childPadding]]; 108 | } 109 | } 110 | return sb; 111 | } 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class BerTlv; 9 | @class BerTlvs; 10 | @class BerTag; 11 | 12 | 13 | @interface BerTlvBuilder : NSObject 14 | 15 | // initialize 16 | - (id)init; 17 | - (id)initWithTlv :(BerTlv * ) aTlv ; 18 | - (id)initWithTlvs :(BerTlvs * ) aTlvs ; 19 | - (id)initWithTemplate :(BerTag * ) aTag ; 20 | 21 | // build 22 | - (NSData *) buildData ; 23 | - (BerTlvs *) buildTlvs ; 24 | - (BerTlv *) buildTlv ; 25 | 26 | // add values 27 | - (void) addBerTlv :(BerTlv *) aTlv ; 28 | - (void) addBerTlvs :(BerTlvs *) aTlvs; 29 | - (void) addAmount :(NSDecimalNumber *) aAmount tag:(BerTag *)aTag; 30 | - (void) addDate :(NSDate *) aDate tag:(BerTag *)aTag; 31 | - (void) addTime :(NSDate *) aTime tag:(BerTag *)aTag; 32 | - (void) addText :(NSString *) aText tag:(BerTag *)aTag; 33 | - (void) addBcd :(NSUInteger ) aValue tag:(BerTag *)aTag length:(NSUInteger )aLength; 34 | - (void) addBytes :(NSData *) aBuf tag:(BerTag *)aTag; 35 | - (void) addHex :(NSString *) aHex tag:(BerTag *)aTag; 36 | 37 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvBuilder.h" 7 | #import "BerTlv.h" 8 | #import "BerTlvs.h" 9 | #import "BerTag.h" 10 | #import "HexUtil.h" 11 | #import "BerTlvParser.h" 12 | 13 | 14 | @implementation BerTlvBuilder { 15 | NSMutableData *data; 16 | BerTag *templateTag; 17 | } 18 | 19 | - (id)init { 20 | self = [super init]; 21 | if (self) { 22 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (id)initWithTemplate:(BerTag *)aTag { 29 | self = [super init]; 30 | if (self) { 31 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 32 | templateTag = aTag; 33 | } 34 | return self; 35 | } 36 | 37 | - (id)initWithTlv:(BerTlv *)aTlv { 38 | self = [super init]; 39 | if (self) { 40 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 41 | if(aTlv.primitive) { 42 | [self addBytes:aTlv.value tag:aTlv.tag]; 43 | } else { 44 | templateTag = aTlv.tag; 45 | for (BerTlv *tlv in aTlv.list) { 46 | [self addBerTlv:tlv]; 47 | } 48 | } 49 | } 50 | return self; 51 | } 52 | 53 | - (id)initWithTlvs:(BerTlvs *)aTlvs { 54 | self = [super init]; 55 | if (self) { 56 | data = [[NSMutableData alloc] initWithCapacity:0xff]; 57 | [self addBerTlvs:aTlvs]; 58 | } 59 | return self; 60 | } 61 | 62 | - (void)addBcd:(NSUInteger )aValue tag:(BerTag *)aTag length:(NSUInteger )aLength { 63 | NSMutableString *hex = [NSMutableString stringWithFormat:@"%@", @(aValue)]; 64 | for(int i=0; hex.length < aLength*2 && i<100; i++) { 65 | [hex insertString:@"0" atIndex:0]; 66 | } 67 | [self addHex:hex tag:aTag]; 68 | } 69 | 70 | - (void)addAmount:(NSDecimalNumber *)aAmount tag:(BerTag *)aTag { 71 | NSUInteger cents = [aAmount decimalNumberByMultiplyingBy:[[NSDecimalNumber alloc] initWithInt:100]].unsignedIntegerValue; 72 | [self addBcd:cents tag:aTag length:6]; 73 | } 74 | 75 | - (void)addDate:(NSDate *)aDate tag:(BerTag *)aTag { 76 | NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init]; 77 | [dateFormat setDateFormat: @"yyMMdd"]; 78 | NSString *hex = [dateFormat stringFromDate:aDate]; 79 | [self addHex:hex tag:aTag]; 80 | } 81 | 82 | - (void)addTime:(NSDate *)aTime tag:(BerTag *)aTag { 83 | NSDateFormatter * dateFormat = [[NSDateFormatter alloc] init]; 84 | [dateFormat setDateFormat: @"HHmmss"]; 85 | NSString *hex = [dateFormat stringFromDate:aTime]; 86 | [self addHex:hex tag:aTag]; 87 | } 88 | 89 | - (void)addBytes:(NSData *)aBuf tag:(BerTag *)aTag { 90 | // TYPE 91 | [data appendData:aTag.data]; 92 | 93 | // LEN 94 | NSData * lenData = [self createLengthData:aBuf.length]; 95 | [data appendData:lenData]; 96 | 97 | // VALUE 98 | [data appendData:aBuf]; 99 | } 100 | 101 | - (void)addText:(NSString *)aText tag:(BerTag *)aTag { 102 | NSData *buf = [aText dataUsingEncoding:NSASCIIStringEncoding]; 103 | [self addBytes:buf tag:aTag]; 104 | } 105 | 106 | - (void)addHex:(NSString *)aHex tag:(BerTag *)aTag { 107 | NSData *buf = [HexUtil parse:aHex]; 108 | [self addBytes:buf tag:aTag]; 109 | } 110 | 111 | - (NSData *)buildData { 112 | // no template tag so can simply return data buffer 113 | if (templateTag == nil) { 114 | return data; 115 | } 116 | 117 | // calculates bytes count for TYPE and LENGTH 118 | NSUInteger typeBytesCount = templateTag.data.length; 119 | NSUInteger lengthBytesCount = [self calcBytesCountForLength:data.length]; 120 | 121 | NSMutableData *ret = [[NSMutableData alloc] initWithCapacity: 122 | + typeBytesCount 123 | + lengthBytesCount 124 | + data.length 125 | ]; 126 | 127 | // TYPE 128 | [ret appendData:templateTag.data]; 129 | 130 | // LENGTH 131 | NSData *lengthData = [self createLengthData:data.length]; 132 | [ret appendData:lengthData]; 133 | 134 | // VALUE 135 | [ret appendData:data]; 136 | 137 | return ret; 138 | 139 | } 140 | 141 | - (NSData *)createLengthData:(NSUInteger)aLength { 142 | if(aLength < 0x80) { 143 | uint8_t buf[1]; 144 | buf[0] = (uint8_t) aLength; 145 | return [NSData dataWithBytes:buf length:1]; 146 | 147 | } else if (aLength <0x100) { 148 | uint8_t buf[2]; 149 | buf[0] = 0x81; 150 | buf[1] = (uint8_t) aLength; 151 | return [NSData dataWithBytes:buf length:2]; 152 | 153 | } else if( aLength < 0x10000) { 154 | uint8_t buf[3]; 155 | buf[0] = 0x82; 156 | buf[1] = (uint8_t) (aLength / 0x100); 157 | buf[2] = (uint8_t) (aLength % 0x100); 158 | return [NSData dataWithBytes:buf length:3]; 159 | 160 | } else if( aLength < 0x1000000 ) { 161 | uint8_t buf[4]; 162 | buf[0] = 0x83; 163 | buf[1] = (uint8_t) (aLength / 0x10000); 164 | buf[2] = (uint8_t) (aLength / 0x100); 165 | buf[3] = (uint8_t) (aLength % 0x100); 166 | return [NSData dataWithBytes:buf length:4]; 167 | 168 | } else { 169 | @throw([NSException exceptionWithName:@"LengthOutOfRangeException" 170 | reason:[NSString stringWithFormat:@"Length [%lu] is out of range ( > 0x1000000)", (unsigned long) aLength] 171 | userInfo:nil]); 172 | } 173 | 174 | } 175 | 176 | - (BerTlv *)buildTlv { 177 | BerTlvParser * parser = [[BerTlvParser alloc] init]; 178 | return [parser parseConstructed:[self buildData]]; 179 | } 180 | 181 | - (BerTlvs *)buildTlvs { 182 | BerTlvParser * parser = [[BerTlvParser alloc] init]; 183 | return [parser parseTlvs:[self buildData]]; 184 | } 185 | 186 | - (NSUInteger) calcBytesCountForLength:(NSUInteger)aLength { 187 | NSUInteger ret; 188 | if(aLength < 0x80) { 189 | ret = 1; 190 | } else if (aLength <0x100) { 191 | ret = 2; 192 | } else if( aLength < 0x10000) { 193 | ret = 3; 194 | } else if( aLength < 0x1000000 ) { 195 | ret = 4; 196 | } else { 197 | @throw([NSException exceptionWithName:@"LengthOutOfRangeException" 198 | reason:[NSString stringWithFormat:@"Length [%lu] is out of range ( > 0x1000000)", (unsigned long) aLength] 199 | userInfo:nil]); 200 | } 201 | return ret; 202 | } 203 | 204 | 205 | - (void)addBerTlv:(BerTlv *)aTlv { 206 | // primitive 207 | if(aTlv.primitive) { 208 | [self addBytes:aTlv.value tag:aTlv.tag]; 209 | 210 | // constructed 211 | } else { 212 | BerTlvBuilder *builder = [[BerTlvBuilder alloc] initWithTemplate:aTlv.tag]; 213 | for (BerTlv *tlv in aTlv.list) { 214 | [builder addBerTlv:tlv]; 215 | } 216 | [data appendData:builder.buildData]; 217 | } 218 | } 219 | 220 | - (void)addBerTlvs:(BerTlvs *)aTlvs { 221 | for (BerTlv *tlv in aTlvs.list) { 222 | [self addBerTlv:tlv]; 223 | } 224 | } 225 | 226 | 227 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvComm.h: -------------------------------------------------------------------------------- 1 | // 2 | // BerTlvComm.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/14. 6 | // Copyright (c) 2015年 paylab. All rights reserved. 7 | // 8 | 9 | 10 | #import "BerTlvParser.h" 11 | #import "BerTlvBuilder.h" 12 | #import "HexUtil.h" 13 | #import "BerTlvs.h" 14 | #import "BerTlv.h" 15 | #import "BerTag.h" 16 | 17 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 05/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @class BerTlv; 9 | @class BerTlvs; 10 | 11 | 12 | @interface BerTlvParser : NSObject 13 | 14 | - (BerTlv *)parseConstructed:(NSData *)aData; 15 | - (BerTlvs *)parseTlvs:(NSData *)aData; 16 | 17 | 18 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 05/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvParser.h" 7 | #import "BerTlv.h" 8 | #import "HexUtil.h" 9 | #import "BerTag.h" 10 | #import "BerTlvs.h" 11 | 12 | 13 | static int IS_DEBUG_ENABLED = 0; 14 | 15 | @implementation BerTlvParser { 16 | 17 | 18 | 19 | } 20 | - (BerTlv *)parseConstructed:(NSData *)aData { 21 | uint result=0; 22 | BerTlv * ret = [self parseWithResult:&result data:aData offset:0 len:(uint)aData.length level:0]; 23 | return ret; 24 | } 25 | 26 | - (BerTlvs *)parseTlvs:(NSData *)aData { 27 | if(aData.length==0) { 28 | return [[BerTlvs alloc] init:[[NSArray alloc] init]]; 29 | } 30 | 31 | NSMutableArray *list = [[NSMutableArray alloc] init]; 32 | int offset = 0; 33 | for(uint i=0; i<100; i++) { 34 | uint result=0; 35 | BerTlv * ret = [self parseWithResult:&result data:aData offset:offset len:(uint)aData.length-offset level:0]; 36 | [list addObject:ret]; 37 | 38 | if (result >= aData.length) { 39 | break; 40 | } 41 | 42 | offset = result; 43 | } 44 | 45 | return [[BerTlvs alloc] init:list]; 46 | } 47 | 48 | - (BerTlv *)parseWithResult:(uint*)aOutResult 49 | data:(NSData *)aBuf 50 | offset:(uint)aOffset 51 | len:(uint)aLen 52 | level:(uint)aLevel 53 | { 54 | if(aOffset+aLen > aBuf.length) { 55 | @throw([NSException exceptionWithName:@"OutOfRangeException" 56 | reason:[NSString stringWithFormat:@"Length is out of the range [offset=%d, len=%d, array.length=%lu, level=%d]" 57 | , aOffset, aLen, (unsigned long) aBuf.length, aLevel] 58 | userInfo:nil]); 59 | } 60 | 61 | NSString *levelPadding = IS_DEBUG_ENABLED ? [self createLevelPadding:aLevel] : @""; 62 | if(IS_DEBUG_ENABLED) { 63 | NSLog(@"%@parseWithResult( level=%d, offset=%d, len=%d, buf=%@)" 64 | , levelPadding, aLevel, aOffset, aLen, [HexUtil format:aBuf] 65 | ); 66 | } 67 | 68 | // TAG 69 | uint tagBytesCount = [self calcTagBytesCount:aBuf offset:aOffset]; 70 | BerTag *tag = [self createTag:aBuf offset:aOffset len:tagBytesCount pad:levelPadding]; 71 | 72 | // LENGTH 73 | uint lengthBytesCount = [self calcLengthBytesCount:aBuf offset:aOffset + tagBytesCount]; 74 | uint valueLength = [self calcDataLength:aBuf offset:aOffset + tagBytesCount]; 75 | 76 | if(IS_DEBUG_ENABLED) { 77 | NSLog(@"%@lenBytesCount = %d, len = %d, lenBuf = %@" 78 | , levelPadding, lengthBytesCount, valueLength, [HexUtil format:aBuf offset:aOffset + tagBytesCount len:lengthBytesCount]); 79 | } 80 | 81 | // VALUE 82 | if(tag.isConstructed) { 83 | NSMutableArray *array = [[NSMutableArray alloc] init]; 84 | [self addChildren:aBuf 85 | offset:aOffset 86 | level:aLevel 87 | levelPadding:levelPadding 88 | tagBytesCount:tagBytesCount 89 | dataBytesCount:lengthBytesCount 90 | valueLength:valueLength 91 | array:array 92 | ]; 93 | uint resultOffset = aOffset + tagBytesCount + lengthBytesCount + valueLength; 94 | if(IS_DEBUG_ENABLED) { 95 | NSLog(@"%@Returning constructed offset = %d", levelPadding, resultOffset ); 96 | } 97 | *aOutResult = resultOffset; 98 | return [[BerTlv alloc] init:tag array:array]; 99 | 100 | } else { 101 | NSRange range = {aOffset+tagBytesCount+lengthBytesCount, valueLength}; 102 | NSData *value = [aBuf subdataWithRange:range]; 103 | uint resultOffset = aOffset + tagBytesCount + lengthBytesCount + valueLength; 104 | 105 | if(IS_DEBUG_ENABLED) { 106 | NSLog(@"%@Primitive value = %@", levelPadding, [HexUtil format:value]); 107 | NSLog(@"%@Returning primitive offset = %d", levelPadding, resultOffset ); 108 | } 109 | *aOutResult = resultOffset; 110 | return [[BerTlv alloc] init:tag value:value]; 111 | } 112 | } 113 | 114 | - (uint)calcTagBytesCount:(NSData *)aBuf offset:(uint)aOffset { 115 | uint8_t const *bytes = aBuf.bytes; 116 | if((bytes[aOffset] & 0x1F) == 0x1F) { // see subsequent bytes 117 | uint len = 2; 118 | //update by peter 119 | // for(int i=aOffset+1; i3) { 164 | @throw([NSException exceptionWithName:@"BadLengthException" 165 | reason:[NSString stringWithFormat:@"At position %d the len is more then 3 [%d]" 166 | , aOffset, numberOfBytes] 167 | userInfo:nil]); 168 | } 169 | 170 | length = 0; 171 | for(int i=aOffset+1; i 7 | 8 | @class BerTag; 9 | @class BerTlv; 10 | 11 | 12 | @interface BerTlvs : NSObject 13 | 14 | @property(copy, nonatomic, readonly) NSArray * list ; 15 | 16 | - (id)init:(NSArray *)aList; 17 | 18 | - (BerTlv *) find :(BerTag *)aTag; 19 | - (NSArray *) findAll:(BerTag *)aTag; 20 | 21 | - (NSString *) dump:(NSString *)aPadding; 22 | 23 | 24 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/BerTlvs.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 06/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "BerTlvs.h" 7 | #import "BerTag.h" 8 | #import "BerTlv.h" 9 | 10 | 11 | @implementation BerTlvs { 12 | 13 | 14 | } 15 | 16 | @synthesize list; 17 | 18 | - (id)init:(NSArray *)aList { 19 | self = [super init]; 20 | if (self) { 21 | list = aList; 22 | } 23 | return self; 24 | } 25 | 26 | - (BerTlv *)find:(BerTag *)aTag { 27 | for (BerTlv *tlv in list) { 28 | BerTlv *found = [tlv find:aTag]; 29 | if(found!=nil) { 30 | return found; 31 | } 32 | } 33 | return nil; 34 | } 35 | 36 | - (NSArray *)findAll:(BerTag *)aTag { 37 | NSMutableArray *ret = [[NSMutableArray alloc] init]; 38 | for (BerTlv *tlv in list) { 39 | [ret addObjectsFromArray:[tlv findAll:aTag]]; 40 | } 41 | return ret; 42 | } 43 | 44 | - (NSString *) dump:(NSString *)aPadding { 45 | NSMutableString *sb = [[NSMutableString alloc] init]; 46 | for (BerTlv *tlv in list) { 47 | [sb appendString:[tlv dump:aPadding]]; 48 | } 49 | 50 | return sb; 51 | } 52 | 53 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/HexUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface HexUtil : NSObject 10 | 11 | + (NSString *) format:(NSData *)aData; 12 | + (NSString *) prettyFormat:(NSData *)aData; 13 | 14 | + (NSData *) parse:(NSString *)aHex; 15 | 16 | + (NSString *)format:(NSData *)data offset:(uint)offset len:(NSUInteger)len; 17 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/BerTlv/HexUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Evgeniy Sinev on 04/08/14. 3 | // Copyright (c) 2014 Evgeniy Sinev. All rights reserved. 4 | // 5 | 6 | #import "HexUtil.h" 7 | 8 | static uint8_t HEX_BYTES[] = { 9 | // 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 | 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 11 | /* 0 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 12 | /* 1 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 13 | /* 2 */, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 99, 99, 99, 99, 99, 99 14 | /* 3 */, 99, 10, 11, 12, 13, 14, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99 15 | /* 4 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 16 | /* 5 */, 99, 10, 11, 12, 13, 14, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99 17 | /* 6 */, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 18 | }; 19 | 20 | static uint8_t HEX_BYTES_LEN = 128; 21 | static uint8_t HEX_BYTE_SKIP = 99; 22 | 23 | 24 | @implementation HexUtil { 25 | 26 | 27 | } 28 | 29 | + (NSString *)prettyFormat:(NSData *)aData { 30 | NSMutableString *sb = [[NSMutableString alloc] initWithCapacity:aData.length*2]; 31 | uint8_t const *bytes = aData.bytes; 32 | [sb appendFormat:@"[%@]", @(aData.length)]; 33 | for(NSUInteger i=0; i < aData.length; i++) { 34 | uint8_t b = bytes[i]; 35 | [sb appendFormat:@" %02X", b]; 36 | } 37 | return sb; 38 | } 39 | 40 | + (NSString *)format:(NSData *)aData { 41 | return [HexUtil format:aData offset:0 len:aData.length]; 42 | } 43 | 44 | + (NSData *)parse:(NSString *)aHex { 45 | char const *text = [aHex cStringUsingEncoding:NSASCIIStringEncoding]; 46 | size_t len = strnlen(text, aHex.length); 47 | 48 | uint8_t high = 0; 49 | BOOL highPassed = NO; 50 | 51 | NSMutableData *data = [[NSMutableData alloc] initWithCapacity:len/2]; 52 | 53 | for(int i=0; i< len; i++) { 54 | char index = text[i]; 55 | 56 | // checks if value out of 127 (ASCII must contains from 0 to 127) 57 | if(index >= HEX_BYTES_LEN ) { 58 | continue; 59 | } 60 | 61 | uint8_t nibble = HEX_BYTES[index]; 62 | 63 | // checks if not HEX chars 64 | if(nibble == HEX_BYTE_SKIP) { 65 | continue; 66 | } 67 | 68 | if(highPassed) { 69 | // fills right nibble, creates byte and adds it 70 | uint8_t low = (uint8_t) (nibble & 0x7f); 71 | highPassed = NO; 72 | uint8_t currentByte = ((high << 4) + low); 73 | [data appendBytes:¤tByte length:1]; 74 | 75 | } else { 76 | // fills left nibble 77 | high = (uint8_t) (nibble & 0x7f); 78 | highPassed = YES; 79 | } 80 | } 81 | 82 | if(highPassed) { 83 | @throw([NSException exceptionWithName:@"EvenException" 84 | reason:[NSString stringWithFormat:@"Even count of HEX chars. Hex string is %@" 85 | , aHex] 86 | userInfo:nil]); 87 | } 88 | // returns immutable 89 | return [NSData dataWithData:data]; 90 | } 91 | 92 | 93 | + (NSString *)format:(NSData *)aData offset:(uint)aOffset len:(NSUInteger)aLen { 94 | NSMutableString *sb = [[NSMutableString alloc] initWithCapacity:aData.length*2]; 95 | uint8_t const *bytes = aData.bytes; 96 | NSUInteger max = aOffset+aLen; 97 | for(NSUInteger i=aOffset; i < max; i++) { 98 | uint8_t b = bytes[i]; 99 | [sb appendFormat:@"%02X", b]; 100 | } 101 | return sb; 102 | } 103 | @end -------------------------------------------------------------------------------- /PZ8583/8583/Utils/NSString+ThreeDes.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+ThreeDes.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (ThreeDes) 12 | 13 | //Des 14 | + (NSString*)encryptDes:(NSString*)plainText withKey:(NSString*)key; 15 | + (NSString*)decryptDes:(NSString*)plainText withKey:(NSString*)key ; 16 | 17 | //3Des 18 | + (NSString *)decrypt3Des:(NSString *)plainText withKey:(NSString *)key ; 19 | + (NSString *)encrypt3Des:(NSString *)plainText withKey:(NSString *)key ; 20 | 21 | //数据异或 22 | + (NSString *)dataXor:(NSString *)data1 withData:(NSString *)data2 ; 23 | 24 | //sha-1 25 | - (NSString*) sha1; 26 | 27 | //md5 28 | -(NSString *) md5; 29 | 30 | //随机数获取 31 | + (NSString *) randomNumberWithLength:(NSInteger)length; 32 | + (NSString *) randomNumberWithLengthAndParityCheck:(NSInteger)length; 33 | 34 | //base64运算 35 | + (NSString *)base64StringFromText:(NSData *)data; 36 | + (NSData *)textFromBase64String:(NSString *)string; 37 | 38 | //mac计算 39 | + (NSString *)macBlock:(NSString *)pack withMacKey:(NSString *)macKey; 40 | + (NSString *)genMacWithMacBlock:(NSString *)block withMacKey:(NSString *)macKey; 41 | 42 | //52#加密 43 | + (NSString *)pinBlock:(NSString *)password withCard:(NSString *)panNum withPinKey:(NSString *)pinkey; 44 | 45 | //磁道加密 46 | + (NSString *)trkStr:(NSString *)trkStr withTrkKey:(NSString *)trkKey; 47 | 48 | //构建rsa公钥,通过模值和指数 49 | + (NSString *)buildRsaPubKeyByModulus:(NSString *)modulus andExponent:(NSString *)exponent; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/PZCRSA.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZCRSA.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/2. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PZCRSA : NSObject { 12 | SecKeyRef publicKey; 13 | SecKeyRef privateKey; 14 | SecCertificateRef certificate; 15 | SecPolicyRef policy; 16 | SecTrustRef trust; 17 | size_t maxPlainLen; 18 | } 19 | - (id)initWithKey:(NSData *)keydata; 20 | - (instancetype)initWithPubKey:(NSData *)data ; 21 | 22 | - (NSData *) encryptWithData:(NSData *)content; 23 | - (NSData *) encryptWithString:(NSString *)content; 24 | 25 | @end 26 | 27 | @interface PZCRSA (privatekey) 28 | 29 | - (instancetype)initWithPrvKey:(NSData *)data ; 30 | 31 | - (NSData *)decryptWithData:(NSData *)cipherString; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/PZMessageUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZMessageUtils.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PZMessageUtils : NSObject 12 | 13 | + (NSString *)hexToAscii:(NSString *)str; 14 | 15 | + (NSString *)asciiToHex:(NSString *)str; 16 | 17 | + (NSData*) hexToBytes:(NSString *)str; 18 | 19 | + (NSString *)hexStringFromData:(NSData *)data; 20 | 21 | //+ (void)showMessageHexWithData:(NSData *)data ; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PZ8583/8583/Utils/PZMessageUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZMessageUtils.m 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/10. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageUtils.h" 10 | //#import "dl_output.h" 11 | 12 | @implementation PZMessageUtils 13 | 14 | + (NSString *)hexToAscii:(NSString *)str { 15 | NSData *hexData = [self hexToBytes:str]; 16 | NSString *asciiStr = [[NSString alloc] initWithData:hexData encoding:NSASCIIStringEncoding]; 17 | 18 | return asciiStr; 19 | } 20 | 21 | + (NSString *)asciiToHex:(NSString *)str { 22 | NSData *hexData = [str dataUsingEncoding:NSASCIIStringEncoding]; 23 | NSString *hexStr = [self hexStringFromData:hexData]; 24 | 25 | return hexStr; 26 | } 27 | 28 | + (NSData*) hexToBytes:(NSString *)str 29 | { 30 | NSMutableData* data = [NSMutableData data]; 31 | 32 | int idx; 33 | for (idx = 0; idx+2 <= str.length; idx+=2) { 34 | 35 | NSRange range = NSMakeRange(idx, 2); 36 | 37 | NSString* hexStr = [str substringWithRange:range]; 38 | 39 | NSScanner* scanner = [NSScanner scannerWithString:hexStr]; 40 | 41 | unsigned int intValue; 42 | 43 | [scanner scanHexInt:&intValue]; 44 | 45 | [data appendBytes:&intValue length:1]; 46 | 47 | } 48 | 49 | return data; 50 | } 51 | 52 | + (NSString *)hexStringFromData:(NSData *)data 53 | { 54 | NSMutableString *str = [NSMutableString string]; 55 | 56 | Byte *byte = (Byte *)[data bytes]; 57 | 58 | for (int i = 0; i<[data length]; i++) { 59 | // byte+i为指针 60 | [str appendString:[self stringFromByte:*(byte+i)]]; 61 | } 62 | 63 | return str; 64 | } 65 | 66 | + (NSString *)stringFromByte:(Byte)byteVal 67 | { 68 | NSMutableString *str = [NSMutableString string]; 69 | 70 | //取高四位 71 | Byte byte1 = byteVal>>4; 72 | 73 | //取低四位 74 | Byte byte2 = byteVal & 0xf; 75 | 76 | //拼接16进制字符串 77 | [str appendFormat:@"%x",byte1]; 78 | [str appendFormat:@"%x",byte2]; 79 | 80 | return str; 81 | } 82 | 83 | //+ (void)showMessageHexWithData:(NSData *)data { 84 | // DL_UINT8 *bytes = (DL_UINT8 *)[data bytes]; 85 | // DL_OUTPUT_Hex(stdout, NULL, bytes, (DL_UINT32)data.length); 86 | //} 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZCustomConstant.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZCustomConstant.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/16. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /******************************************************************************/ 12 | //签到的60.1和60.3域 13 | extern NSString *const kSignInField60MsgType ; 14 | extern NSString *const kSignInField60Network ; 15 | 16 | //消费的60.1和3域 17 | extern NSString *const kPurchaseField60MsgType ; 18 | extern NSString *const kPurchaseField3ProcessCode ; 19 | 20 | //余额查询的60.1和3域 21 | extern NSString *const kBalanceField60MsgType ; 22 | extern NSString *const kBalanceField3ProcessCode ; 23 | 24 | //IC卡参数/公钥下载结束60.1和60.3域 25 | extern NSString *const kICParamOverField60MsgType; 26 | extern NSString *const kICPubKeyOverField60Network ; 27 | extern NSString *const kICParamOverField60Network ; 28 | 29 | //POS状态上送60.1和60.3域 30 | extern NSString *const kPosStateField60MsgType ; 31 | extern NSString *const kPosStateMagcardField60Network ; 32 | extern NSString *const kPosStateICPubKeyField60Network ; 33 | extern NSString *const kPosStateICParamField60Network ; 34 | 35 | //Pos参数传递 36 | extern NSString *const kPosParamField60MsgType ; 37 | extern NSString *const kPosParamMagcardField60Network ; 38 | extern NSString *const kPosParamICPubKeyField60Network ; 39 | extern NSString *const kPosParamICParamField60Network ; 40 | 41 | /******************************************************************************/ 42 | 43 | //响应码 44 | extern NSString *const kResponseCodeSuccess00 ; 45 | extern NSString *const kResponseCodeCheckIssBankError01; 46 | extern NSString *const kResponseCodeInvalidCardError14 ; 47 | extern NSString *const kResponseCodeNoFoundError25 ; 48 | extern NSString *const kResponseCodePinError55 ; 49 | extern NSString *const kResponseCodeError98 ; 50 | extern NSString *const kResponseCodePinError99 ; 51 | extern NSString *const kResponseCodeMacErrorA0 ; 52 | 53 | /******************************************************************************/ 54 | @interface PZCustomConstant : NSObject 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZCustomConstant.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZCustomConstant.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/16. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZCustomConstant.h" 10 | 11 | /******************************************************************************/ 12 | //签到的60.1和60.3域 13 | NSString *const kSignInField60MsgType = @"00"; 14 | NSString *const kSignInField60Network = @"003"; 15 | 16 | //消费的60.1和3域 17 | NSString *const kPurchaseField60MsgType = @"00"; 18 | NSString *const kPurchaseField3ProcessCode = @"300000"; 19 | 20 | //余额查询的60.1和3域 21 | NSString *const kBalanceField60MsgType = @"00"; 22 | NSString *const kBalanceField3ProcessCode = @"300000"; 23 | 24 | //IC卡参数/公钥下载结束60.1和60.3域 25 | NSString *const kICParamOverField60MsgType = @"00"; 26 | NSString *const kICPubKeyOverField60Network = @"003"; 27 | NSString *const kICParamOverField60Network = @"003"; 28 | 29 | //POS状态上送60.1和60.3域 30 | NSString *const kPosStateField60MsgType = @"00"; 31 | NSString *const kPosStateMagcardField60Network = @"003"; 32 | NSString *const kPosStateICPubKeyField60Network = @"003"; 33 | NSString *const kPosStateICParamField60Network = @"003"; 34 | 35 | //Pos参数传递 36 | NSString *const kPosParamField60MsgType = @"96"; 37 | NSString *const kPosParamMagcardField60Network = @"003"; 38 | NSString *const kPosParamICPubKeyField60Network = @"003"; 39 | NSString *const kPosParamICParamField60Network = @"003"; 40 | 41 | /******************************************************************************/ 42 | 43 | //响应码 44 | NSString *const kResponseCodeSuccess00 = @"00"; 45 | NSString *const kResponseCodeMacErrorA0 = @"A0"; 46 | NSString *const kResponseCodePinError99 = @"99"; 47 | NSString *const kResponseCodePinError55 = @"55"; 48 | NSString *const kResponseCodeError98 = @"98"; 49 | NSString *const kResponseCodeNoFoundError25 = @"25"; 50 | NSString *const kResponseCodeInvalidCardError14 = @"14"; 51 | NSString *const kResponseCodeCheckIssBankError01 = @"01"; 52 | 53 | /******************************************************************************/ 54 | @implementation PZCustomConstant 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosParamRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosParamRequest.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageRequest.h" 10 | 11 | @interface PZPosParamRequest : PZMessageRequest 12 | 13 | @property (nonatomic,strong) NSString *transKey; 14 | 15 | - (BOOL)decode:(NSData *)mes ; 16 | 17 | - (NSData *)encode; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosParamRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosParamRequest.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPosParamRequest.h" 10 | 11 | static NSString *const kMessageType = @"0800"; 12 | 13 | @implementation PZPosParamRequest 14 | 15 | - (BOOL)decode:(NSData *)mes { 16 | [super decode:mes]; 17 | 18 | return YES; 19 | } 20 | 21 | /** 22 | * @brief 打包成8583格式报文 23 | * @return 转换网络传输的字节 24 | */ 25 | - (NSData *)encode { 26 | self.posFields.messageType = kMessageType; 27 | 28 | return [super encode]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosParamResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosParamResponse.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageResponse.h" 10 | #import "PZPublicKeyObject.h" 11 | 12 | @interface PZPosParamResponse : PZMessageResponse 13 | 14 | @property (nonatomic,strong) NSString *tagOf62; 15 | @property (nonatomic,strong) NSMutableArray *tlvArray; 16 | 17 | @property (nonatomic,strong) PZPublicKeyObject *pubKey; 18 | 19 | - (void)parsePosField62:(NSString *)field62; 20 | 21 | - (void)parsePosField62ToPublicKey:(NSString *)field62; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosParamResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosParamResponse.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPosParamResponse.h" 10 | #import "BerTlvParser.h" 11 | #import "HexUtil.h" 12 | #import "BerTlvs.h" 13 | #import "BerTlv.h" 14 | #import "BerTag.h" 15 | 16 | @implementation PZPosParamResponse 17 | 18 | - (void)parsePosField62:(NSString *)field62 { 19 | NSString *field62Tag = [field62 substringToIndex:2]; 20 | self.tagOf62 = [PZMessageUtils hexToAscii:field62Tag]; 21 | 22 | NSString *field62TlvStr = [field62 substringFromIndex:2]; 23 | NSData *data = [HexUtil parse:field62TlvStr]; 24 | BerTlvParser *parser = [[BerTlvParser alloc] init]; 25 | BerTlvs *tlvs = [parser parseTlvs:data]; 26 | NSLog(@"%lu",(long)tlvs.list.count); 27 | NSLog(@"tlvs=\n%@",[tlvs dump:@" "]); 28 | 29 | self.tlvArray = [NSMutableArray array]; 30 | for (BerTlv *tlv in tlvs.list) { 31 | TlvTagValue *tagValue = [[TlvTagValue alloc] init]; 32 | tagValue.tlvTag = tlv.tag.hex; 33 | tagValue.tlvValue = tlv.hexValue; 34 | [self.tlvArray addObject:tagValue]; 35 | } 36 | } 37 | 38 | - (void)parsePosField62ToPublicKey:(NSString *)field62 { 39 | NSString *field62Tag = [field62 substringToIndex:2]; 40 | self.tagOf62 = [PZMessageUtils hexToAscii:field62Tag]; 41 | 42 | NSString *field62TlvStr = [field62 substringFromIndex:2]; 43 | NSData *data = [HexUtil parse:field62TlvStr]; 44 | BerTlvParser *parser = [[BerTlvParser alloc] init]; 45 | BerTlvs *tlvs = [parser parseTlvs:data]; 46 | 47 | self.pubKey = [[PZPublicKeyObject alloc] init]; 48 | NSDictionary *tagMap = [self.pubKey tagMap]; 49 | [tagMap enumerateKeysAndObjectsUsingBlock:^(NSString *key,NSString *obj,BOOL *stop){ 50 | NSString *tlvTag = key; 51 | BerTag *berTag = [BerTag parse:tlvTag]; 52 | BerTlv *berTlv = [tlvs find:berTag]; 53 | if (berTlv) { 54 | [self.pubKey setValue:berTlv.hexValue forKeyPath:obj]; 55 | } 56 | }]; 57 | 58 | [self.pubKey description]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosStateRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosStateRequest.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageRequest.h" 10 | 11 | @interface PZPosStateRequest : PZMessageRequest 12 | 13 | - (BOOL)decode:(NSData *)mes ; 14 | 15 | - (NSData *)encode; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosStateRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosStateRequest.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPosStateRequest.h" 10 | #import "BerTlvComm.h" 11 | 12 | static NSString *const kMessageType = @"0820"; 13 | 14 | @implementation PZPosStateRequest 15 | 16 | - (BOOL)decode:(NSData *)mes { 17 | [super decode:mes]; 18 | 19 | return YES; 20 | } 21 | 22 | /** 23 | * @brief 打包成8583格式报文 24 | * @return 转换网络传输的字节 25 | */ 26 | - (NSData *)encode { 27 | self.posFields.messageType = kMessageType; 28 | 29 | return [super encode]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosStateResponse.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosStateResponse.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZMessageResponse.h" 10 | 11 | @interface PZPosStateResponse : PZMessageResponse 12 | 13 | @property (nonatomic,strong) NSString *tagOf62; 14 | @property (nonatomic,assign) NSInteger numberOfRecive; 15 | @property (nonatomic,strong) NSArray *reciveData; 16 | 17 | - (void)parsePosStateField62:(NSString *)field62; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPosStateResponse.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPosStateResponse.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPosStateResponse.h" 10 | 11 | #import "BerTlvComm.h" 12 | 13 | @implementation PZPosStateResponse 14 | 15 | - (void)parsePosStateField62:(NSString *)field62 { 16 | NSData *data = [HexUtil parse:field62]; 17 | BerTlvParser *parser = [[BerTlvParser alloc] init]; 18 | BerTlvs *tlvs = [parser parseTlvs:data]; 19 | NSLog(@"%lu",(long)tlvs.list.count); 20 | NSLog(@"tlvs=\n%@",[tlvs dump:@" "]); 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPublicKeyObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZPublicKeyObject.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/2. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TlvTagValue.h" 11 | 12 | extern NSString *const kRidKey ; 13 | extern NSString *const kIndexKey ; //索引 14 | extern NSString *const kExpireKey ; //有效期 15 | extern NSString *const kHashTagKey ; //hash算法标识 16 | extern NSString *const kAlgorithmTagKey ; //算法标识 17 | extern NSString *const kModeKey ; //模值 18 | extern NSString *const kIndicesKey ; //指数 19 | extern NSString *const kCheckValueKey ; 20 | 21 | @interface PZPublicKeyObject : NSObject 22 | 23 | @property (nonatomic,strong) TlvTagValue *rid; 24 | @property (nonatomic,strong) TlvTagValue *pubKeyIndex; 25 | @property (nonatomic,strong) TlvTagValue *pubKeyExpire; 26 | @property (nonatomic,strong) TlvTagValue *pubKeyHashTag; 27 | @property (nonatomic,strong) TlvTagValue *pubKeyAlgorithmTag; 28 | @property (nonatomic,strong) TlvTagValue *pubKeyMode; 29 | @property (nonatomic,strong) TlvTagValue *pubKeyIndices; 30 | @property (nonatomic,strong) TlvTagValue *pubKeyCheckValue; 31 | 32 | - (NSDictionary *)tagMap; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/PZPublicKeyObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZPublicKeyObject.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/2. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PZPublicKeyObject.h" 10 | #import 11 | 12 | NSString *const kRidKey = @"9F06"; 13 | NSString *const kIndexKey = @"9F22"; 14 | NSString *const kExpireKey = @"DF05"; 15 | NSString *const kHashTagKey = @"DF06"; 16 | NSString *const kAlgorithmTagKey = @"DF07"; 17 | NSString *const kModeKey = @"DF02"; 18 | NSString *const kIndicesKey = @"DF04"; 19 | NSString *const kCheckValueKey = @"DF03"; 20 | 21 | @implementation PZPublicKeyObject 22 | 23 | - (instancetype)init { 24 | if (self = [super init]) { 25 | [self initProperty]; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (void)initProperty { 32 | _rid = [[TlvTagValue alloc] initWithTag:kRidKey]; 33 | _pubKeyIndex = [[TlvTagValue alloc] initWithTag:kIndexKey]; 34 | _pubKeyExpire = [[TlvTagValue alloc] initWithTag:kExpireKey]; 35 | _pubKeyHashTag = [[TlvTagValue alloc] initWithTag:kHashTagKey]; 36 | _pubKeyAlgorithmTag = [[TlvTagValue alloc] initWithTag:kAlgorithmTagKey]; 37 | _pubKeyMode = [[TlvTagValue alloc] initWithTag:kModeKey]; 38 | _pubKeyIndices = [[TlvTagValue alloc] initWithTag:kIndicesKey]; 39 | _pubKeyCheckValue = [[TlvTagValue alloc] initWithTag:kCheckValueKey]; 40 | } 41 | 42 | - (NSDictionary *)tagMap { 43 | return @{kRidKey:@"rid.tlvValue", 44 | kIndexKey:@"pubKeyIndex.tlvValue", 45 | kExpireKey:@"pubKeyExpire.tlvValue", 46 | kHashTagKey:@"pubKeyHashTag.tlvValue", 47 | kAlgorithmTagKey:@"pubKeyAlgorithmTag.tlvValue", 48 | kModeKey:@"pubKeyMode.tlvValue", 49 | kIndicesKey:@"pubKeyIndices.tlvValue", 50 | kCheckValueKey:@"pubKeyCheckValue.tlvValue"}; 51 | } 52 | 53 | - (NSString *)description { 54 | NSMutableString *descStr = [NSMutableString new]; 55 | unsigned int outCount, i; 56 | objc_property_t *properties = class_copyPropertyList([PZPublicKeyObject class], &outCount); 57 | for (i=0; i 10 | 11 | @interface TlvTagValue : NSObject 12 | 13 | @property (nonatomic,strong) NSString *tlvTag; 14 | @property (nonatomic,strong) NSString *tlvValue; 15 | 16 | - (instancetype)initWithTag:(NSString *)tagStr ; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /PZ8583/8583/handler/TlvTagValue.m: -------------------------------------------------------------------------------- 1 | // 2 | // TlvTagValue.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/7/14. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "TlvTagValue.h" 10 | 11 | @implementation TlvTagValue 12 | 13 | - (instancetype)initWithTag:(NSString *)tagStr { 14 | if (self = [super init]) { 15 | _tlvTag = tagStr; 16 | _tlvValue = nil; 17 | } 18 | 19 | return self; 20 | } 21 | 22 | - (NSString *)description { 23 | NSString *desc = [NSString stringWithFormat:@"< - [%@] %@>",self.tlvTag,self.tlvValue]; 24 | return desc; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_err.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2001-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Error code definitions */ 26 | /* */ 27 | /******************************************************************************/ 28 | 29 | #ifndef __INC_DL_ERR 30 | #define __INC_DL_ERR 31 | 32 | #include "dl_base.h" 33 | 34 | /******************************************************************************/ 35 | // 36 | // TYPES 37 | // 38 | 39 | typedef DL_UINT32 DL_ERR; 40 | 41 | /******************************************************************************/ 42 | // 43 | // GENERIC ERROR CODES 44 | // 45 | 46 | #define kDL_ERR_NONE (DL_ERR)0 47 | 48 | #define kDL_ERR_OTHER (DL_ERR)1 49 | #define kDL_ERR_NOT_IMPLEMENTED (DL_ERR)2 50 | 51 | /******************************************************************************/ 52 | // 53 | // ALLOCATED ERROR CODES 54 | // 55 | 56 | // 0000-0019 57 | // 0020-0999 58 | // 1000-1019 dl_mem 59 | // 1020-1039 dl_cgi 60 | // 1040-1059 dl_hash 61 | // 1060-1079 dl_sess 62 | // 1080-1099 63 | // 1100-1119 dl_file 64 | // 1120-1139 dl_dblib 65 | // 1140-1159 dl_socket 66 | // 1160-1179 dl_smtp 67 | // 1180-2499 68 | // 2500-2519 dl_avl 69 | // 2520-2999 70 | // 3000-3019 dl_threadpool 71 | // 3020-3999 72 | // 4000-4019 dl_staticQ 73 | 74 | /******************************************************************************/ 75 | 76 | #endif /* __INC_DL_ERR */ 77 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* dl_iso8583.c - An implementation of the ISO-8583 message protocol */ 26 | /* */ 27 | /******************************************************************************/ 28 | 29 | #ifndef __INC_DL_ISO8583 30 | #define __INC_DL_ISO8583 31 | 32 | #include "dl_base.h" 33 | #include "dl_err.h" 34 | #include "dl_str.h" 35 | 36 | #include "dl_iso8583_common.h" 37 | #include "dl_iso8583_fields.h" 38 | 39 | /******************************************************************************/ 40 | 41 | // Initialises an ISO8583 message 42 | // returns: none 43 | void DL_ISO8583_MSG_Init ( DL_UINT8 *_iStaticBuf, 44 | DL_UINT16 _iStaticBufSize, 45 | DL_ISO8583_MSG *ioMsg ); 46 | 47 | // Frees a previously initialised ISO8583 message, de-allocating memory as req 48 | // returns: none 49 | void DL_ISO8583_MSG_Free ( DL_ISO8583_MSG *ioMsg ); 50 | 51 | /******************************************************************************/ 52 | 53 | // allocates and sets the specified (string) field 54 | // NB iField range is 0..kDL_ISO8583_MAX_FIELD_IDX 55 | // returns: error code 56 | DL_ERR DL_ISO8583_MSG_SetField_Str ( DL_UINT16 iField, 57 | const DL_UINT8 *iDataStr, 58 | DL_ISO8583_MSG *ioMsg ); 59 | 60 | // allocates and sets the specified field 61 | // NB iField range is 0..kDL_ISO8583_MAX_FIELD_IDX 62 | // NB iDataLen indicates the length of the data (0..n) 63 | // NB iData can be NULL if iDataLen is 0 64 | // returns: error code 65 | DL_ERR DL_ISO8583_MSG_SetField_Bin ( DL_UINT16 iField, 66 | const DL_UINT8 *_iData, 67 | DL_UINT16 _iDataLen, 68 | DL_ISO8583_MSG *ioMsg ); 69 | 70 | /******************************************************************************/ 71 | 72 | // NB iField range is 0..kDL_ISO8583_MAX_FIELD_IDX 73 | // returns: 1 if the field is set / 0 otherwise 74 | int DL_ISO8583_MSG_HaveField ( DL_UINT16 iField, 75 | const DL_ISO8583_MSG *iMsg ); 76 | 77 | /******************************************************************************/ 78 | 79 | // NB iField range is 0..kDL_ISO8583_MAX_FIELD_IDX 80 | // outputs: oPtr - static pointer to field data 81 | // returns: error code 82 | DL_ERR DL_ISO8583_MSG_GetField_Str ( DL_UINT16 iField, 83 | const DL_ISO8583_MSG *iMsg, 84 | DL_UINT8 **oPtr ); 85 | 86 | // NB iField range is 0..kDL_ISO8583_MAX_FIELD_IDX 87 | // outputs: oPtr - static pointer to field data 88 | // oByteLen - byte length of field data 89 | // returns: error code 90 | DL_ERR DL_ISO8583_MSG_GetField_Bin ( DL_UINT16 iField, 91 | const DL_ISO8583_MSG *iMsg, 92 | DL_UINT8 **oPtr, 93 | DL_UINT16 *oByteLen ); 94 | 95 | /******************************************************************************/ 96 | 97 | // NB doesn't check for overwrite of 'oByteArr'! 98 | // returns: error code 99 | DL_ERR DL_ISO8583_MSG_Pack ( const DL_ISO8583_HANDLER *iHandler, 100 | const DL_ISO8583_MSG *iMsg, 101 | DL_UINT8 *ioByteArr, 102 | DL_UINT16 *oNumBytes ); 103 | 104 | // NB 'ioMsg' must be initialised (using 'DL_ISO_MSG_Init') before calling 105 | // returns: error code 106 | DL_ERR DL_ISO8583_MSG_Unpack ( const DL_ISO8583_HANDLER *iHandler, 107 | const DL_UINT8 *iByteArr, 108 | DL_UINT16 iByteArrSize, 109 | DL_ISO8583_MSG *ioMsg ); 110 | 111 | /******************************************************************************/ 112 | 113 | // outputs the contents of the ISO8583 message to the specified file 114 | // inputs : iOutFile - output stream 115 | // _iEolStr - EOL terminator string, defaults to '\n' if NULL 116 | // iHandler - ISO8583 handler instance 117 | // iMsg - ISO8583 message 118 | // returns: none 119 | void DL_ISO8583_MSG_Dump ( FILE *iOutFile, 120 | const char *_iEolStr, 121 | const DL_ISO8583_HANDLER *iHandler, 122 | const DL_ISO8583_MSG *iMsg ); 123 | 124 | /******************************************************************************/ 125 | 126 | #endif /* __INC_DL_ISO8583 */ 127 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583_common.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | 25 | #include "dl_iso8583_common.h" 26 | 27 | /******************************************************************************/ 28 | 29 | DL_ERR _DL_ISO8583_MSG_AllocField ( DL_UINT16 iField, 30 | DL_UINT16 iSize, 31 | DL_ISO8583_MSG *ioMsg, 32 | DL_UINT8 **oPtr ) 33 | { 34 | DL_ERR err = kDL_ERR_NONE; 35 | DL_UINT8 *tmpPtr = NULL; 36 | 37 | *oPtr = NULL; 38 | 39 | if ( ioMsg->sPtrNext ) /* static mode */ 40 | { 41 | /* we cannot over-write an existing entry in static mode */ 42 | if ( NULL != ioMsg->field[iField].ptr ) /* error */ 43 | { 44 | return kDL_ERR_OTHER; 45 | } 46 | else /* ok */ 47 | { 48 | /* allocate from static buffer */ 49 | if ( (ioMsg->sPtrNext + iSize + 1) > ioMsg->sPtrEnd ) /* error */ 50 | { 51 | return kDL_ERR_OTHER; 52 | } 53 | else /* ok */ 54 | { 55 | ioMsg->field[iField].len = iSize; 56 | tmpPtr = ioMsg->sPtrNext; 57 | ioMsg->field[iField].ptr = tmpPtr; 58 | ioMsg->sPtrNext += iSize + 1; 59 | } 60 | } 61 | } 62 | else /* dynamic mode */ 63 | { 64 | err = DL_MEM_malloc(iSize+1,(void**)&tmpPtr); 65 | 66 | if ( !err ) 67 | { 68 | DL_MEM_free(ioMsg->field[iField].ptr); 69 | ioMsg->field[iField].len = iSize; 70 | ioMsg->field[iField].ptr = tmpPtr; 71 | } 72 | } 73 | 74 | *oPtr = tmpPtr; 75 | 76 | return err; 77 | } 78 | 79 | /******************************************************************************/ 80 | 81 | void DL_ISO8583_COMMON_SetHandler ( DL_ISO8583_FIELD_DEF *iFieldDefArr, 82 | DL_UINT8 iFieldDefItems, 83 | DL_ISO8583_HANDLER *oData ) 84 | { 85 | /* init outputs */ 86 | DL_MEM_memset((void*)oData,0,sizeof(DL_ISO8583_HANDLER)); 87 | 88 | /* set fields */ 89 | oData->fieldArr = iFieldDefArr; 90 | oData->fieldItems = iFieldDefItems; 91 | 92 | return; 93 | } 94 | 95 | /******************************************************************************/ 96 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583_common.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | 25 | #ifndef __INC_DL_ISO8583_COMMON 26 | #define __INC_DL_ISO8583_COMMON 27 | 28 | #include "dl_base.h" 29 | #include "dl_err.h" 30 | #include "dl_mem.h" 31 | 32 | /******************************************************************************/ 33 | // 34 | // CONSTANTS 35 | // 36 | 37 | //#define kDL_ISO8583_MAX_FIELD_IDX 128 38 | #define kDL_ISO8583_MAX_FIELD_IDX 64 39 | 40 | /******************************************************************************/ 41 | // 42 | // CONSTANTS (Fixed/Variable size indicators) 43 | // 44 | // ** DO NOT MODIFY - used by 'dl_iso8583_field.c' ** 45 | // 46 | 47 | #define kDL_ISO8583_FIXED 0 /* Fixed */ 48 | #define kDL_ISO8583_LLVAR 2 /* Variable - 0..99 */ 49 | #define kDL_ISO8583_LLLVAR 3 /* Variable - 0..999 */ 50 | #define kDL_ISO8583_LLLLVAR 4 /* Variable - 0..9999 */ 51 | 52 | // NB special type for bitmap continuation bit 53 | #define kDL_ISO8583_CONTVAR 0 54 | 55 | /******************************************************************************/ 56 | // 57 | // CONSTANTS (Field Types) 58 | // 59 | // ** DO NOT MODIFY - used by 'dl_iso8583_field.c' ** 60 | // 61 | 62 | #define kDL_ISO8583_N 0 63 | #define kDL_ISO8583_NS 1 64 | #define kDL_ISO8583_XN 2 65 | #define kDL_ISO8583_A 3 66 | #define kDL_ISO8583_AN 4 67 | #define kDL_ISO8583_ANS 5 68 | #define kDL_ISO8583_ANSB 6 69 | #define kDL_ISO8583_ANP 7 70 | #define kDL_ISO8583_B 8 71 | #define kDL_ISO8583_Z 9 72 | #define kDL_ISO8583_BMP 10 73 | 74 | /******************************************************************************/ 75 | // 76 | // MACROS 77 | // 78 | 79 | // Indicates whether the field type is BITMAP 80 | #define DL_ISO8583_IS_BITMAP(fieldType)\ 81 | (kDL_ISO8583_BMP==(fieldType)) 82 | 83 | // Gets the field definition for the specified handler 84 | #define DL_ISO8583_GetFieldDef(fieldIdx,handler)\ 85 | ((DL_ISO8583_FIELD_DEF*)(((handler)->fieldArr) + (fieldIdx))) 86 | 87 | /******************************************************************************/ 88 | // 89 | // TYPES 90 | // 91 | 92 | struct DL_ISO8583_FIELD_DEF_S 93 | { 94 | DL_UINT8 fieldType; 95 | DL_UINT16 len; /* length for fixed size / max-len for variables */ 96 | DL_UINT8 varLen; /* number of variable length digits - e.g. 0-4 */ 97 | }; 98 | typedef struct DL_ISO8583_FIELD_DEF_S DL_ISO8583_FIELD_DEF; 99 | 100 | struct DL_ISO8583_HANDLER_S 101 | { 102 | DL_ISO8583_FIELD_DEF *fieldArr; 103 | DL_UINT8 fieldItems; 104 | }; 105 | typedef struct DL_ISO8583_HANDLER_S DL_ISO8583_HANDLER; 106 | 107 | struct DL_ISO8583_MSG_FIELD_S 108 | { 109 | DL_UINT16 len; /* used mainly for binary fields */ 110 | DL_UINT8 *ptr; /* null terminated data bytes (even if binary) */ 111 | }; 112 | typedef struct DL_ISO8583_MSG_FIELD_S DL_ISO8583_MSG_FIELD; 113 | 114 | struct DL_ISO8583_MSG_S 115 | { 116 | /* static memory details */ 117 | DL_UINT8 *sPtrNext; /* next static point - NULL if dynamic mode */ 118 | DL_UINT8 *sPtrEnd; /* end of the static buffer (if static mode) */ 119 | 120 | /* NB bitmap is not stored, it is implied if the field is set */ 121 | 122 | /* fields */ 123 | DL_ISO8583_MSG_FIELD field[1+kDL_ISO8583_MAX_FIELD_IDX]; 124 | }; 125 | typedef struct DL_ISO8583_MSG_S DL_ISO8583_MSG; 126 | 127 | /******************************************************************************/ 128 | 129 | // attempts to allocate memory for a field within the ISO8583 message 130 | // NB used internally - not for client usage 131 | // returns: error code 132 | DL_ERR _DL_ISO8583_MSG_AllocField ( DL_UINT16 iField, 133 | DL_UINT16 iSize, 134 | DL_ISO8583_MSG *ioMsg, 135 | DL_UINT8 **oPtr ); 136 | 137 | /******************************************************************************/ 138 | 139 | // sets the handler details in 'oData' 140 | // returns: none 141 | void DL_ISO8583_COMMON_SetHandler ( DL_ISO8583_FIELD_DEF *iFieldDefArr, 142 | DL_UINT8 iFieldDefItems, 143 | DL_ISO8583_HANDLER *oData ); 144 | 145 | /******************************************************************************/ 146 | 147 | #endif /* __INC_DL_ISO8583_COMMON */ 148 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583_defs_pos.c: -------------------------------------------------------------------------------- 1 | // 2 | // dl_iso8583_defs_zhifu.c 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/9. 6 | // Copyright (c) 2015年 paylab. All rights reserved. 7 | // 8 | 9 | #include "dl_iso8583_defs_pos.h" 10 | 11 | /******************************************************************************/ 12 | 13 | static DL_ISO8583_FIELD_DEF _iso8583_pos_fields[] = { 14 | /* 0 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Message Type Indicator 15 | /* 1 */ {kDL_ISO8583_BMP, 8,kDL_ISO8583_CONTVAR}, // Bitmap 16 | /* 2 */ {kDL_ISO8583_N , 19,kDL_ISO8583_LLVAR }, // Primary Account Number 17 | /* 3 */ {kDL_ISO8583_N , 6,kDL_ISO8583_FIXED }, // Processing Code 18 | /* 4 */ {kDL_ISO8583_N , 12,kDL_ISO8583_FIXED }, // Amount, Txn 19 | /* 5 */ {kDL_ISO8583_N , 12,kDL_ISO8583_FIXED }, // Amount, Settlement 20 | /* 6 */ {kDL_ISO8583_N , 12,kDL_ISO8583_FIXED }, // Amount, Cardholder Billing 21 | /* 7 */ {kDL_ISO8583_N , 10,kDL_ISO8583_FIXED }, // Date and Time, Transmission 22 | /* 8 */ {kDL_ISO8583_N , 8,kDL_ISO8583_FIXED }, // Amount, Cardholder Billing Fee 23 | /* 9 */ {kDL_ISO8583_N , 8,kDL_ISO8583_FIXED }, // Conversion Rate, Settlement 24 | /* 10 */ {kDL_ISO8583_N , 8,kDL_ISO8583_FIXED }, // Conversion Rate, Cardholder Billing 25 | /* 11 */ {kDL_ISO8583_N , 6,kDL_ISO8583_FIXED }, // Systems Trace Audit Number 26 | /* 12 */ {kDL_ISO8583_N , 6,kDL_ISO8583_FIXED }, // Time, Local Txn 27 | /* 13 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Date, Local Txn 28 | /* 14 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Date, Expiration 29 | /* 15 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Date, Settlement 30 | /* 16 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Date, Conversion 31 | /* 17 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Date, Capture 32 | /* 18 */ {kDL_ISO8583_N , 4,kDL_ISO8583_FIXED }, // Merchant Type 33 | /* 19 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Country Code, Acquiring Inst 34 | /* 20 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Country Code, Primary Account Number 35 | /* 21 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Country Code, Forwarding Inst 36 | /* 22 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Point of Service Entry Mode 37 | /* 23 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Application PAN number 38 | /* 24 */ {kDL_ISO8583_N , 3,kDL_ISO8583_FIXED }, // Network International Identifier 39 | /* 25 */ {kDL_ISO8583_N , 2,kDL_ISO8583_FIXED }, // Point of Service Condition Code 40 | /* 26 */ {kDL_ISO8583_N , 2,kDL_ISO8583_FIXED }, // Point of Service PIN Capture Code 41 | /* 27 */ {kDL_ISO8583_N , 1,kDL_ISO8583_FIXED }, // Authorization Identification Response Length 42 | /* 28 */ {kDL_ISO8583_XN , 9,kDL_ISO8583_FIXED }, // Amount, Txn Fee 43 | /* 29 */ {kDL_ISO8583_XN , 9,kDL_ISO8583_FIXED }, // Amount, Settlement Fee 44 | /* 30 */ {kDL_ISO8583_XN , 9,kDL_ISO8583_FIXED }, // Amount, Txn Processing Fee 45 | /* 31 */ {kDL_ISO8583_XN , 9,kDL_ISO8583_FIXED }, // Amount, Settlement Processing Fee 46 | /* 32 */ {kDL_ISO8583_N , 11,kDL_ISO8583_LLVAR }, // Acquirer Inst Id Code 47 | /* 33 */ {kDL_ISO8583_N , 11,kDL_ISO8583_LLVAR }, // Forwarding Inst Id Code 48 | /* 34 */ {kDL_ISO8583_NS , 28,kDL_ISO8583_LLVAR }, // Primary Account Number, Extended 49 | /* 35 */ {kDL_ISO8583_Z , 37,kDL_ISO8583_LLVAR }, // Track 2 Data 50 | /* 36 */ {kDL_ISO8583_AN ,104,kDL_ISO8583_LLLVAR }, // Track 3 Data 51 | /* 37 */ {kDL_ISO8583_AN , 12,kDL_ISO8583_FIXED }, // Retrieval Reference Number 52 | /* 38 */ {kDL_ISO8583_AN , 6,kDL_ISO8583_FIXED }, // Approval Code 53 | /* 39 */ {kDL_ISO8583_AN , 2,kDL_ISO8583_FIXED }, // Response Code 54 | /* 40 */ {kDL_ISO8583_ANS, 3,kDL_ISO8583_FIXED }, // Service Restriction Code 55 | /* 41 */ {kDL_ISO8583_ANS, 8,kDL_ISO8583_FIXED }, // Card Acceptor Terminal Id 56 | /* 42 */ {kDL_ISO8583_ANS, 15,kDL_ISO8583_FIXED }, // Card Acceptor Id Code 57 | /* 43 */ {kDL_ISO8583_ANS, 40,kDL_ISO8583_FIXED }, // Card Acceptor Name/Location 58 | /* 44 */ {kDL_ISO8583_ANS, 25,kDL_ISO8583_LLVAR }, // Additional Response Data 59 | /* 45 */ {kDL_ISO8583_ANS, 76,kDL_ISO8583_LLVAR }, // Track 1 Data 60 | /* 46 */ {kDL_ISO8583_ANS,999,kDL_ISO8583_LLLVAR }, // Additional Data - ISO 61 | /* 47 */ {kDL_ISO8583_ANS,128,kDL_ISO8583_LLLVAR }, // Additional Data - National 62 | /* 48 */ {kDL_ISO8583_N , 62,kDL_ISO8583_LLLVAR }, // Additional Data - Private 63 | /* 49 */ {kDL_ISO8583_ANS, 3,kDL_ISO8583_FIXED }, // Currency Code, Txn 64 | /* 50 */ {kDL_ISO8583_AN , 3,kDL_ISO8583_FIXED }, // Currency Code, Settlement 65 | /* 51 */ {kDL_ISO8583_AN , 3,kDL_ISO8583_FIXED }, // Currency Code, Cardholder Billing 66 | /* 52 */ {kDL_ISO8583_B , 8,kDL_ISO8583_FIXED }, // Personal Id Number (PIN) Data 67 | /* 53 */ {kDL_ISO8583_N , 16,kDL_ISO8583_FIXED }, // Security Related Control Information 68 | /* 54 */ {kDL_ISO8583_ANS, 20,kDL_ISO8583_LLLVAR }, // Amounts, Additional 69 | /* 55 */ {kDL_ISO8583_B ,255,kDL_ISO8583_LLLVAR }, // IC card data 70 | /* 56 */ {kDL_ISO8583_ANS,999,kDL_ISO8583_LLLVAR }, // Reserved for ISO use 71 | /* 57 */ {kDL_ISO8583_ANS,999,kDL_ISO8583_LLLVAR }, // Reserved for National use 72 | /* 58 */ {kDL_ISO8583_ANS,999,kDL_ISO8583_LLLVAR }, // Reserved for National use 73 | /* 59 */ {kDL_ISO8583_ANS,999,kDL_ISO8583_LLLVAR }, // Reserved for National use 74 | /* 60 */ {kDL_ISO8583_N, 20,kDL_ISO8583_LLLVAR }, // Reserved for Private use 75 | /* 61 */ {kDL_ISO8583_N, 29,kDL_ISO8583_LLLVAR }, // Reserved for Private use 76 | /* 62 */ {kDL_ISO8583_ANSB,400,kDL_ISO8583_LLLVAR }, // Reserved for Private use 77 | /* 63 */ {kDL_ISO8583_ANS, 99,kDL_ISO8583_LLLVAR }, // Reserved for Private use 78 | /* 64 */ {kDL_ISO8583_B , 8,kDL_ISO8583_FIXED }, // Message Authentication Code Field 79 | }; 80 | 81 | /******************************************************************************/ 82 | 83 | void DL_ISO8583_DEFS_POS_GetHandler ( DL_ISO8583_HANDLER *oHandler ) 84 | { 85 | DL_ISO8583_COMMON_SetHandler(_iso8583_pos_fields, 86 | (DL_UINT8)(sizeof(_iso8583_pos_fields)/sizeof(DL_ISO8583_FIELD_DEF)), 87 | oHandler); 88 | 89 | return; 90 | } 91 | 92 | /******************************************************************************/ 93 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583_defs_pos.h: -------------------------------------------------------------------------------- 1 | // 2 | // dl_iso8583_defs_zhifu.h 3 | // iso8583_demo 4 | // 5 | // Created by mark zheng on 15/6/9. 6 | // Copyright (c) 2015年 paylab. All rights reserved. 7 | // 8 | 9 | #ifndef __iso8583_demo__dl_iso8583_defs_zhifu__ 10 | #define __iso8583_demo__dl_iso8583_defs_zhifu__ 11 | 12 | #include 13 | 14 | #include "dl_base.h" 15 | #include "dl_iso8583_common.h" 16 | 17 | /******************************************************************************/ 18 | 19 | // sets the specified handler 20 | void DL_ISO8583_DEFS_POS_GetHandler ( DL_ISO8583_HANDLER *oHandler ); 21 | 22 | /******************************************************************************/ 23 | 24 | #endif /* defined(__iso8583_demo__dl_iso8583_defs_zhifu__) */ 25 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_iso8583_fields.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* ISO8583 field packers / unpackers */ 26 | /* */ 27 | /******************************************************************************/ 28 | 29 | #ifndef __INC_DL_ISO8583_FIELDS 30 | #define __INC_DL_ISO8583_FIELDS 31 | 32 | #include "dl_base.h" 33 | #include "dl_err.h" 34 | #include "dl_mem.h" 35 | 36 | #include "dl_iso8583_common.h" 37 | 38 | /******************************************************************************/ 39 | 40 | DL_ERR _DL_ISO8583_FIELD_Pack ( DL_UINT16 iField, 41 | const DL_ISO8583_MSG *iMsg, 42 | const DL_ISO8583_HANDLER *iHandler, 43 | DL_UINT8 **ioPtr ); 44 | 45 | DL_ERR _DL_ISO8583_FIELD_Unpack ( DL_UINT16 iField, 46 | DL_ISO8583_MSG *ioMsg, 47 | const DL_ISO8583_HANDLER *iHandler, 48 | DL_UINT8 **ioPtr ); 49 | 50 | /******************************************************************************/ 51 | 52 | #endif /* __INC_DL_ISO8583_FIELDS */ 53 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_mem.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | 25 | #include "dl_mem.h" 26 | 27 | /******************************************************************************/ 28 | 29 | // allocates a chunk of memory 30 | // returns: error code 31 | DL_ERR DL_MEM_malloc ( DL_UINT32 iNumBytes, 32 | void **oPtr ) 33 | { 34 | DL_ERR err = 0; 35 | 36 | err = DL_MEM_callocWithInit(1,iNumBytes,oPtr); 37 | 38 | return err; 39 | } 40 | 41 | /* based on calloc - but does not indicate an error if 0 items requested 42 | NB also init's the array elements to 0 on success 43 | returns: 1 if ok / 0 otherwise */ 44 | DL_ERR DL_MEM_callocWithInit ( DL_UINT32 numItems, 45 | size_t itemSize, 46 | void **out ) 47 | { 48 | DL_ERR err = 0; 49 | 50 | /* init output params */ 51 | *out = NULL; 52 | 53 | /* attempt to allocate memory - if numItems > 0 */ 54 | if ( numItems > 0 ) 55 | { 56 | /* allocate array - with error check */ 57 | if ( (*out = (void*)calloc(numItems,itemSize)) == NULL ) 58 | { 59 | err = kDL_ERR_MEM_ALLOC; 60 | } 61 | else /* init array elements (to 0) */ 62 | { 63 | DL_MEM_memset(*out,0,numItems*itemSize); 64 | } 65 | } 66 | 67 | /* cleanup (on error) */ 68 | if ( err ) 69 | { 70 | DL_MEM_free(*out); 71 | } 72 | 73 | return err; 74 | } 75 | 76 | /******************************************************************************/ 77 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_mem.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | 25 | #ifndef __INC_DL_MEM 26 | #define __INC_DL_MEM 27 | 28 | #include "dl_base.h" 29 | #include "dl_err.h" 30 | 31 | #include 32 | 33 | /******************************************************************************/ 34 | // 35 | // ERROR CODES (1000-1019) 36 | // 37 | 38 | #define kDL_ERR_MEM_ALLOC (DL_ERR)(1000+0) 39 | 40 | /******************************************************************************/ 41 | 42 | #define DL_MEM_free(ptr)\ 43 | { if ( (ptr) != NULL ) { free(ptr) ; (ptr) = NULL ; } } 44 | 45 | /******************************************************************************/ 46 | 47 | #define DL_MEM_memset(ptr,value,numBytes)\ 48 | ((void)memset((void*)(ptr),(int)(value),(size_t)(numBytes))) 49 | 50 | #define DL_MEM_memcpy(toPtr,fromPtr,numBytes)\ 51 | ((void)memcpy((void*)(toPtr),(void*)(fromPtr),(size_t)(numBytes))) 52 | 53 | #define DL_MEM_memcmp(aPtr,bPtr,len)\ 54 | (memcmp((void*)(aPtr),(void*)(bPtr),(size_t)(len))) 55 | 56 | /******************************************************************************/ 57 | 58 | // allocates a chunk of memory 59 | // returns: error code 60 | DL_ERR DL_MEM_malloc ( DL_UINT32 iNumBytes, 61 | void **oPtr ); 62 | 63 | /* based on calloc - but does not indicate an error if 0 items requested 64 | NB also init's the array elements to 0 on success */ 65 | // returns: error code 66 | DL_ERR DL_MEM_callocWithInit ( DL_UINT32 numItems, 67 | size_t itemSize, 68 | void **out ); 69 | 70 | /******************************************************************************/ 71 | 72 | #endif /* __INC_DL_MEM */ 73 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_output.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2007-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Output Functions */ 26 | /* */ 27 | /******************************************************************************/ 28 | 29 | #include "dl_output.h" 30 | 31 | /******************************************************************************/ 32 | // 33 | // CONSTANTS 34 | // 35 | 36 | #define kDL_OUTPUT_HEX_COLS 16 37 | 38 | /******************************************************************************/ 39 | 40 | void DL_OUTPUT_Hex ( FILE *iOutFile, 41 | const char *_iEolStr, 42 | const DL_UINT8 *iPtr, 43 | DL_UINT32 iNumBytes ) 44 | { 45 | DL_UINT32 rowIdx, 46 | colIdx; 47 | const char *tmpEOL = _iEolStr == NULL ? "\n" : _iEolStr; 48 | 49 | for ( rowIdx=0 ; rowIdx<(iNumBytes+kDL_OUTPUT_HEX_COLS-1)/kDL_OUTPUT_HEX_COLS ; rowIdx++ ) 50 | { 51 | fprintf(iOutFile,"%08xh ",rowIdx*kDL_OUTPUT_HEX_COLS); 52 | 53 | /* output hex characters */ 54 | for ( colIdx=0 ; colIdx= iNumBytes ) 59 | fprintf(iOutFile," "); 60 | else 61 | fprintf(iOutFile,"%02x ",(int)(iPtr[offset])); 62 | } /* end-for (colIdx) */ 63 | 64 | /* output ascii characters (if printable) */ 65 | for ( colIdx=0 ; colIdx= iNumBytes ) 70 | fprintf(iOutFile," "); 71 | else if ( (iPtr[offset] >= 33) && (iPtr[offset] <= 126) ) 72 | fprintf(iOutFile,"%c",(char)(iPtr[offset])); 73 | else 74 | fprintf(iOutFile,"."); 75 | } /* end-for (colIdx) */ 76 | 77 | fprintf(iOutFile,"%s",tmpEOL); 78 | } /* end-for (rowIdx) */ 79 | 80 | return; 81 | } 82 | 83 | /******************************************************************************/ 84 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_output.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2007-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Output Functions */ 26 | /* */ 27 | /******************************************************************************/ 28 | 29 | #ifndef __INC_DL_OUTPUT 30 | #define __INC_DL_OUTPUT 31 | #include "dl_base.h" 32 | 33 | /******************************************************************************/ 34 | 35 | /* outputs the hex dump of the specified data (iPtr/iNumBytes) to the */ 36 | /* specified stream (iOutFile) */ 37 | /* NB '_iEolStr' defaults to '\n' if NULL */ 38 | /* returns: n/a */ 39 | void DL_OUTPUT_Hex ( FILE *iOutFile, 40 | const char *_iEolStr, 41 | const DL_UINT8 *iPtr, 42 | DL_UINT32 iNumBytes ); 43 | 44 | /******************************************************************************/ 45 | 46 | #endif /* __INC_DL_OUTPUT */ 47 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_time.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2004-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Date/Time module providing functionality for both UTC and Local values. */ 26 | /* Uses a standard Epoch of 1/1/1970 00:00:00 */ 27 | /* */ 28 | /* Provides full support if WIN32 is defined, otherwise defaults to GMT */ 29 | /* */ 30 | /******************************************************************************/ 31 | 32 | #ifndef __INC_DL_TIME 33 | #define __INC_DL_TIME 34 | 35 | #include "dl_base.h" 36 | #include "dl_mem.h" 37 | #include "dl_str.h" 38 | 39 | #include // included for 'time' 40 | 41 | #ifdef DL_WIN32 42 | #include 43 | #include 44 | #endif /* DL_WIN32 */ 45 | 46 | #ifdef DL_UNIX 47 | #include 48 | #endif /* DL_UNIX */ 49 | 50 | /******************************************************************************/ 51 | // 52 | // CONSTANTS 53 | // 54 | 55 | // indicates the length of a YYYYMMDDHHMISS format timestamp 56 | #define kDL_TIME_TIMESTAMP_LEN 14 57 | 58 | // indicates the length of a 'DD/MM/YYYY (HH:MI:SS)' format string 59 | #define kDL_TIME_FORMAT_STR_LEN 21 60 | 61 | // Day-of-Week definitions 62 | #define kDL_TIME_DOW_SUNDAY 0 63 | #define kDL_TIME_DOW_MONDAY 1 64 | #define kDL_TIME_DOW_TUESDAY 2 65 | #define kDL_TIME_DOW_WEDNESDAY 3 66 | #define kDL_TIME_DOW_THURSDAY 4 67 | #define kDL_TIME_DOW_FRIDAY 5 68 | #define kDL_TIME_DOW_SATURDAY 6 69 | 70 | // Month definitions 71 | #define kDL_TIME_MON_JANUARY 1 72 | #define kDL_TIME_MON_FEBRUARY 2 73 | #define kDL_TIME_MON_MARCH 3 74 | #define kDL_TIME_MON_APRIL 4 75 | #define kDL_TIME_MON_MAY 5 76 | #define kDL_TIME_MON_JUNE 6 77 | #define kDL_TIME_MON_JULY 7 78 | #define kDL_TIME_MON_AUGUST 8 79 | #define kDL_TIME_MON_SEPTEMBER 9 80 | #define kDL_TIME_MON_OCTOBER 10 81 | #define kDL_TIME_MON_NOVEMBER 11 82 | #define kDL_TIME_MON_DECEMBER 12 83 | 84 | /******************************************************************************/ 85 | // 86 | // TYPES 87 | // 88 | 89 | // Note: supports either Absolute or Day-in-Month modes 90 | struct DL_TIME_S 91 | { 92 | // Day-in-month mode: 93 | // 94 | // Identified by 'Year' = 0 95 | // 'dayOfWeek' indicates Sunday->Saturday 96 | // 'day' indicates week (1-5, where 5=last) 97 | // 98 | // e.g. Last Thursday of April... 99 | // 100 | // Year : 0 101 | // Month : 4 (April) 102 | // Day : 5 (Last) 103 | // DayOfWeek: 4 (Thursday) 104 | 105 | int year; /* 1970-2106 */ 106 | int month; /* 1-12, as per kDL_TIME_MON_* */ 107 | int day; /* 1-31 */ 108 | int hour; /* 0-23 */ 109 | int minute; /* 0-59 */ 110 | int second; /* 0-59 */ 111 | 112 | int _dayOfWeek; /* 0-6, as per kDL_TIME_DOW_* */ 113 | }; 114 | typedef struct DL_TIME_S DL_TIME; 115 | 116 | /******************************************************************************/ 117 | 118 | // returns: number of UTC seconds since epoch 119 | DL_UINT32 DL_TIME_GetUTCSeconds ( void ); 120 | 121 | /******************************************************************************/ 122 | 123 | // converts UTC seconds to local time structure 124 | void DL_TIME_ConvUTCSecondsToLocalStruct ( DL_UINT32 iUtcSecs, 125 | DL_TIME *oData ); 126 | 127 | // converts UTC seconds to local timestamp 128 | void DL_TIME_ConvUTCSecondsToLocalTimestamp ( DL_UINT32 iUtcSecs, 129 | char oTimestamp[] ); 130 | 131 | // converts UTC seconds to UTC time structure 132 | void DL_TIME_ConvUTCSecondsToUTCStruct ( DL_UINT32 iUtcSecs, 133 | DL_TIME *oData ); 134 | 135 | // converts UTC seconds to UTC timestamp 136 | void DL_TIME_ConvUTCSecondsToUTCTimestamp ( DL_UINT32 iUtcSecs, 137 | char oTimestamp[] ); 138 | 139 | /******************************************************************************/ 140 | 141 | // converts UTC timestamp to UTC seconds 142 | // returns: 1 if okay, 0 if error (ie invalid timestamp) 143 | int DL_TIME_ConvUTCTimestampToUTCSeconds ( const char iTimestamp[], 144 | DL_UINT32 *oUtcSecs ); 145 | 146 | /******************************************************************************/ 147 | 148 | // converts local timestamp to UTC seconds 149 | // returns: 1 if okay, 0 if error (ie invalid timestamp) 150 | int DL_TIME_ConvLocalTimestampToUTCSeconds ( const char iTimestamp[], 151 | DL_UINT32 *oUtcSecs ); 152 | 153 | /******************************************************************************/ 154 | 155 | // converts UTC seconds to a local time formatted string 156 | // NB ioFormatStr must point to at least kDL_TIME_FORMAT_STR_LEN byte of memory 157 | void DL_TIME_ConvUTCSecondsToLocalFormatStr ( DL_UINT32 iUtcSecs, 158 | char *ioFormatStr ); 159 | 160 | /******************************************************************************/ 161 | 162 | // adds the months (iNumMonths) to the date/time value (iSeconds) 163 | // outputs: oSeconds - updated value with months added 164 | // returns: 1 if success / 0 if error (ie would exceed max date/time) 165 | int _DL_TIME_AddMonths ( DL_UINT32 iSeconds, 166 | DL_UINT16 iNumMonths, 167 | DL_UINT32 *oSeconds ); 168 | 169 | /******************************************************************************/ 170 | 171 | // outputs the number of days based on the specified year and month 172 | void _DL_TIME_GetDaysInMonth ( int iMonth, 173 | int iYear, 174 | int *oDaysInMonth ); 175 | 176 | /******************************************************************************/ 177 | 178 | #endif /* __INC_DL_TIME */ 179 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_timer.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Timer Module - Providing millisecond level timer capabilities */ 26 | /* */ 27 | /* NB Rollover occurs after 49.7 days due to UINT32 precision */ 28 | /* */ 29 | /******************************************************************************/ 30 | 31 | #include "dl_timer.h" 32 | 33 | /******************************************************************************/ 34 | 35 | // returns: number of milliseconds 36 | static DL_UINT32 getMSec ( void ); 37 | 38 | /******************************************************************************/ 39 | 40 | void DL_TIMER_Start ( DL_TIMER *oTimer ) 41 | { 42 | /* init outputs */ 43 | DL_MEM_memset(oTimer,0,sizeof(DL_TIMER)); 44 | 45 | /* record seconds */ 46 | oTimer->sec = DL_TIME_GetUTCSeconds(); 47 | 48 | /* record micro-seconds */ 49 | oTimer->msec = getMSec(); 50 | 51 | return; 52 | } 53 | 54 | /******************************************************************************/ 55 | 56 | DL_UINT32 DL_TIMER_GetDuration ( DL_TIMER iTimer ) 57 | { 58 | DL_UINT32 durMs = 0; 59 | DL_TIMER tmpTimer; 60 | 61 | /* start temp timer (to determine current time) */ 62 | DL_TIMER_Start(&tmpTimer); 63 | 64 | /* calculate millisecond difference between current and original timer */ 65 | durMs = ( ((tmpTimer.sec - iTimer.sec) * 1000) + 66 | ((tmpTimer.msec - iTimer.msec) % 1000) ) 67 | & DL_MAX_UINT32; 68 | 69 | return durMs; 70 | } 71 | 72 | /******************************************************************************/ 73 | 74 | static DL_UINT32 getMSec ( void ) 75 | { 76 | DL_UINT32 ret = 0; 77 | 78 | #if defined(DL_WIN32) 79 | { 80 | ret = (DL_UINT32)(GetTickCount() % 1000); 81 | } 82 | #elif defined(DL_UNIX) 83 | { 84 | struct timeval tv; 85 | struct timezone tz; 86 | 87 | gettimeofday(&tv, &tz); 88 | 89 | ret = (DL_UINT32)((tv.tv_usec / 1000) % 1000); 90 | } 91 | #else 92 | #error Platform Not Supported 93 | #endif 94 | 95 | return ret; 96 | } 97 | 98 | /******************************************************************************/ 99 | -------------------------------------------------------------------------------- /PZ8583/8583/iso8583/dl_timer.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | /* */ 3 | /* Copyright (C) 2005-2007 Oscar Sanderson */ 4 | /* */ 5 | /* This software is provided 'as-is', without any express or implied */ 6 | /* warranty. In no event will the author(s) be held liable for any damages */ 7 | /* arising from the use of this software. */ 8 | /* */ 9 | /* Permission is granted to anyone to use this software for any purpose, */ 10 | /* including commercial applications, and to alter it and redistribute it */ 11 | /* freely, subject to the following restrictions: */ 12 | /* */ 13 | /* 1. The origin of this software must not be misrepresented; you must not */ 14 | /* claim that you wrote the original software. If you use this software */ 15 | /* in a product, an acknowledgment in the product documentation would be */ 16 | /* appreciated but is not required. */ 17 | /* */ 18 | /* 2. Altered source versions must be plainly marked as such, and must not be */ 19 | /* misrepresented as being the original software. */ 20 | /* */ 21 | /* 3. This notice may not be removed or altered from any source distribution. */ 22 | /* */ 23 | /******************************************************************************/ 24 | /* */ 25 | /* Timer Module - Providing millisecond level timer capabilities */ 26 | /* */ 27 | /* NB Rollover occurs after 49.7 days due to UINT32 precision */ 28 | /* */ 29 | /******************************************************************************/ 30 | 31 | #ifndef __INC_DL_TIMER 32 | #define __INC_DL_TIMER 33 | 34 | #include "dl_base.h" 35 | #include "dl_mem.h" 36 | #include "dl_time.h" // for second level date/time 37 | 38 | #ifdef DL_WIN32 39 | #include 40 | #include 41 | #endif 42 | 43 | #ifdef DL_UNIX 44 | #include 45 | #include 46 | #endif 47 | 48 | /******************************************************************************/ 49 | // 50 | // TYPES 51 | // 52 | 53 | struct DL_TIMER_S 54 | { 55 | DL_UINT32 sec; 56 | DL_UINT32 msec; 57 | }; 58 | typedef struct DL_TIMER_S DL_TIMER; 59 | 60 | /******************************************************************************/ 61 | 62 | // Starts/Initialises the specified timer instance 63 | void DL_TIMER_Start ( DL_TIMER *oTimer ); 64 | 65 | /******************************************************************************/ 66 | 67 | // Returns the duration of the specified timer (in Ms) 68 | // NB can be called multiple times, to obtain durations at different points 69 | // for the same timer instance 70 | DL_UINT32 DL_TIMER_GetDuration ( DL_TIMER iTimer ); 71 | 72 | /******************************************************************************/ 73 | 74 | #endif /* __INC_DL_TIMER */ 75 | -------------------------------------------------------------------------------- /PZ8583/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PZ8583 4 | // 5 | // Created by mark zheng on 15/7/17. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /PZ8583/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PZ8583 4 | // 5 | // Created by mark zheng on 15/7/17. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /PZ8583/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PZ8583/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PZ8583/CocoaAsyncSocket/README.markdown: -------------------------------------------------------------------------------- 1 | CocoaAsyncSocket provides easy-to-use and powerful asynchronous socket libraries for Mac and iOS. The classes are described below. 2 | 3 | ## TCP 4 | 5 | **GCDAsyncSocket** and **AsyncSocket** are TCP/IP socket networking libraries. Here are the key features available in both: 6 | 7 | - Native objective-c, fully self-contained in one class.
8 | _No need to muck around with sockets or streams. This class handles everything for you._ 9 | 10 | - Full delegate support
11 | _Errors, connections, read completions, write completions, progress, and disconnections all result in a call to your delegate method._ 12 | 13 | - Queued non-blocking reads and writes, with optional timeouts.
14 | _You tell it what to read or write, and it handles everything for you. Queueing, buffering, and searching for termination sequences within the stream - all handled for you automatically._ 15 | 16 | - Automatic socket acceptance.
17 | _Spin up a server socket, tell it to accept connections, and it will call you with new instances of itself for each connection._ 18 | 19 | - Support for TCP streams over IPv4 and IPv6.
20 | _Automatically connect to IPv4 or IPv6 hosts. Automatically accept incoming connections over both IPv4 and IPv6 with a single instance of this class. No more worrying about multiple sockets._ 21 | 22 | - Support for TLS / SSL
23 | _Secure your socket with ease using just a single method call. Available for both client and server sockets._ 24 | 25 | **GCDAsyncSocket** is built atop Grand Central Dispatch: 26 | 27 | - Fully GCD based and Thread-Safe
28 | _It runs entirely within its own GCD dispatch_queue, and is completely thread-safe. Further, the delegate methods are all invoked asynchronously onto a dispatch_queue of your choosing. This means parallel operation of your socket code, and your delegate/processing code._ 29 | 30 | - The Latest Technology & Performance Optimizations
31 | _Internally the library takes advantage of technologies such as [kqueue's](http://en.wikipedia.org/wiki/Kqueue) to limit [system calls](http://en.wikipedia.org/wiki/System_call) and optimize buffer allocations. In other words, peak performance._ 32 | 33 | **AsyncSocket** wraps CFSocket and CFStream: 34 | 35 | - Fully Run-loop based
36 | _Use it on the main thread or a worker thread. It plugs into the NSRunLoop with configurable modes._ 37 | 38 | ## UDP 39 | 40 | **GCDAsyncUdpSocket** and **AsyncUdpSocket** are UDP/IP socket networking libraries. Here are the key features available in both: 41 | 42 | - Native objective-c, fully self-contained in one class.
43 | _No need to muck around with low-level sockets. This class handles everything for you._ 44 | 45 | - Full delegate support.
46 | _Errors, send completions, receive completions, and disconnections all result in a call to your delegate method._ 47 | 48 | - Queued non-blocking send and receive operations, with optional timeouts.
49 | _You tell it what to send or receive, and it handles everything for you. Queueing, buffering, waiting and checking errno - all handled for you automatically._ 50 | 51 | - Support for IPv4 and IPv6.
52 | _Automatically send/recv using IPv4 and/or IPv6. No more worrying about multiple sockets._ 53 | 54 | **GCDAsyncUdpSocket** is built atop Grand Central Dispatch: 55 | 56 | - Fully GCD based and Thread-Safe
57 | _It runs entirely within its own GCD dispatch_queue, and is completely thread-safe. Further, the delegate methods are all invoked asynchronously onto a dispatch_queue of your choosing. This means parallel operation of your socket code, and your delegate/processing code._ 58 | 59 | **AsyncUdpSocket** wraps CFSocket: 60 | 61 | - Fully Run-loop based
62 | _Use it on the main thread or a worker thread. It plugs into the NSRunLoop with configurable modes._ 63 | 64 | *** 65 | 66 | Can't find the answer to your question in any of the [wiki](https://github.com/robbiehanson/CocoaAsyncSocket/wiki) articles? Try the **[mailing list](http://groups.google.com/group/cocoaasyncsocket)**. 67 |
68 |
69 | Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](http://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2M8C699FQ8AW2) 70 | 71 | -------------------------------------------------------------------------------- /PZ8583/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /PZ8583/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.codefunny.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /PZ8583/PLSocketCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // PLSocketCenter.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void (^finishRecvDataFromPosp)(NSData *pospData,NSError *error); 12 | 13 | @interface PLSocketCenter : NSObject 14 | 15 | + (instancetype)defaultCenter; 16 | 17 | - (BOOL)startStop; 18 | 19 | - (BOOL)isConnected; 20 | - (void)didDisconnected; 21 | 22 | - (void)sendDataToServer:(NSData *)data finishCallBack:(finishRecvDataFromPosp)block; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /PZ8583/PLSocketCenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // PLSocketCenter.m 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/1. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import "PLSocketCenter.h" 10 | #import "AsyncSocket.h" 11 | #import "GCDAsyncSocket.h" 12 | 13 | #import "PZMessageUtils.h" 14 | 15 | #define FORMAT(format, ...) [NSString stringWithFormat:(format), ##__VA_ARGS__] 16 | 17 | static NSString *const kPospServerIP = @"127.0.0.1"; 18 | static NSInteger kPospServerPort = 10002; 19 | 20 | @interface PLSocketCenter () 21 | 22 | @property(nonatomic,strong)AsyncSocket* socket; 23 | @property(nonatomic,strong)NSCondition* condition; 24 | @property(nonatomic,assign)BOOL isRecving; 25 | @property(nonatomic,strong)NSData* recvData; 26 | 27 | @property (nonatomic,copy) finishRecvDataFromPosp finishDataFromPosp; 28 | 29 | @end 30 | 31 | @implementation PLSocketCenter 32 | 33 | + (instancetype)defaultCenter { 34 | static PLSocketCenter *instance = nil; 35 | static dispatch_once_t onceToken; 36 | dispatch_once(&onceToken, ^{ 37 | instance = [[[self class] alloc] init]; 38 | }); 39 | 40 | return instance; 41 | } 42 | 43 | - (id)init 44 | { 45 | if((self = [super init])) 46 | { 47 | _socket = [[AsyncSocket alloc] initWithDelegate:self]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)dealloc { 53 | [self.socket disconnect]; 54 | self.socket = nil; 55 | 56 | _condition = nil; 57 | } 58 | 59 | - (void)logError:(NSString *)msg 60 | { 61 | [self logMessage:msg]; 62 | } 63 | 64 | - (void)logInfo:(NSString *)msg 65 | { 66 | [self logMessage:msg]; 67 | } 68 | 69 | - (void)logMessage:(NSString *)msg 70 | { 71 | 72 | NSLog(@"log:%@",msg); 73 | } 74 | 75 | - (BOOL)startStop 76 | { 77 | NSError *error; 78 | BOOL result = [self.socket connectToHost:kPospServerIP onPort:kPospServerPort error:&error]; 79 | if (!result) { 80 | [self logError:FORMAT(@"%@",error)]; 81 | } 82 | _condition = [[NSCondition alloc] init]; 83 | 84 | return result; 85 | } 86 | 87 | - (BOOL)isConnected { 88 | return [self.socket isConnected]; 89 | } 90 | 91 | - (void)didDisconnected { 92 | // if ([self.socket isConnected]) { 93 | [self.socket disconnect]; 94 | // } 95 | } 96 | 97 | - (void)sendDataToServer:(NSData *)data finishCallBack:(finishRecvDataFromPosp)block { 98 | self.finishDataFromPosp = block; 99 | __weak typeof(self) weakSelf = self; 100 | dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 101 | dispatch_async(dispatch_get_main_queue(),^{ 102 | NSInteger dataLen = data.length; 103 | NSString *hexStr = [NSString stringWithFormat:@"%04lx",(long)dataLen]; 104 | NSData *msgLen = [PZMessageUtils hexToBytes:hexStr]; 105 | 106 | NSMutableData *sendData = [NSMutableData data]; 107 | [sendData appendData:msgLen]; 108 | [sendData appendData:data]; 109 | [weakSelf.socket writeData:sendData withTimeout:10 tag:0]; 110 | [weakSelf.socket readDataWithTimeout:-1 tag:0]; 111 | }); 112 | }); 113 | 114 | self.isRecving = true; 115 | } 116 | 117 | #pragma mark - AsyncSocketDelegate 118 | 119 | /*将要建立连接*/ 120 | -(BOOL)onSocketWillConnect:(AsyncSocket *)sock { 121 | NSLog(@"onSocketWillConnect:"); 122 | return YES; 123 | } 124 | 125 | /*成功建立连接*/ 126 | -(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port 127 | { 128 | NSLog(@"didConnectToHost"); 129 | } 130 | 131 | /*错误,断开连接*/ 132 | -(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err 133 | { 134 | NSLog(@"willDisconnectWithError:%@",err); 135 | } 136 | 137 | /*断开连接*/ 138 | -(void)onSocketDidDisconnect:(AsyncSocket *)sock 139 | { 140 | NSLog(@"onSocketDidDisconnect"); 141 | self.isRecving = NO; 142 | } 143 | 144 | /* 145 | * 成功接收数据 146 | */ 147 | -(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 148 | { 149 | NSLog(@"接收数据:%@",data); 150 | if ([self isRecving]==YES) { 151 | self.recvData = data; 152 | self.isRecving = NO; 153 | if (self.finishDataFromPosp) { 154 | self.finishDataFromPosp(self.recvData,nil); 155 | } 156 | } 157 | 158 | NSString *readData = [PZMessageUtils hexStringFromData:data]; 159 | [self logMessage:readData]; 160 | } 161 | 162 | /*成功写入数据*/ 163 | -(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag 164 | { 165 | NSLog(@"didWriteDataWithTag:%ld",tag); 166 | } 167 | 168 | - (void)readDataWithTimeout:(GCDAsyncSocket *)sock withError:(NSError *)err 169 | { 170 | NSLog(@"网络链接失败!"); 171 | if (self.finishDataFromPosp) { 172 | self.finishDataFromPosp(nil,err); 173 | } 174 | } 175 | 176 | @end 177 | -------------------------------------------------------------------------------- /PZ8583/PZTransService.h: -------------------------------------------------------------------------------- 1 | // 2 | // PZTransService.h 3 | // PaylabMPos 4 | // 5 | // Created by mark zheng on 15/6/18. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "PLSocketCenter.h" 11 | 12 | @class PZPosField; 13 | @interface PZTransService : NSObject 14 | 15 | @property (nonatomic,strong) PLSocketCenter *sockMgr; 16 | 17 | @property (nonatomic,strong) NSString *pinKey; 18 | @property (nonatomic,strong) NSString *macKey; 19 | @property (nonatomic,strong) NSString *trkKey; 20 | 21 | @property (nonatomic,strong) NSString *masterKey; 22 | @property (nonatomic,strong) NSString *posKey; 23 | 24 | @property (nonatomic,strong) PZPosField *fields; 25 | @property (nonatomic,strong) PZPosField *uploadSign; 26 | 27 | + (instancetype)instance; 28 | 29 | //终端工作密钥 30 | - (void)mposGetWorkKeyFromServerWithBlock:(void(^)(NSString *text))display; 31 | 32 | //POS状态上送(IC公钥) 33 | - (void)mposGetPosICKeyFromServer ; 34 | 35 | //POS状态上送(IC参数) 36 | - (void)mposGetPosICParamFromServer ; 37 | 38 | //POS参数下载 39 | - (void)mposGetICKeyFromServer; 40 | 41 | //消费交易 42 | - (void)mposPurchaseFromServerWithBlock:(void(^)(NSString *text))display; 43 | 44 | //余额查询 45 | - (void)mposBalanceFromServerWithBlock:(void(^)(NSString *text))display; 46 | 47 | //冲正 48 | - (void)mposReverseFromServerWithBlock:(void(^)(NSString *text))display; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /PZ8583/UIViewExt.h: -------------------------------------------------------------------------------- 1 | /* 2 | Erica Sadun, http://ericasadun.com 3 | iPhone Developer's Cookbook, 3.0 Edition 4 | BSD License, Use at your own risk 5 | */ 6 | 7 | #import 8 | 9 | CGPoint CGRectGetCenter(CGRect rect); 10 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center); 11 | 12 | @interface UIView (ViewFrameGeometry) 13 | @property CGPoint origin; 14 | @property CGSize size; 15 | 16 | @property (readonly) CGPoint bottomLeft; 17 | @property (readonly) CGPoint bottomRight; 18 | @property (readonly) CGPoint topRight; 19 | 20 | @property CGFloat height; 21 | @property CGFloat width; 22 | 23 | @property CGFloat top; 24 | @property CGFloat left; 25 | 26 | @property CGFloat bottom; 27 | @property CGFloat right; 28 | 29 | - (void) moveBy: (CGPoint) delta; 30 | - (void) scaleBy: (CGFloat) scaleFactor; 31 | - (void) fitInSize: (CGSize) aSize; 32 | @end -------------------------------------------------------------------------------- /PZ8583/UIViewExt.m: -------------------------------------------------------------------------------- 1 | /* 2 | Erica Sadun, http://ericasadun.com 3 | iPhone Developer's Cookbook, 3.0 Edition 4 | BSD License, Use at your own risk 5 | */ 6 | 7 | #import "UIViewExt.h" 8 | 9 | CGPoint CGRectGetCenter(CGRect rect) 10 | { 11 | CGPoint pt; 12 | pt.x = CGRectGetMidX(rect); 13 | pt.y = CGRectGetMidY(rect); 14 | return pt; 15 | } 16 | 17 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center) 18 | { 19 | CGRect newrect = CGRectZero; 20 | newrect.origin.x = center.x-CGRectGetMidX(rect); 21 | newrect.origin.y = center.y-CGRectGetMidY(rect); 22 | newrect.size = rect.size; 23 | return newrect; 24 | } 25 | 26 | @implementation UIView (ViewGeometry) 27 | 28 | // Retrieve and set the origin 29 | - (CGPoint) origin 30 | { 31 | return self.frame.origin; 32 | } 33 | 34 | - (void) setOrigin: (CGPoint) aPoint 35 | { 36 | CGRect newframe = self.frame; 37 | newframe.origin = aPoint; 38 | self.frame = newframe; 39 | } 40 | 41 | 42 | // Retrieve and set the size 43 | - (CGSize) size 44 | { 45 | return self.frame.size; 46 | } 47 | 48 | - (void) setSize: (CGSize) aSize 49 | { 50 | CGRect newframe = self.frame; 51 | newframe.size = aSize; 52 | self.frame = newframe; 53 | } 54 | 55 | // Query other frame locations 56 | - (CGPoint) bottomRight 57 | { 58 | CGFloat x = self.frame.origin.x + self.frame.size.width; 59 | CGFloat y = self.frame.origin.y + self.frame.size.height; 60 | return CGPointMake(x, y); 61 | } 62 | 63 | - (CGPoint) bottomLeft 64 | { 65 | CGFloat x = self.frame.origin.x; 66 | CGFloat y = self.frame.origin.y + self.frame.size.height; 67 | return CGPointMake(x, y); 68 | } 69 | 70 | - (CGPoint) topRight 71 | { 72 | CGFloat x = self.frame.origin.x + self.frame.size.width; 73 | CGFloat y = self.frame.origin.y; 74 | return CGPointMake(x, y); 75 | } 76 | 77 | 78 | // Retrieve and set height, width, top, bottom, left, right 79 | - (CGFloat) height 80 | { 81 | return self.frame.size.height; 82 | } 83 | 84 | - (void) setHeight: (CGFloat) newheight 85 | { 86 | CGRect newframe = self.frame; 87 | newframe.size.height = newheight; 88 | self.frame = newframe; 89 | } 90 | 91 | - (CGFloat) width 92 | { 93 | return self.frame.size.width; 94 | } 95 | 96 | - (void) setWidth: (CGFloat) newwidth 97 | { 98 | CGRect newframe = self.frame; 99 | newframe.size.width = newwidth; 100 | self.frame = newframe; 101 | } 102 | 103 | - (CGFloat) top 104 | { 105 | return self.frame.origin.y; 106 | } 107 | 108 | - (void) setTop: (CGFloat) newtop 109 | { 110 | CGRect newframe = self.frame; 111 | newframe.origin.y = newtop; 112 | self.frame = newframe; 113 | } 114 | 115 | - (CGFloat) left 116 | { 117 | return self.frame.origin.x; 118 | } 119 | 120 | - (void) setLeft: (CGFloat) newleft 121 | { 122 | CGRect newframe = self.frame; 123 | newframe.origin.x = newleft; 124 | self.frame = newframe; 125 | } 126 | 127 | - (CGFloat) bottom 128 | { 129 | return self.frame.origin.y + self.frame.size.height; 130 | } 131 | 132 | - (void) setBottom: (CGFloat) newbottom 133 | { 134 | CGRect newframe = self.frame; 135 | newframe.origin.y = newbottom - self.frame.size.height; 136 | self.frame = newframe; 137 | } 138 | 139 | - (CGFloat) right 140 | { 141 | return self.frame.origin.x + self.frame.size.width; 142 | } 143 | 144 | - (void) setRight: (CGFloat) newright 145 | { 146 | CGFloat delta = newright - (self.frame.origin.x + self.frame.size.width); 147 | CGRect newframe = self.frame; 148 | newframe.origin.x += delta ; 149 | self.frame = newframe; 150 | } 151 | 152 | // Move via offset 153 | - (void) moveBy: (CGPoint) delta 154 | { 155 | CGPoint newcenter = self.center; 156 | newcenter.x += delta.x; 157 | newcenter.y += delta.y; 158 | self.center = newcenter; 159 | } 160 | 161 | // Scaling 162 | - (void) scaleBy: (CGFloat) scaleFactor 163 | { 164 | CGRect newframe = self.frame; 165 | newframe.size.width *= scaleFactor; 166 | newframe.size.height *= scaleFactor; 167 | self.frame = newframe; 168 | } 169 | 170 | // Ensure that both dimensions fit within the given size by scaling down 171 | - (void) fitInSize: (CGSize) aSize 172 | { 173 | CGFloat scale; 174 | CGRect newframe = self.frame; 175 | 176 | if (newframe.size.height && (newframe.size.height > aSize.height)) 177 | { 178 | scale = aSize.height / newframe.size.height; 179 | newframe.size.width *= scale; 180 | newframe.size.height *= scale; 181 | } 182 | 183 | if (newframe.size.width && (newframe.size.width >= aSize.width)) 184 | { 185 | scale = aSize.width / newframe.size.width; 186 | newframe.size.width *= scale; 187 | newframe.size.height *= scale; 188 | } 189 | 190 | self.frame = newframe; 191 | } 192 | @end -------------------------------------------------------------------------------- /PZ8583/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PZ8583 4 | // 5 | // Created by mark zheng on 15/7/17. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /PZ8583/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PZ8583 4 | // 5 | // Created by mark zheng on 15/7/17. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PZ8583Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.codefunny.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /PZ8583Tests/PZ8583Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PZ8583Tests.m 3 | // PZ8583Tests 4 | // 5 | // Created by mark zheng on 15/7/17. 6 | // Copyright (c) 2015年 codefunny. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface PZ8583Tests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation PZ8583Tests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ObjC-PZ8583 2 | 3 | --- 4 | ObjC-PZ8583是基于BerTlv和Oscar-ISO8583的基础上进行的iOS封装,底层8583的打包和拆包使用了C语言的Oscar-ISO8583版本,为了适应开发需求,进行了Objective-C的封装,使得使用起来更方便一些,目前在国内这方面的资源还是非常罕见的,在对该代码开源的过程中,我进行了一些删减的工作,主要是一些非银联常见做法的接口,所以大家还是先了解自己的需求,进行一些微调之后再使用。 5 | 6 | # 开源 7 | 8 | --- 9 | 在开发过程中得益于开源的贡献,大大的帮助了我的开发,这几年在支付领域的开发经验,使我对这方面可能更熟悉一点,所以拿出来晒一晒,如果对你有帮助,欢迎收藏,如有一些好的意见,欢迎加我QQ:504299929讨论。 10 | 11 | # 使用说明 12 | 13 | --- 14 | 比如签到交易,大家可以在PZTransService中看到 15 | 16 | ``` 17 | - (void)mposGetWorkKeyFromServerWithBlock:(void(^)(NSString *text))display { 18 | display(@"----------------签到-------------"); 19 | // NSString *lmk = @"a2dff4e59289a82fc740f4f4e5d997e6"; 20 | NSString *lmk = self.masterKey; 21 | BOOL ret =[self.sockMgr startStop]; 22 | if (ret ) { 23 | PZSignInRequest *request = [PZSignInRequest new]; 24 | [request.posFields setTranTtc:self.transTtc]; 25 | [request.posFields setTerminalId:self.terminalId]; 26 | [request.posFields setMerchantId:self.merchantId]; 27 | PZPrivateField60 *field60 = [PZPrivateField60 new]; 28 | field60.msgType = kSignInField60MsgType; 29 | field60.batchNumber = self.batchNumber; 30 | field60.networkCode = kSignInField60Network; 31 | [request.posFields setPrivate60:[field60 encode]]; 32 | [request setOprNumber:@"01 "]; 33 | 34 | NSData *data = [request encode]; 35 | NSLog(@"send:%@",data); 36 | 37 | display(request.posFields.description); 38 | 39 | __block NSData *recvData = nil; 40 | [self.sockMgr sendDataToServer:data finishCallBack:^(NSData *pospData,NSError *error){ 41 | if (!error) { 42 | recvData = [pospData subdataWithRange:NSMakeRange(2, pospData.length -2)]; 43 | 44 | PZSignInResponse *signResp = [PZSignInResponse new]; 45 | [signResp decode:recvData]; 46 | 47 | display(signResp.posFields.description); 48 | 49 | if ([signResp.respCode isEqualToString:kResponseCodeSuccess00]) { 50 | NSLog(@"%@",[signResp.private62 description]); 51 | PZPrivateField62 *field62 = signResp.private62; 52 | NSString *pinKey = [NSString decrypt3Des:field62.pinKey withKey:lmk]; 53 | NSString *macKey = [NSString decrypt3Des:field62.macKey withKey:lmk]; 54 | NSString *trkKey = [NSString decrypt3Des:field62.trkKey withKey:lmk]; 55 | 56 | NSString *pinCheck = [NSString encrypt3Des:@"0000000000000000" withKey:pinKey]; 57 | NSString *macCheck = [NSString encrypt3Des:@"0000000000000000" withKey:macKey]; 58 | NSString *trkCheck = [NSString encrypt3Des:@"0000000000000000" withKey:trkKey]; 59 | 60 | NSLog(@"pinkey:%@,check:%@;macKey:%@,check:%@;trkKey:%@,check:%@",pinKey,pinCheck,macKey,macCheck,trkKey,trkCheck); 61 | NSString *log = [NSString stringWithFormat:@"%@\npinkey:%@,check:%@;macKey:%@,check:%@;trkKey:%@,check:%@",[signResp.private62 description],pinKey,pinCheck,macKey,macCheck,trkKey,trkCheck]; 62 | display(log); 63 | 64 | self.pinKey = pinKey; 65 | self.macKey = macKey; 66 | self.trkKey = trkKey; 67 | 68 | } else { 69 | NSLog(@"response:%@",signResp.respCode); 70 | } 71 | } 72 | [self.sockMgr didDisconnected]; 73 | }]; 74 | } 75 | } 76 | 77 | ``` 78 | 79 | # 补充 80 | 近日有不少人来问,35域问题,有些35域不是加密处理的,如果遇到该问题,请找到下面代码 81 | ``` 82 | static DL_ISO8583_TYPE fieldTypeArr[] = { 83 | /* ISO_N */ {_unpack_iso_ASCHEX,_pack_iso_ASCHEX}, 84 | /* ISO_NS */ {_unpack_iso_BINARY,_pack_iso_BINARY}, 85 | /* ISO_XN */ {_unpack_iso_ASCHEX,_pack_iso_ASCHEX}, 86 | /* ISO_A */ {_unpack_iso_ASCII ,_pack_iso_ASCII }, 87 | /* ISO_AN */ {_unpack_iso_ASCII ,_pack_iso_ASCII }, 88 | /* ISO_ANS */ {_unpack_iso_ASCII ,_pack_iso_ASCII }, 89 | /* ISO_ANSB */ {_unpack_iso_ASCII ,_pack_iso_ASCII }, 90 | /* ISO_ANP */ {_unpack_iso_ASCII ,_pack_iso_ASCII }, 91 | /* ISO_B */ {_unpack_iso_BINARY,_pack_iso_BINARY}, 92 | /* ISO_Z */ {_unpack_iso_BINARY,_pack_iso_BINARY}, 93 | /* ISO_BMAP */ {_unpack_iso_BITMAP,_pack_iso_BITMAP} }; 94 | ``` 95 | 将/* ISO_Z    */ {_unpack_iso_BINARY,_pack_iso_BINARY},这一行改为 /* ISO_Z    */ {_unpack_iso_ASCHEX,_pack_iso_ASCHEX},即可。 96 | 97 | # License 98 | 99 | --- 100 | 101 | MTI 102 | --------------------------------------------------------------------------------